This repository has been archived by the owner on Sep 12, 2021. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 66
/
weather.dm
220 lines (204 loc) · 6.84 KB
/
weather.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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/**
* Causes weather to occur on a z level in certain area types
*
* The effects of weather occur across an entire z-level. For instance, lavaland has periodic ash storms that scorch most unprotected creatures.
* Weather always occurs on different z levels at different times, regardless of weather type.
* Can have custom durations, targets, and can automatically protect indoor areas.
*
*/
/datum/weather
/// name of weather
var/name = "space wind"
/// description of weather
var/desc = "Heavy gusts of wind blanket the area, periodically knocking down anyone caught in the open."
/// The message displayed in chat to foreshadow the weather's beginning
var/telegraph_message = "<span class='warning'>The wind begins to pick up.</span>"
/// In deciseconds, how long from the beginning of the telegraph until the weather begins
var/telegraph_duration = 300
/// The sound file played to everyone on an affected z-level
var/telegraph_sound
/// The overlay applied to all tiles on the z-level
var/telegraph_overlay
/// Displayed in chat once the weather begins in earnest
var/weather_message = "<span class='userdanger'>The wind begins to blow ferociously!</span>"
/// In deciseconds, how long the weather lasts once it begins
var/weather_duration = 1200
/// See above - this is the lowest possible duration
var/weather_duration_lower = 1200
/// See above - this is the highest possible duration
var/weather_duration_upper = 1500
/// Looping sound while weather is occuring
var/weather_sound
/// Area overlay while the weather is occuring
var/weather_overlay
/// Color to apply to the area while weather is occuring
var/weather_color = null
/// Displayed once the weather is over
var/end_message = "<span class='danger'>The wind relents its assault.</span>"
/// In deciseconds, how long the "wind-down" graphic will appear before vanishing entirely
var/end_duration = 300
/// Sound that plays while weather is ending
var/end_sound
/// Area overlay while weather is ending
var/end_overlay
/// Types of area to affect
var/area_type = /area/space
/// TRUE value protects areas with outdoors marked as false, regardless of area type
var/protect_indoors = FALSE
/// Areas to be affected by the weather, calculated when the weather begins
var/list/impacted_areas = list()
/// Areas that are protected and excluded from the affected areas.
var/list/protected_areas = list()
/// The list of z-levels that this weather is actively affecting
var/impacted_z_levels
/// 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.
var/overlay_layer = AREA_LAYER
/// Plane for the overlay
var/overlay_plane = BLACKNESS_PLANE
/// If the weather has no purpose other than looks
var/aesthetic = FALSE
/// Used by mobs to prevent them from being affected by the weather
var/immunity_type = "storm"
/// The stage of the weather, from 1-4
var/stage = END_STAGE
/// Weight amongst other eligible weather. If zero, will never happen randomly.
var/probability = 0
/// The z-level trait to affect when run randomly or when not overridden.
var/target_trait = ZTRAIT_STATION
/// Whether a barometer can predict when the weather will happen
var/barometer_predictable = FALSE
/// For barometers to know when the next storm will hit
var/next_hit_time = 0
/datum/weather/New(z_levels)
..()
impacted_z_levels = z_levels
/**
* Telegraphs the beginning of the weather on the impacted z levels
*
* Sends sounds and details to mobs in the area
* Calculates duration and hit areas, and makes a callback for the actual weather to start
*
*/
/datum/weather/proc/telegraph()
if(stage == STARTUP_STAGE)
return
stage = STARTUP_STAGE
var/list/affectareas = list()
for(var/V in get_areas(area_type))
affectareas += V
for(var/V in protected_areas)
affectareas -= get_areas(V)
for(var/V in affectareas)
var/area/A = V
if(protect_indoors && !A.outdoors)
continue
if(A.z in impacted_z_levels)
impacted_areas |= A
weather_duration = rand(weather_duration_lower, weather_duration_upper)
START_PROCESSING(SSweather, src)
update_areas()
for(var/M in GLOB.player_list)
var/turf/mob_turf = get_turf(M)
if(mob_turf && (mob_turf.z in impacted_z_levels))
if(telegraph_message)
to_chat(M, telegraph_message)
if(telegraph_sound)
SEND_SOUND(M, sound(telegraph_sound))
addtimer(CALLBACK(src, .proc/start), telegraph_duration)
/**
* Starts the actual weather and effects from it
*
* Updates area overlays and sends sounds and messages to mobs to notify them
* Begins dealing effects from weather to mobs in the area
*
*/
/datum/weather/proc/start()
if(stage >= MAIN_STAGE)
return
stage = MAIN_STAGE
update_areas()
for(var/M in GLOB.player_list)
var/turf/mob_turf = get_turf(M)
if(mob_turf && (mob_turf.z in impacted_z_levels))
if(weather_message)
to_chat(M, weather_message)
if(weather_sound)
SEND_SOUND(M, sound(weather_sound))
addtimer(CALLBACK(src, .proc/wind_down), weather_duration)
/**
* Weather enters the winding down phase, stops effects
*
* Updates areas to be in the winding down phase
* Sends sounds and messages to mobs to notify them
*
*/
/datum/weather/proc/wind_down()
if(stage >= WIND_DOWN_STAGE)
return
stage = WIND_DOWN_STAGE
update_areas()
for(var/M in GLOB.player_list)
var/turf/mob_turf = get_turf(M)
if(mob_turf && (mob_turf.z in impacted_z_levels))
if(end_message)
to_chat(M, end_message)
if(end_sound)
SEND_SOUND(M, sound(end_sound))
addtimer(CALLBACK(src, .proc/end), end_duration)
/**
* Fully ends the weather
*
* Effects no longer occur and area overlays are removed
* Removes weather from processing completely
*
*/
/datum/weather/proc/end()
if(stage == END_STAGE)
return 1
stage = END_STAGE
STOP_PROCESSING(SSweather, src)
update_areas()
/**
* Returns TRUE if the living mob can be affected by the weather
*
*/
/datum/weather/proc/can_weather_act(mob/living/L)
var/turf/mob_turf = get_turf(L)
if(mob_turf && !(mob_turf.z in impacted_z_levels))
return
if(immunity_type in L.weather_immunities)
return
if(!(get_area(L) in impacted_areas))
return
return TRUE
/**
* Affects the mob with whatever the weather does
*
*/
/datum/weather/proc/weather_act(mob/living/L)
return
/**
* Updates the overlays on impacted areas
*
*/
/datum/weather/proc/update_areas()
for(var/V in impacted_areas)
var/area/N = V
N.layer = overlay_layer
N.plane = overlay_plane
N.icon = 'icons/effects/weather_effects.dmi'
N.color = weather_color
switch(stage)
if(STARTUP_STAGE)
N.icon_state = telegraph_overlay
if(MAIN_STAGE)
N.icon_state = weather_overlay
if(WIND_DOWN_STAGE)
N.icon_state = end_overlay
if(END_STAGE)
N.color = null
N.icon_state = ""
N.icon = 'icons/turf/areas.dmi'
N.layer = initial(N.layer)
N.plane = initial(N.plane)
N.set_opacity(FALSE)