@@ -20,28 +20,46 @@ var/list/weathertracker = list() //associative list, gathers time spent one each
20
20
var /datum /weather/current_weather
21
21
var /list /datum/weather/forecasts = list ()
22
22
var /cycle_freq = list (3 MINUTES ,6 MINUTES ) // shortest possible time, longest possible time until next weather
23
+ var /z // z-level the climate is occupying
24
+ var /list /allowed_weather_types = list () // List of weather types this climate can have
25
+ var /list /weather_transitions = list () // Associative list: weather_type = list(possible_transitions)
26
+ var /list /weather_intensities = list () // Associative list: weather_type = intensity_level
27
+ var /starting_weather_type = null // The initial weather type for this climate
23
28
24
- / datum / climate/ New()
29
+ / datum / climate/ New(var / active_z )
25
30
.. ()
26
- if (current_weather)
31
+ if (active_z)
32
+ z = active_z
33
+ else
34
+ z = map. zMainStation
35
+ setup_weather_system ()
36
+ if (starting_weather_type)
37
+ current_weather = new starting_weather_type(src )
27
38
forecast ()
28
39
else
29
40
WARNING (" Climate tried to forecast without a starting weather." )
30
41
message_admins (" Climate tried to forecast without a starting weather." )
31
42
43
+ // Override this in climate subtypes to define the weather system
44
+ / datum / climate/ proc / setup_weather_system()
45
+ return
46
+
32
47
/ datum / climate/ proc / forecast()
33
48
var /cycle = 1
34
49
clear_forecast ()
35
50
forecasts = list (current_weather) // project based on current weather
36
51
while (forecasts. len <= PREDICTION_MINIMUM + 1 && cycle <= PREDICTION_MAXIMUM )
37
52
var /datum /weather/W = forecasts[forecasts. len]
38
- var /path = pickweight(W. next_weather)
53
+ var /list /possible_transitions = weather_transitions[W. type]
54
+ if (! possible_transitions || ! possible_transitions. len)
55
+ break // No further transitions possible
56
+ var /path = pickweight(possible_transitions)
39
57
if (path == W. type)
40
58
W. timeleft += round(rand(cycle_freq[1 ],cycle_freq[2 ]),SS_WAIT_WEATHER )
41
59
else
42
60
var /datum /weather/future = new path(src )
43
61
forecasts += future
44
- if (W . next_weather . len == 1 )
62
+ if (possible_transitions . len == 1 )
45
63
break // Forecast no further.
46
64
cycle++
47
65
forecasts -= current_weather // remove it from our future weather
@@ -57,7 +75,7 @@ var/list/weathertracker = list() //associative list, gathers time spent one each
57
75
return
58
76
current_weather. tick()
59
77
if (current_weather. timeleft <= 0 )
60
- change_weather (forecasts[1 ])
78
+ change_weather (forecasts[1 ],force = TRUE )
61
79
forecasts -= forecasts[1 ]
62
80
if (forecasts. len < PREDICTION_MINIMUM )
63
81
forecast ()
@@ -69,59 +87,106 @@ var/list/weathertracker = list() //associative list, gathers time spent one each
69
87
if (direction** 2 != 1 )
70
88
return INVALID_STEP // must be 1 or -1
71
89
if (current_weather)
72
- var /weathers = current_weather. next_weather. len
73
- if (weathers == 1 )
90
+ var /current_intensity = weather_intensities[current_weather. type]
91
+ if (isnull(current_intensity))
92
+ return CANNOT_CHANGE
93
+ var /target_intensity = current_intensity + direction
94
+ var /preferred_weather = null
95
+ for (var /weather_type in allowed_weather_types)
96
+ if (weather_intensities[weather_type] == target_intensity)
97
+ var /list /possible_transitions = weather_transitions[current_weather. type]
98
+ if (possible_transitions && (weather_type in possible_transitions))
99
+ preferred_weather = weather_type
100
+ break
101
+ if (! preferred_weather)
74
102
return CANNOT_CHANGE
75
- var /preferred_weather
76
- if (direction == INTENSIFY )
77
- preferred_weather = current_weather. next_weather[weathers] // the last value
78
- else if (direction == ABATE )
79
- preferred_weather = current_weather. next_weather[1 ] // the first value
80
103
if (preferred_weather == current_weather. type)
81
104
return FALSE
82
105
current_weather. timeleft = min(1 MINUTES , current_weather. timeleft)
83
- current_weather. next_weather. Cut()
84
- current_weather. next_weather[preferred_weather] = 100
106
+ var /list /old_transitions = weather_transitions[current_weather. type]
107
+ weather_transitions[current_weather. type] = list ()
108
+ weather_transitions[current_weather. type][preferred_weather] = 100
85
109
forecast ()
110
+ weather_transitions[current_weather. type] = old_transitions
86
111
return TRUE
87
112
88
- / datum / climate/ proc / change_weather(weather)
113
+ / datum / climate/ proc / change_weather(weather, force = FALSE )
89
114
if (ispath(weather))
90
115
// We have been provided a path. Let's see if it's identical to the one we have.
91
116
if (ispath(weather, current_weather. type)) // This is a separate check so that we can have our warning work.
92
117
return // No need to change, this is our current type.
93
118
else
94
- qdel (current_weather)
95
- current_weather = new weather(src )
96
- current_weather. execute()
119
+ if (force)
120
+ qdel (current_weather)
121
+ current_weather = new weather(src )
122
+ current_weather. execute()
123
+ else
124
+ weather_transitions[current_weather. type] = list (weather = 100 )
97
125
98
126
else if (istype(weather,/ datum / weather))
99
127
// We have been given a specific weather datum. It may be modified, so run it no matter what.
100
- qdel (current_weather)
101
- current_weather = weather
102
- current_weather. execute()
128
+ if (force)
129
+ qdel (current_weather)
130
+ current_weather = weather
131
+ current_weather. execute()
132
+ else
133
+ var /datum /weather/W = weather
134
+ weather_transitions[current_weather. type] = list (W. type = 100 )
103
135
104
136
else
105
137
WARNING (" Change weather was called with [ weather] , neither a weather datum nor a path." )
106
138
107
139
/ datum / climate/ arctic
108
140
name = " snow" // what scoreboard displays
109
- // some day this may not be the norm
141
+
142
+ starting_weather_type = / datum / weather/ snow/ calm
143
+ allowed_weather_types = list (
144
+ / datum / weather/ snow/ calm,
145
+ / datum / weather/ snow/ light,
146
+ / datum / weather/ snow/ heavy,
147
+ / datum / weather/ snow/ blizzard,
148
+ / datum / weather/ snow/ blizzard/ omega
149
+ )
150
+ weather_intensities = list (
151
+ / datum / weather/ snow/ calm = 0 ,
152
+ / datum / weather/ snow/ light = 1 ,
153
+ / datum / weather/ snow/ heavy = 2 ,
154
+ / datum / weather/ snow/ blizzard = 3 ,
155
+ / datum / weather/ snow/ blizzard/ omega = 4
156
+ )
157
+ weather_transitions = list (
158
+ / datum / weather/ snow/ calm = list (
159
+ / datum / weather/ snow/ calm = 60 ,
160
+ / datum / weather/ snow/ light = 40
161
+ ),
162
+ / datum / weather/ snow/ light = list (
163
+ / datum / weather/ snow/ calm = 25 ,
164
+ / datum / weather/ snow/ light = 55 ,
165
+ / datum / weather/ snow/ heavy = 20
166
+ ),
167
+ / datum / weather/ snow/ heavy = list (
168
+ / datum / weather/ snow/ light = 30 ,
169
+ / datum / weather/ snow/ heavy = 60 ,
170
+ / datum / weather/ snow/ blizzard = 10
171
+ ),
172
+ / datum / weather/ snow/ blizzard = list (
173
+ / datum / weather/ snow/ heavy = 65 ,
174
+ / datum / weather/ snow/ blizzard = 35
175
+ ),
176
+ / datum / weather/ snow/ blizzard/ omega = list (
177
+ / datum / weather/ snow/ heavy = 100
178
+ )
179
+ )
110
180
111
181
/ datum / climate/ arctic/ New()
112
- current_weather = new / datum / weather / snow / calm( src )
182
+ .. ( )
113
183
if (! blizzard_image)
114
- blizzard_image = new
184
+ blizzard_image = new ( src )
115
185
blizzard_image. UpdateSnowfall(SNOW_CALM )
116
- .. ()
117
186
118
187
// ///////////////////////////////// WEATHER DATUMS //////////////////////////////
119
-
120
188
/ datum / weather
121
189
var /name = " weather"
122
- var /list /next_weather = list () // associative list
123
- // for next_weather, order matters: put in order of weather intensity, so that step() will work
124
- // only one in list means it can't be changed by the weather control device
125
190
var /timeleft = 1
126
191
var /datum /climate/parent
127
192
var /temperature = T20C
@@ -141,13 +206,19 @@ var/list/global_snowtiles = list()
141
206
var /list /environment_snowtiles = list ()
142
207
var /list /snow_state_to_texture = list ()
143
208
209
+ / datum / weather/ proc / weather_details()
210
+ return // additional info to report to the climate computer
211
+
144
212
/ datum / weather/ snow
145
213
var /snow_intensity = SNOW_CALM
146
214
var /tile_interval = 5
147
215
var /snowfall_prob = 0
148
216
var /snowfall_rate = list (0 ,0 )
149
217
var /snow_fluff_estimate = " snowing"
150
218
219
+ / datum / weather/ snow/ weather_details()
220
+ return " <b>Snowfall:</b> <div class='line'>[ snow_fluff_estimate] </div>"
221
+
151
222
var /obj /effect/blizzard_holder/blizzard_image = null
152
223
153
224
/ datum / weather/ snow/ New(var /datum /climate/C )
@@ -190,7 +261,6 @@ var/list/snowstorm_ambience_volumes = list(30,40,60,80)
190
261
/ datum / weather/ snow/ calm
191
262
name = " calm"
192
263
snow_intensity = SNOW_CALM
193
- next_weather = list (/ datum / weather/ snow/ calm = 60 , / datum / weather/ snow/ light = 40 )
194
264
snowfall_prob = 3
195
265
snowfall_rate = list (- 1 ,0 )
196
266
temperature = T_ARCTIC
@@ -205,7 +275,6 @@ var/list/snowstorm_ambience_volumes = list(30,40,60,80)
205
275
/ datum / weather/ snow/ light
206
276
name = " light"
207
277
snow_intensity = SNOW_AVERAGE
208
- next_weather = list (/ datum / weather/ snow/ calm = 25 , / datum / weather/ snow/ light = 55 , / datum / weather/ snow/ heavy = 20 )
209
278
snowfall_prob = 5
210
279
snowfall_rate = list (1 ,8 )
211
280
temperature = T_ARCTIC - 5
@@ -220,7 +289,6 @@ var/list/snowstorm_ambience_volumes = list(30,40,60,80)
220
289
/ datum / weather/ snow/ heavy
221
290
name = " <font color='orange'>heavy</font>"
222
291
snow_intensity = SNOW_HARD
223
- next_weather = list (/ datum / weather/ snow/ light = 30 , / datum / weather/ snow/ heavy = 60 , / datum / weather/ snow/ blizzard = 10 )
224
292
snowfall_prob = 8
225
293
snowfall_rate = list (2 ,15 )
226
294
temperature = T_ARCTIC - 10
@@ -235,7 +303,6 @@ var/list/snowstorm_ambience_volumes = list(30,40,60,80)
235
303
/ datum / weather/ snow/ blizzard
236
304
name = " <font color='red'>blizzard</font>"
237
305
snow_intensity = SNOW_BLIZZARD
238
- next_weather = list (/ datum / weather/ snow/ heavy = 65 , / datum / weather/ snow/ blizzard = 35 )
239
306
tile_interval = 3
240
307
snowfall_prob = 12
241
308
snowfall_rate = list (3 ,20 )
@@ -250,7 +317,6 @@ var/list/snowstorm_ambience_volumes = list(30,40,60,80)
250
317
251
318
/ datum / weather/ snow/ blizzard/ omega
252
319
name = " <font color='purple'>dark season</font>"
253
- next_weather = list (/ datum / weather/ snow/ heavy = 100 )
254
320
snowfall_prob = 15
255
321
snow_fluff_estimate = " <font color='purple'>more than 13.5cm/minute (Dark Season)</font>"
256
322
0 commit comments