1 #include "Font_Control.h"
2 #include "Lighting.h"
3 #include "Environment.h"
4 #include "RenderWorld.h"
5 #include "Sound_Control.h"
6 #include "Overhead.h"
7 #include "Game_Clock.h"
8 #include "Quests.h"
9 #include "Ambient_Control.h"
10 #include "AIMMembers.h"
11 #include "Strategic_Event_Handler.h"
12 #include "BobbyR.h"
13 #include "Mercs.h"
14 #include "Merc_Hiring.h"
15 #include "Insurance_Contract.h"
16 #include "Strategic_Merc_Handler.h"
17 #include "Game_Events.h"
18 #include "Message.h"
19 #include "OppList.h"
20 #include "Random.h"
21 #include "StrategicMap.h"
22 #include "SoundMan.h"
23
24
25 //effects whether or not time of day effects the lighting. Underground
26 //maps have an ambient light level that is saved in the map, and doesn't change.
27 BOOLEAN gfBasement = FALSE;
28 BOOLEAN gfCaves = FALSE;
29
30 /*
31 #define DAWNLIGHT_START ( 5 * 60 )
32 #define DAWN_START ( 6 * 60 )
33 #define DAY_START ( 8 * 60 )
34 #define TWILLIGHT_START ( 19 * 60 )
35 #define DUSK_START ( 20 * 60 )
36 #define NIGHT_START ( 22 * 60 )
37 */
38 #define DAWN_START ( 6 * 60 + 47 ) //6:47AM
39 #define DAY_START ( 7 * 60 + 5 ) //7:05AM
40 #define DUSK_START ( 20 * 60 + 57 ) //8:57PM
41 #define NIGHT_START ( 21 * 60 + 15 ) //9:15PM
42
43 #define DAWN_TO_DAY (DAY_START-DAWN_START)
44 #define DAY_TO_DUSK (DUSK_START-DAY_START)
45 #define DUSK_TO_NIGHT (NIGHT_START-DUSK_START)
46 #define NIGHT_TO_DAWN (24*60-NIGHT_START+DAWN_START)
47
48 UINT32 guiEnvWeather = 0;
49 UINT32 guiRainLoop = NO_SAMPLE;
50
51
52 // frame cues for lightning
53 UINT8 ubLightningTable[3][10][2] = {
54 {
55 {0, 15},
56 {1, 0},
57 {2, 0},
58 {3, 6},
59 {4, 0},
60 {5, 0},
61 {6, 0},
62 {7, 0},
63 {8, 0},
64 {9, 0}
65 },
66
67 {
68 {0, 15},
69 {1, 0},
70 {2, 0},
71 {3, 6},
72 {4, 0},
73 {5, 15},
74 {6, 0},
75 {7, 6},
76 {8, 0},
77 {9, 0}
78 },
79
80 {
81 {0, 15},
82 {1, 0},
83 {2, 15},
84 {3, 0},
85 {4, 0},
86 {5, 0},
87 {6, 0},
88 {7, 0},
89 {8, 0},
90 {9, 0}
91 }
92 };
93
94
95 enum Temperatures
96 {
97 COOL,
98 WARM,
99 HOT
100 };
101
102 enum TemperatureEvents
103 {
104 TEMPERATURE_DESERT_COOL,
105 TEMPERATURE_DESERT_WARM,
106 TEMPERATURE_DESERT_HOT,
107 TEMPERATURE_GLOBAL_COOL,
108 TEMPERATURE_GLOBAL_WARM,
109 TEMPERATURE_GLOBAL_HOT,
110 };
111
112 #define DESERT_WARM_START ( 8 * 60 )
113 #define DESERT_HOT_START ( 9 * 60 )
114 #define DESERT_HOT_END (17 * 60 )
115 #define DESERT_WARM_END (19 * 60 )
116
117 #define GLOBAL_WARM_START ( 9 * 60 )
118 #define GLOBAL_HOT_START (12 * 60 )
119 #define GLOBAL_HOT_END (14 * 60 )
120 #define GLOBAL_WARM_END (17 * 60 )
121
122 #define HOT_DAY_LIGHTLEVEL 2
123
124 BOOLEAN fTimeOfDayControls=TRUE;
125 UINT32 guiEnvTime=0;
126 UINT32 guiEnvDay=0;
127 UINT8 gubEnvLightValue = 0;
128 BOOLEAN gfDoLighting = FALSE;
129
130 UINT8 gubDesertTemperature = 0;
131 UINT8 gubGlobalTemperature = 0;
132
133 // polled by the game to handle time/atmosphere changes from gamescreen
EnvironmentController(BOOLEAN fCheckForLights)134 void EnvironmentController( BOOLEAN fCheckForLights )
135 {
136 UINT32 uiOldWorldHour;
137 UINT8 ubLightAdjustFromWeather = 0;
138
139
140 // do none of this stuff in the basement or caves
141 if( gfBasement || gfCaves )
142 {
143 guiEnvWeather &= (~WEATHER_FORECAST_THUNDERSHOWERS );
144 guiEnvWeather &= (~WEATHER_FORECAST_SHOWERS );
145
146 if ( guiRainLoop != NO_SAMPLE )
147 {
148 SoundStop( guiRainLoop );
149 guiRainLoop = NO_SAMPLE;
150 }
151 return;
152 }
153
154 if(fTimeOfDayControls )
155 {
156 uiOldWorldHour = GetWorldHour();
157
158 // If hour is different
159 if ( uiOldWorldHour != guiEnvTime )
160 {
161 // Hour change....
162
163 guiEnvTime=uiOldWorldHour;
164 }
165
166 //ExecuteStrategicEventsUntilTimeStamp( (UINT16)GetWorldTotalMin( ) );
167
168 // Polled weather stuff...
169 // ONly do indooors
170 if( !gfBasement && !gfCaves )
171 {
172 #if 0
173 if ( guiEnvWeather & ( WEATHER_FORECAST_THUNDERSHOWERS | WEATHER_FORECAST_SHOWERS ) )
174 {
175 if ( guiRainLoop == NO_SAMPLE )
176 {
177 guiRainLoop = PlayJA2Ambient( RAIN_1, MIDVOLUME, 0 );
178 }
179
180 // Do lightning if we want...
181 if ( guiEnvWeather & ( WEATHER_FORECAST_THUNDERSHOWERS ) )
182 {
183 EnvDoLightning( );
184 }
185
186 }
187 else
188 {
189 if ( guiRainLoop != NO_SAMPLE )
190 {
191 SoundStop( guiRainLoop );
192 guiRainLoop = NO_SAMPLE;
193 }
194 }
195 #endif
196 }
197
198 if ( gfDoLighting && fCheckForLights )
199 {
200 // Adjust light level based on weather...
201 ubLightAdjustFromWeather = GetTimeOfDayAmbientLightLevel();
202
203 // ONly do indooors
204 if( !gfBasement && !gfCaves )
205 {
206 // Rain storms....
207 #if 0
208 if ( guiEnvWeather & ( WEATHER_FORECAST_THUNDERSHOWERS | WEATHER_FORECAST_SHOWERS ) )
209 {
210 // Thunder showers.. make darker
211 if ( guiEnvWeather & ( WEATHER_FORECAST_THUNDERSHOWERS ) )
212 {
213 ubLightAdjustFromWeather = (UINT8)(__min( gubEnvLightValue+2, NORMAL_LIGHTLEVEL_NIGHT ));
214 }
215 else
216 {
217 ubLightAdjustFromWeather = (UINT8)(__min( gubEnvLightValue+1, NORMAL_LIGHTLEVEL_NIGHT ));
218 }
219 }
220 #endif
221 }
222
223
224 LightSetBaseLevel( ubLightAdjustFromWeather );
225
226 //Update Merc Lights since the above function modifies it.
227 HandlePlayerTogglingLightEffects( FALSE );
228
229 // Make teams look for all
230 // AllTeamsLookForAll( FALSE );
231
232 // Set global light value
233 SetRenderFlags(RENDER_FLAG_FULL);
234 gfDoLighting = FALSE;
235 }
236
237 }
238
239 }
240
BuildDayLightLevels()241 void BuildDayLightLevels()
242 {
243 UINT32 uiLoop, uiHour;
244
245 /*
246 // Dawn; light 12
247 AddEveryDayStrategicEvent( EVENT_CHANGELIGHTVAL, DAWNLIGHT_START, NORMAL_LIGHTLEVEL_NIGHT - 1 );
248
249 // loop from light 12 down to light 4
250 for (uiLoop = 1; uiLoop < 8; uiLoop++)
251 {
252 AddEveryDayStrategicEvent( EVENT_CHANGELIGHTVAL, DAWN_START + 15 * uiLoop, NORMAL_LIGHTLEVEL_NIGHT - 1 - uiLoop );
253 }
254 */
255
256 //Transition from night to day
257 for( uiLoop = 0; uiLoop < 9; uiLoop++ )
258 {
259 AddEveryDayStrategicEvent( EVENT_CHANGELIGHTVAL, DAWN_START + 2 * uiLoop, NORMAL_LIGHTLEVEL_NIGHT - 1 - uiLoop );
260 }
261
262 // Add events for hot times
263 AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, DESERT_WARM_START, TEMPERATURE_DESERT_WARM );
264 AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, DESERT_HOT_START, TEMPERATURE_DESERT_HOT );
265 AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, DESERT_HOT_END, TEMPERATURE_DESERT_WARM );
266 AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, DESERT_WARM_END, TEMPERATURE_DESERT_COOL );
267
268 AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, GLOBAL_WARM_START, TEMPERATURE_GLOBAL_WARM );
269 AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, GLOBAL_HOT_START, TEMPERATURE_GLOBAL_HOT );
270 AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, GLOBAL_HOT_END, TEMPERATURE_GLOBAL_WARM );
271 AddEveryDayStrategicEvent( EVENT_TEMPERATURE_UPDATE, GLOBAL_WARM_END, TEMPERATURE_GLOBAL_COOL );
272
273 /*
274 // Twilight; light 5
275 AddEveryDayStrategicEvent( EVENT_CHANGELIGHTVAL, TWILLIGHT_START, NORMAL_LIGHTLEVEL_DAY + 1 );
276
277 // Dusk; loop from light 5 up to 12
278 for (uiLoop = 1; uiLoop < 8; uiLoop++)
279 {
280 AddEveryDayStrategicEvent( EVENT_CHANGELIGHTVAL, DUSK_START + 15 * uiLoop, NORMAL_LIGHTLEVEL_DAY + 1 + uiLoop );
281 }
282 */
283
284 //Transition from day to night
285 for( uiLoop = 0; uiLoop < 9; uiLoop++ )
286 {
287 AddEveryDayStrategicEvent( EVENT_CHANGELIGHTVAL, DUSK_START + 2 * uiLoop, NORMAL_LIGHTLEVEL_DAY + 1 + uiLoop );
288 }
289
290 //Set up the scheduling for turning lights on and off based on the various types.
291 uiHour = NIGHT_TIME_LIGHT_START_HOUR == 24 ? 0 : NIGHT_TIME_LIGHT_START_HOUR;
292 AddEveryDayStrategicEvent( EVENT_TURN_ON_NIGHT_LIGHTS, uiHour * 60, 0 );
293 uiHour = NIGHT_TIME_LIGHT_END_HOUR == 24 ? 0 : NIGHT_TIME_LIGHT_END_HOUR;
294 AddEveryDayStrategicEvent( EVENT_TURN_OFF_NIGHT_LIGHTS, uiHour * 60, 0 );
295 uiHour = PRIME_TIME_LIGHT_START_HOUR == 24 ? 0 : PRIME_TIME_LIGHT_START_HOUR;
296 AddEveryDayStrategicEvent( EVENT_TURN_ON_PRIME_LIGHTS, uiHour * 60, 0 );
297 uiHour = PRIME_TIME_LIGHT_END_HOUR == 24 ? 0 : PRIME_TIME_LIGHT_END_HOUR;
298 AddEveryDayStrategicEvent( EVENT_TURN_OFF_PRIME_LIGHTS, uiHour * 60, 0 );
299 }
300
BuildDayAmbientSounds()301 void BuildDayAmbientSounds( )
302 {
303 INT32 cnt;
304
305 // Add events!
306 for ( cnt = 0; cnt < gsNumAmbData; cnt++ )
307 {
308 switch( gAmbData[ cnt ].ubTimeCatagory )
309 {
310 case AMB_TOD_DAWN:
311 AddSameDayRangedStrategicEvent( EVENT_AMBIENT, DAWN_START, DAWN_TO_DAY, cnt );
312 break;
313 case AMB_TOD_DAY:
314 AddSameDayRangedStrategicEvent( EVENT_AMBIENT, DAY_START, DAY_TO_DUSK, cnt );
315 break;
316 case AMB_TOD_DUSK:
317 AddSameDayRangedStrategicEvent( EVENT_AMBIENT, DUSK_START, DUSK_TO_NIGHT, cnt );
318 break;
319 case AMB_TOD_NIGHT:
320 AddSameDayRangedStrategicEvent( EVENT_AMBIENT, NIGHT_START, NIGHT_TO_DAWN, cnt );
321 break;
322 }
323
324 }
325
326 guiRainLoop = NO_SAMPLE;
327
328 }
329
ForecastDayEvents()330 void ForecastDayEvents( )
331 {
332 UINT32 uiOldDay;
333 //UINT32 uiStartTime, uiEndTime;
334 //UINT8 ubStormIntensity;
335
336 // Get current day and see if different
337 if ( ( uiOldDay = GetWorldDay() ) != guiEnvDay )
338 {
339 // It's a new day, forecast weather
340 guiEnvDay = uiOldDay;
341
342 // Set light level changes
343 //BuildDayLightLevels();
344
345 // Build ambient sound queues
346 BuildDayAmbientSounds( );
347
348 // Build weather....
349
350 // ATE: Don't forecast if start of game...
351 //if ( guiEnvDay > 1 )
352 //{
353 // Should it rain...?
354 //if ( Random( 100 ) < 20 )
355 //{
356 // Add rain!
357 // Between 6:00 and 10:00
358 //uiStartTime = (UINT32)( 360 + Random( 1080 ) );
359 // Between 5 - 15 miniutes
360 //uiEndTime = uiStartTime + ( 5 + Random( 10 ) );
361
362 //ubStormIntensity = 0;
363
364 // Randomze for a storm!
365 //if ( Random( 10 ) < 5 )
366 //{
367 //ubStormIntensity = 1;
368 //}
369
370 // ATE: Disable RAIN!
371 //AddSameDayRangedStrategicEvent( EVENT_RAINSTORM, uiStartTime, uiEndTime - uiStartTime, ubStormIntensity );
372
373 //AddSameDayStrategicEvent( EVENT_BEGINRAINSTORM, uiStartTime, ubStormIntensity );
374 //AddSameDayStrategicEvent( EVENT_ENDRAINSTORM, uiEndTime, 0 );
375 //}
376 //}
377 }
378
379 }
380
GetTimeOfDayAmbientLightLevel()381 UINT8 GetTimeOfDayAmbientLightLevel()
382 {
383 if ( SectorTemperature( GetWorldMinutesInDay(), gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) == HOT )
384 {
385 return( HOT_DAY_LIGHTLEVEL );
386 }
387 else
388 {
389 return( gubEnvLightValue );
390 }
391 }
392
393
EnvBeginRainStorm(UINT8 ubIntensity)394 void EnvBeginRainStorm( UINT8 ubIntensity )
395 {
396 if( !gfBasement && !gfCaves )
397 {
398 gfDoLighting = TRUE;
399 SLOGD("Starting Rain...." );
400
401 if ( ubIntensity == 1 )
402 {
403 // Turn on rain storms
404 guiEnvWeather |= WEATHER_FORECAST_THUNDERSHOWERS;
405 }
406 else
407 {
408 guiEnvWeather |= WEATHER_FORECAST_SHOWERS;
409 }
410 }
411
412 }
413
EnvEndRainStorm()414 void EnvEndRainStorm( )
415 {
416 gfDoLighting = TRUE;
417 SLOGD("Ending Rain...." );
418
419 guiEnvWeather &= (~WEATHER_FORECAST_THUNDERSHOWERS );
420 guiEnvWeather &= (~WEATHER_FORECAST_SHOWERS );
421 }
422
423
TurnOnNightLights()424 void TurnOnNightLights()
425 {
426 FOR_EACH_LIGHT_SPRITE(l)
427 {
428 if (l->uiFlags & LIGHT_NIGHTTIME &&
429 !(l->uiFlags & (LIGHT_SPR_ON | MERC_LIGHT)))
430 {
431 LightSpritePower(l, TRUE);
432 }
433 }
434 }
435
436
TurnOffNightLights()437 void TurnOffNightLights()
438 {
439 FOR_EACH_LIGHT_SPRITE(l)
440 {
441 if (l->uiFlags & LIGHT_NIGHTTIME &&
442 l->uiFlags & LIGHT_SPR_ON &&
443 !(l->uiFlags & MERC_LIGHT))
444 {
445 LightSpritePower(l, FALSE);
446 }
447 }
448 }
449
450
TurnOnPrimeLights()451 void TurnOnPrimeLights()
452 {
453 FOR_EACH_LIGHT_SPRITE(l)
454 {
455 if (l->uiFlags & LIGHT_PRIMETIME &&
456 !(l->uiFlags & (LIGHT_SPR_ON | MERC_LIGHT)))
457 {
458 LightSpritePower(l, TRUE);
459 }
460 }
461 }
462
463
TurnOffPrimeLights()464 void TurnOffPrimeLights()
465 {
466 FOR_EACH_LIGHT_SPRITE(l)
467 {
468 if (l->uiFlags & LIGHT_PRIMETIME &&
469 l->uiFlags & LIGHT_SPR_ON &&
470 !(l->uiFlags & MERC_LIGHT))
471 {
472 LightSpritePower(l, FALSE);
473 }
474 }
475 }
476
UpdateTemperature(UINT8 ubTemperatureCode)477 void UpdateTemperature( UINT8 ubTemperatureCode )
478 {
479 switch( ubTemperatureCode )
480 {
481 case TEMPERATURE_DESERT_COOL:
482 gubDesertTemperature = 0;
483 break;
484 case TEMPERATURE_DESERT_WARM:
485 gubDesertTemperature = 1;
486 break;
487 case TEMPERATURE_DESERT_HOT:
488 gubDesertTemperature = 2;
489 break;
490 case TEMPERATURE_GLOBAL_COOL:
491 gubGlobalTemperature = 0;
492 break;
493 case TEMPERATURE_GLOBAL_WARM:
494 gubGlobalTemperature = 1;
495 break;
496 case TEMPERATURE_GLOBAL_HOT:
497 gubGlobalTemperature = 2;
498 break;
499 }
500 gfDoLighting = TRUE;
501 }
502
SectorTemperature(UINT32 uiTime,INT16 sSectorX,INT16 sSectorY,INT8 bSectorZ)503 INT8 SectorTemperature( UINT32 uiTime, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
504 {
505 if (bSectorZ > 0)
506 {
507 // cool underground
508 return( 0 );
509 }
510 else if ( IsSectorDesert( sSectorX, sSectorY ) ) // is desert
511 {
512 return( gubDesertTemperature );
513 }
514 else
515 {
516 return( gubGlobalTemperature );
517 }
518 }
519