-
-
Notifications
You must be signed in to change notification settings - Fork 444
/
Copy pathCaveGenerator.dm
172 lines (143 loc) · 7.36 KB
/
CaveGenerator.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/datum/map_generator/cave_generator
var/name = "Cave Generator"
///Weighted list of the types that spawns if the turf is open
var/weighted_open_turf_types = list(/turf/open/floor/plating/asteroid/airless = 1)
///Expanded list of the types that spawns if the turf is open
var/open_turf_types
///Weighted list of the types that spawns if the turf is closed
var/weighted_closed_turf_types = list(/turf/closed/mineral/random = 1)
///Expanded list of the types that spawns if the turf is closed
var/closed_turf_types
///If this is set to TRUE then it will only change turfs that are /turf/open/genturf, for more flexability in design
var/gen_gurf_only = TRUE
///Weighted list of mobs that can spawn in the area.
var/list/weighted_mob_spawn_list
///Expanded list of mobs that can spawn in the area. Reads from the weighted list
var/list/mob_spawn_list
///The mob spawn list but with no megafauna markers. autogenerated
var/list/mob_spawn_no_mega_list
// Weighted list of Megafauna that can spawn in the area
var/list/weighted_megafauna_spawn_list
///Expanded list of Megafauna that can spawn in the area. Reads from the weighted list
var/list/megafauna_spawn_list
///Weighted list of flora that can spawn in the area.
var/list/weighted_flora_spawn_list
///Expanded list of flora that can spawn in the area. Reads from the weighted list
var/list/flora_spawn_list
///Weighted list of extra features that can spawn in the area, such as geysers.
var/list/weighted_feature_spawn_list
///Expanded list of extra features that can spawn in the area. Reads from the weighted list
var/list/feature_spawn_list
///Base chance of spawning a mob
var/mob_spawn_chance = 6
///Base chance of spawning flora
var/flora_spawn_chance = 2
///Base chance of spawning features
var/feature_spawn_chance = 0.1
///Unique ID for this spawner
var/string_gen
///Chance of cells starting closed
var/initial_closed_chance = 45
///Amount of smoothing iterations
var/smoothing_iterations = 20
///How much neighbours does a dead cell need to become alive
var/birth_limit = 4
///How little neighbours does a alive cell need to die
var/death_limit = 3
/datum/map_generator/cave_generator/New()
. = ..()
if(!weighted_mob_spawn_list)
weighted_mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goldgrub = 1, /mob/living/simple_animal/hostile/asteroid/goliath = 5, /mob/living/simple_animal/hostile/asteroid/basilisk = 4, /mob/living/simple_animal/hostile/asteroid/hivelord = 3)
mob_spawn_list = expand_weights(weighted_mob_spawn_list)
mob_spawn_no_mega_list = expand_weights(weighted_mob_spawn_list - SPAWN_MEGAFAUNA)
if(!weighted_megafauna_spawn_list)
weighted_megafauna_spawn_list = GLOB.megafauna_spawn_list
megafauna_spawn_list = expand_weights(weighted_megafauna_spawn_list)
if(!weighted_flora_spawn_list)
weighted_flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2, /obj/structure/flora/ash/seraka = 2)
flora_spawn_list = expand_weights(weighted_flora_spawn_list)
if(!weighted_feature_spawn_list)
weighted_feature_spawn_list = list() // yogs - no geysers in asteroid caves
feature_spawn_list = expand_weights(weighted_feature_spawn_list)
open_turf_types = expand_weights(weighted_open_turf_types)
closed_turf_types = expand_weights(weighted_closed_turf_types)
/datum/map_generator/cave_generator/generate_terrain(list/turfs, area/generate_in)
. = ..()
if(!(generate_in.area_flags & CAVES_ALLOWED))
return
var/start_time = REALTIMEOFDAY
string_gen = rustg_cnoise_generate("[initial_closed_chance]", "[smoothing_iterations]", "[birth_limit]", "[death_limit]", "[world.maxx]", "[world.maxy]") //Generate the raw CA data
// Area var pullouts to make accessing in the loop faster
var/flora_allowed = (generate_in.area_flags & FLORA_ALLOWED) && length(flora_spawn_list)
var/feature_allowed = (generate_in.area_flags & FLORA_ALLOWED) && length(feature_spawn_list)
var/mobs_allowed = (generate_in.area_flags & MOB_SPAWN_ALLOWED) && length(mob_spawn_list)
var/megas_allowed = (generate_in.area_flags & MEGAFAUNA_SPAWN_ALLOWED) && length(megafauna_spawn_list)
for(var/i in turfs) //Go through all the turfs and generate them
var/turf/gen_turf = i
if(gen_gurf_only && !istype(gen_turf, /turf/open/genturf))
continue
if(istype(gen_turf, /turf/closed/mineral))
continue
var/closed = string_gen[world.maxx * (gen_turf.y - 1) + gen_turf.x] != "0"
var/turf/new_turf = pick(closed ? closed_turf_types : open_turf_types)
// The assumption is this will be faster then changeturf, and changeturf isn't required since by this point
// The old tile hasn't got the chance to init yet
new_turf = new new_turf(gen_turf)
if(gen_turf.turf_flags & NO_RUINS)
new_turf.turf_flags |= NO_RUINS
if(closed) //Open turfs have some special behavior related to spawning flora and mobs.
CHECK_TICK
continue
// If we've spawned something yet
var/spawned_something = FALSE
///Spawning isn't done in procs to save on overhead on the 60k turfs we're going through.
//FLORA SPAWNING HERE
if(flora_allowed && prob(flora_spawn_chance))
var/flora_type = pick(flora_spawn_list)
new flora_type(new_turf)
spawned_something = TRUE
//FEATURE SPAWNING HERE
if(feature_allowed && prob(feature_spawn_chance))
var/can_spawn = TRUE
var/atom/picked_feature = pick(feature_spawn_list)
for(var/obj/structure/existing_feature in range(7, new_turf))
if(istype(existing_feature, picked_feature))
can_spawn = FALSE
break
if(can_spawn)
new picked_feature(new_turf)
spawned_something = TRUE
//MOB SPAWNING HERE
if(mobs_allowed && !spawned_something && prob(mob_spawn_chance))
var/atom/picked_mob = pick(mob_spawn_list)
if(picked_mob == SPAWN_MEGAFAUNA)
if(megas_allowed) //this is danger. it's boss time.
picked_mob = pick(megafauna_spawn_list)
else //this is not danger, don't spawn a boss, spawn something else
picked_mob = pick(mob_spawn_no_mega_list) //What if we used 100% of the brain...and did something (slightly) less shit than a while loop?
var/can_spawn = TRUE
//avoid spawning if there's another hostile nearby within 12 tiles
for(var/mob/living/simple_animal/hostile/asteroid/mob_blocker in urange(12, new_turf))
can_spawn = FALSE
break
// prevents mobs from spawning within 2 tiles of a spawner
if(can_spawn)
for(var/obj/structure/spawner/lavaland/spawn_blocker in range(2, new_turf))
can_spawn = FALSE
break
//if there's a megafauna within standard view don't spawn anything at all (This isn't really consistent, I don't know why we do this. you do you tho)
if(can_spawn)
for(var/mob/living/simple_animal/hostile/megafauna/found_fauna in range(7, new_turf))
can_spawn = FALSE
break
if(can_spawn)
if(ispath(picked_mob, /mob/living/simple_animal/hostile/megafauna/bubblegum)) //there can be only one bubblegum, so don't waste spawns on it
weighted_megafauna_spawn_list.Remove(picked_mob)
megafauna_spawn_list = expand_weights(weighted_megafauna_spawn_list)
megas_allowed = megas_allowed && length(megafauna_spawn_list)
new picked_mob(new_turf)
spawned_something = TRUE
CHECK_TICK
var/message = "[name] finished in [(REALTIMEOFDAY - start_time)/10]s!"
to_chat(world, span_boldannounce("[message]"))
log_world(message)