|
59 | 59 | /// Since it's above everything else, this is the layer used by default. TURF_LAYER is below mobs and walls if you need to use that.
|
60 | 60 | var/overlay_layer = AREA_LAYER
|
61 | 61 | /// Plane for the overlay
|
62 |
| - var/overlay_plane = ABOVE_LIGHTING_PLANE |
| 62 | + var/overlay_plane = AREA_PLANE |
63 | 63 | /// If the weather has no purpose other than looks
|
64 | 64 | var/aesthetic = FALSE
|
65 | 65 | /// Used by mobs (or movables containing mobs, such as enviro bags) to prevent them from being affected by the weather.
|
66 | 66 | var/immunity_type
|
| 67 | + /// If this bit of weather should also draw an overlay that's uneffected by lighting onto the area |
| 68 | + /// Taken from weather_glow.dmi |
| 69 | + var/use_glow = TRUE |
| 70 | + /// List of all overlays to apply to our turfs |
| 71 | + var/list/overlay_cache |
67 | 72 |
|
68 | 73 | /// The stage of the weather, from 1-4
|
69 | 74 | var/stage = END_STAGE
|
|
94 | 99 | /datum/weather/proc/telegraph(get_to_the_good_part)
|
95 | 100 | if(stage == STARTUP_STAGE)
|
96 | 101 | return
|
| 102 | + |
97 | 103 | SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_TELEGRAPH(type))
|
98 | 104 | stage = STARTUP_STAGE
|
| 105 | + |
99 | 106 | var/list/affectareas = list()
|
100 | 107 | for(var/V in get_areas(area_type))
|
101 | 108 | affectareas += V
|
| 109 | + |
102 | 110 | for(var/V in protected_areas)
|
103 | 111 | affectareas -= get_areas(V)
|
| 112 | + |
104 | 113 | for(var/V in affectareas)
|
105 | 114 | var/area/A = V
|
106 | 115 | if(protect_indoors && !A.outdoors)
|
107 | 116 | continue
|
108 | 117 | if(A.z in impacted_z_levels)
|
109 | 118 | impacted_areas |= A
|
| 119 | + |
110 | 120 | weather_duration = rand(weather_duration_lower, weather_duration_upper)
|
111 | 121 | SSweather.processing |= src
|
112 | 122 | update_areas()
|
113 |
| - if(!get_to_the_good_part) |
114 |
| - for(var/z_level in impacted_z_levels) |
115 |
| - for(var/mob/player as anything in SSmobs.clients_by_zlevel[z_level]) |
116 |
| - var/turf/mob_turf = get_turf(player) |
117 |
| - if(!mob_turf) |
118 |
| - continue |
119 |
| - if(telegraph_message) |
120 |
| - to_chat(player, telegraph_message) |
121 |
| - if(telegraph_sound) |
122 |
| - SEND_SOUND(player, sound(telegraph_sound)) |
123 |
| - addtimer(CALLBACK(src, PROC_REF(start)), telegraph_duration) |
124 |
| - else |
| 123 | + |
| 124 | + if(get_to_the_good_part) |
125 | 125 | start()
|
| 126 | + else |
| 127 | + send_alert(telegraph_message, telegraph_sound) |
| 128 | + addtimer(CALLBACK(src, PROC_REF(start)), telegraph_duration) |
126 | 129 |
|
127 | 130 | /**
|
128 | 131 | * Starts the actual weather and effects from it
|
|
134 | 137 | /datum/weather/proc/start()
|
135 | 138 | if(stage >= MAIN_STAGE)
|
136 | 139 | return
|
| 140 | + |
137 | 141 | SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_START(type))
|
| 142 | + |
138 | 143 | stage = MAIN_STAGE
|
139 | 144 | update_areas()
|
140 |
| - for(var/z_level in impacted_z_levels) |
141 |
| - for(var/mob/player as anything in SSmobs.clients_by_zlevel[z_level]) |
142 |
| - var/turf/mob_turf = get_turf(player) |
143 |
| - if(!mob_turf) |
144 |
| - continue |
145 |
| - if(weather_message) |
146 |
| - to_chat(player, weather_message) |
147 |
| - if(weather_sound) |
148 |
| - SEND_SOUND(player, sound(weather_sound)) |
| 145 | + |
| 146 | + send_alert(weather_message, weather_sound) |
149 | 147 | if(!perpetual)
|
150 | 148 | addtimer(CALLBACK(src, PROC_REF(wind_down)), weather_duration)
|
151 | 149 |
|
|
159 | 157 | /datum/weather/proc/wind_down()
|
160 | 158 | if(stage >= WIND_DOWN_STAGE)
|
161 | 159 | return
|
| 160 | + |
162 | 161 | SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_WINDDOWN(type))
|
163 | 162 | stage = WIND_DOWN_STAGE
|
| 163 | + |
164 | 164 | update_areas()
|
165 |
| - for(var/z_level in impacted_z_levels) |
166 |
| - for(var/mob/player as anything in SSmobs.clients_by_zlevel[z_level]) |
167 |
| - var/turf/mob_turf = get_turf(player) |
168 |
| - if(!mob_turf) |
169 |
| - continue |
170 |
| - if(end_message) |
171 |
| - to_chat(player, end_message) |
172 |
| - if(end_sound) |
173 |
| - SEND_SOUND(player, sound(end_sound)) |
| 165 | + |
| 166 | + send_alert(end_message, end_sound) |
174 | 167 | addtimer(CALLBACK(src, PROC_REF(end)), end_duration)
|
175 | 168 |
|
176 | 169 | /**
|
|
183 | 176 | /datum/weather/proc/end()
|
184 | 177 | if(stage == END_STAGE)
|
185 | 178 | return
|
| 179 | + |
186 | 180 | SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_END(type))
|
187 | 181 | stage = END_STAGE
|
| 182 | + |
188 | 183 | SSweather.processing -= src
|
189 | 184 | update_areas()
|
190 | 185 |
|
| 186 | +/datum/weather/proc/send_alert(alert_msg, alert_sfx) |
| 187 | + for(var/z_level in impacted_z_levels) |
| 188 | + for(var/mob/player as anything in SSmobs.clients_by_zlevel[z_level]) |
| 189 | + if(!can_get_alert(player)) |
| 190 | + continue |
| 191 | + |
| 192 | + if(telegraph_message) |
| 193 | + to_chat(player, alert_msg) |
| 194 | + |
| 195 | + if(telegraph_sound) |
| 196 | + SEND_SOUND(player, sound(alert_sfx)) |
| 197 | + |
| 198 | +// the checks for if a mob should recieve alerts, returns TRUE if can |
| 199 | +/datum/weather/proc/can_get_alert(mob/player) |
| 200 | + var/turf/mob_turf = get_turf(player) |
| 201 | + return !isnull(mob_turf) |
| 202 | + |
191 | 203 | /**
|
192 | 204 | * Returns TRUE if the living mob can be affected by the weather
|
193 | 205 | *
|
|
227 | 239 | *
|
228 | 240 | */
|
229 | 241 | /datum/weather/proc/update_areas()
|
230 |
| - for(var/V in impacted_areas) |
231 |
| - var/area/N = V |
232 |
| - N.layer = overlay_layer |
233 |
| - N.plane = overlay_plane |
234 |
| - N.icon = 'icons/effects/weather_effects.dmi' |
235 |
| - N.color = weather_color |
236 |
| - switch(stage) |
237 |
| - if(STARTUP_STAGE) |
238 |
| - N.icon_state = telegraph_overlay |
239 |
| - if(MAIN_STAGE) |
240 |
| - N.icon_state = weather_overlay |
241 |
| - if(WIND_DOWN_STAGE) |
242 |
| - N.icon_state = end_overlay |
243 |
| - if(END_STAGE) |
244 |
| - N.color = null |
245 |
| - N.icon_state = "" |
246 |
| - N.icon = null |
247 |
| - N.layer = initial(N.layer) |
248 |
| - N.plane = initial(N.plane) |
249 |
| - N.set_opacity(FALSE) |
| 242 | + var/list/new_overlay_cache = generate_overlay_cache() |
| 243 | + for(var/area/impacted as anything in impacted_areas) |
| 244 | + if(length(overlay_cache)) |
| 245 | + impacted.overlays -= overlay_cache |
| 246 | + if(length(new_overlay_cache)) |
| 247 | + impacted.overlays += new_overlay_cache |
| 248 | + |
| 249 | + overlay_cache = new_overlay_cache |
| 250 | + |
| 251 | +/// Returns a list of visual offset -> overlays to use |
| 252 | +/datum/weather/proc/generate_overlay_cache() |
| 253 | + // We're ending, so no overlays at all |
| 254 | + if(stage == END_STAGE) |
| 255 | + return list() |
| 256 | + |
| 257 | + var/weather_state = "" |
| 258 | + switch(stage) |
| 259 | + if(STARTUP_STAGE) |
| 260 | + weather_state = telegraph_overlay |
| 261 | + if(MAIN_STAGE) |
| 262 | + weather_state = weather_overlay |
| 263 | + if(WIND_DOWN_STAGE) |
| 264 | + weather_state = end_overlay |
| 265 | + |
| 266 | + var/list/gen_overlay_cache = list() |
| 267 | + if(use_glow) |
| 268 | + var/mutable_appearance/glow_image = mutable_appearance('icons/effects/glow_weather.dmi', weather_state, overlay_layer, ABOVE_LIGHTING_PLANE, 100) |
| 269 | + glow_image.color = weather_color |
| 270 | + gen_overlay_cache += glow_image |
| 271 | + |
| 272 | + var/mutable_appearance/weather_image = mutable_appearance('icons/effects/weather_effects.dmi', weather_state, overlay_layer, plane = overlay_plane) |
| 273 | + weather_image.color = weather_color |
| 274 | + gen_overlay_cache += weather_image |
| 275 | + |
| 276 | + return gen_overlay_cache |
0 commit comments