From 503523a9fa64cd7aba9166f87060294e240d74e1 Mon Sep 17 00:00:00 2001 From: Flugente Date: Sat, 18 Jun 2016 20:57:03 +0000 Subject: [PATCH] New feature: localized weather adds more weather types, different weather can happen in different sectors at the same time. For more info, see http://thepit.ja-galaxy-forum.com/index.php?t=msg&th=23094&#msg_345949 Requires GameDir >= r2325 git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8253 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- GameSettings.cpp | 54 +- GameSettings.h | 29 +- GameVersion.cpp | 18 +- GameVersion.h | 3 +- Laptop/laptop.cpp | 50 +- Laptop/personnel.cpp | 4 +- SaveLoadGame.cpp | 9 +- Strategic/Campaign Types.h | 8 +- Strategic/Game Event Hook.cpp | 37 +- Strategic/Game Event Hook.h | 6 + Strategic/Game Events.cpp | 5 + Strategic/LuaInitNPCs.cpp | 29 -- Strategic/Map Screen Interface Border.cpp | 153 ++++++ Strategic/Map Screen Interface Border.h | 8 + Strategic/Map Screen Interface Map.cpp | 6 +- Strategic/XML_SectorNames.cpp | 40 +- Tactical/Disease.cpp | 37 +- Tactical/Disease.h | 4 +- Tactical/Items.h | 3 + Tactical/LOS.cpp | 7 +- Tactical/Points.cpp | 21 +- Tactical/Rain.cpp | 208 +++++--- Tactical/Soldier Profile.cpp | 2 +- Tactical/Turn Based Input.cpp | 20 +- Tactical/Weapons.cpp | 16 +- Tactical/opplist.cpp | 49 +- TileEngine/environment.cpp | 588 +++++++++++++--------- TileEngine/environment.h | 27 +- Utils/Sound Control.cpp | 3 +- Utils/Sound Control.h | 3 +- Utils/Text.h | 3 + Utils/_ChineseText.cpp | 14 + Utils/_DutchText.cpp | 14 + Utils/_EnglishText.cpp | 14 + Utils/_FrenchText.cpp | 14 + Utils/_GermanText.cpp | 14 + Utils/_ItalianText.cpp | 14 + Utils/_PolishText.cpp | 14 + Utils/_RussianText.cpp | 14 + lua/lua_env.cpp | 19 +- 40 files changed, 1059 insertions(+), 522 deletions(-) diff --git a/GameSettings.cpp b/GameSettings.cpp index 6f68982f..185cca9c 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -1626,18 +1626,15 @@ void LoadGameExternalOptions() //################# Tactical Weather Settings ################## - - gGameExternalOptions.ubVisDistDecreasePerRainIntensity = iniReader.ReadInteger("Tactical Weather Settings","VISUAL_DISTANCE_DECREASE_PER_RAIN_INTENSITY",30, 0, 100); - + // Rain settings - gGameExternalOptions.gfAllowRain = iniReader.ReadBoolean("Tactical Weather Settings","ALLOW_RAIN",0); + gGameExternalOptions.gfAllowRain = iniReader.ReadBoolean("Tactical Weather Settings","ALLOW_RAIN", FALSE); + gGameExternalOptions.gusWeatherPerDayRain = iniReader.ReadInteger("Tactical Weather Settings","RAIN_EVENTS_PER_DAY", 3, 1, 24 ); gGameExternalOptions.gusRainChancePerDay = iniReader.ReadInteger("Tactical Weather Settings","RAIN_CHANCE_PER_DAY",100, 0, 100); gGameExternalOptions.gusRainMinLength = iniReader.ReadInteger("Tactical Weather Settings","RAIN_MIN_LENGTH_IN_MINUTES",60, 1, 1438 /* 24 hrs - 2 minutes */); gGameExternalOptions.gusRainMaxLength = iniReader.ReadInteger("Tactical Weather Settings","RAIN_MAX_LENGTH_IN_MINUTES",300, gGameExternalOptions.gusRainMinLength+1, 1439); gGameExternalOptions.guiMaxRainDrops = iniReader.ReadInteger("Tactical Weather Settings","MAX_RAIN_DROPS",80, 1, 800); - gGameExternalOptions.ubWeaponReliabilityReductionPerRainIntensity = iniReader.ReadInteger("Tactical Weather Settings","WEAPON_RELIABILITY_REDUCTION_PER_RAIN_INTENSITY",0, 0, 10); - gGameExternalOptions.ubBreathGainReductionPerRainIntensity = iniReader.ReadDouble("Tactical Weather Settings","BREATH_GAIN_REDUCTION_PER_RAIN_INTENSITY",25, 1, 100); - + // Thunder settings gGameExternalOptions.gfAllowLightning = iniReader.ReadBoolean("Tactical Weather Settings","ALLOW_LIGHTNING",TRUE); gGameExternalOptions.guiMinLightningInterval = iniReader.ReadInteger("Tactical Weather Settings","MIN_INTERVAL_BETWEEN_LIGHTNINGS_IN_REAL_TIME_SECONDS",5, 1, 100); @@ -1646,7 +1643,48 @@ void LoadGameExternalOptions() gGameExternalOptions.guiMaxDLInterval = iniReader.ReadInteger("Tactical Weather Settings","MAX_INTERVAL_BETWEEN_LIGHTNING_AND_THUNDERCLAPS_IN_SECONDS",5, 2, 600); gGameExternalOptions.guiProlongLightningIfSeenSomeone = iniReader.ReadInteger("Tactical Weather Settings","DELAY_IN_SECONDS_IF_SEEN_SOMEONE_DURING_LIGHTNING_IN_TURNBASED",5, 1, 60); gGameExternalOptions.guiChanceToDoLightningBetweenTurns = iniReader.ReadInteger("Tactical Weather Settings","CHANCE_TO_DO_LIGHTNING_BETWEEN_TURNS",35, 0, 100); + + // Flugente: sandstorm settings + gGameExternalOptions.gfAllowSandStorms = iniReader.ReadBoolean( "Tactical Weather Settings", "ALLOW_SANDSTORM", TRUE ); + gGameExternalOptions.gusWeatherPerDaySandstorm = iniReader.ReadInteger( "Tactical Weather Settings", "SANDSTORM_EVENTS_PER_DAY", 1, 1, 24 ); + gGameExternalOptions.gusSandStormsChancePerDay = iniReader.ReadInteger( "Tactical Weather Settings", "SANDSTORM_CHANCE_PER_DAY", 100, 0, 100 ); + gGameExternalOptions.gusSandStormsMinLength = iniReader.ReadInteger( "Tactical Weather Settings", "SANDSTORM_MIN_LENGTH_IN_MINUTES", 60, 1, 1438 /* 24 hrs - 2 minutes */ ); + gGameExternalOptions.gusSandStormsMaxLength = iniReader.ReadInteger( "Tactical Weather Settings", "SANDSTORM_MAX_LENGTH_IN_MINUTES", 300, gGameExternalOptions.gusSandStormsMinLength + 1, 1439 ); + // Snow settings + gGameExternalOptions.gfAllowSnow = iniReader.ReadBoolean( "Tactical Weather Settings", "ALLOW_SNOW", TRUE ); + gGameExternalOptions.gusWeatherPerDaySnow = iniReader.ReadInteger( "Tactical Weather Settings", "SNOW_EVENTS_PER_DAY", 1, 1, 24 ); + gGameExternalOptions.gusSnowChancePerDay = iniReader.ReadInteger( "Tactical Weather Settings", "SNOW_CHANCE_PER_DAY", 100, 0, 100 ); + gGameExternalOptions.gusSnowMinLength = iniReader.ReadInteger( "Tactical Weather Settings", "SNOW_MIN_LENGTH_IN_MINUTES", 60, 1, 1438 /* 24 hrs - 2 minutes */ ); + gGameExternalOptions.gusSnowMaxLength = iniReader.ReadInteger( "Tactical Weather Settings", "SNOW_MAX_LENGTH_IN_MINUTES", 300, gGameExternalOptions.gusSnowMinLength + 1, 1439 ); + + // weather penalties + gGameExternalOptions.ubWeaponReliabilityReduction[WEATHER_FORECAST_NORMAL] = 0; + gGameExternalOptions.ubWeaponReliabilityReduction[WEATHER_FORECAST_RAIN] = iniReader.ReadInteger( "Tactical Weather Settings", "WEAPON_RELIABILITY_REDUCTION_RAIN", 0, 0, 10 ); + gGameExternalOptions.ubWeaponReliabilityReduction[WEATHER_FORECAST_THUNDERSHOWERS] = iniReader.ReadInteger( "Tactical Weather Settings", "WEAPON_RELIABILITY_REDUCTION_THUNDERSTORM", 1, 0, 10 ); + gGameExternalOptions.ubWeaponReliabilityReduction[WEATHER_FORECAST_SANDSTORM] = iniReader.ReadInteger( "Tactical Weather Settings", "WEAPON_RELIABILITY_REDUCTION_SANDSTORM", 4, 0, 10 ); + gGameExternalOptions.ubWeaponReliabilityReduction[WEATHER_FORECAST_SNOW] = iniReader.ReadInteger( "Tactical Weather Settings", "WEAPON_RELIABILITY_REDUCTION_SNOW", 2, 0, 10 ); + + gGameExternalOptions.dBreathGainReduction[WEATHER_FORECAST_NORMAL] = 0.0f; + gGameExternalOptions.dBreathGainReduction[WEATHER_FORECAST_RAIN] = iniReader.ReadDouble( "Tactical Weather Settings", "BREATH_GAIN_REDUCTION_RAIN", 0.1f, 0.0f, 1.0f ); + gGameExternalOptions.dBreathGainReduction[WEATHER_FORECAST_THUNDERSHOWERS] = iniReader.ReadDouble( "Tactical Weather Settings", "BREATH_GAIN_REDUCTION_THUNDERSTORM", 0.4f, 0.0f, 1.0f ); + gGameExternalOptions.dBreathGainReduction[WEATHER_FORECAST_SANDSTORM] = iniReader.ReadDouble( "Tactical Weather Settings", "BREATH_GAIN_REDUCTION_SANDSTORM", 0.7f, 0.0f, 1.0f ); + gGameExternalOptions.dBreathGainReduction[WEATHER_FORECAST_SNOW] = iniReader.ReadDouble( "Tactical Weather Settings", "BREATH_GAIN_REDUCTION_SNOW", 0.2f, 0.0f, 1.0f ); + + gGameExternalOptions.dVisDistDecrease[WEATHER_FORECAST_NORMAL] = 0.0f; + gGameExternalOptions.dVisDistDecrease[WEATHER_FORECAST_RAIN] = iniReader.ReadDouble( "Tactical Weather Settings", "VISUAL_DISTANCE_DECREASE_RAIN", 0.05f, 0.0f, 1.0f ); + gGameExternalOptions.dVisDistDecrease[WEATHER_FORECAST_THUNDERSHOWERS] = iniReader.ReadDouble( "Tactical Weather Settings", "VISUAL_DISTANCE_DECREASE_THUNDERSTORM", 0.15f, 0.0f, 1.0f ); + gGameExternalOptions.dVisDistDecrease[WEATHER_FORECAST_SANDSTORM] = iniReader.ReadDouble( "Tactical Weather Settings", "VISUAL_DISTANCE_DECREASE_SANDSTORM", 0.4f, 0.0f, 1.0f ); + gGameExternalOptions.dVisDistDecrease[WEATHER_FORECAST_SNOW] = iniReader.ReadDouble( "Tactical Weather Settings", "VISUAL_DISTANCE_DECREASE_SNOW", 0.3f, 0.0f, 1.0f ); + + gGameExternalOptions.dHearingReduction[WEATHER_FORECAST_NORMAL] = 0.0f; + gGameExternalOptions.dHearingReduction[WEATHER_FORECAST_RAIN] = iniReader.ReadDouble( "Tactical Weather Settings", "HEARING_REDUCTION_RAIN", 0.3f, 0.0f, 1.0f ); + gGameExternalOptions.dHearingReduction[WEATHER_FORECAST_THUNDERSHOWERS] = iniReader.ReadDouble( "Tactical Weather Settings", "HEARING_REDUCTION_THUNDERSTORM", 0.8f, 0.0f, 1.0f ); + gGameExternalOptions.dHearingReduction[WEATHER_FORECAST_SANDSTORM] = iniReader.ReadDouble( "Tactical Weather Settings", "HEARING_REDUCTION_SANDSTORM", 0.6f, 0.0f, 1.0f ); + gGameExternalOptions.dHearingReduction[WEATHER_FORECAST_SNOW] = iniReader.ReadDouble( "Tactical Weather Settings", "HEARING_REDUCTION_SNOW", 0.1f, 0.0f, 1.0f ); + + FLOAT dHearingReduction[WEATHER_FORECAST_MAX]; + //################# Tactical Weapon Overheating Settings ################## // Flugente: These settings control the behavior of Weapon Overheating, its severity, and its display. gGameExternalOptions.fWeaponOverheating = iniReader.ReadBoolean("Tactical Weapon Overheating Settings","OVERHEATING",FALSE); @@ -2588,7 +2626,7 @@ void LoadSkillTraitsExternalSettings() gSkillTraitValues.ubSVGroupTimeSpentForTravellingVehicle = iniReader.ReadInteger( "Survival", "GROUP_TIME_SPENT_FOR_TRAVELLING_IN_VEHICLE_REDUCTION", 15, 0, 100 ); gSkillTraitValues.ubSVMaxBonusesToTravelSpeed = iniReader.ReadInteger( "Survival", "MAX_STACKABLE_LESS_TRAVEL_TIME_BONUSES", 2, 0, 20 ); gSkillTraitValues.ubSVBreathForTravellingReduction = iniReader.ReadInteger( "Survival", "ENERGY_SPENT_TRAVEL_REDUCTION", 50, 0, 100 ); - gSkillTraitValues.ubSVWeatherPenaltiesReduction = iniReader.ReadInteger( "Survival", "WEATHER_PENALTIES_REDUCTION", 35, 0, 100 ); + gSkillTraitValues.dSVWeatherPenaltiesReduction = iniReader.ReadFloat( "Survival", "WEATHER_PENALTIES_REDUCTION", 0.35f, 0.0f, 1.0f ); gSkillTraitValues.ubSVCamoWornountSpeedReduction = iniReader.ReadInteger( "Survival", "CAMO_WORNOUT_SPEED_REDUCTION", 75, 0, 100 ); gSkillTraitValues.usSVTrackerMaxRange = iniReader.ReadInteger( "Survival", "TRACKER_MAX_RANGE", 30, 0, 50 ); gSkillTraitValues.usSVTrackerAbility = iniReader.ReadInteger( "Survival", "TRACKER_ABILITY", 30, 0, 50 ); diff --git a/GameSettings.h b/GameSettings.h index 993348fc..09e28866 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -6,6 +6,7 @@ #include "Morale.h" #include "GameInitOptionsScreen.h" #include "Campaign Types.h" +#include "environment.h" #define GAME_INI_FILE "Ja2.ini" @@ -546,7 +547,6 @@ typedef struct INT8 ubBrightnessVisionMod[16]; - UINT32 ubVisDistDecreasePerRainIntensity; BOOLEAN gfAllowLimitedVision; BOOLEAN gfShiftFUnloadWeapons; @@ -554,13 +554,12 @@ typedef struct // Rain settings BOOLEAN gfAllowRain; + UINT16 gusWeatherPerDayRain; UINT32 gusRainChancePerDay; UINT32 gusRainMinLength; UINT32 gusRainMaxLength; UINT32 guiMaxRainDrops; - UINT32 ubWeaponReliabilityReductionPerRainIntensity; - double ubBreathGainReductionPerRainIntensity; - + // Thunder settings BOOLEAN gfAllowLightning; UINT32 guiMinLightningInterval; @@ -570,6 +569,26 @@ typedef struct UINT32 guiProlongLightningIfSeenSomeone; UINT32 guiChanceToDoLightningBetweenTurns; + // Sandstorm settings + BOOLEAN gfAllowSandStorms; + UINT16 gusWeatherPerDaySandstorm; + UINT32 gusSandStormsChancePerDay; + UINT32 gusSandStormsMinLength; + UINT32 gusSandStormsMaxLength; + + // Snow settings + BOOLEAN gfAllowSnow; + UINT16 gusWeatherPerDaySnow; + UINT32 gusSnowChancePerDay; + UINT32 gusSnowMinLength; + UINT32 gusSnowMaxLength; + + // weather penalties + UINT32 ubWeaponReliabilityReduction[WEATHER_FORECAST_MAX]; + FLOAT dBreathGainReduction[WEATHER_FORECAST_MAX]; + FLOAT dVisDistDecrease[WEATHER_FORECAST_MAX]; + FLOAT dHearingReduction[WEATHER_FORECAST_MAX]; + // WDS - Progress settings UINT32 ubGameProgressPortionKills; UINT32 ubGameProgressPortionControl; @@ -1873,7 +1892,7 @@ typedef struct UINT8 ubSVGroupTimeSpentForTravellingVehicle; UINT8 ubSVMaxBonusesToTravelSpeed; UINT8 ubSVBreathForTravellingReduction; - UINT8 ubSVWeatherPenaltiesReduction; + FLOAT dSVWeatherPenaltiesReduction; UINT8 ubSVCamoWornountSpeedReduction; UINT16 usSVTrackerMaxRange; UINT8 usSVTrackerAbility; diff --git a/GameVersion.cpp b/GameVersion.cpp index d2da9557..b5f72990 100644 --- a/GameVersion.cpp +++ b/GameVersion.cpp @@ -15,9 +15,9 @@ #ifdef JA2EDITOR #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.8249 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.8253 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.8249 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.8253 (Development Build)" }; #endif // ------------------------------ @@ -27,11 +27,11 @@ //DEBUG BUILD VERSION #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.8249 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.8253 (Development Build)" }; #elif defined (JA113DEMO) - CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.8249 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.8253 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Debug: v1.13.8249 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: v1.13.8253 (Development Build)" }; #endif #elif defined CRIPPLED_VERSION @@ -46,16 +46,16 @@ //RELEASE BUILD VERSION #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.8249 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.8253 (Development Build)" }; #elif defined (JA113DEMO) - CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.8249 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.8253 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Release v1.13.8249 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release v1.13.8253 (Development Build)" }; #endif #endif -CHAR8 czVersionNumber[16] = { "Build 16.06.06" }; //YY.MM.DD +CHAR8 czVersionNumber[16] = { "Build 18.06.06" }; //YY.MM.DD CHAR16 zTrackingNumber[16] = { L"Z" }; // SAVE_GAME_VERSION is defined in header, change it there diff --git a/GameVersion.h b/GameVersion.h index 46194d34..c1f74861 100644 --- a/GameVersion.h +++ b/GameVersion.h @@ -21,6 +21,7 @@ extern CHAR16 zTrackingNumber[16]; // Keeps track of the saved game version. Increment the saved game version whenever // you will invalidate the saved game file +#define WEATHER_CHANGE 169 // Flugente: sector-specific weather & more weather types #define ASD_INIT_FIX 168 // Flugente: fix for ASD feature introduced with ENEMY_HELICOPTERS #define NONPROFILE_MERCHANTS 167 // Flugente: merchants can be created from non-profile NPCs #define INDIVIDUAL_MILITIA 166 // Flugente: individual militia @@ -87,7 +88,7 @@ extern CHAR16 zTrackingNumber[16]; #define AP100_SAVEGAME_DATATYPE_CHANGE 105 // Before this, we didn't have the 100AP structure changes #define NIV_SAVEGAME_DATATYPE_CHANGE 102 // Before this, we used the old structure system -#define SAVE_GAME_VERSION ASD_INIT_FIX +#define SAVE_GAME_VERSION WEATHER_CHANGE //#define RUSSIANGOLD #ifdef __cplusplus diff --git a/Laptop/laptop.cpp b/Laptop/laptop.cpp index 8b73f11a..eacddc13 100644 --- a/Laptop/laptop.cpp +++ b/Laptop/laptop.cpp @@ -657,11 +657,6 @@ void CreateFileAndNewEmailIconFastHelpText( UINT32 uiHelpTextID, BOOLEAN fClearH void CreateLaptopButtonHelpText( INT32 iButtonIndex, UINT32 uiButtonHelpTextID ); //ppp -//Used to determine delay if its raining -BOOLEAN IsItRaining(); -INT32 WWaitDelayIncreasedIfRaining( INT32 iLoadTime ); -void InternetRainDelayMessageBoxCallBack( UINT8 bExitValue ); - extern void ClearHistoryList( void ); @@ -4172,23 +4167,9 @@ void BookmarkCallBack(MOUSE_REGION * pRegion, INT32 iReason ) void GoToWebPage(INT32 iPageId ) { - - // WANNE: disabled rain sound when laptop is displayed - ////if it is raining, popup a warning first saying connection time may be slow - //if( IsItRaining() ) - //{ - // if( giRainDelayInternetSite == -1 ) - // { - // DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, pErrorStrings[4], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, InternetRainDelayMessageBoxCallBack ); - // giRainDelayInternetSite = iPageId; - // return; - // } - //} - //else - // giRainDelayInternetSite = -1; #ifdef JA2UB //if the laptop is broken -if( (gubQuest[ QUEST_FIX_LAPTOP ] != QUESTINPROGRESS) || (gGameUBOptions.LaptopQuestEnabled != TRUE) ) + if( (gubQuest[ QUEST_FIX_LAPTOP ] != QUESTINPROGRESS) || (gGameUBOptions.LaptopQuestEnabled != TRUE) ) { #endif switch(iPageId) @@ -4585,9 +4566,7 @@ BOOLEAN DisplayLoadPending( void ) { iUnitTime=UNIT_TIME; } - - iUnitTime += WWaitDelayIncreasedIfRaining( iUnitTime ); - + iLoadTime = iUnitTime * 30; #ifdef JA2UB //if the site we are going to is the web poage not found page @@ -7143,31 +7122,14 @@ void LaptopSaveVariablesInit() { } - -INT32 WWaitDelayIncreasedIfRaining( INT32 iUnitTime ) +/*BOOLEAN IsItRaining() { - INT32 iRetVal = 0; - - if( guiEnvWeather & WEATHER_FORECAST_THUNDERSHOWERS ) - { - iRetVal = (INT32)( iUnitTime * (FLOAT) 0.80 ); - } - else if( guiEnvWeather & WEATHER_FORECAST_SHOWERS ) - { - iRetVal = (INT32)( iUnitTime * (FLOAT) 0.6 ); - } - - return( iRetVal ); -} - - -BOOLEAN IsItRaining() -{ - if( guiEnvWeather & WEATHER_FORECAST_SHOWERS || guiEnvWeather & WEATHER_FORECAST_THUNDERSHOWERS ) + if ( (SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_RAIN || SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_THUNDERSHOWERS + || SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_SANDSTORM || SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_SNOW) ) return( TRUE ); return( FALSE ); -} +}*/ void InternetRainDelayMessageBoxCallBack( UINT8 bExitValue ) diff --git a/Laptop/personnel.cpp b/Laptop/personnel.cpp index 421e9bfe..fa0c1d1f 100644 --- a/Laptop/personnel.cpp +++ b/Laptop/personnel.cpp @@ -8295,9 +8295,9 @@ void AssignPersonnelSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLeve swprintf( atStr, gzIMPMajorTraitsHelpTextsSurvival[2], gSkillTraitValues.ubSVBreathForTravellingReduction, sSpecialCharacters[0] ); wcscat( apStr, atStr ); } - if ( gSkillTraitValues.ubSVWeatherPenaltiesReduction != 0 ) + if ( gSkillTraitValues.dSVWeatherPenaltiesReduction != 0 ) { - swprintf( atStr, gzIMPMajorTraitsHelpTextsSurvival[3], gSkillTraitValues.ubSVWeatherPenaltiesReduction, sSpecialCharacters[0] ); + swprintf( atStr, gzIMPMajorTraitsHelpTextsSurvival[3], (UINT8)(100 * gSkillTraitValues.dSVWeatherPenaltiesReduction), sSpecialCharacters[0] ); wcscat( apStr, atStr ); } diff --git a/SaveLoadGame.cpp b/SaveLoadGame.cpp index 46578a63..d40ea273 100644 --- a/SaveLoadGame.cpp +++ b/SaveLoadGame.cpp @@ -295,7 +295,7 @@ typedef struct BOOLEAN fShowOtherSAMHighLight; BOOLEAN fShowDrassenSAMHighLight; - UINT32 uiEnvWeather; + UINT32 uiEnvWeather; // Flugente: unused UINT8 ubDefaultButton; @@ -8320,7 +8320,7 @@ BOOLEAN SaveGeneralInfo( HWFILE hFile ) sGeneralInfo.fShowCambriaHospitalHighLight = fShowCambriaHospitalHighLight; //The current state of the weather - sGeneralInfo.uiEnvWeather = guiEnvWeather; + sGeneralInfo.uiEnvWeather = 0; sGeneralInfo.ubDefaultButton = gubDefaultButton; @@ -8858,10 +8858,7 @@ BOOLEAN LoadGeneralInfo( HWFILE hFile ) fShowOtherSAMHighLight = sGeneralInfo.fShowOtherSAMHighLight; fShowDrassenSAMHighLight = sGeneralInfo.fShowDrassenSAMHighLight; fShowCambriaHospitalHighLight = sGeneralInfo.fShowCambriaHospitalHighLight; - - //The current state of the weather - guiEnvWeather = sGeneralInfo.uiEnvWeather; - + //rain if ( guiRainLoop != NO_SAMPLE ) { diff --git a/Strategic/Campaign Types.h b/Strategic/Campaign Types.h index 8d05201c..7773be05 100644 --- a/Strategic/Campaign Types.h +++ b/Strategic/Campaign Types.h @@ -528,10 +528,16 @@ typedef struct SECTORINFO FLOAT dFortification_MaxPossible; // the amount of fortification that can still be done in this sector, given the current layout plans. Is updated every time we unload a sector FLOAT dFortification_UnappliedProgress; // progress done via assignment work. As we cannot update unloaded sectors, update happens once sector is loaded + // Flugente: enemy jeeps UINT8 ubNumJeeps; UINT8 ubJeepsInBattle; - INT8 bPadding[ 22 ]; + INT8 bPadding1[2]; + + // Flugente: localized weather + UINT32 usWeather; + + INT8 bPadding[ 16 ]; }SECTORINFO; diff --git a/Strategic/Game Event Hook.cpp b/Strategic/Game Event Hook.cpp index 744bd7a7..f598dde4 100644 --- a/Strategic/Game Event Hook.cpp +++ b/Strategic/Game Event Hook.cpp @@ -341,24 +341,8 @@ BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent ) ProcessTacticalSchedule( (UINT8)pEvent->uiParam ); break; case EVENT_BEGINRAINSTORM: - //EnvBeginRainStorm( (UINT8)pEvent->uiParam ); - break; case EVENT_ENDRAINSTORM: - //EnvEndRainStorm( ); - break; case EVENT_RAINSTORM: - - // ATE: Disabled - //rain - if( pEvent->ubEventType == ENDRANGED_EVENT ) - { - EnvEndRainStorm( ); - } - else - { - EnvBeginRainStorm( (UINT8)pEvent->uiParam ); - } - //end rain break; case EVENT_MAKE_CIV_GROUP_HOSTILE_ON_NEXT_SECTOR_ENTRANCE: @@ -634,6 +618,27 @@ BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent ) AddEmail( MILITIAROSTER_INTRO, MILITIAROSTER_INTRO_LENGTH, MAIL_ENRICO, GetWorldTotalMin( ), -1, -1, TYPE_EMAIL_EMAIL_EDT ); break; #endif + + // Flugente: localized weather + case EVENT_WEATHER_NORMAL: + ChangeWeather( (UINT8)pEvent->uiParam, WEATHER_FORECAST_NORMAL ); + break; + + case EVENT_WEATHER_SHOWERS: + ChangeWeather( (UINT8)pEvent->uiParam, WEATHER_FORECAST_RAIN ); + break; + + case EVENT_WEATHER_THUNDERSHOWERS: + ChangeWeather( (UINT8)pEvent->uiParam, WEATHER_FORECAST_THUNDERSHOWERS ); + break; + + case EVENT_WEATHER_SANDSTORM: + ChangeWeather( (UINT8)pEvent->uiParam, WEATHER_FORECAST_SANDSTORM ); + break; + + case EVENT_WEATHER_SNOW: + ChangeWeather( (UINT8)pEvent->uiParam, WEATHER_FORECAST_SNOW ); + break; } gfPreventDeletionOfAnyEvent = fOrigPreventFlag; return TRUE; diff --git a/Strategic/Game Event Hook.h b/Strategic/Game Event Hook.h index 21decff7..c94d7bbf 100644 --- a/Strategic/Game Event Hook.h +++ b/Strategic/Game Event Hook.h @@ -133,6 +133,12 @@ enum EVENT_SAMSITE_REPAIRED, // Flugente: have a SAM site be fully repaired EVENT_MILITIAROSTER_EMAIL, // Flugente: we get an email giving us the bookmark to the militia roster webpage + + EVENT_WEATHER_NORMAL, // Flugente: localized weather + EVENT_WEATHER_SHOWERS, + EVENT_WEATHER_THUNDERSHOWERS, + EVENT_WEATHER_SANDSTORM, + EVENT_WEATHER_SNOW, NUMBER_OF_EVENT_TYPES_PLUS_ONE, NUMBER_OF_EVENT_TYPES = NUMBER_OF_EVENT_TYPES_PLUS_ONE - 1 diff --git a/Strategic/Game Events.cpp b/Strategic/Game Events.cpp index 2c8969b6..397b2c1a 100644 --- a/Strategic/Game Events.cpp +++ b/Strategic/Game Events.cpp @@ -125,6 +125,11 @@ CHAR16 gEventName[NUMBER_OF_EVENT_TYPES_PLUS_ONE][40]={ L"EnemyHeliRefuel", L"SAMsiteRepaired", L"MilitiaWebsiteEmail", + L"Weather Normal", + L"Weather Rain", + L"Weather Thunderstorm", + L"Weather Sandstorm", + L"Weather Snow", }; #endif diff --git a/Strategic/LuaInitNPCs.cpp b/Strategic/LuaInitNPCs.cpp index 27ff0eec..055c7669 100644 --- a/Strategic/LuaInitNPCs.cpp +++ b/Strategic/LuaInitNPCs.cpp @@ -835,9 +835,6 @@ static int l_CreateItemInv (lua_State *L); static int l_MercSalary(lua_State *L); static int l_PlayerTeamFull (lua_State *L); -static int l_EnvBeginRainStorm (lua_State *L); -static int l_EnvEndRainStorm (lua_State *L); - static int l_ProfilesStrategicInsertionData (lua_State *L); static int l_ResetBoxers( lua_State *L ); @@ -1701,9 +1698,6 @@ void IniFunction(lua_State *L, BOOLEAN bQuests ) lua_register(L,"StartDialogueMessageBox", l_StartDialogueMessageBox); - lua_register(L,"EnvBeginRainStorm", l_EnvBeginRainStorm); - lua_register(L,"EnvEndRainStorm", l_EnvEndRainStorm); - lua_register( L, "AddVolunteers", l_AddVolunteers ); lua_register(L, "CreateArmedCivilain", l_CreateArmedCivilain ); @@ -4201,29 +4195,6 @@ static int l_ProfilesStrategicInsertionData (lua_State *L) return 0; } -static int l_EnvBeginRainStorm (lua_State *L) -{ -UINT8 n = lua_gettop(L); -int i; - UINT8 ubIntensity = 1; - - for (i= 1; i<=n; i++ ) - { - if (i == 1 ) ubIntensity = lua_tointeger(L,i); - } - - EnvBeginRainStorm( ubIntensity ); - - return 0; -} - -static int l_EnvEndRainStorm (lua_State *L) -{ - - EnvEndRainStorm(); - return 0; -} - static int l_SetGroupNextSectorValue(lua_State *L) { UINT8 n = lua_gettop(L); diff --git a/Strategic/Map Screen Interface Border.cpp b/Strategic/Map Screen Interface Border.cpp index 2e2c36aa..c679ee06 100644 --- a/Strategic/Map Screen Interface Border.cpp +++ b/Strategic/Map Screen Interface Border.cpp @@ -58,6 +58,8 @@ UINT16 MAP_BORDER_MOBILE_BTN_X; UINT16 MAP_BORDER_MOBILE_BTN_Y; UINT16 MAP_BORDER_DISEASE_BTN_X; // Flugente: disease UINT16 MAP_BORDER_DISEASE_BTN_Y; +UINT16 MAP_BORDER_WEATHER_BTN_X; // Flugente: weather +UINT16 MAP_BORDER_WEATHER_BTN_Y; UINT16 MAP_LEVEL_MARKER_X; UINT16 MAP_LEVEL_MARKER_Y; @@ -132,6 +134,9 @@ void BtnMobileCallback(GUI_BUTTON *btn,INT32 reason); // Flugente: disease void BtnDiseaseCallback(GUI_BUTTON *btn,INT32 reason); +// Flugente: weather +void BtnWeatherCallback( GUI_BUTTON *btn, INT32 reason ); + void LevelMarkerBtnCallback(MOUSE_REGION * pRegion, INT32 iReason ); void CommonBtnCallbackBtnDownChecks( void ); @@ -344,6 +349,28 @@ BOOLEAN CreateButtonsForMapBorder( void ) SetButtonCursor( giMapBorderButtons[MAP_BORDER_DISEASE_BTN], MSYS_NO_CURSOR ); } + // Flugente: weather + if ( gGameExternalOptions.gfAllowRain || gGameExternalOptions.gfAllowSandStorms || gGameExternalOptions.gfAllowSnow ) + { + giMapBorderButtonsImage[MAP_BORDER_WEATHER_BTN] = LoadButtonImage( "INTERFACE\\map_border_buttons.sti", -1, 37, -1, 38, -1 ); + + // if the button image cannot be created, this is likely to a custom sti replacement that isn't up to date to this feature - just use some other images then + if ( giMapBorderButtonsImage[MAP_BORDER_WEATHER_BTN] < 0 ) + giMapBorderButtonsImage[MAP_BORDER_WEATHER_BTN] = LoadButtonImage( "INTERFACE\\map_border_buttons.sti", -1, 2, -1, 11, -1 ); + + INT16 x = MAP_BORDER_WEATHER_BTN_X; + if ( giMapBorderButtonsImage[MAP_BORDER_DISEASE_BTN] < 0 ) + x = MAP_BORDER_DISEASE_BTN_X; + + giMapBorderButtons[MAP_BORDER_WEATHER_BTN] = QuickCreateButton( giMapBorderButtonsImage[MAP_BORDER_WEATHER_BTN], x, MAP_BORDER_WEATHER_BTN_Y, + BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH, + (GUI_CALLBACK)MSYS_NO_CALLBACK, (GUI_CALLBACK)BtnWeatherCallback ); + + SetButtonFastHelpText( giMapBorderButtons[MAP_BORDER_WEATHER_BTN], pMapScreenBorderButtonHelpText[MAP_BORDER_WEATHER_BTN] ); + + SetButtonCursor( giMapBorderButtons[MAP_BORDER_WEATHER_BTN], MSYS_NO_CURSOR ); + } + #ifdef JA2UB //EnableButton @@ -411,6 +438,7 @@ BOOLEAN CreateButtonsForMapBorder( void ) DisableButton( giMapBorderButtons[ MAP_BORDER_ITEM_BTN ]); DisableButton( giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ]); DisableButton( giMapBorderButtons[ MAP_BORDER_DISEASE_BTN ]); + DisableButton( giMapBorderButtons[ MAP_BORDER_WEATHER_BTN ]); fShowTownFlag = FALSE; #endif @@ -439,6 +467,9 @@ void DeleteMapBorderButtons( void ) if ( giMapBorderButtons[MAP_BORDER_DISEASE_BTN] != -1 ) RemoveButton( giMapBorderButtons[MAP_BORDER_DISEASE_BTN] ); + if ( giMapBorderButtons[MAP_BORDER_WEATHER_BTN] != -1 ) + RemoveButton( giMapBorderButtons[MAP_BORDER_WEATHER_BTN] ); + // images UnloadButtonImage( giMapBorderButtonsImage[ MAP_BORDER_TOWN_BTN ] ); @@ -454,6 +485,9 @@ void DeleteMapBorderButtons( void ) if ( giMapBorderButtonsImage[MAP_BORDER_DISEASE_BTN] != -1 ) UnloadButtonImage( giMapBorderButtonsImage[MAP_BORDER_DISEASE_BTN] ); + + if ( giMapBorderButtonsImage[MAP_BORDER_WEATHER_BTN] != -1 ) + UnloadButtonImage( giMapBorderButtonsImage[MAP_BORDER_WEATHER_BTN] ); // HEADROCK HAM 4: Increased number of buttons by one. for ( ubCnt = 0; ubCnt < NUM_MAP_BORDER_BTNS; ++ubCnt ) @@ -565,6 +599,21 @@ void BtnDiseaseCallback( GUI_BUTTON *btn, INT32 reason ) } } +// Flugente: weather +void BtnWeatherCallback( GUI_BUTTON *btn, INT32 reason ) +{ + if ( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) + { + CommonBtnCallbackBtnDownChecks( ); + + ToggleWeatherFilter( ); + } + else if ( reason & MSYS_CALLBACK_REASON_RBUTTON_DWN ) + { + CommonBtnCallbackBtnDownChecks( ); + } +} + // HEADROCK HAM 4: Callback for Mobile Restrictions Button void BtnMobileCallback(GUI_BUTTON *btn,INT32 reason) { @@ -797,6 +846,27 @@ void ToggleDiseaseFilter( void ) } } +// Flugente: weather +void ToggleWeatherFilter( void ) +{ + if ( gusMapDisplayColourMode == MAP_DISPLAY_WEATHER ) + { + gusMapDisplayColourMode = MAP_DISPLAY_NORMAL; + + MapBorderButtonOff( MAP_BORDER_WEATHER_BTN ); + + // dirty regions + fMapPanelDirty = TRUE; + fTeamPanelDirty = TRUE; + fCharacterInfoPanelDirty = TRUE; + } + else + { + // turn ON + TurnOnWeatherFilterMode( ); + } +} + // HEADROCK HAM 4: Toggle Mobile Restrictions Button void ToggleMobileFilter( void ) { @@ -943,6 +1013,7 @@ void TurnOnAirSpaceMode( void ) MapBorderButtonOn( MAP_BORDER_AIRSPACE_BTN ); MapBorderButtonOff( MAP_BORDER_MOBILE_BTN ); MapBorderButtonOff( MAP_BORDER_DISEASE_BTN ); + MapBorderButtonOff( MAP_BORDER_WEATHER_BTN ); // Turn off towns & mines (mostly because town/mine names overlap SAM site names) if( fShowTownFlag == TRUE ) @@ -1069,6 +1140,7 @@ void TurnOnDiseaseFilterMode( void ) MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN ); MapBorderButtonOff( MAP_BORDER_MOBILE_BTN ); MapBorderButtonOn( MAP_BORDER_DISEASE_BTN ); + MapBorderButtonOff( MAP_BORDER_WEATHER_BTN ); if( fShowItemsFlag == TRUE ) { @@ -1124,6 +1196,74 @@ void TurnOnDiseaseFilterMode( void ) } } +void TurnOnWeatherFilterMode() +{ + // if mode already on, leave, else set and redraw + if ( gusMapDisplayColourMode != MAP_DISPLAY_WEATHER ) + { + gusMapDisplayColourMode = MAP_DISPLAY_WEATHER; + + MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN ); + MapBorderButtonOff( MAP_BORDER_MOBILE_BTN ); + MapBorderButtonOff( MAP_BORDER_DISEASE_BTN ); + MapBorderButtonOn( MAP_BORDER_WEATHER_BTN ); + + if ( fShowItemsFlag == TRUE ) + { + fShowItemsFlag = FALSE; + MapBorderButtonOff( MAP_BORDER_ITEM_BTN ); + } + + // Turn off towns, mines, teams, militia & airspace if any are on + if ( fShowTownFlag == TRUE ) + { + fShowTownFlag = FALSE; + MapBorderButtonOff( MAP_BORDER_TOWN_BTN ); + } + + if ( fShowMineFlag == TRUE ) + { + fShowMineFlag = FALSE; + MapBorderButtonOff( MAP_BORDER_MINE_BTN ); + } + + if ( fShowTeamFlag == TRUE ) + { + fShowTeamFlag = FALSE; + MapBorderButtonOff( MAP_BORDER_TEAMS_BTN ); + } + + if ( fShowMilitia == TRUE ) + { + fShowMilitia = FALSE; + MapBorderButtonOff( MAP_BORDER_MILITIA_BTN ); + } + + if ( (bSelectedDestChar != -1) || fPlotForHelicopter || fPlotForMilitia ) + { + AbortMovementPlottingMode( ); + } + else if ( gfInChangeArrivalSectorMode ) + { + CancelChangeArrivalSectorMode( ); + } + + // Flugente: basically only show this message the first time every session + static BOOLEAN sWeatherviewed = FALSE; + if ( !sWeatherviewed ) + { + MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, zMarksMapScreenText[28] ); + + sWeatherviewed = TRUE; + } + + // dirty regions + fMapPanelDirty = TRUE; + fTeamPanelDirty = TRUE; + fCharacterInfoPanelDirty = TRUE; + } +} + // HEADROCK HAM 4: Activate "View Mobile Restrictions" mode. void TurnOnMobileFilterMode( void ) { @@ -1136,6 +1276,7 @@ void TurnOnMobileFilterMode( void ) MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN ); MapBorderButtonOn( MAP_BORDER_MOBILE_BTN ); MapBorderButtonOff( MAP_BORDER_DISEASE_BTN ); + MapBorderButtonOff( MAP_BORDER_WEATHER_BTN ); // Also turn on Militia mode fShowMilitia = FALSE; // Fool the function so that it always turns militia ON. @@ -1252,18 +1393,28 @@ void InitializeMapBorderButtonStates( void ) MapBorderButtonOn( MAP_BORDER_AIRSPACE_BTN ); MapBorderButtonOff( MAP_BORDER_MOBILE_BTN ); MapBorderButtonOff( MAP_BORDER_DISEASE_BTN ); + MapBorderButtonOff( MAP_BORDER_WEATHER_BTN ); break; case MAP_DISPLAY_MOBILEMILITIARESTRICTIONS: MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN ); MapBorderButtonOn( MAP_BORDER_MOBILE_BTN ); MapBorderButtonOff( MAP_BORDER_DISEASE_BTN ); + MapBorderButtonOff( MAP_BORDER_WEATHER_BTN ); break; case MAP_DISPLAY_DISEASE: MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN ); MapBorderButtonOff( MAP_BORDER_MOBILE_BTN ); MapBorderButtonOn( MAP_BORDER_DISEASE_BTN ); + MapBorderButtonOff( MAP_BORDER_WEATHER_BTN ); + break; + + case MAP_DISPLAY_WEATHER: + MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN ); + MapBorderButtonOff( MAP_BORDER_MOBILE_BTN ); + MapBorderButtonOff( MAP_BORDER_DISEASE_BTN ); + MapBorderButtonOn( MAP_BORDER_WEATHER_BTN ); break; } } @@ -1415,6 +1566,8 @@ void InitMapBorderButtonCoordinates() MAP_BORDER_MOBILE_BTN_Y = 0; MAP_BORDER_DISEASE_BTN_X = xResOffset + MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X - 2 * xResOffset) / 2) + 190; MAP_BORDER_DISEASE_BTN_Y = (SCREEN_HEIGHT - yResOffset - buttonOffset); + MAP_BORDER_WEATHER_BTN_X = xResOffset + MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X - 2 * xResOffset) / 2) + 233; + MAP_BORDER_WEATHER_BTN_Y = (SCREEN_HEIGHT - yResOffset - buttonOffset); MAP_LEVEL_MARKER_X = xResOffset + MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X - 2 * xResOffset) / 2) + 114; MAP_LEVEL_MARKER_Y = (SCREEN_HEIGHT - yResOffset - buttonOffset); diff --git a/Strategic/Map Screen Interface Border.h b/Strategic/Map Screen Interface Border.h index 5ad7e63c..c9ac453e 100644 --- a/Strategic/Map Screen Interface Border.h +++ b/Strategic/Map Screen Interface Border.h @@ -32,6 +32,7 @@ enum{ MAP_BORDER_MILITIA_BTN, MAP_BORDER_MOBILE_BTN, // HEADROCK HAM 4: Mobile Militia Restrictions button MAP_BORDER_DISEASE_BTN, // Flugente: toggle disease views + MAP_BORDER_WEATHER_BTN, // Flugente: toggle weather display NUM_MAP_BORDER_BTNS, // end enumeration marker }; @@ -57,6 +58,7 @@ enum MAP_DISPLAY_AIRSPACE, MAP_DISPLAY_MOBILEMILITIARESTRICTIONS, MAP_DISPLAY_DISEASE, + MAP_DISPLAY_WEATHER, }; extern UINT8 gusMapDisplayColourMode; @@ -83,6 +85,9 @@ void ToggleMobileFilter( void ); // Flugente: disease void ToggleDiseaseFilter( ); +// Flugente: weather +void ToggleWeatherFilter( ); + void TurnOnShowTeamsMode( void ); void TurnOnAirSpaceMode( void ); void TurnOnItemFilterMode( void ); @@ -92,6 +97,9 @@ void TurnOnMobileFilterMode( void ); // Flugente: disease void TurnOnDiseaseFilterMode(); +// Flugente: weather +void TurnOnWeatherFilterMode( ); + // create/destroy buttons for map border region void DeleteMapBorderButtons( void ); BOOLEAN CreateButtonsForMapBorder( void ); diff --git a/Strategic/Map Screen Interface Map.cpp b/Strategic/Map Screen Interface Map.cpp index 82613d17..6c94de92 100644 --- a/Strategic/Map Screen Interface Map.cpp +++ b/Strategic/Map Screen Interface Map.cpp @@ -808,7 +808,11 @@ UINT32 DrawMap( void ) break; case MAP_DISPLAY_DISEASE: - ShadeMapElem( cnt, cnt2, GetMapColour( cnt, cnt2, TRUE ) ); + ShadeMapElem( cnt, cnt2, GetMapColour( cnt, cnt2, 0 ) ); + break; + + case MAP_DISPLAY_WEATHER: + ShadeMapElem( cnt, cnt2, GetMapColour( cnt, cnt2, 1 ) ); break; case MAP_DISPLAY_NORMAL: diff --git a/Strategic/XML_SectorNames.cpp b/Strategic/XML_SectorNames.cpp index 1f42b76f..01d08d6f 100644 --- a/Strategic/XML_SectorNames.cpp +++ b/Strategic/XML_SectorNames.cpp @@ -93,7 +93,10 @@ SectorNameStartElementHandle(void *userData, const XML_Char *name, const char ** strcmp(name, "usCurfewValue") == 0 || strcmp(name, "sRadioScanModifier") == 0 || strcmp(name, "usPrisonRoomNumber" ) == 0 || - strcmp(name, "usCivilianPopulation") == 0 )) + strcmp(name, "usCivilianPopulation" ) == 0 || + strcmp(name, "rainchance" ) == 0 || + strcmp(name, "sandstormchance") == 0 || + strcmp(name, "snowchance" ) == 0 )) { pData->curElement = ELEMENT_PROPERTY; @@ -194,7 +197,22 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name) SectorExternalData[ubSectorId][1].usCivilianPopulation = pData->sectordata.usCivilianPopulation; SectorExternalData[ubSectorId][2].usCivilianPopulation = pData->sectordata.usCivilianPopulation; SectorExternalData[ubSectorId][3].usCivilianPopulation = pData->sectordata.usCivilianPopulation; - + + SectorExternalData[ubSectorId][0].rainchance = pData->sectordata.rainchance; + SectorExternalData[ubSectorId][1].rainchance = 0; + SectorExternalData[ubSectorId][2].rainchance = 0; + SectorExternalData[ubSectorId][3].rainchance = 0; + + SectorExternalData[ubSectorId][0].sandstormchance = pData->sectordata.sandstormchance; + SectorExternalData[ubSectorId][1].sandstormchance = 0; + SectorExternalData[ubSectorId][2].sandstormchance = 0; + SectorExternalData[ubSectorId][3].sandstormchance = 0; + + SectorExternalData[ubSectorId][0].snowchance = pData->sectordata.snowchance; + SectorExternalData[ubSectorId][1].snowchance = 0; + SectorExternalData[ubSectorId][2].snowchance = 0; + SectorExternalData[ubSectorId][3].snowchance = 0; + if ( !prisonroomvector.empty( ) ) { std::vector::iterator itend = prisonroomvector.end( ); @@ -213,6 +231,9 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name) pData->sectordata.usCurfewValue = 0; pData->sectordata.sRadioScanModifier = 0; pData->sectordata.usCivilianPopulation = 0; + pData->sectordata.rainchance = 0; + pData->sectordata.sandstormchance = 0; + pData->sectordata.snowchance = 0; } else { @@ -307,6 +328,21 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name) pData->curElement = ELEMENT; pData->sectordata.usCivilianPopulation = (UINT16)atoi( pData->szCharData ); } + else if ( strcmp( name, "rainchance" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->sectordata.rainchance = min( 100, (UINT8)atoi( pData->szCharData ) ); + } + else if ( strcmp( name, "sandstormchance" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->sectordata.sandstormchance = min( 100, (UINT8)atoi( pData->szCharData ) ); + } + else if ( strcmp( name, "snowchance" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->sectordata.snowchance = min( 100, (UINT8)atoi( pData->szCharData ) ); + } pData->maxReadDepth--; } diff --git a/Tactical/Disease.cpp b/Tactical/Disease.cpp index 1e642be0..c069de85 100644 --- a/Tactical/Disease.cpp +++ b/Tactical/Disease.cpp @@ -20,6 +20,7 @@ #include "DynamicDialogue.h" #include #include "Drugs And Alcohol.h" // for DoesMercHaveDisability( ... ) +#include "environment.h" //GLOBALS DISEASE Disease[NUM_DISEASES]; @@ -503,9 +504,11 @@ UINT16 GetSectorPopulation( INT16 sX, INT16 sY, BOOLEAN fWithMilitary ) } // colour for a sector on the map -INT32 GetMapColour( INT16 sX, INT16 sY, BOOLEAN aDiseaseOn ) +// aType = 0: disease +// aType = 1: weather +INT32 GetMapColour( INT16 sX, INT16 sY, UINT8 aType ) { - if ( aDiseaseOn ) + if ( aType == 0 ) { UINT16 population = GetSectorPopulation( sX, sY ); @@ -541,6 +544,36 @@ INT32 GetMapColour( INT16 sX, INT16 sY, BOOLEAN aDiseaseOn ) } } } + else if ( aType == 1 ) + { + UINT8 sector = SECTOR( sX, sY ); + + SECTORINFO *pSectorInfo = &(SectorInfo[sector]); + + // display sector information only if we know about infection there + if ( pSectorInfo ) + { + switch ( pSectorInfo->usWeather ) + { + case WEATHER_FORECAST_RAIN: + return MAP_SHADE_LT_CYAN; + break; + case WEATHER_FORECAST_THUNDERSHOWERS: + return MAP_SHADE_LT_BLUE; + break; + case WEATHER_FORECAST_SANDSTORM: + return MAP_SHADE_ORANGE; + break; + case WEATHER_FORECAST_SNOW: + return MAP_SHADE_LT_GREY; + break; + case WEATHER_FORECAST_NORMAL: + default: + return MAP_SHADE_BLACK; + break; + } + } + } return MAP_SHADE_DK_GREY; } diff --git a/Tactical/Disease.h b/Tactical/Disease.h index b2d6f68d..d1ded664 100644 --- a/Tactical/Disease.h +++ b/Tactical/Disease.h @@ -138,7 +138,9 @@ INT16 GetAdjacentSector( UINT8 sector, UINT8 spdir ); UINT16 GetSectorPopulation( INT16 sX, INT16 sY, BOOLEAN fWithMilitary = TRUE ); // colour for a sector on the map -INT32 GetMapColour( INT16 sX, INT16 sY, BOOLEAN aDiseaseOn ); +// aType = 0: disease +// aType = 1: weather +INT32 GetMapColour( INT16 sX, INT16 sY, UINT8 aType ); // handle infection redistribution if people move from A to B (set sXB and sYB to negative values to simply remove infected people in A) void PopulationMove( INT16 sXA, INT16 sYA, INT16 sXB, INT16 sYB, UINT16 usAmount ); diff --git a/Tactical/Items.h b/Tactical/Items.h index 48a07abb..63307eec 100644 --- a/Tactical/Items.h +++ b/Tactical/Items.h @@ -505,6 +505,9 @@ typedef struct UINT16 usCivilianPopulation; // total amount of civilians that are supposed to be in this sector. This does not have to be the number of civilians in tactical + UINT8 rainchance; // chance that it rains in this sector + UINT8 sandstormchance; // chance that a sandstorm happens in this sector + UINT8 snowchance; // chance that it snows in this sector } SECTOR_EXT_DATA; // get dirt increase for object with attachments, fConsiderAmmo: with ammo diff --git a/Tactical/LOS.cpp b/Tactical/LOS.cpp index f10eef58..df87589c 100644 --- a/Tactical/LOS.cpp +++ b/Tactical/LOS.cpp @@ -6154,7 +6154,12 @@ INT8 FireBulletGivenTargetTrapOnly( SOLDIERTYPE* pThrower, OBJECTTYPE* pObj, INT int maxJamChance = 50; // Externalize this? int reliability = GetReliability( pObj ); int condition = (*pObj)[0]->data.gun.bGunStatus; - int invertedBaseJamChance = condition + (reliability * 2) - gGameExternalOptions.ubWeaponReliabilityReductionPerRainIntensity * 1; + + int weatherpenalty = 0; + if ( pThrower && !pThrower->bSectorZ ) + weatherpenalty = gGameExternalOptions.ubWeaponReliabilityReduction[SectorInfo[SECTOR( pThrower->sSectorX, pThrower->sSectorY )].usWeather]; + + int invertedBaseJamChance = condition + (reliability * 2) - weatherpenalty; // Flugente: If overheating is allowed, a gun will be prone to more overheating if its temperature is high if ( gGameExternalOptions.fWeaponOverheating ) diff --git a/Tactical/Points.cpp b/Tactical/Points.cpp index 5dd265e7..209654bf 100644 --- a/Tactical/Points.cpp +++ b/Tactical/Points.cpp @@ -1461,10 +1461,6 @@ void UnusedAPsToBreath( SOLDIERTYPE * pSoldier ) } -//rain -extern INT8 gbCurrentRainIntensity; -//end rain - INT16 GetBreathPerAP( SOLDIERTYPE *pSoldier, UINT16 usAnimState ) { INT16 sBreathPerAP = 0; @@ -1540,21 +1536,18 @@ INT16 GetBreathPerAP( SOLDIERTYPE *pSoldier, UINT16 usAnimState ) //rain // Reduce breath gain on 25%/rain intensity // Lalien: only for soldiers that are in loaded sector, - if ( gfWorldLoaded && pSoldier->bInSector) + if ( gfWorldLoaded && pSoldier->bInSector && !pSoldier->bSectorZ ) { if( sBreathPerAP < 0 && ( pSoldier->pathing.bLevel || !FindStructure( pSoldier->sGridNo, STRUCTURE_ROOF ) ) && pSoldier->bBreath > 1) { + FLOAT weatherpenalty = gGameExternalOptions.dBreathGainReduction[SectorInfo[SECTOR( pSoldier->sSectorX, pSoldier->sSectorY )].usWeather]; + // Added a feature to reduce rain effect on regaining breath with Ranger trait - SANDRO - if ( HAS_SKILL_TRAIT( pSoldier, SURVIVAL_NT ) && (gGameOptions.fNewTraitSystem) ) - { - INT16 sBreathGainPenalty = 0; - sBreathGainPenalty = (INT16)((gGameExternalOptions.ubBreathGainReductionPerRainIntensity * (100 - gSkillTraitValues.ubSVWeatherPenaltiesReduction * NUM_SKILL_TRAITS( pSoldier, SURVIVAL_NT ))) / 100); - sBreathGainPenalty = min( max( 0, sBreathGainPenalty ), 100); // keep it 0-100% - sBreathPerAP -= (INT16)( sBreathPerAP * gbCurrentRainIntensity * sBreathGainPenalty /100 ); - } - else - sBreathPerAP -= (INT16)( sBreathPerAP * gbCurrentRainIntensity * gGameExternalOptions.ubBreathGainReductionPerRainIntensity / 100 ); + FLOAT appliedpenalty = 1.0f; + if ( HAS_SKILL_TRAIT( pSoldier, SURVIVAL_NT ) && gGameOptions.fNewTraitSystem ) + appliedpenalty = min( 1.0f, max( 0.0f, appliedpenalty - gSkillTraitValues.dSVWeatherPenaltiesReduction * NUM_SKILL_TRAITS( pSoldier, SURVIVAL_NT ) ) ); + sBreathPerAP -= (INT16)(sBreathPerAP * weatherpenalty * appliedpenalty); } } //end rain diff --git a/Tactical/Rain.cpp b/Tactical/Rain.cpp index 707ab29c..3cca1810 100644 --- a/Tactical/Rain.cpp +++ b/Tactical/Rain.cpp @@ -107,7 +107,7 @@ TRainDrop *pRainDrops = 0; UINT32 guiCurrMaxAmountOfRainDrops = 0; UINT32 guiCurrAmountOfDeadRainDrops = 0; -INT8 gbCurrentRainIntensity = 0; +UINT8 gbCurrentWeather = 0; FLOAT fpCurrDropAngleOfFalling = 0; FLOAT fpCurrDropLength = 0; @@ -123,7 +123,6 @@ FLOAT fpMinDropSpeed = 0; extern UINT32 guiCurrentScreen; -//extern BOOLEAN gfAllowRain; extern INT16 gsVIEWPORT_WINDOW_END_Y; extern INT16 gsVIEWPORT_WINDOW_START_Y; @@ -134,26 +133,17 @@ extern UINT32 guiNumVideoOverlays; extern MercPopUpBox *gPopUpTextBox; -INT8 GetRainIntensityFromEnvWeather() -{ - INT8 bRes = 0; - - // Debug!!! -// guiEnvWeather |= WEATHER_FORECAST_THUNDERSHOWERS; - - if( guiEnvWeather & WEATHER_FORECAST_SHOWERS ) bRes += 1; - if( guiEnvWeather & WEATHER_FORECAST_THUNDERSHOWERS ) bRes += 2; - - return bRes; -} - BOOLEAN IsItAllowedToRenderRain() { - if( !gGameExternalOptions.gfAllowRain )return FALSE; + if ( !(gGameExternalOptions.gfAllowRain || gGameExternalOptions.gfAllowSandStorms || gGameExternalOptions.gfAllowSnow) ) + return FALSE; - if( !( guiEnvWeather & (WEATHER_FORECAST_THUNDERSHOWERS | WEATHER_FORECAST_SHOWERS) ) )return FALSE; + if ( !(GetWeatherInCurrentSector( ) == WEATHER_FORECAST_RAIN || GetWeatherInCurrentSector( ) == WEATHER_FORECAST_THUNDERSHOWERS + || GetWeatherInCurrentSector( ) == WEATHER_FORECAST_SANDSTORM || GetWeatherInCurrentSector( ) == WEATHER_FORECAST_SNOW ) ) + return FALSE; - if( guiCurrentScreen != GAME_SCREEN && guiCurrentScreen != SHOPKEEPER_SCREEN ) return FALSE; + if( guiCurrentScreen != GAME_SCREEN && guiCurrentScreen != SHOPKEEPER_SCREEN ) + return FALSE; return TRUE; } @@ -194,7 +184,7 @@ void ResetRain() } // Rain - BASE_DROP_SPEED = 7.0f; + BASE_DROP_SPEED = 3.5f; DROP_SPEED_RANGE = 3.5f; DROP_SPEED_CHANGE_RATE = 0.1f; DROP_SPEED_RAND = 5.0f; @@ -204,8 +194,29 @@ void ResetRain() void GenerateRainDropsList() { - // HEADROCK HAM 5 XMAS: More snow than rain. - guiCurrMaxAmountOfRainDrops = (UINT32)(BASE_MAXIMUM_DROPS) * gbCurrentRainIntensity; + switch ( gbCurrentWeather ) + { + case WEATHER_FORECAST_NORMAL: + guiCurrMaxAmountOfRainDrops = 0; + break; + + case WEATHER_FORECAST_THUNDERSHOWERS: + guiCurrMaxAmountOfRainDrops = (UINT32)(BASE_MAXIMUM_DROPS)* 2; + break; + + case WEATHER_FORECAST_SANDSTORM: + guiCurrMaxAmountOfRainDrops = (UINT32)(BASE_MAXIMUM_DROPS)* 8; + break; + + case WEATHER_FORECAST_SNOW: + guiCurrMaxAmountOfRainDrops = (UINT32)(BASE_MAXIMUM_DROPS)* 4; + break; + + case WEATHER_FORECAST_RAIN: + default: + guiCurrMaxAmountOfRainDrops = (UINT32)(BASE_MAXIMUM_DROPS); + break; + } pRainDrops = (TRainDrop *)MemAlloc( sizeof( TRainDrop ) * guiCurrMaxAmountOfRainDrops ); memset( pRainDrops, 0, sizeof( TRainDrop ) * guiCurrMaxAmountOfRainDrops ); @@ -213,9 +224,7 @@ void GenerateRainDropsList() void KillOutOfRegionRainDrops() { - UINT32 uiIndex; - - for( uiIndex = 0; uiIndex < guiCurrMaxAmountOfRainDrops; ++uiIndex ) + for ( UINT32 uiIndex = 0; uiIndex < guiCurrMaxAmountOfRainDrops; ++uiIndex ) { TRainDrop *pCurr = &pRainDrops[ uiIndex ]; @@ -225,9 +234,8 @@ void KillOutOfRegionRainDrops() pCurr->fpY + pCurr->fpEndRelY < gRainRegion.top || pCurr->fpY + pCurr->fpEndRelY >= gRainRegion.bottom ) ) { pCurr->fAlive = FALSE; - guiCurrAmountOfDeadRainDrops++; + ++guiCurrAmountOfDeadRainDrops; } - } } @@ -342,29 +350,29 @@ void CreateRainDrops() } } - uiCreatedDrops++; + ++uiCreatedDrops; // drop creation is done!!! - } } void UpdateRainDrops() { - UINT32 uiIndex; - - for( uiIndex = 0; uiIndex < guiCurrMaxAmountOfRainDrops; ++uiIndex ) + for ( UINT32 uiIndex = 0; uiIndex < guiCurrMaxAmountOfRainDrops; ++uiIndex ) { TRainDrop *pCurr = &pRainDrops[ uiIndex ]; - if( !pCurr->fAlive )continue; + if( !pCurr->fAlive ) + continue; if( pCurr->uiAmountOfTicksToLive ) { pCurr->fpX += pCurr->fpIncrX; pCurr->fpY += pCurr->fpIncrY; pCurr->uiAmountOfTicksToLive--; - }else{ + } + else + { pCurr->fpEndRelX += pCurr->fpIncrX; pCurr->fpEndRelY += pCurr->fpIncrY; @@ -374,11 +382,10 @@ void UpdateRainDrops() ( pCurr->fpEndRelY < 0 && pCurr->fpIncrY < 0 ) ) { pCurr->fAlive = FALSE; - guiCurrAmountOfDeadRainDrops++; + ++guiCurrAmountOfDeadRainDrops; } } } - } void BlankRainRenderSurface() @@ -393,7 +400,25 @@ UINT16 GetDropColor() uiRGBPart = max( 0, uiRGBPart ); uiRGBPart = min( 255, uiRGBPart ); - return Get16BPPColor( FROMRGB( uiRGBPart, uiRGBPart, uiRGBPart ) ); + UINT32 red = uiRGBPart; + UINT32 green = uiRGBPart; + UINT32 blue = uiRGBPart; + + // in a sandstorm, the 'raindrops' are tiny sand particles + if ( GetWeatherInCurrentSector( ) == WEATHER_FORECAST_SANDSTORM ) + { + red = 252; + green = 141; + blue = 41; + } + else if ( GetWeatherInCurrentSector() == WEATHER_FORECAST_SNOW ) + { + red = 255; + green = 255; + blue = 255; + } + + return Get16BPPColor( FROMRGB( red, green, blue ) ); } void RenderRainOnSurface() @@ -419,13 +444,26 @@ void RenderRainOnSurface() UnLockVideoSurface( guiRainRenderSurface ); } +extern UINT32 guiRainLoop; + + void GenerateRainMaximums() { - if( gbCurrentRainIntensity == 1 ) + if ( GetWeatherInCurrentSector( ) == WEATHER_FORECAST_THUNDERSHOWERS ) { fpMinDropAngleOfFalling = 45; fpMaxDropAngleOfFalling = 135; } + else if ( GetWeatherInCurrentSector( ) == WEATHER_FORECAST_SANDSTORM ) + { + fpMinDropAngleOfFalling = 5; + fpMaxDropAngleOfFalling = 15; + } + else if ( GetWeatherInCurrentSector() == WEATHER_FORECAST_SNOW ) + { + fpMinDropAngleOfFalling = 80; + fpMaxDropAngleOfFalling = 100; + } else { if( Random( 2 ) ) @@ -442,46 +480,97 @@ void GenerateRainMaximums() fpCurrDropAngleOfFalling = fpMinDropAngleOfFalling + Random( (UINT32)(fpMaxDropAngleOfFalling - fpMinDropAngleOfFalling) ); - fpMinDropLength = MIN_DROP_LENGTH + ADD_DROP_LENGTH_IF_STORM * ( gbCurrentRainIntensity - 1 ); - fpMaxDropLength = fpMinDropLength + DROP_LENGTH_RANGE; + fpMinDropLength = MIN_DROP_LENGTH; + if ( GetWeatherInCurrentSector( ) == WEATHER_FORECAST_THUNDERSHOWERS ) + fpMinDropLength += ADD_DROP_LENGTH_IF_STORM; + else if ( GetWeatherInCurrentSector( ) == WEATHER_FORECAST_SANDSTORM || GetWeatherInCurrentSector( ) == WEATHER_FORECAST_SNOW ) + fpMinDropLength = 1.0f; + fpMaxDropLength = fpMinDropLength + DROP_LENGTH_RANGE; + fpCurrDropLength = fpMinDropLength + Random( (UINT32)(fpMaxDropLength - fpMinDropLength) ); - fpMinDropSpeed = BASE_DROP_SPEED * gbCurrentRainIntensity; + switch ( gbCurrentWeather ) + { + case WEATHER_FORECAST_NORMAL: + fpMinDropSpeed = 0; + break; + + case WEATHER_FORECAST_THUNDERSHOWERS: + fpMinDropSpeed = BASE_DROP_SPEED * 4; + break; + + case WEATHER_FORECAST_SANDSTORM: + fpMinDropSpeed = BASE_DROP_SPEED * 8; + break; + + case WEATHER_FORECAST_SNOW: + fpMinDropSpeed = 1.0f;//BASE_DROP_SPEED; + break; + + case WEATHER_FORECAST_RAIN: + default: + fpMinDropSpeed = BASE_DROP_SPEED * 2; + break; + } + + // haxx + if ( guiRainLoop != NO_SAMPLE ) + { + SoundStop( guiRainLoop ); + guiRainLoop = NO_SAMPLE; + } + fpMaxDropSpeed = fpMinDropSpeed + DROP_SPEED_RANGE; fpCurrDropSpeed = fpMinDropSpeed + Random( (UINT32)(fpMaxDropSpeed - fpMinDropSpeed) ); - } void UpdateRainDropsProperities() { - fpCurrDropAngleOfFalling += Random( (UINT32)(1000 * DROP_ANGLE_CHANGE_RATE * gbCurrentRainIntensity * 2 )) / 1000.0f - DROP_ANGLE_CHANGE_RATE * gbCurrentRainIntensity; + switch ( gbCurrentWeather ) + { + case WEATHER_FORECAST_NORMAL: + fpCurrDropAngleOfFalling = 0; + break; + case WEATHER_FORECAST_THUNDERSHOWERS: + fpCurrDropAngleOfFalling += Random( (UINT32)(1000 * DROP_ANGLE_CHANGE_RATE * 4) ) / 1000.0f - DROP_ANGLE_CHANGE_RATE * 2; + break; + + case WEATHER_FORECAST_SANDSTORM: + fpCurrDropAngleOfFalling += Random( (UINT32)(1000 * DROP_ANGLE_CHANGE_RATE * 6) ) / 1000.0f - DROP_ANGLE_CHANGE_RATE * 3; + break; + + case WEATHER_FORECAST_SNOW: + fpCurrDropAngleOfFalling += Random( (UINT32)(1000 * DROP_ANGLE_CHANGE_RATE * 1) ) / 1000.0f - DROP_ANGLE_CHANGE_RATE * 1; + break; + + case WEATHER_FORECAST_RAIN: + default: + fpCurrDropAngleOfFalling += Random( (UINT32)(1000 * DROP_ANGLE_CHANGE_RATE * 2) ) / 1000.0f - DROP_ANGLE_CHANGE_RATE; + break; + } + fpCurrDropAngleOfFalling = max( fpMinDropAngleOfFalling, fpCurrDropAngleOfFalling ); fpCurrDropAngleOfFalling = min( fpMaxDropAngleOfFalling, fpCurrDropAngleOfFalling ); - - + fpCurrDropLength += Random( (UINT32)(1000 * DROP_LENGTH_CHANGE_RATE * 2 )) / 1000.0f - DROP_LENGTH_CHANGE_RATE; fpCurrDropLength = max( fpMinDropLength, fpCurrDropLength ); fpCurrDropLength = min( fpMaxDropLength, fpCurrDropLength ); - - + fpCurrDropSpeed += Random( (UINT32)(1000 * DROP_SPEED_CHANGE_RATE * 2 )) / 1000.0f - DROP_SPEED_CHANGE_RATE; fpCurrDropSpeed = max( fpMinDropSpeed, fpCurrDropSpeed ); fpCurrDropSpeed = min( fpMaxDropSpeed, fpCurrDropSpeed ); - - } void RandomizeRainDropsPosition() { - UINT32 uiIndex; UINT32 ubMoveTo; - for( uiIndex = 0; uiIndex < guiCurrMaxAmountOfRainDrops; ++uiIndex ) + for ( UINT32 uiIndex = 0; uiIndex < guiCurrMaxAmountOfRainDrops; ++uiIndex ) { TRainDrop *pCurr = &pRainDrops[ uiIndex ]; @@ -499,15 +588,13 @@ void RandomizeRainDropsPosition() } } } - } void RainClipVideoOverlay() { - UINT32 uiIndex; BACKGROUND_SAVE *pCurr; - for( uiIndex = 0; uiIndex < guiNumVideoOverlays ; ++uiIndex ) + for ( UINT32 uiIndex = 0; uiIndex < guiNumVideoOverlays; ++uiIndex ) { pCurr = gVideoOverlays[ uiIndex ].pBackground; @@ -521,13 +608,14 @@ void RainClipVideoOverlay() void RenderRain() { - if( !GetRainIntensityFromEnvWeather() && gbCurrentRainIntensity ) + if ( !GetWeatherInCurrentSector( ) && gbCurrentWeather ) { - gbCurrentRainIntensity = GetRainIntensityFromEnvWeather(); + gbCurrentWeather = GetWeatherInCurrentSector( ); ResetRain(); } - if( !IsItAllowedToRenderRain() )return; + if( !IsItAllowedToRenderRain() ) + return; if( guiCurrentScreen == SHOPKEEPER_SCREEN ) { @@ -555,14 +643,13 @@ void RenderRain() else guiLastRainUpdate = GetJA2Clock(); - if( gbCurrentRainIntensity != GetRainIntensityFromEnvWeather() ) + if ( gbCurrentWeather != GetWeatherInCurrentSector( ) ) { - gbCurrentRainIntensity = GetRainIntensityFromEnvWeather(); + gbCurrentWeather = GetWeatherInCurrentSector( ); ResetRain(); GenerateRainDropsList(); GenerateRainMaximums(); - - + guiCurrAmountOfDeadRainDrops = guiCurrMaxAmountOfRainDrops; CreateRainDrops(); @@ -590,5 +677,4 @@ void RenderRain() ColorFillVideoSurfaceArea( guiRainRenderSurface, gTalkPanel.sPopupX, gTalkPanel.sPopupY, (INT16)( gTalkPanel.sPopupX + gPopUpTextBox->sWidth ), (INT16)( gTalkPanel.sPopupY + gPopUpTextBox->sHeight ), Get16BPPColor( FROMRGB( 0, 0, 0 ) ) ); } } - } diff --git a/Tactical/Soldier Profile.cpp b/Tactical/Soldier Profile.cpp index 56d2b866..081403a8 100644 --- a/Tactical/Soldier Profile.cpp +++ b/Tactical/Soldier Profile.cpp @@ -2304,7 +2304,7 @@ BOOLEAN MercIsHot( SOLDIERTYPE * pSoldier ) // Flugente: drugs can temporarily cause a merc to be heat intolerant if ( !pSoldier->MercInWater( ) && DoesMercHaveDisability( pSoldier, HEAT_INTOLERANT ) ) { - if ((pSoldier->bSectorZ > 0) || (guiEnvWeather & ( WEATHER_FORECAST_SHOWERS | WEATHER_FORECAST_THUNDERSHOWERS ))) + if ( (pSoldier->bSectorZ > 0) || (SectorInfo[SECTOR( pSoldier->sSectorX, pSoldier->sSectorY )].usWeather == WEATHER_FORECAST_RAIN || SectorInfo[SECTOR( pSoldier->sSectorX, pSoldier->sSectorY )].usWeather == WEATHER_FORECAST_THUNDERSHOWERS) ) { // cool underground or raining return( FALSE ); diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp index 1a520f3c..482bab3e 100644 --- a/Tactical/Turn Based Input.cpp +++ b/Tactical/Turn Based Input.cpp @@ -2761,25 +2761,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) if( fAlt ) { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - EnvBeginRainStorm( 1 ); - } - else - { - HandleTacticalStoreInvItem(); - } - } - else if( fCtrl ) - { - if ( CHEATER_CHEAT_LEVEL( ) ) - { - EnvEndRainStorm( ); - } - else - { - //HandleTacticalTakeItem(); - } + HandleTacticalStoreInvItem( ); } else // Switch panels... diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index c61e9fe3..a8b6ab65 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -63,11 +63,6 @@ class SOLDIERTYPE; #include "GameInitOptionsScreen.h" -//rain -//#define WEAPON_RELIABILITY_REDUCTION_PER_RAIN_INTENSITY 0 -extern INT8 gbCurrentRainIntensity; -//end rain - // sevenfm: this global variable is needed to correctly set default number of bullets for autofire extern BOOLEAN gfAutofireInitBulletNum; @@ -1274,9 +1269,6 @@ void AdjustImpactByHitLocation( INT32 iImpact, UINT8 ubHitLocation, INT32 * piNe // #define TESTGUNJAM -//rain -extern INT8 gbCurrentRainIntensity; -//end rain BOOLEAN CheckForGunJam( SOLDIERTYPE * pSoldier ) { OBJECTTYPE * pObj; @@ -1295,8 +1287,12 @@ BOOLEAN CheckForGunJam( SOLDIERTYPE * pSoldier ) int maxJamChance = 50; // Externalize this? int reliability = GetReliability( pObj ); int condition = (*pObj)[0]->data.gun.bGunStatus; - int invertedBaseJamChance = condition + (reliability * 2) - - gGameExternalOptions.ubWeaponReliabilityReductionPerRainIntensity * gbCurrentRainIntensity; + + int weatherpenalty = 0; + if ( !pSoldier->bSectorZ ) + weatherpenalty = gGameExternalOptions.ubWeaponReliabilityReduction[SectorInfo[SECTOR( pSoldier->sSectorX, pSoldier->sSectorY )].usWeather]; + + int invertedBaseJamChance = condition + (reliability * 2) - weatherpenalty; // Flugente: If overheating is allowed, a gun will be prone to more overheating if its temperature is high if ( gGameExternalOptions.fWeaponOverheating ) diff --git a/Tactical/opplist.cpp b/Tactical/opplist.cpp index a5c9e164..2d7a042f 100644 --- a/Tactical/opplist.cpp +++ b/Tactical/opplist.cpp @@ -328,7 +328,6 @@ void DECAY_OPPLIST_VALUE( INT8& value ) //rain -extern INT8 gbCurrentRainIntensity; extern BOOLEAN gfLightningInProgress; extern BOOLEAN gfHaveSeenSomeone; extern UINT8 ubRealAmbientLightLevel; @@ -337,34 +336,25 @@ extern UINT8 ubRealAmbientLightLevel; INT16 AdjustMaxSightRangeForEnvEffects( SOLDIERTYPE *pSoldier, INT8 bLightLevel, INT16 sDistVisible ) { - INT16 sNewDist = 0; + INT16 sNewDist = sDistVisible * gGameExternalOptions.ubBrightnessVisionMod[bLightLevel] / 100; - //sNewDist = sDistVisible * gbLightSighting[ 0 ][ bLightLevel ] / 100; - sNewDist = sDistVisible * gGameExternalOptions.ubBrightnessVisionMod[ bLightLevel ] / 100; // Adjust it based on weather... - if ( guiEnvWeather & ( WEATHER_FORECAST_SHOWERS | WEATHER_FORECAST_THUNDERSHOWERS ) ) + if ( !pSoldier->bSectorZ ) { - //sNewDist = sNewDist * 70 / 100; + FLOAT weatherpenalty = gGameExternalOptions.dVisDistDecrease[SectorInfo[SECTOR( pSoldier->sSectorX, pSoldier->sSectorY )].usWeather]; + + FLOAT appliedpenalty = 1.0f; + if ( HAS_SKILL_TRAIT( pSoldier, SURVIVAL_NT ) && (gGameOptions.fNewTraitSystem) ) + appliedpenalty = min( 1.0f, max( 0.0f, appliedpenalty - gSkillTraitValues.dSVWeatherPenaltiesReduction * NUM_SKILL_TRAITS( pSoldier, SURVIVAL_NT ) ) ); + + sNewDist -= (INT16)(sNewDist * weatherpenalty * appliedpenalty); + //rain - //Added a feature reducing weather penalty for ranger trait - SANDRO - INT16 sWeatherPenalty = 0; // percent vision reduction 0-100% - sWeatherPenalty = min( (max( 0, (gGameExternalOptions.ubVisDistDecreasePerRainIntensity * gbCurrentRainIntensity))), 100) ; - if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, SURVIVAL_NT ) ) - { - sWeatherPenalty = (sWeatherPenalty * (100 - (gSkillTraitValues.ubSVWeatherPenaltiesReduction * NUM_SKILL_TRAITS( pSoldier, SURVIVAL_NT )))) / 100; - sWeatherPenalty = min( (max( 0, sWeatherPenalty)), 100 ); // keep it in 0-100 range - } - - sNewDist = (sNewDist * ( 100 - sWeatherPenalty )) / 100; - + if ( gfLightningInProgress ) + sNewDist += sNewDist * (ubRealAmbientLightLevel) / 10; // 10% per dark level //end rain } - - //rain - if( gfLightningInProgress ) - sNewDist += sNewDist * ( ubRealAmbientLightLevel ) / 10; // 10% per dark level - //end rain - + return( sNewDist ); } @@ -1630,6 +1620,19 @@ INT8 DecideHearing( SOLDIERTYPE * pSoldier ) break; } + // adjust for weather + if ( !pSoldier->bSectorZ ) + { + FLOAT weatherpenalty = gGameExternalOptions.dHearingReduction[SectorInfo[SECTOR( pSoldier->sSectorX, pSoldier->sSectorY )].usWeather]; + + // Added a feature to reduce rain effect on regaining breath with Ranger trait - SANDRO + FLOAT appliedpenalty = 1.0f; + if ( HAS_SKILL_TRAIT( pSoldier, SURVIVAL_NT ) && gGameOptions.fNewTraitSystem ) + appliedpenalty = min( 1.0f, max( 0.0f, appliedpenalty - gSkillTraitValues.dSVWeatherPenaltiesReduction * NUM_SKILL_TRAITS( pSoldier, SURVIVAL_NT ) ) ); + + bHearing -= (INT16)(bHearing * weatherpenalty * appliedpenalty); + } + return( bHearing ); } diff --git a/TileEngine/environment.cpp b/TileEngine/environment.cpp index 4402438c..36af2675 100644 --- a/TileEngine/environment.cpp +++ b/TileEngine/environment.cpp @@ -56,7 +56,7 @@ BOOLEAN gfCaves = FALSE; #define DUSK_TO_NIGHT (NIGHT_START-DUSK_START) #define NIGHT_TO_DAWN (24*60-NIGHT_START+DAWN_START) -UINT32 guiEnvWeather = 0; +//UINT32 guiEnvWeather = 0; // Flugente: this was used as a flagmask, but will now be used as an enum - we can't have several types of weather at the same time anyway UINT32 guiRainLoop = NO_SAMPLE; @@ -160,27 +160,18 @@ BOOLEAN gfDoLighting = FALSE; UINT8 gubDesertTemperature = 0; UINT8 gubGlobalTemperature = 0; -//rain -//extern BOOLEAN gfAllowRain; -//end rain - // local prototypes void EnvDoLightning(void); - // polled by the game to handle time/atmosphere changes from gamescreen void EnvironmentController( BOOLEAN fCheckForLights ) { UINT32 uiOldWorldHour; - UINT8 ubLightAdjustFromWeather = 0; - - + UINT8 ubLightAdjustFromWeather = 0; + // do none of this stuff in the basement or caves if( gfBasement || gfCaves ) { - guiEnvWeather &= (~WEATHER_FORECAST_THUNDERSHOWERS ); - guiEnvWeather &= (~WEATHER_FORECAST_SHOWERS ); - if (gGameSettings.fOptions[ TOPTION_RAIN_SOUND ] == TRUE) { if ( guiRainLoop != NO_SAMPLE ) @@ -189,6 +180,7 @@ void EnvironmentController( BOOLEAN fCheckForLights ) guiRainLoop = NO_SAMPLE; } } + return; } @@ -200,7 +192,6 @@ void EnvironmentController( BOOLEAN fCheckForLights ) if ( uiOldWorldHour != guiEnvTime ) { // Hour change.... - guiEnvTime=uiOldWorldHour; } @@ -210,18 +201,22 @@ void EnvironmentController( BOOLEAN fCheckForLights ) // ONly do indooors if( !gfBasement && !gfCaves ) { -//#if 0 //rain - if ( guiEnvWeather & ( WEATHER_FORECAST_THUNDERSHOWERS | WEATHER_FORECAST_SHOWERS ) ) + if ( SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_RAIN + || SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_THUNDERSHOWERS + || SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_SANDSTORM ) { - if (gGameSettings.fOptions[ TOPTION_RAIN_SOUND ] == TRUE) { if ( guiRainLoop == NO_SAMPLE ) { - if (guiEnvWeather & WEATHER_FORECAST_THUNDERSHOWERS ) + if ( SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_THUNDERSHOWERS ) { guiRainLoop = PlayJA2Ambient( RAIN_1, 140, 0 ); } + else if ( SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_SANDSTORM ) + { + guiRainLoop = PlayJA2Ambient( WIND, 105, 0 ); + } else { guiRainLoop = PlayJA2Ambient( RAIN_1, 70, 0 ); @@ -230,11 +225,10 @@ void EnvironmentController( BOOLEAN fCheckForLights ) } // Do lightning if we want... - if ( guiEnvWeather & ( WEATHER_FORECAST_THUNDERSHOWERS ) ) + if ( SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_THUNDERSHOWERS ) { EnvDoLightning( ); } - } else { @@ -247,7 +241,6 @@ void EnvironmentController( BOOLEAN fCheckForLights ) } } } -//#endif //rain } if ( gfDoLighting && fCheckForLights ) @@ -259,23 +252,25 @@ void EnvironmentController( BOOLEAN fCheckForLights ) if( !gfBasement && !gfCaves ) { // Rain storms.... -//#if 0 //rain - if ( guiEnvWeather & ( WEATHER_FORECAST_THUNDERSHOWERS | WEATHER_FORECAST_SHOWERS ) ) + // Thunder showers.. make darker + if ( SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_THUNDERSHOWERS ) { - // Thunder showers.. make darker - if ( guiEnvWeather & ( WEATHER_FORECAST_THUNDERSHOWERS ) ) - { - ubLightAdjustFromWeather = (UINT8)(__min( gubEnvLightValue+2, NORMAL_LIGHTLEVEL_NIGHT )); - } - else - { - ubLightAdjustFromWeather = (UINT8)(__min( gubEnvLightValue+1, NORMAL_LIGHTLEVEL_NIGHT )); - } + ubLightAdjustFromWeather = (UINT8)(__min( gubEnvLightValue+2, NORMAL_LIGHTLEVEL_NIGHT )); + } + else if ( SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_RAIN ) + { + ubLightAdjustFromWeather = (UINT8)(__min( gubEnvLightValue+1, NORMAL_LIGHTLEVEL_NIGHT )); + } + else if ( SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_SANDSTORM ) + { + ubLightAdjustFromWeather = (UINT8)(__min( gubEnvLightValue + 5, NORMAL_LIGHTLEVEL_NIGHT )); + } + else if ( SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_SNOW ) + { + ubLightAdjustFromWeather = (UINT8)(__min( gubEnvLightValue + 1, NORMAL_LIGHTLEVEL_NIGHT )); } -//#endif //rain } - LightSetBaseLevel( ubLightAdjustFromWeather ); //Update Merc Lights since the above function modifies it. @@ -288,9 +283,7 @@ void EnvironmentController( BOOLEAN fCheckForLights ) SetRenderFlags(RENDER_FLAG_FULL); gfDoLighting = FALSE; } - } - } void BuildDayLightLevels() @@ -309,7 +302,7 @@ void BuildDayLightLevels() */ //Transition from night to day - for( uiLoop = 0; uiLoop < 9; uiLoop++ ) + for( uiLoop = 0; uiLoop < 9; ++uiLoop ) { AddEveryDayStrategicEvent( EVENT_CHANGELIGHTVAL, DAWN_START + 2 * uiLoop, NORMAL_LIGHTLEVEL_NIGHT - 1 - uiLoop ); } @@ -337,7 +330,7 @@ void BuildDayLightLevels() */ //Transition from day to night - for( uiLoop = 0; uiLoop < 9; uiLoop++ ) + for( uiLoop = 0; uiLoop < 9; ++uiLoop ) { AddEveryDayStrategicEvent( EVENT_CHANGELIGHTVAL, DUSK_START + 2 * uiLoop, NORMAL_LIGHTLEVEL_DAY + 1 + uiLoop ); } @@ -355,10 +348,8 @@ void BuildDayLightLevels() void BuildDayAmbientSounds( ) { - INT32 cnt; - // Add events! - for ( cnt = 0; cnt < gsNumAmbData; cnt++ ) + for ( INT32 cnt = 0; cnt < gsNumAmbData; ++cnt ) { switch( gAmbData[ cnt ].ubTimeCatagory ) { @@ -375,7 +366,6 @@ void BuildDayAmbientSounds( ) AddSameDayRangedStrategicEvent( EVENT_AMBIENT, NIGHT_START, NIGHT_TO_DAWN, cnt ); break; } - } //guiRainLoop = NO_SAMPLE; @@ -392,15 +382,150 @@ void BuildDayAmbientSounds( ) //end rain } -//extern UINT16 gusRainChancePerDay, gusRainMinLength, gusRainMaxLength; //rain +// Flugente: weather can now be localized, meaning that different sectors can have different types of weather at the same time +extern SECTOR_EXT_DATA SectorExternalData[256][4]; +// we use this structure to set up weather. For a given weather type, we put the chance of the weather happening in here, and later note whether a sector has been checked, and if weather does occur +struct WeatherHelperStruct +{ + WeatherHelperStruct( ) : weatherhappens( FALSE ), handled( FALSE ), chance( 0 ) {} + + BOOLEAN weatherhappens; + BOOLEAN handled; + UINT8 chance; +}; + +void DetermineLocalizedWeatherGivenHelperArray( WeatherHelperStruct helperstruct[256] ) +{ + UINT32 totalweatherpoints = 0; + for ( UINT8 sector = 0; sector < 255; ++sector ) + { + totalweatherpoints += helperstruct[sector].chance; + } + + if ( totalweatherpoints ) + { + INT32 chosenweatherpoint = Random( totalweatherpoints ); + UINT8 chosensector = 0; + + for ( UINT8 sector = 0; sector < 255; ++sector ) + { + chosenweatherpoint -= helperstruct[sector].chance; + + if ( chosenweatherpoint < 0 ) + { + chosensector = sector; + + break; + } + } + + // we now have a starting sector. We now loop over all sectors several times. If a sector is adjacent to a sector with new weather, determine whether the weather will also happen there + helperstruct[chosensector].weatherhappens = TRUE; + helperstruct[chosensector].handled = TRUE; + + BOOLEAN weatherchangehappened = TRUE; + + while ( weatherchangehappened ) + { + weatherchangehappened = FALSE; + + for ( UINT8 sector = 0; sector < 255; ++sector ) + { + if ( !helperstruct[sector].handled ) + { + // if it can't rain in a sector anyway, screw this + if ( !helperstruct[sector].chance ) + { + helperstruct[sector].handled = TRUE; + continue; + } + + INT8 x = SECTORX( sector ); + INT8 y = SECTORY( sector ); + + // check adjacent sectors; + INT16 adjacentsectors[4] = {-1, -1, -1, -1}; + + if ( x > 0 ) adjacentsectors[0] = SECTOR( x - 1, y ); + if ( x < 15 ) adjacentsectors[1] = SECTOR( x + 1, y ); + if ( y > 0 ) adjacentsectors[2] = SECTOR( x, y - 1 ); + if ( y < 15 ) adjacentsectors[3] = SECTOR( x, y + 1 ); + + for ( int i = 0; i < 4; ++i ) + { + if ( adjacentsectors[i] > 0 ) + { + UINT8 adjacentsector = (UINT8)(adjacentsectors[i]); + + // if weather happens in the adjacent sector, determine whether it also happens here + if ( helperstruct[adjacentsector].handled && helperstruct[adjacentsector].weatherhappens ) + { + helperstruct[sector].weatherhappens = Chance( helperstruct[sector].chance ); + helperstruct[sector].handled = TRUE; + + // if weather spreads, we will continue with this function + if ( helperstruct[sector].weatherhappens ) + { + weatherchangehappened = TRUE; + continue; + } + } + } + } + } + } + } + + // loop over all sectors again. If a sector doesn't have the new weather, but most or all adjacent sectors do, consider adding it here too + for ( UINT8 sector = 0; sector < 255; ++sector ) + { + if ( !helperstruct[sector].weatherhappens && helperstruct[sector].chance ) + { + INT8 x = SECTORX( sector ); + INT8 y = SECTORY( sector ); + + // check adjacent sectors; + INT16 adjacentsectors[4] = {-1, -1, -1, -1}; + + if ( x > 0 ) adjacentsectors[0] = SECTOR( x - 1, y ); + if ( x < 15 ) adjacentsectors[1] = SECTOR( x + 1, y ); + if ( y > 0 ) adjacentsectors[2] = SECTOR( x, y - 1 ); + if ( y < 15 ) adjacentsectors[3] = SECTOR( x, y + 1 ); + + UINT8 adjacentweathercount = 0; + for ( int i = 0; i < 4; ++i ) + { + if ( adjacentsectors[i] > 0 ) + { + UINT8 adjacentsector = (UINT8)(adjacentsectors[i]); + + if ( helperstruct[adjacentsector].weatherhappens ) + { + ++adjacentweathercount; + } + } + } + + // no weather 'holes' + if ( adjacentweathercount >= 4 ) + { + helperstruct[sector].weatherhappens = TRUE; + } + // if weather is on 3 sides, at least consider awarding it + else if ( adjacentweathercount == 3 && Chance( 66 ) ) + { + helperstruct[sector].weatherhappens = TRUE; + } + } + } + } +} void ForecastDayEvents( ) { UINT32 uiOldDay; UINT32 uiStartTime, uiEndTime; - UINT8 ubStormIntensity; -// UINT32 cnt; // Get current day and see if different if ( ( uiOldDay = GetWorldDay() ) != guiEnvDay ) @@ -414,70 +539,115 @@ void ForecastDayEvents( ) // Build ambient sound queues BuildDayAmbientSounds( ); - // Build weather.... - // ATE: Don't forecast if start of game... if ( guiEnvDay > 1 ) { //rain - if ( Random( 100 ) < gGameExternalOptions.gusRainChancePerDay ) + if ( gGameExternalOptions.gfAllowRain ) { - // Add rain! - // Between 6:00 and 10:00 - uiStartTime = (UINT32)( Random( 1440 - 1 - gGameExternalOptions.gusRainMaxLength ) ); - // Between 5 - 15 miniutes - uiEndTime = uiStartTime + ( gGameExternalOptions.gusRainMinLength + Random( gGameExternalOptions.gusRainMaxLength - gGameExternalOptions.gusRainMinLength ) ); - - ubStormIntensity = 0; - - - //Kaiden: making thunderstorms optional - if (gGameExternalOptions.gfAllowLightning) + for ( int i = 0; i < gGameExternalOptions.gusWeatherPerDayRain; ++i ) { - // Randomze for a storm! - if ( Random( 10 ) < 5 ) + if ( Chance( gGameExternalOptions.gusRainChancePerDay ) ) { - ubStormIntensity = 1; + uiStartTime = GetWorldTotalMin( ) + 9 * 60 ;//(UINT32)(Random( 1440 - 1 - gGameExternalOptions.gusRainMaxLength )); + + UINT32 length = max( gGameExternalOptions.gusRainMinLength, Random( gGameExternalOptions.gusRainMaxLength ) ); + + // Between 5 - 15 miniutes + uiEndTime = uiStartTime + length; + + // We determine the 'start point' of the weather via xml chances. Weather can then spread to adjacent sectors according to chances + WeatherHelperStruct helperstruct[256]; + + for ( UINT8 sector = 0; sector < 255; ++sector ) + helperstruct[sector].chance = SectorExternalData[sector][0].rainchance; + + DetermineLocalizedWeatherGivenHelperArray( helperstruct ); + + // now that we know in which sectors the new weather will happen, set up timed events + BOOLEAN dothunderstorm = (gGameExternalOptions.gfAllowLightning && Chance( 50 )); + + for ( UINT8 sector = 0; sector < 255; ++sector ) + { + if ( helperstruct[sector].weatherhappens ) + { + AddStrategicEvent( dothunderstorm ? EVENT_WEATHER_THUNDERSHOWERS : EVENT_WEATHER_SHOWERS, uiStartTime, sector ); + AddStrategicEvent( EVENT_WEATHER_NORMAL, uiEndTime, sector ); + } + } } } - - - if( gGameExternalOptions.gfAllowRain ) AddSameDayRangedStrategicEvent( EVENT_RAINSTORM, uiStartTime, uiEndTime - uiStartTime, ubStormIntensity ); - - //AddSameDayStrategicEvent( EVENT_BEGINRAINSTORM, uiStartTime, ubStormIntensity ); - //AddSameDayStrategicEvent( EVENT_ENDRAINSTORM, uiEndTime, 0 ); } - //end rain - - /* - // Should it rain...? - if ( Random( 100 ) < 20 ) + // sandstorm + if ( gGameExternalOptions.gfAllowSandStorms ) { - // Add rain! - // Between 6:00 and 10:00 - uiStartTime = (UINT32)( 360 + Random( 1080 ) ); - // Between 5 - 15 miniutes - uiEndTime = uiStartTime + ( 5 + Random( 10 ) ); - - ubStormIntensity = 0; - - // Randomze for a storm! - if ( Random( 10 ) < 5 ) + for ( int i = 0; i < gGameExternalOptions.gusWeatherPerDaySandstorm; ++i ) { - ubStormIntensity = 1; + if ( Chance( gGameExternalOptions.gusSandStormsChancePerDay ) ) + { + uiStartTime = GetWorldTotalMin( ) + 9 * 60; //(UINT32)(Random( 1440 - 1 - gGameExternalOptions.gusSandStormsMaxLength )); + + UINT32 length = max( gGameExternalOptions.gusSandStormsMinLength, Random( gGameExternalOptions.gusSandStormsMaxLength ) ); + + // Between 5 - 15 miniutes + uiEndTime = uiStartTime + length; + + // We determine the 'start point' of the weather via xml chances. Weather can then spread to adjacent sectors according to chances + WeatherHelperStruct helperstruct[256]; + + for ( UINT8 sector = 0; sector < 255; ++sector ) + helperstruct[sector].chance = SectorExternalData[sector][0].sandstormchance; + + DetermineLocalizedWeatherGivenHelperArray( helperstruct ); + + for ( UINT8 sector = 0; sector < 255; ++sector ) + { + if ( helperstruct[sector].weatherhappens ) + { + AddStrategicEvent( EVENT_WEATHER_SANDSTORM, uiStartTime, sector ); + AddStrategicEvent( EVENT_WEATHER_NORMAL, uiEndTime, sector ); + } + } + } + } + } + + // snow + if ( gGameExternalOptions.gfAllowSnow && Chance( gGameExternalOptions.gusSnowChancePerDay ) ) + { + for ( int i = 0; i < gGameExternalOptions.gusWeatherPerDaySnow; ++i ) + { + if ( Chance( gGameExternalOptions.gusSnowChancePerDay ) ) + { + uiStartTime = GetWorldTotalMin( ) + 9 * 60; //(UINT32)(Random( 1440 - 1 - gGameExternalOptions.gusSnowMaxLength )); + + UINT32 length = max( gGameExternalOptions.gusSnowMinLength, Random( gGameExternalOptions.gusSnowMaxLength ) ); + + // Between 5 - 15 miniutes + uiEndTime = uiStartTime + length; + + // We determine the 'start point' of the weather via xml chances. Weather can then spread to adjacent sectors according to chances + WeatherHelperStruct helperstruct[256]; + + for ( UINT8 sector = 0; sector < 255; ++sector ) + helperstruct[sector].chance = SectorExternalData[sector][0].snowchance; + + DetermineLocalizedWeatherGivenHelperArray( helperstruct ); + + for ( UINT8 sector = 0; sector < 255; ++sector ) + { + if ( helperstruct[sector].weatherhappens ) + { + AddStrategicEvent( EVENT_WEATHER_SNOW, uiStartTime, sector ); + AddStrategicEvent( EVENT_WEATHER_NORMAL, uiEndTime, sector ); + } + } + } } - - // ATE: Disable RAIN! - // AddSameDayRangedStrategicEvent( EVENT_RAINSTORM, uiStartTime, uiEndTime - uiStartTime, ubStormIntensity ); - - //AddSameDayStrategicEvent( EVENT_BEGINRAINSTORM, uiStartTime, ubStormIntensity ); - //AddSameDayStrategicEvent( EVENT_ENDRAINSTORM, uiEndTime, 0 ); } - */ } } - } void EnvEnableTOD(void) @@ -533,8 +703,6 @@ UINT8 gubLastTeamLightning; void BeginTeamTurn( UINT8 ubTeam ); - - void EnvDoLightning(void) { static UINT32 uiCount=10, uiIndex=0, uiStrike=0, uiFrameNext=0; @@ -546,55 +714,58 @@ void EnvDoLightning(void) if( GetJA2Clock() < uiLastUpdate ) { - uiLastUpdate = 0; - memset( pDelayedSounds, NO_DL_SOUND, sizeof( UINT32 ) * MAX_DELAYED_SOUNDS ); + uiLastUpdate = 0; + memset( pDelayedSounds, NO_DL_SOUND, sizeof( UINT32 ) * MAX_DELAYED_SOUNDS ); } - if( GetJA2Clock() < uiLastUpdate + 1000 / 60 )return; + if( GetJA2Clock() < uiLastUpdate + 1000 / 60 ) + return; else uiLastUpdate = GetJA2Clock(); if( GetJA2Clock() > uiTurnOffExtraVisDist ) { - AllTeamsLookForAll( FALSE ); - uiTurnOffExtraVisDist = 0xFFFFFFFF; + AllTeamsLookForAll( FALSE ); + uiTurnOffExtraVisDist = 0xFFFFFFFF; - if( gfTurnBasedLightningEnd ) - { - BeginTeamTurn( gubLastTeamLightning ); - gfTurnBasedLightningEnd = FALSE; + if( gfTurnBasedLightningEnd ) + { + BeginTeamTurn( gubLastTeamLightning ); + gfTurnBasedLightningEnd = FALSE; + } } - } - - for( uiDSIndex = 0; uiDSIndex < MAX_DELAYED_SOUNDS; ++uiDSIndex ) - if( GetJA2Clock() > pDelayedSounds[ uiDSIndex ] ) + for ( uiDSIndex = 0; uiDSIndex < MAX_DELAYED_SOUNDS; ++uiDSIndex ) { - PlayJA2Ambient(LIGHTNING_1+Random(2), HIGHVOLUME, 1); - pDelayedSounds[ uiDSIndex ] = NO_DL_SOUND; + if( GetJA2Clock() > pDelayedSounds[ uiDSIndex ] ) + { + PlayJA2Ambient(LIGHTNING_1+Random(2), HIGHVOLUME, 1); + pDelayedSounds[ uiDSIndex ] = NO_DL_SOUND; + } } if ( gfPauseDueToPlayerGamePause ) { - return; + return; } if( IS_TURNBASED && !gfLightningInProgress ) { - if( !gfTurnBasedDoLightning ) - { - return; - } - else - { - gfTurnBasedDoLightning = FALSE; - uiFrameNext = 1; - uiCount = 0; - gfTurnBasedLightningEnd = TRUE; - } + if( !gfTurnBasedDoLightning ) + { + return; + } + else + { + gfTurnBasedDoLightning = FALSE; + uiFrameNext = 1; + uiCount = 0; + gfTurnBasedLightningEnd = TRUE; + } } - uiCount++; + ++uiCount; + if(uiCount >= (uiFrameNext+10)) { if( gfHaveSeenSomeone && gfWasTurnBasedWhenLightningBegin ) @@ -635,43 +806,46 @@ void EnvDoLightning(void) } while(uiCount > ((UINT32)ubLightningTable[uiStrike][uiIndex][0] + uiFrameNext)) - uiIndex++; + ++uiIndex; ubLastLevel=ubLevel; ubLevel=min( ubRealAmbientLightLevel - 1, ubLightningTable[uiStrike][uiIndex][1] ); -/* // ATE: Don't modify if scrolling! - if ( gfScrollPending || gfScrollInertia ) - { - } - else*/ - { - if(ubLastLevel!=ubLevel) +/* // ATE: Don't modify if scrolling! + if ( gfScrollPending || gfScrollInertia ) { - if(ubLevel > ubLastLevel) - { - LightAddBaseLevel(0, (UINT8)(ubLevel-ubLastLevel)); - if(ubLevel > 0) - RenderSetShadows(TRUE); - } - else - { -// LightSubtractBaseLevel(0, (UINT8)(ubLastLevel-ubLevel)); - LightSetBaseLevel( ubRealAmbientLightLevel - ubLevel ); - if(ubLevel > 0) - RenderSetShadows(TRUE); - } - SetRenderFlags(RENDER_FLAG_FULL); } - } + else*/ + { + if(ubLastLevel!=ubLevel) + { + if(ubLevel > ubLastLevel) + { + LightAddBaseLevel(0, (UINT8)(ubLevel-ubLastLevel)); + if(ubLevel > 0) + RenderSetShadows(TRUE); + } + else + { + // LightSubtractBaseLevel(0, (UINT8)(ubLastLevel-ubLevel)); + LightSetBaseLevel( ubRealAmbientLightLevel - ubLevel ); + if(ubLevel > 0) + RenderSetShadows(TRUE); + } + SetRenderFlags(RENDER_FLAG_FULL); + } + } } } BOOLEAN LightningEndOfTurn( UINT8 ubTeam ) { - if( !(guiEnvWeather & WEATHER_FORECAST_THUNDERSHOWERS) )return TRUE; - if( Random(100) >= CHANCE_TO_DO_LIGHTNING_BETWEEN_TURNS ) return TRUE; + if ( SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather != WEATHER_FORECAST_THUNDERSHOWERS ) + return TRUE; + + if ( Random(100) >= CHANCE_TO_DO_LIGHTNING_BETWEEN_TURNS ) + return TRUE; if( !gfTurnBasedLightningEnd ) { @@ -680,10 +854,8 @@ BOOLEAN LightningEndOfTurn( UINT8 ubTeam ) EnvDoLightning(); return FALSE; } - else - { - return TRUE; - } + + return TRUE; } UINT8 GetTimeOfDayAmbientLightLevel() @@ -705,57 +877,35 @@ UINT8 GetTimeOfDayAmbientLightLevel() } } - -void EnvBeginRainStorm( UINT8 ubIntensity ) +void ChangeWeather( UINT8 aSector, UINT8 aType ) { - if( !gfBasement && !gfCaves ) + if ( aType >= WEATHER_FORECAST_MAX ) { - gfDoLighting = TRUE; + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Error in ChangeWeather(): Invalid weather" ); + return; + } - #ifdef JA2TESTVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Starting Rain...." ); - #endif + if ( SectorInfo[aSector].usWeather != aType ) + { + if ( SECTOR( gWorldSectorX, gWorldSectorY ) == aSector && !gbWorldSectorZ ) + { + if ( !gfBasement && !gfCaves ) + gfDoLighting = TRUE; + + CHAR16 pStrSectorName[128]; + GetSectorIDString( SECTORX( aSector ), SECTORY( aSector ), 0, pStrSectorName, TRUE ); + + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s: Changed weather from %s to %s", pStrSectorName, szWeatherTypeText[SectorInfo[aSector].usWeather], szWeatherTypeText[aType] ); + } // First turn off whatever rain it is, then turn on the requested rain - guiEnvWeather &= ~(WEATHER_FORECAST_THUNDERSHOWERS | WEATHER_FORECAST_SHOWERS); - - if ( ubIntensity == 1 ) - { - // Turn on rain storms - guiEnvWeather |= WEATHER_FORECAST_THUNDERSHOWERS; - - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_STORM_STARTED] ); - } - else - { - guiEnvWeather |= WEATHER_FORECAST_SHOWERS; - - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_RAIN_STARTED] ); - } + SectorInfo[aSector].usWeather = aType; } - } -void EnvEndRainStorm( ) +UINT8 GetWeatherInCurrentSector() { - gfDoLighting = TRUE; - -#ifdef JA2TESTVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Ending Rain...." ); -#endif - - if ( guiEnvWeather & WEATHER_FORECAST_THUNDERSHOWERS ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_STORM_ENDED] ); - } - else - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_RAIN_ENDED] ); - } - - - guiEnvWeather &= (~WEATHER_FORECAST_THUNDERSHOWERS ); - guiEnvWeather &= (~WEATHER_FORECAST_SHOWERS ); + return SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather; } //end rain @@ -764,10 +914,6 @@ void EnvEndRainStorm( ) - - - - /* void EnvDoLightning(void) { @@ -842,49 +988,12 @@ UINT8 GetTimeOfDayAmbientLightLevel() return( gubEnvLightValue ); } } - - -void EnvBeginRainStorm( UINT8 ubIntensity ) -{ - if( !gfBasement && !gfCaves ) - { - gfDoLighting = TRUE; - - #ifdef JA2TESTVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Starting Rain...." ); - #endif - - if ( ubIntensity == 1 ) - { - // Turn on rain storms - guiEnvWeather |= WEATHER_FORECAST_THUNDERSHOWERS; - } - else - { - guiEnvWeather |= WEATHER_FORECAST_SHOWERS; - } - } - -} - -void EnvEndRainStorm( ) -{ - gfDoLighting = TRUE; - -#ifdef JA2TESTVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Ending Rain...." ); -#endif - - guiEnvWeather &= (~WEATHER_FORECAST_THUNDERSHOWERS ); - guiEnvWeather &= (~WEATHER_FORECAST_SHOWERS ); -} */ void TurnOnNightLights() { - INT32 i; - for( i = 0; i < MAX_LIGHT_SPRITES; i++ ) + for ( INT32 i = 0; i < MAX_LIGHT_SPRITES; ++i ) { if( LightSprites[ i ].uiFlags & LIGHT_SPR_ACTIVE && LightSprites[ i ].uiFlags & LIGHT_NIGHTTIME && @@ -897,8 +1006,7 @@ void TurnOnNightLights() void TurnOffNightLights() { - INT32 i; - for( i = 0; i < MAX_LIGHT_SPRITES; i++ ) + for ( INT32 i = 0; i < MAX_LIGHT_SPRITES; ++i ) { if( LightSprites[ i ].uiFlags & LIGHT_SPR_ACTIVE && LightSprites[ i ].uiFlags & LIGHT_NIGHTTIME && @@ -912,8 +1020,7 @@ void TurnOffNightLights() void TurnOnPrimeLights() { - INT32 i; - for( i = 0; i < MAX_LIGHT_SPRITES; i++ ) + for ( INT32 i = 0; i < MAX_LIGHT_SPRITES; ++i ) { if( LightSprites[ i ].uiFlags & LIGHT_SPR_ACTIVE && LightSprites[ i ].uiFlags & LIGHT_PRIMETIME && @@ -926,8 +1033,7 @@ void TurnOnPrimeLights() void TurnOffPrimeLights() { - INT32 i; - for( i = 0; i < MAX_LIGHT_SPRITES; i++ ) + for ( INT32 i = 0; i < MAX_LIGHT_SPRITES; ++i ) { if( LightSprites[ i ].uiFlags & LIGHT_SPR_ACTIVE && LightSprites[ i ].uiFlags & LIGHT_PRIMETIME && @@ -973,7 +1079,7 @@ INT8 SectorTemperature( UINT32 uiTime, INT16 sSectorX, INT16 sSectorY, INT8 bSec // cool underground return( 0 ); } - else if ( IsSectorDesert( sSectorX, sSectorY ) && !( guiEnvWeather & ( WEATHER_FORECAST_SHOWERS | WEATHER_FORECAST_THUNDERSHOWERS ) ) ) // is desert + else if ( IsSectorDesert( sSectorX, sSectorY ) && !(SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_RAIN || SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )].usWeather == WEATHER_FORECAST_THUNDERSHOWERS) ) // is desert { return( gubDesertTemperature ); } diff --git a/TileEngine/environment.h b/TileEngine/environment.h index 81d7adb7..c0274141 100644 --- a/TileEngine/environment.h +++ b/TileEngine/environment.h @@ -35,12 +35,16 @@ #define PRIME_TIME_LIGHT_START_HOUR 21 #define PRIME_TIME_LIGHT_END_HOUR 24 -#define WEATHER_FORECAST_SUNNY 0x00000001 -#define WEATHER_FORECAST_OVERCAST 0x00000002 -#define WEATHER_FORECAST_PARTLYSUNNY 0x00000004 -#define WEATHER_FORECAST_DRIZZLE 0x00000008 -#define WEATHER_FORECAST_SHOWERS 0x00000010 -#define WEATHER_FORECAST_THUNDERSHOWERS 0x00000020 +enum +{ + WEATHER_FORECAST_NORMAL, + WEATHER_FORECAST_RAIN, + WEATHER_FORECAST_THUNDERSHOWERS, + WEATHER_FORECAST_SANDSTORM, + WEATHER_FORECAST_SNOW, + + WEATHER_FORECAST_MAX +}; // higher is darker, remember #define NORMAL_LIGHTLEVEL_NIGHT 12 @@ -56,13 +60,12 @@ void BuildDayAmbientSounds( ); void BuildDayLightLevels(); UINT8 GetTimeOfDayAmbientLightLevel(); -void EnvBeginRainStorm( UINT8 ubIntensity ); -void EnvEndRainStorm( ); +void ChangeWeather( UINT8 aSector, UINT8 aType ); +UINT8 GetWeatherInCurrentSector(); -extern UINT8 gubEnvLightValue; +extern UINT8 gubEnvLightValue; extern BOOLEAN gfDoLighting; -extern UINT32 guiEnvWeather; void TurnOnNightLights(); void TurnOffNightLights(); @@ -76,9 +79,9 @@ void TurnOffPrimeLights(); extern BOOLEAN gfCaves; extern BOOLEAN gfBasement; -extern INT8 SectorTemperature( UINT32 uiTime, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ); +INT8 SectorTemperature( UINT32 uiTime, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ); -extern void UpdateTemperature( UINT8 ubTemperatureCode ); +void UpdateTemperature( UINT8 ubTemperatureCode ); #endif diff --git a/Utils/Sound Control.cpp b/Utils/Sound Control.cpp index a95010d2..dcc26cca 100644 --- a/Utils/Sound Control.cpp +++ b/Utils/Sound Control.cpp @@ -386,7 +386,8 @@ char szAmbientEffects[NUM_AMBIENTS][255] = "SOUNDS\\owl2.wav", "SOUNDS\\owl3.wav", "SOUNDS\\night_bird1.wav", - "SOUNDS\\night_bird3.wav" + "SOUNDS\\night_bird3.wav", + "SOUNDS\\wind.wav", }; UINT8 AmbientVols[NUM_AMBIENTS]={ diff --git a/Utils/Sound Control.h b/Utils/Sound Control.h index 6d8d386f..1aa04f93 100644 --- a/Utils/Sound Control.h +++ b/Utils/Sound Control.h @@ -398,7 +398,8 @@ enum AmbientDefines OWL_3, NIGHT_BIRD_1, NIGHT_BIRD_2, - + WIND, + NUM_AMBIENTS }; diff --git a/Utils/Text.h b/Utils/Text.h index cd6ed5d3..4a0b5a32 100644 --- a/Utils/Text.h +++ b/Utils/Text.h @@ -2966,6 +2966,9 @@ extern STR16 szIdividualMilitiaWebsiteFilterText_Sector[]; // Flugente: non-profile merchants extern STR16 szNonProfileMerchantText[]; +// Flugente: externalised weather +extern STR16 szWeatherTypeText[]; + #define TACTICAL_INVENTORY_DIALOG_NUM 16 #define TACTICAL_COVER_DIALOG_NUM 16 diff --git a/Utils/_ChineseText.cpp b/Utils/_ChineseText.cpp index d46f462c..25ac89b6 100644 --- a/Utils/_ChineseText.cpp +++ b/Utils/_ChineseText.cpp @@ -4300,6 +4300,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"显示民兵和敌人 (|Z)", L"显示民兵移动 (|R)", // HEADROCK HAM 4: Mobile Restrictions Button L"显示疾病消息", //L"Show Disease Data", + L"Show Weather", // TODO.Translate }; STR16 pMapScreenInvenButtonHelpText[] = @@ -6172,6 +6173,9 @@ STR16 zMarksMapScreenText[] = // Flugente: disease texts describing what a map view does //文本描述疾病查看地图并做翻译。 L"这个视图会展示出哪个地区爆发了瘟疫,这个数字表明,平均每个人的感染程度,颜色表示它的范围。 灰色=无病。 绿色到红色=不断升级的感染程度。", //L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", + + // Flugente: weather texts describing what a map view does + L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.", // TODO.Translate }; @@ -11121,6 +11125,16 @@ STR16 szNonProfileMerchantText[] = L"Merchant refuses to interact with you.", }; +STR16 szWeatherTypeText[] = // TODO.Translate +{ + L"normal", + L"rain", + L"thunderstorm", + L"sandstorm", + + L"snow", +}; + // WANNE: Some Chinese specific strings that needs to be in unicode! STR16 ChineseSpecString1 = L"%%"; //defined in _ChineseText.cpp as this file is already unicode STR16 ChineseSpecString2 = L"*%3d%%%%"; //defined in _ChineseText.cpp as this file is already unicode diff --git a/Utils/_DutchText.cpp b/Utils/_DutchText.cpp index b735a110..5587ceee 100644 --- a/Utils/_DutchText.cpp +++ b/Utils/_DutchText.cpp @@ -4299,6 +4299,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"Toon Milities & Vijanden (|Z)", L"Show Mobile Militia |Restrictions", // HEADROCK HAM 4: Mobile Restrictions Button // TODO.Translate L"Show Disease Data", // TODO.Translate + L"Show Weather", // TODO.Translate }; STR16 pMapScreenInvenButtonHelpText[] = @@ -6176,6 +6177,9 @@ STR16 zMarksMapScreenText[] = // Flugente: disease texts describing what a map view does TODO.Translate L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", + + // Flugente: weather texts describing what a map view does + L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.", // TODO.Translate }; @@ -11138,4 +11142,14 @@ STR16 szNonProfileMerchantText[] = L"Merchant refuses to interact with you.", }; +STR16 szWeatherTypeText[] = // TODO.Translate +{ + L"normal", + L"rain", + L"thunderstorm", + L"sandstorm", + + L"snow", +}; + #endif //DUTCH diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp index 8041c9ac..cd30cb49 100644 --- a/Utils/_EnglishText.cpp +++ b/Utils/_EnglishText.cpp @@ -4297,6 +4297,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"Show Militia & Enemies (|Z)", L"Show Mobile Militia |Restrictions", // HEADROCK HAM 4: Mobile Restrictions Button L"Show Disease Data", + L"Show Weather", }; STR16 pMapScreenInvenButtonHelpText[] = @@ -6169,6 +6170,9 @@ STR16 zMarksMapScreenText[] = // Flugente: disease texts describing what a map view does L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", + + // Flugente: weather texts describing what a map view does + L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.", }; @@ -11121,4 +11125,14 @@ STR16 szNonProfileMerchantText[] = L"Merchant refuses to interact with you.", }; +STR16 szWeatherTypeText[] = +{ + L"normal", + L"rain", + L"thunderstorm", + L"sandstorm", + + L"snow", +}; + #endif //ENGLISH diff --git a/Utils/_FrenchText.cpp b/Utils/_FrenchText.cpp index 724a4532..5409b053 100644 --- a/Utils/_FrenchText.cpp +++ b/Utils/_FrenchText.cpp @@ -4303,6 +4303,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"Milice & Ennemis (|Z)", L"Montrer la milice mobile |Restrictions", // HEADROCK HAM 4: Mobile Restrictions Button L"Show Disease Data", // TODO.Translate + L"Show Weather", // TODO.Translate }; STR16 pMapScreenInvenButtonHelpText[] = @@ -6181,6 +6182,9 @@ STR16 zMarksMapScreenText[] = // Flugente: disease texts describing what a map view does TODO.Translate L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", + + // Flugente: weather texts describing what a map view does + L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.", // TODO.Translate }; @@ -11120,4 +11124,14 @@ STR16 szNonProfileMerchantText[] = L"Merchant refuses to interact with you.", }; +STR16 szWeatherTypeText[] = // TODO.Translate +{ + L"normal", + L"rain", + L"thunderstorm", + L"sandstorm", + + L"snow", +}; + #endif //FRENCH diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index 18610410..0bd90fd1 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -4289,6 +4289,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"Mili|z & Feinde zeigen", L"Zeige Mobile Miliz Begrenzungen (|R)", // HEADROCK HAM 4: Mobile Restrictions Button L"Show Disease Data", // TODO.Translate + L"Show Weather", // TODO.Translate }; STR16 pMapScreenInvenButtonHelpText[] = @@ -6021,6 +6022,9 @@ STR16 zMarksMapScreenText[] = // Flugente: disease texts describing what a map view does TODO.Translate L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", + + // Flugente: weather texts describing what a map view does + L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.", // TODO.Translate }; STR16 pLandMarkInSectorString[] = @@ -10950,4 +10954,14 @@ STR16 szNonProfileMerchantText[] = L"Merchant refuses to interact with you.", }; +STR16 szWeatherTypeText[] = // TODO.Translate +{ + L"normal", + L"rain", + L"thunderstorm", + L"sandstorm", + + L"snow", +}; + #endif //GERMAN diff --git a/Utils/_ItalianText.cpp b/Utils/_ItalianText.cpp index cae4514e..204988c0 100644 --- a/Utils/_ItalianText.cpp +++ b/Utils/_ItalianText.cpp @@ -4293,6 +4293,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"Mostra esercito & nemici (|Z)", L"Show Mobile Militia |Restrictions", // HEADROCK HAM 4: Mobile Restrictions Button // TODO.Translate L"Show Disease Data", // TODO.Translate + L"Show Weather", // TODO.Translate }; STR16 pMapScreenInvenButtonHelpText[] = @@ -6159,6 +6160,9 @@ STR16 zMarksMapScreenText[] = // Flugente: disease texts describing what a map view does TODO.Translate L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", + + // Flugente: weather texts describing what a map view does + L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.", // TODO.Translate }; @@ -11129,4 +11133,14 @@ STR16 szNonProfileMerchantText[] = L"Merchant refuses to interact with you.", }; +STR16 szWeatherTypeText[] = // TODO.Translate +{ + L"normal", + L"rain", + L"thunderstorm", + L"sandstorm", + + L"snow", +}; + #endif //ITALIAN diff --git a/Utils/_PolishText.cpp b/Utils/_PolishText.cpp index 2119ff16..0af5e13e 100644 --- a/Utils/_PolishText.cpp +++ b/Utils/_PolishText.cpp @@ -4304,6 +4304,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"Pokaż samoobronę i wrogów (|Z)", L"Show Mobile Militia |Restrictions", // HEADROCK HAM 4: Mobile Restrictions Button // TODO.Translate L"Show Disease Data", // TODO.Translate + L"Show Weather", // TODO.Translate }; STR16 pMapScreenInvenButtonHelpText[] = @@ -6177,6 +6178,9 @@ STR16 zMarksMapScreenText[] = // Flugente: disease texts describing what a map view does TODO.Translate L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", + + // Flugente: weather texts describing what a map view does + L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.", // TODO.Translate }; @@ -11142,4 +11146,14 @@ STR16 szNonProfileMerchantText[] = L"Merchant refuses to interact with you.", }; +STR16 szWeatherTypeText[] = // TODO.Translate +{ + L"normal", + L"rain", + L"thunderstorm", + L"sandstorm", + + L"snow", +}; + #endif //POLISH diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index fe323284..bad1f747 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -4297,6 +4297,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"Ополчение и враги (|Z)", L"Патруль ополчения (|R)", // HEADROCK HAM 4: Mobile Restrictions Button L"Очаги заболеваний", + L"Show Weather", // TODO.Translate }; STR16 pMapScreenInvenButtonHelpText[] = @@ -6169,6 +6170,9 @@ STR16 zMarksMapScreenText[] = // Flugente: disease texts describing what a map view does L"Здесь показаны вспышки заболеваний по секторам. Число указывает средний показатель инфекции на человека, цвет - насколько широко распространена инфекция. СЕРЫЙ= нет информации о заболеваемости. ЗЕЛЁНЫЙ - КРАСНЫЙ = уровень роста заболеваемости.", + + // Flugente: weather texts describing what a map view does + L"This view shows current weather. No colour=Sunny. CYAN=Rain. BLUE=Thunderstorm. ORANGE=Sandstorm. WHITE=Snow.", // TODO.Translate }; @@ -11121,4 +11125,14 @@ STR16 szNonProfileMerchantText[] = L"Merchant refuses to interact with you.", }; +STR16 szWeatherTypeText[] = // TODO.Translate +{ + L"normal", + L"rain", + L"thunderstorm", + L"sandstorm", + + L"snow", +}; + #endif //RUSSIAN diff --git a/lua/lua_env.cpp b/lua/lua_env.cpp index 87abdf58..00b407a1 100644 --- a/lua/lua_env.cpp +++ b/lua/lua_env.cpp @@ -5,22 +5,19 @@ static int LuaGetRainVal( lua_State *L ) { - lua_pushinteger( L, guiEnvWeather); + lua_pushinteger( L, GetWeatherInCurrentSector() ); return 1; } static int LuaSetRainVal( lua_State *L ) { - int newrain = luaL_checkinteger( L, 3); - luaL_argcheck( L, newrain >= 0 && newrain <= 2, 2, "The rain must be between 0 and 2" ); - if (newrain == 0) - { - EnvEndRainStorm(); - } - else - { - EnvBeginRainStorm( (UINT8)(newrain-1)); - } + int newweather = luaL_checkinteger( L, 3); + int sector = luaL_checkinteger( L, 4 ); + luaL_argcheck( L, newweather >= 0 && newweather < WEATHER_FORECAST_MAX, 2, "The rain must be between 0 and 5" ); + luaL_argcheck( L, sector >= 0 && sector <= 255, 2, "The secor must be between 0 and 255" ); + + ChangeWeather( sector, newweather ); + return 0; }