diff --git a/JA2.suo b/JA2.suo
index 7c08a09a..ccabe3bc 100644
Binary files a/JA2.suo and b/JA2.suo differ
diff --git a/JA2.vcproj b/JA2.vcproj
index 65a9edae..5de4515d 100644
--- a/JA2.vcproj
+++ b/JA2.vcproj
@@ -1980,6 +1980,9 @@
BrowseInformation="1"/>
+
+
+
+
diff --git a/Laptop/laptop.cpp b/Laptop/laptop.cpp
index 924154f9..41f75a30 100644
--- a/Laptop/laptop.cpp
+++ b/Laptop/laptop.cpp
@@ -353,8 +353,11 @@ static BOOLEAN fNewWWW=TRUE;
extern UINT32 guiRainLoop;
+// WANNE 2
INT32 giRainDelayInternetSite=-1;
+
+
// have we visitied this site already?
//BOOLEAN fVisitedBookmarkAlready[20];
@@ -850,15 +853,16 @@ INT32 EnterLaptop()
// Stop ambients...
StopAmbients( );
- //if its raining, start the rain showers
- if( IsItRaining() )
- {
- //Enable the rain delay warning
- giRainDelayInternetSite = -1;
+ // WANNE 2: disabled rain sound when laptop is displayed
+ ////if its raining, start the rain showers
+ //if( IsItRaining() )
+ //{
+ // //Enable the rain delay warning
+ // giRainDelayInternetSite = -1;
- //lower the volume
- guiRainLoop = PlayJA2Ambient( RAIN_1, LOWVOLUME, 0 );
- }
+ // //lower the volume
+ // guiRainLoop = PlayJA2Ambient( RAIN_1, LOWVOLUME, 0 );
+ //}
//open the laptop library
@@ -1013,12 +1017,13 @@ void ExitLaptop()
// Start ambients...
BuildDayAmbientSounds( );
+ // WANNE 2: disabled rain sound when laptop is displayed
//if its raining, start the rain showers
- if( IsItRaining() )
- {
- //Raise the volume to where it was
- guiRainLoop = PlayJA2Ambient( RAIN_1, MIDVOLUME, 0 );
- }
+ //if( IsItRaining() )
+ //{
+ // //Raise the volume to where it was
+ // guiRainLoop = PlayJA2Ambient( RAIN_1, MIDVOLUME, 0 );
+ //}
// release cursor
FreeMouseCursor( );
@@ -3556,18 +3561,19 @@ void BookmarkCallBack(MOUSE_REGION * pRegion, INT32 iReason )
void GoToWebPage(INT32 iPageId )
{
- //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;
+ // WANNE 2: 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;
switch(iPageId)
{
@@ -6347,10 +6353,11 @@ BOOLEAN IsItRaining()
void InternetRainDelayMessageBoxCallBack( UINT8 bExitValue )
{
- GoToWebPage( giRainDelayInternetSite );
+ // WANNE 2
+ //GoToWebPage( giRainDelayInternetSite );
//Set to -2 so we dont due the message for this occurence of laptop
- giRainDelayInternetSite = -2;
+ //giRainDelayInternetSite = -2;
}
diff --git a/NewGameSettings.cpp b/NewGameSettings.cpp
new file mode 100644
index 00000000..238f4625
--- /dev/null
+++ b/NewGameSettings.cpp
@@ -0,0 +1,160 @@
+#include "types.h"
+#include "NewGameSettings.h"
+#include "FileMan.h"
+
+#include
+#include
+
+#define GAME_INI_FILE "\\Ja2.ini"
+
+BOOLEAN gfStretch = FALSE;
+BOOLEAN gfStretchWinGDI = FALSE;
+BOOLEAN gfVSync = FALSE;
+
+BOOLEAN gfAllowRain = FALSE;
+
+UINT16 gusRainChancePerDay = 100, gusRainMinLength = 60, gusRainMaxLength = 180;
+
+extern UINT32 guiMinLightningInterval;
+extern UINT32 guiMaxLightningInterval;
+extern UINT32 guiMinDLInterval;
+extern UINT32 guiMaxDLInterval;
+extern UINT32 guiProlongLightningIfSeenSomeone;
+extern UINT32 guiChanceToDoLightningBetweenTurns;
+
+extern UINT32 guiMaxRainDrops;
+
+typedef struct
+{
+ CHAR8* strParamName;
+ CHAR8* strSectionName;
+ LPVOID pVar;
+ UINT8 ubVarType;
+}TSetting;
+
+#define SET_RAIN "JA2 Rain Settings"
+#define SET_THUNDER "JA2 Thunder Settings"
+
+enum
+{
+ VT_UINT32,
+ VT_UINT16,
+ VT_UINT8,
+ VT_INT32,
+ VT_INT16,
+ VT_INT8,
+ VT_BOOLEAN
+};
+
+TSetting gpSettings[] = {
+
+ // Rain settings
+ {"ALLOW_RAIN", SET_RAIN, &gfAllowRain, VT_BOOLEAN},
+ {"RAIN_CHANCE_PER_DAY", SET_RAIN, &gusRainChancePerDay, VT_UINT16},
+ {"RAIN_MIN_LENGTH_IN_MINUTES", SET_RAIN, &gusRainMinLength, VT_UINT16},
+ {"RAIN_MAX_LENGTH_IN_MINUTES", SET_RAIN, &gusRainMaxLength, VT_UINT16},
+ {"MAX_RAIN_DROPS", SET_RAIN, &guiMaxRainDrops, VT_UINT32},
+
+ // Thunder settings
+ {"MIN_INTERVAL_BETWEEN_LIGHTNINGS_IN_REAL_TIME_SECONDS", SET_THUNDER, &guiMinLightningInterval, VT_UINT32},
+ {"MAX_INTERVAL_BETWEEN_LIGHTNINGS_IN_REAL_TIME_SECONDS", SET_THUNDER, &guiMaxLightningInterval, VT_UINT32},
+ {"MIN_INTERVAL_BETWEEN_LIGHTNING_AND_THUNDERCLAPS_IN_SECONDS", SET_THUNDER, &guiMinDLInterval, VT_UINT32},
+ {"MAX_INTERVAL_BETWEEN_LIGHTNING_AND_THUNDERCLAPS_IN_SECONDS", SET_THUNDER, &guiMaxDLInterval, VT_UINT32},
+ {"PROLOGNE_DELAY_IF_SEEN_SOMEONE_DURING_LIGHTNING_IN_TURNBASED_IN_SECONDS", SET_THUNDER, &guiProlongLightningIfSeenSomeone, VT_UINT32},
+ {"CHANCE_TO_DO_LIGHTNING_BETWEEN_TURNS", SET_THUNDER, &guiChanceToDoLightningBetweenTurns, VT_UINT32},
+
+ {0,0,0,VT_UINT8}
+};
+
+
+void NSSaveSettings()
+{
+ CHAR8 zStr[ 256 ];
+ TSetting* pCurr = gpSettings;
+ INT32 iBuf;
+ BOOLEAN fFileCreated = !FileExists( GAME_INI_FILE );
+
+ FileDelete( GAME_INI_FILE );
+
+ while( pCurr->pVar )
+ {
+ switch( pCurr->ubVarType )
+ {
+ case VT_UINT32:
+ iBuf = *((UINT32*)pCurr->pVar);
+ break;
+ case VT_UINT16:
+ iBuf = *((UINT16*)pCurr->pVar);
+ break;
+ case VT_UINT8:
+ iBuf = *((UINT8*)pCurr->pVar);
+ break;
+ case VT_INT32:
+ iBuf = *((INT32*)pCurr->pVar);
+ break;
+ case VT_INT16:
+ iBuf = *((INT16*)pCurr->pVar);
+ break;
+ case VT_INT8:
+ iBuf = *((INT8*)pCurr->pVar);
+ break;
+ case VT_BOOLEAN:
+ iBuf = *((BOOLEAN*)pCurr->pVar);
+ break;
+ }
+
+ sprintf( zStr, "%d", iBuf );
+
+ WritePrivateProfileString( pCurr->strSectionName, pCurr->strParamName, zStr, GAME_INI_FILE );
+
+ ++pCurr;
+ }
+}
+
+void NSLoadSettings()
+{
+ CHAR8 zStr[ 256 ];
+ UINT32 uiRetVal=0;
+ TSetting* pCurr = gpSettings;
+ INT32 iBuf;
+ STRING512 INIFile; // Path to the ini file
+
+ // Get Executable Directory
+ GetExecutableDirectory( INIFile );
+
+ strcat(INIFile, "\\Ja2.ini");
+
+ while( pCurr->pVar )
+ {
+ uiRetVal = GetPrivateProfileString( pCurr->strSectionName, pCurr->strParamName, "", zStr, 256, INIFile );
+ if( uiRetVal && strlen( zStr ) )
+ {
+ sscanf( zStr, "%d", &iBuf );
+ switch( pCurr->ubVarType )
+ {
+ case VT_UINT32:
+ *((UINT32*)pCurr->pVar) = iBuf;
+ break;
+ case VT_UINT16:
+ *((UINT16*)pCurr->pVar) = iBuf;
+ break;
+ case VT_UINT8:
+ *((UINT8*)pCurr->pVar) = iBuf;
+ break;
+ case VT_INT32:
+ *((INT32*)pCurr->pVar) = iBuf;
+ break;
+ case VT_INT16:
+ *((INT16*)pCurr->pVar) = iBuf;
+ break;
+ case VT_INT8:
+ *((INT8*)pCurr->pVar) = iBuf;
+ break;
+ case VT_BOOLEAN:
+ *((BOOLEAN*)pCurr->pVar) = iBuf;
+ break;
+ }
+ }
+ pCurr++;
+ }
+}
\ No newline at end of file
diff --git a/NewGameSettings.h b/NewGameSettings.h
new file mode 100644
index 00000000..e8845b59
--- /dev/null
+++ b/NewGameSettings.h
@@ -0,0 +1,12 @@
+#ifndef ___NEW_GAME_SETTINGS___
+#define ___NEW_GAME_SETTINGS___
+
+extern BOOLEAN gfUseABResources;
+extern BOOLEAN gfEnableEmergencyButton_SkipStrategicEvents;
+extern UINT32 guiMaxTossSearchDist;
+extern BOOLEAN gfShowItemShadow;
+
+void NSSaveSettings();
+void NSLoadSettings();
+
+#endif
\ No newline at end of file
diff --git a/SaveLoadGame.cpp b/SaveLoadGame.cpp
index f55ece0b..e9501312 100644
--- a/SaveLoadGame.cpp
+++ b/SaveLoadGame.cpp
@@ -101,6 +101,11 @@
#include "Enemy Soldier Save.h"
#include "BobbyRMailOrder.h"
#include "Mercs.h"
+#include "INIReader.h"
+
+//rain
+#include "Rain.h"
+//end rain
/////////////////////////////////////////////////////
//
@@ -4538,6 +4543,10 @@ BOOLEAN SaveGeneralInfo( HWFILE hFile )
return( TRUE );
}
+//rain
+extern UINT32 guiRainLoop;
+//end rain
+
BOOLEAN LoadGeneralInfo( HWFILE hFile )
{
@@ -4617,6 +4626,14 @@ BOOLEAN LoadGeneralInfo( HWFILE hFile )
//The current state of the weather
guiEnvWeather = sGeneralInfo.uiEnvWeather;
+ //rain
+ if ( guiRainLoop != NO_SAMPLE )
+ {
+ SoundStop( guiRainLoop );
+ guiRainLoop = NO_SAMPLE;
+ }
+ //end rain
+
gubDefaultButton = sGeneralInfo.ubDefaultButton;
gfSkyriderEmptyHelpGiven = sGeneralInfo.fSkyriderEmptyHelpGiven;
diff --git a/Standard Gaming Platform/sgp.cpp b/Standard Gaming Platform/sgp.cpp
index a8ba3013..989e692c 100644
--- a/Standard Gaming Platform/sgp.cpp
+++ b/Standard Gaming Platform/sgp.cpp
@@ -705,6 +705,15 @@ int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR p
return( 0 );
}
+ //rain
+ NSLoadSettings();
+ //NSSaveSettings();
+ //InitResolution();
+
+ //EmergencyExitButtonInit();
+ //end rain
+
+
ghInstance = hInstance;
// Copy commandline!
diff --git a/Standard Gaming Platform/video.cpp b/Standard Gaming Platform/video.cpp
index 2e6c1a73..251b16ac 100644
--- a/Standard Gaming Platform/video.cpp
+++ b/Standard Gaming Platform/video.cpp
@@ -772,7 +772,6 @@ BOOLEAN CanBlitToMouseBuffer(void)
void InvalidateRegion(INT32 iLeft, INT32 iTop, INT32 iRight, INT32 iBottom)
{
- // WANNE 2
if (gfForceFullScreenRefresh == TRUE)
{
//
@@ -1504,6 +1503,12 @@ void ScrollJA2Background(UINT32 uiDirection, INT16 sScrollXIncrement, INT16 sScr
}
+//rain
+BOOLEAN IsItAllowedToRenderRain();
+extern UINT32 guiRainRenderSurface;
+
+BOOLEAN gfNextRefreshFullScreen = FALSE;
+//end rain
void RefreshScreen(void *DummyVariable)
{
@@ -1523,6 +1528,17 @@ void RefreshScreen(void *DummyVariable)
fShowMouse = FALSE;
}
+ if( gfNextRefreshFullScreen )
+ {
+ if( guiCurrentScreen == GAME_SCREEN )
+ {
+ InvalidateScreen();
+ gfRenderScroll = FALSE;
+ // gfForceFullScreenRefresh = TRUE;
+ // guiFrameBufferState == BUFFER_DIRTY;
+ }
+ gfNextRefreshFullScreen = FALSE;
+ }
//DebugMsg(TOPIC_VIDEO, DBG_LEVEL_0, "Looping in refresh");
@@ -2102,6 +2118,20 @@ void RefreshScreen(void *DummyVariable)
}
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+ // Rain //
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ if( IsItAllowedToRenderRain() && gfProgramIsRunning )
+ {
+ BltVideoSurface( BACKBUFFER, guiRainRenderSurface, 0, 0, 0, VS_BLT_FAST | VS_BLT_USECOLORKEY, NULL );
+ gfNextRefreshFullScreen = TRUE;
+ }
+
+
+
///////////////////////////////////////////////////////////////////////////////////////////////
//
// (1) Flip Pages
diff --git a/Standard Gaming Platform/video.h b/Standard Gaming Platform/video.h
index 16a01525..c7cd4e00 100644
--- a/Standard Gaming Platform/video.h
+++ b/Standard Gaming Platform/video.h
@@ -66,6 +66,8 @@ extern void StartFrameBufferRender(void);
extern void EndFrameBufferRender(void);
extern void PrintScreen(void);
+
+
extern BOOLEAN EraseMouseCursor( );
extern BOOLEAN SetMouseCursorProperties( INT16 sOffsetX, INT16 sOffsetY, UINT16 usCursorHeight, UINT16 usCursorWidth );
extern BOOLEAN BltToMouseCursor(UINT32 uiVideoObjectHandle, UINT16 usVideoObjectSubIndex, UINT16 usXPos, UINT16 usYPos );
diff --git a/Strategic/Game Event Hook.cpp b/Strategic/Game Event Hook.cpp
index 64f7975a..fe6c1aae 100644
--- a/Strategic/Game Event Hook.cpp
+++ b/Strategic/Game Event Hook.cpp
@@ -297,15 +297,16 @@ BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent )
case EVENT_RAINSTORM:
// ATE: Disabled
- //
- //if( pEvent->ubEventType == ENDRANGED_EVENT )
- //{
- // EnvEndRainStorm( );
- //}
- //else
- //{
- // EnvBeginRainStorm( (UINT8)pEvent->uiParam );
- //}
+ //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:
diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp
index 242f4896..95d83224 100644
--- a/Tactical/Handle Items.cpp
+++ b/Tactical/Handle Items.cpp
@@ -402,14 +402,14 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us
pSoldier->fDontChargeTurningAPs = TRUE;
}
}
- else
+ /*else
{
// If raising gun, don't charge turning!
if ( fAddingTurningCost )
{
pSoldier->fDontChargeReadyAPs = TRUE;
}
- }
+ }*/
@@ -1301,14 +1301,14 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, UINT16 usGridNo, INT8 bLevel, UINT16 us
pSoldier->fDontChargeTurningAPs = TRUE;
}
}
- else
+ /*else
{
// If raising gun, don't charge turning!
if ( fAddingTurningCost )
{
pSoldier->fDontChargeReadyAPs = TRUE;
}
- }
+ }*/
}
// If this is a player guy, show message about no APS
diff --git a/Tactical/Handle UI.cpp b/Tactical/Handle UI.cpp
index afbba3c5..f581ebe8 100644
--- a/Tactical/Handle UI.cpp
+++ b/Tactical/Handle UI.cpp
@@ -75,6 +75,13 @@
#endif
+//extern BOOLEAN gfDisplayFullCountRingBurst;
+extern UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady );
+
+//#define AP_TO_AIM_TILE_IF_GETTING_READY 1
+#define AP_TO_AIM_TILE_IF_ALREADY_READY ( Weapon[ Item[pSoldier->inv[HANDPOS].usItem].ubClassIndex ].ubReadyTime ? 2 : 1 )
+#define AP_TO_AIM_TILE_IF_GETTING_READY AP_TO_AIM_TILE_IF_ALREADY_READY
+
#define MAX_ON_DUTY_SOLDIERS 6
/////////////////////////////////////////////////////////////////////////////////////
@@ -4476,11 +4483,13 @@ void SetConfirmMovementModeCursor( SOLDIERTYPE *pSoldier, BOOLEAN fFromMove )
}
+UINT8 gubShowActionPointsInRed = 0;
UINT32 UIHandleLCOnTerrain( UI_EVENT *pUIEvent )
{
SOLDIERTYPE *pSoldier;
INT16 sFacingDir, sXPos, sYPos;
+ UINT16 usAnimState;
guiNewUICursor = LOOK_UICURSOR;
@@ -4511,10 +4520,26 @@ UINT32 UIHandleLCOnTerrain( UI_EVENT *pUIEvent )
if ( sFacingDir != pSoldier->bDirection )
{
gsCurrentActionPoints = GetAPsToLook( pSoldier );
+ gfUIHandleShowMoveGrid = FALSE;
}
else
{
+ usAnimState = PickSoldierReadyAnimation( pSoldier, FALSE );
+
+ if( usAnimState != INVALID_ANIMATION )
+ {
+ gsCurrentActionPoints = GetAPsToReadyWeapon( pSoldier, usAnimState ) + AP_TO_AIM_TILE_IF_GETTING_READY;
+ }
+ else if( pSoldier->sLastTarget != sXPos + (MAXCOL * sYPos ) )
+ gsCurrentActionPoints = AP_TO_AIM_TILE_IF_ALREADY_READY;
+ else
gsCurrentActionPoints = 0;
+
+ gfUIHandleShowMoveGrid = TRUE;
+ gsUIHandleShowMoveGridLocation = sXPos + (MAXCOL * sYPos );
+
+ gubShowActionPointsInRed = 5;
+ //gfDisplayFullCountRingBurst = FALSE;
}
// Determine if we can afford!
@@ -4538,7 +4563,8 @@ UINT32 UIHandleLCChangeToLook( UI_EVENT *pUIEvent )
BOOLEAN MakeSoldierTurn( SOLDIERTYPE *pSoldier, INT16 sXPos, INT16 sYPos )
{
- INT16 sFacingDir, sAPCost;
+ INT16 sFacingDir, sAPCost, sAPCostToReady;
+ UINT16 usAnimState;
// Get direction from mouse pos
sFacingDir = GetDirectionFromXY( sXPos, sYPos, pSoldier );
@@ -4569,8 +4595,42 @@ BOOLEAN MakeSoldierTurn( SOLDIERTYPE *pSoldier, INT16 sXPos, INT16 sYPos )
return( TRUE );
}
+ else
+ {
+ usAnimState = PickSoldierReadyAnimation( pSoldier, FALSE );
+ sAPCostToReady = 0;
+
+ if( usAnimState != INVALID_ANIMATION )
+ {
+ sAPCostToReady = GetAPsToReadyWeapon( pSoldier, usAnimState );
+ sAPCost = sAPCostToReady + AP_TO_AIM_TILE_IF_GETTING_READY;
+ }
+ else if( pSoldier->sLastTarget != sXPos + (MAXCOL * sYPos ) )
+ sAPCost = AP_TO_AIM_TILE_IF_ALREADY_READY;
+ else
+ return FALSE;
+
+
+ // Check AP cost...
+ if ( !EnoughPoints( pSoldier, sAPCost, 0, TRUE ) )
+ {
return( FALSE );
+ }
+
+ if( usAnimState != INVALID_ANIMATION )
+ SoldierReadyWeapon( pSoldier, sXPos, sYPos, FALSE );
+
+ pSoldier->bTurningFromUI = TRUE;
+ guiOldEvent = LA_BEGINUIOURTURNLOCK;
+
+ // Setting "Last Target"
+
+ pSoldier->sLastTarget = sXPos + (MAXCOL * sYPos);
+ DeductPoints( pSoldier, (INT16)(sAPCost - sAPCostToReady), 0 );
+
+ return( TRUE );
+ }
}
diff --git a/Tactical/Points.cpp b/Tactical/Points.cpp
index 3cd0fbcd..23629d59 100644
--- a/Tactical/Points.cpp
+++ b/Tactical/Points.cpp
@@ -26,6 +26,10 @@
#include "Soldier Profile.h"
#endif
+//rain
+#define BREATH_GAIN_REDUCTION_PER_RAIN_INTENSITY 25
+//end rain
+
extern BOOLEAN IsValidSecondHandShot( SOLDIERTYPE *pSoldier );
@@ -770,6 +774,10 @@ void UnusedAPsToBreath(SOLDIERTYPE *pSold)
}
+//rain
+extern INT8 gbCurrentRainIntensity;
+//end rain
+
INT16 GetBreathPerAP( SOLDIERTYPE *pSoldier, UINT16 usAnimState )
{
INT16 sBreathPerAP = 0;
@@ -844,6 +852,14 @@ INT16 GetBreathPerAP( SOLDIERTYPE *pSoldier, UINT16 usAnimState )
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Unknown end-of-turn breath anim: %s", gAnimControl[ usAnimState ].zAnimStr ) );
}
+ //rain
+ // Reduce breath gain on 25%/rain intensity
+ if( sBreathPerAP < 0 && ( pSoldier->bLevel ||!FindStructure( pSoldier->sGridNo, STRUCTURE_ROOF ) ) && pSoldier->bBreath > 1)
+ {
+ sBreathPerAP -= sBreathPerAP * gbCurrentRainIntensity * BREATH_GAIN_REDUCTION_PER_RAIN_INTENSITY / 100 ;
+ }
+ //end rain
+
return( sBreathPerAP );
}
@@ -1296,6 +1312,8 @@ UINT8 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubAddTurni
// bFullAPs are BASE APs, which do not include APs caried over from the previous turn.
bFullAPs = CalcActionPoints( pSoldier );
+ //bFullAPs = pSoldier->bInitialActionPoints;//CalcActionPoints( pSoldier ); //lal
+
// aim skill is the same whether we are using 1 or 2 guns
bAimSkill = CalcAimSkill( pSoldier, usItem );
diff --git a/Tactical/Rain.cpp b/Tactical/Rain.cpp
new file mode 100644
index 00000000..7d7bec46
--- /dev/null
+++ b/Tactical/Rain.cpp
@@ -0,0 +1,582 @@
+// WANNE 2
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "types.h"
+ #include "soldier control.h"
+ #include "overhead.h"
+ #include "animation control.h"
+ #include "points.h"
+ #include "opplist.h"
+ #include "timer.h"
+ #include "event pump.h"
+ #include "Sound Control.h"
+ #include "interface.h"
+ #include "Isometric Utils.h"
+ #include "Font Control.H"
+ #include "ai.h"
+ #include "interface.h"
+ #include "message.h"
+ #include "text.h"
+ #include "TeamTurns.h"
+ #include "Smell.h"
+ #include "game clock.h"
+ #include "Soldier Functions.h"
+ #include "cursors.h"
+ #include "Queen Command.h"
+ #include "Pathai.h"
+ #include "Music Control.h"
+ #include "Strategic Turns.h"
+ #include "lighting.h"
+ #include "environment.h"
+ #include "Explosion Control.h"
+ #include "dialogue control.h"
+ #include "Soldier Profile Type.h"
+ #include "SmokeEffects.h"
+ #include "lighteffects.h"
+ #include "air raid.h"
+ #include "meanwhile.h"
+ #include "SkillCheck.h"
+ #include "AIInternals.h"
+ #include "AIList.h"
+ #ifdef DEBUG_INTERRUPTS
+ #include "debug.h"
+ #endif
+#endif
+
+#include "Rain.h"
+
+// WANNE 2
+// Shop Keeper Interface
+#define SKI_X_OFFSET (((SCREEN_WIDTH - 536) / 2))
+#define SKI_Y_OFFSET ((((SCREEN_HEIGHT - 140) - 340) / 2))
+
+// WANNE 2
+// Overhead Map
+#define OM_X_OFFSET 0
+#define OM_Y_OFFSET 0
+
+
+
+
+#define RAIN_UPDATE_RATE 60
+#define PERCENT_OF_DROPS_GOING_TO_THE_EDGE_OF_SCREEN 0.25f
+
+#define DROP_ANGLE_CHANGE_RATE 1.0f
+
+#define MIN_DROP_LENGTH 2.0f
+#define ADD_DROP_LENGTH_IF_STORM 2.0f
+#define DROP_LENGTH_RANGE 2.0f
+#define DROP_LENGTH_CHANGE_RATE 0.1f
+#define DROP_LENGTH_RAND 2.0f
+
+#define BASE_DROP_SPEED 7.0f
+#define DROP_SPEED_RANGE 3.5f
+#define DROP_SPEED_CHANGE_RATE 0.1f
+#define DROP_SPEED_RAND 5.0f
+
+UINT32 guiMaxRainDrops = 79;
+
+#define RESOLUTION_FACTOR_ON_MAXIMUM_DROPS ((FLOAT) ( SCREEN_WIDTH * SCREEN_HEIGHT ) / ((FLOAT) 640 * 480 ) )
+#define BASE_MAXIMUM_DROPS guiMaxRainDrops * RESOLUTION_FACTOR_ON_MAXIMUM_DROPS
+
+#define DEGREE(a) ( 3.14159 / 180 * a )
+
+typedef struct
+{
+ BOOLEAN fAlive;
+
+ FLOAT fpX;
+ FLOAT fpY;
+ FLOAT fpIncrX;
+ FLOAT fpIncrY;
+
+ FLOAT fpEndRelX;
+ FLOAT fpEndRelY;
+
+ UINT32 uiAmountOfTicksToLive;
+}TRainDrop;
+
+
+static BOOLEAN fFirstTime = TRUE;
+UINT32 guiRainRenderSurface = 0;
+UINT32 guiLastRainUpdate = 0;
+RECT gRainRegion;
+
+TRainDrop *pRainDrops = 0;
+UINT32 guiCurrMaxAmountOfRainDrops = 0;
+UINT32 guiCurrAmountOfDeadRainDrops = 0;
+
+INT8 gbCurrentRainIntensity = 0;
+
+FLOAT fpCurrDropAngleOfFalling = 0;
+FLOAT fpCurrDropLength = 0;
+FLOAT fpCurrDropSpeed = 0;
+
+FLOAT fpMaxDropAngleOfFalling = 0;
+FLOAT fpMaxDropLength = 0;
+FLOAT fpMaxDropSpeed = 0;
+
+FLOAT fpMinDropAngleOfFalling = 0;
+FLOAT fpMinDropLength = 0;
+FLOAT fpMinDropSpeed = 0;
+
+
+extern UINT32 guiCurrentScreen;
+extern BOOLEAN gfAllowRain;
+
+extern INT16 gsVIEWPORT_WINDOW_END_Y;
+extern INT16 gsVIEWPORT_WINDOW_START_Y;
+
+#define VIDEO_OVERLAYS 100
+extern VIDEO_OVERLAY gVideoOverlays[ VIDEO_OVERLAYS ];
+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( !gfAllowRain )return FALSE;
+
+ if( !( guiEnvWeather & WEATHER_FORECAST_THUNDERSHOWERS | WEATHER_FORECAST_SHOWERS ) )return FALSE;
+
+ if( guiCurrentScreen != GAME_SCREEN && guiCurrentScreen != SHOPKEEPER_SCREEN ) return FALSE;
+
+ return TRUE;
+}
+
+void InitializeRainVideoObject( )
+{
+ VSURFACE_DESC vs_desc;
+ UINT16 usWidth;
+ UINT16 usHeight;
+ UINT8 ubBitDepth;
+
+ // Create render buffer
+ GetCurrentVideoSettings( &usWidth, &usHeight, &ubBitDepth );
+ vs_desc.fCreateFlags = VSURFACE_CREATE_DEFAULT | VSURFACE_SYSTEM_MEM_USAGE;
+ vs_desc.usWidth = usWidth;
+ vs_desc.usHeight = usHeight;
+ vs_desc.ubBitDepth = ubBitDepth;
+
+ AddVideoSurface( &vs_desc, &guiRainRenderSurface );
+}
+
+void InitializeRainData()
+{
+ InitializeRainVideoObject();
+
+ gRainRegion.left = 0;
+ gRainRegion.top = 0;
+ gRainRegion.right = SCREEN_WIDTH;
+ gRainRegion.bottom = SCREEN_HEIGHT - 120;
+}
+
+void ResetRain()
+{
+ if( pRainDrops )
+ {
+ MemFree( pRainDrops );
+ pRainDrops = NULL;
+ }
+
+ guiCurrMaxAmountOfRainDrops = 0;
+}
+
+void GenerateRainDropsList()
+{
+ guiCurrMaxAmountOfRainDrops = (UINT32)BASE_MAXIMUM_DROPS * gbCurrentRainIntensity;
+
+ pRainDrops = (TRainDrop *)MemAlloc( sizeof( TRainDrop ) * guiCurrMaxAmountOfRainDrops );
+ memset( pRainDrops, 0, sizeof( TRainDrop ) * guiCurrMaxAmountOfRainDrops );
+}
+
+void KillOutOfRegionRainDrops()
+{
+ UINT32 uiIndex;
+
+ for( uiIndex = 0; uiIndex < guiCurrMaxAmountOfRainDrops; ++uiIndex )
+ {
+ TRainDrop *pCurr = &pRainDrops[ uiIndex ];
+
+ if( ( pCurr->fpX < gRainRegion.left || pCurr->fpX >= gRainRegion.right ||
+ pCurr->fpY < gRainRegion.top || pCurr->fpY >= gRainRegion.bottom ) &&
+ ( pCurr->fpX + pCurr->fpEndRelX < gRainRegion.left || pCurr->fpX + pCurr->fpEndRelX >= gRainRegion.right ||
+ pCurr->fpY + pCurr->fpEndRelY < gRainRegion.top || pCurr->fpY + pCurr->fpEndRelY >= gRainRegion.bottom ) )
+ {
+ pCurr->fAlive = FALSE;
+ guiCurrAmountOfDeadRainDrops++;
+ }
+
+ }
+}
+
+void CreateRainDrops()
+{
+ UINT32 uiIndex;
+ UINT32 uiCreatedDrops = 0;
+ FLOAT fpCos, fpSin, fpAbsTg;
+ FLOAT fpDropLength = fpCurrDropLength;
+ FLOAT fpDropSpeed = fpCurrDropSpeed;
+ FLOAT fpNumDropsToXBorder = 0;
+ BOOLEAN fLoopIsDone;
+ UINT32 uiIndRand;
+
+ fpCos = cos( DEGREE(fpCurrDropAngleOfFalling) );
+ fpSin = sin( DEGREE(fpCurrDropAngleOfFalling) );
+
+ if( fpCos )
+ fpAbsTg = fabs( fpSin / fpCos ); // take only absolute valuse
+ else
+ fpAbsTg = 0; // well, it can't really be ;)
+
+ for( uiIndex = 0; uiIndex < guiCurrMaxAmountOfRainDrops; ++uiIndex )
+ {
+ TRainDrop *pCurr = &pRainDrops[ uiIndex ];
+
+ if( pCurr->fAlive )continue;
+
+ uiIndRand = (((UINT32)pCurr) / sizeof(TRainDrop) ) % 20;
+
+ fpDropLength = fpCurrDropLength + ( (((UINT32)pCurr) / sizeof(TRainDrop) ) % 7 ) * DROP_LENGTH_RAND / 6;
+ fpDropSpeed = fpCurrDropSpeed + ( ( ((UINT32)pCurr) / sizeof(TRainDrop) + 43 ) % 13 ) * DROP_SPEED_RAND / 12;
+
+ pCurr->fAlive = TRUE;
+
+ pCurr->fpIncrX = fpCos * fpDropSpeed;
+ pCurr->fpIncrY = fpSin * fpDropSpeed;
+
+ pCurr->fpEndRelX = -fpCos * fpDropLength;
+ pCurr->fpEndRelY = -fpSin * fpDropLength;
+
+ // where we want the drops to fall
+
+ if( uiIndex < guiCurrMaxAmountOfRainDrops * PERCENT_OF_DROPS_GOING_TO_THE_EDGE_OF_SCREEN )
+ {
+ if( !fpCos )
+ fpNumDropsToXBorder = 0;
+ else
+ {
+ if( fpAbsTg < 1 )
+ {
+ fpNumDropsToXBorder = 1.0f - fpAbsTg;
+ fpNumDropsToXBorder *= (((FLOAT)SCREEN_HEIGHT - 120) / (FLOAT)SCREEN_WIDTH);
+ fpNumDropsToXBorder *= guiCurrMaxAmountOfRainDrops * PERCENT_OF_DROPS_GOING_TO_THE_EDGE_OF_SCREEN / 2;
+
+ fpNumDropsToXBorder += guiCurrMaxAmountOfRainDrops * PERCENT_OF_DROPS_GOING_TO_THE_EDGE_OF_SCREEN / 2;
+ }
+ else
+ {
+ fpNumDropsToXBorder = 1 / fpAbsTg;
+ fpNumDropsToXBorder *= (((FLOAT)SCREEN_HEIGHT - 120) / (FLOAT)SCREEN_WIDTH);
+ fpNumDropsToXBorder *= guiCurrMaxAmountOfRainDrops * PERCENT_OF_DROPS_GOING_TO_THE_EDGE_OF_SCREEN / 2;
+ }
+ }
+
+ if( uiIndex >= fpNumDropsToXBorder )
+ {
+ pCurr->fpX = gRainRegion.left + Random( gRainRegion.right - gRainRegion.left );
+ pCurr->fpY = gRainRegion.bottom - 1;
+ }
+ else if( fpCos > 0 )
+ {
+ pCurr->fpX = gRainRegion.right - 1;
+ pCurr->fpY = gRainRegion.top + Random( gRainRegion.bottom - gRainRegion.top );
+ }else{
+ pCurr->fpX = 0;
+ pCurr->fpY = gRainRegion.top + Random( gRainRegion.bottom - gRainRegion.top );
+ }
+ }else{
+ pCurr->fpX = gRainRegion.left + Random( gRainRegion.right - gRainRegion.left );
+ pCurr->fpY = gRainRegion.top + Random( gRainRegion.bottom - gRainRegion.top );
+ }
+
+ pCurr->uiAmountOfTicksToLive = 0;
+ fLoopIsDone = FALSE;
+
+ while( !fLoopIsDone )
+ {
+ pCurr->fpX -= pCurr->fpIncrX;
+ pCurr->fpY -= pCurr->fpIncrY;
+ pCurr->uiAmountOfTicksToLive++;
+
+ if( pCurr->fpX >= gRainRegion.right - 1 )
+ {
+ pCurr->fpX = gRainRegion.right - 1 - uiIndRand * pCurr->fpIncrX / 20 ;
+ fLoopIsDone = TRUE;
+ }
+ if( pCurr->fpX < gRainRegion.left )
+ {
+ pCurr->fpX = gRainRegion.left - uiIndRand * pCurr->fpIncrX / 20 ;
+ fLoopIsDone = TRUE;
+ }
+ if( pCurr->fpY >= gRainRegion.bottom - 1 )
+ {
+ pCurr->fpY = gRainRegion.bottom - 1 - uiIndRand * pCurr->fpIncrX / 20 ;
+ fLoopIsDone = TRUE;
+ }
+ if( pCurr->fpY < gRainRegion.top )
+ {
+ pCurr->fpY = gRainRegion.top - uiIndRand * pCurr->fpIncrX / 20 ;
+ fLoopIsDone = TRUE;
+ }
+ }
+
+ uiCreatedDrops++;
+
+ // drop creation is done!!!
+
+ }
+}
+
+void UpdateRainDrops()
+{
+ UINT32 uiIndex;
+
+ for( uiIndex = 0; uiIndex < guiCurrMaxAmountOfRainDrops; ++uiIndex )
+ {
+ TRainDrop *pCurr = &pRainDrops[ uiIndex ];
+
+ if( !pCurr->fAlive )continue;
+
+ if( pCurr->uiAmountOfTicksToLive )
+ {
+ pCurr->fpX += pCurr->fpIncrX;
+ pCurr->fpY += pCurr->fpIncrY;
+ pCurr->uiAmountOfTicksToLive--;
+ }else{
+ pCurr->fpEndRelX += pCurr->fpIncrX;
+ pCurr->fpEndRelY += pCurr->fpIncrY;
+
+ if( ( pCurr->fpEndRelX > 0 && pCurr->fpIncrX > 0 ) ||
+ ( pCurr->fpEndRelX < 0 && pCurr->fpIncrX < 0 ) ||
+ ( pCurr->fpEndRelY > 0 && pCurr->fpIncrY > 0 ) ||
+ ( pCurr->fpEndRelY < 0 && pCurr->fpIncrY < 0 ) )
+ {
+ pCurr->fAlive = FALSE;
+ guiCurrAmountOfDeadRainDrops++;
+ }
+ }
+ }
+
+}
+
+void BlankRainRenderSurface()
+{
+ ColorFillVideoSurfaceArea( guiRainRenderSurface, gRainRegion.left, gRainRegion.top, gRainRegion.right, gRainRegion.bottom, Get16BPPColor( FROMRGB( 0, 0, 0 ) ) );
+}
+
+UINT16 GetDropColor()
+{
+ UINT32 uiRGBPart = 32 + ( 15 - GetTimeOfDayAmbientLightLevel() ) * 8;
+
+ uiRGBPart = max( 0, uiRGBPart );
+ uiRGBPart = min( 255, uiRGBPart );
+
+ return Get16BPPColor( FROMRGB( uiRGBPart, uiRGBPart, uiRGBPart ) );
+}
+
+void RenderRainOnSurface()
+{
+ UINT8 *pDestBuf;
+ UINT32 uiDestPitchBYTES;
+ UINT32 uiIndex;
+ UINT16 sDropsColor = GetDropColor();
+
+ pDestBuf = LockVideoSurface( guiRainRenderSurface, &uiDestPitchBYTES );
+ SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, gsVIEWPORT_WINDOW_START_Y, SCREEN_WIDTH, gsVIEWPORT_WINDOW_END_Y - gsVIEWPORT_WINDOW_START_Y );
+
+ for( uiIndex = 0; uiIndex < guiCurrMaxAmountOfRainDrops; ++uiIndex )
+ {
+ TRainDrop *pCurr = &pRainDrops[ uiIndex ];
+
+ if( !pCurr->fAlive )continue;
+
+ LineDraw( TRUE, pCurr->fpX, pCurr->fpY, pCurr->fpX + pCurr->fpEndRelX, pCurr->fpY + pCurr->fpEndRelY, sDropsColor, pDestBuf );
+ }
+
+ UnLockVideoSurface( guiRainRenderSurface );
+}
+
+void GenerateRainMaximums()
+{
+ if( gbCurrentRainIntensity == 1 )
+ {
+ fpMinDropAngleOfFalling = 45;
+ fpMaxDropAngleOfFalling = 135;
+ }else
+ if( Random( 2 ) )
+ {
+ fpMinDropAngleOfFalling = 20;
+ fpMaxDropAngleOfFalling = 70;
+ }else{
+ fpMinDropAngleOfFalling = 110;
+ fpMaxDropAngleOfFalling = 160;
+ }
+
+ fpCurrDropAngleOfFalling = fpMinDropAngleOfFalling + Random( fpMaxDropAngleOfFalling - fpMinDropAngleOfFalling );
+
+ fpMinDropLength = MIN_DROP_LENGTH + ADD_DROP_LENGTH_IF_STORM * ( gbCurrentRainIntensity - 1 );
+ fpMaxDropLength = fpMinDropLength + DROP_LENGTH_RANGE;
+
+ fpCurrDropLength = fpMinDropLength + Random( fpMaxDropLength - fpMinDropLength );
+
+ fpMinDropSpeed = BASE_DROP_SPEED * gbCurrentRainIntensity;
+ fpMaxDropSpeed = fpMinDropSpeed + DROP_SPEED_RANGE;
+
+ fpCurrDropSpeed = fpMinDropSpeed + Random( fpMaxDropSpeed - fpMinDropSpeed );
+
+}
+
+void UpdateRainDropsProperities()
+{
+ fpCurrDropAngleOfFalling += Random( 1000 * DROP_ANGLE_CHANGE_RATE * gbCurrentRainIntensity * 2 ) / 1000.0f - DROP_ANGLE_CHANGE_RATE * gbCurrentRainIntensity;
+
+ fpCurrDropAngleOfFalling = max( fpMinDropAngleOfFalling, fpCurrDropAngleOfFalling );
+ fpCurrDropAngleOfFalling = min( fpMaxDropAngleOfFalling, fpCurrDropAngleOfFalling );
+
+
+ fpCurrDropLength += Random( 1000 * DROP_LENGTH_CHANGE_RATE * 2 ) / 1000.0f - DROP_LENGTH_CHANGE_RATE;
+
+ fpCurrDropLength = max( fpMinDropLength, fpCurrDropLength );
+ fpCurrDropLength = min( fpMaxDropLength, fpCurrDropLength );
+
+
+ fpCurrDropSpeed += Random( 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 )
+ {
+ TRainDrop *pCurr = &pRainDrops[ uiIndex ];
+
+ if( !pCurr->fAlive )continue;
+
+ if( pCurr->uiAmountOfTicksToLive )
+ {
+ ubMoveTo = Random( pCurr->uiAmountOfTicksToLive ) + 1;
+
+ while( ubMoveTo < pCurr->uiAmountOfTicksToLive )
+ {
+ pCurr->fpX += pCurr->fpIncrX;
+ pCurr->fpY += pCurr->fpIncrY;
+ pCurr->uiAmountOfTicksToLive--;
+ }
+ }
+ }
+
+}
+
+void RainClipVideoOverlay()
+{
+ UINT32 uiIndex;
+ BACKGROUND_SAVE *pCurr;
+
+ for( uiIndex = 0; uiIndex < guiNumVideoOverlays ; ++uiIndex )
+ {
+ pCurr = gVideoOverlays[ uiIndex ].pBackground;
+
+ if( pCurr->sLeft < gRainRegion.right ||
+ pCurr->sTop < gRainRegion.bottom ||
+ pCurr->sRight >= gRainRegion.left ||
+ pCurr->sBottom >= gRainRegion.top )
+ ColorFillVideoSurfaceArea( guiRainRenderSurface, pCurr->sLeft, pCurr->sTop, pCurr->sRight, pCurr->sBottom, Get16BPPColor( FROMRGB( 0, 0, 0 ) ) );
+ }
+}
+
+void RenderRain()
+{
+ if( !GetRainIntensityFromEnvWeather() && gbCurrentRainIntensity )
+ {
+ gbCurrentRainIntensity = GetRainIntensityFromEnvWeather();
+ ResetRain();
+ }
+
+ if( !IsItAllowedToRenderRain() )return;
+
+ if( guiCurrentScreen == SHOPKEEPER_SCREEN )
+ {
+ ColorFillVideoSurfaceArea( guiRainRenderSurface, SKI_X_OFFSET, SKI_Y_OFFSET, 535, 340, Get16BPPColor( FROMRGB( 0, 0, 0 ) ) );
+ return;
+ }
+
+ if( InOverheadMap() )
+ {
+ // WANNE 2
+ ColorFillVideoSurfaceArea( guiRainRenderSurface, OM_X_OFFSET, OM_Y_OFFSET, SCREEN_WIDTH, SCREEN_HEIGHT - 120, Get16BPPColor( FROMRGB( 0, 0, 0 ) ) );
+ return;
+ }
+
+ if( fFirstTime )
+ {
+ InitializeRainData();
+ fFirstTime = FALSE;
+ }
+
+ if( GetJA2Clock() < guiLastRainUpdate )
+ guiLastRainUpdate = GetJA2Clock();
+
+ if( GetJA2Clock() < guiLastRainUpdate + 1000 / RAIN_UPDATE_RATE )
+ return;
+ else
+ guiLastRainUpdate = GetJA2Clock();
+
+ if( gbCurrentRainIntensity != GetRainIntensityFromEnvWeather() )
+ {
+ gbCurrentRainIntensity = GetRainIntensityFromEnvWeather();
+ ResetRain();
+ GenerateRainDropsList();
+ GenerateRainMaximums();
+
+
+ guiCurrAmountOfDeadRainDrops = guiCurrMaxAmountOfRainDrops;
+
+ CreateRainDrops();
+ RandomizeRainDropsPosition();
+ }
+
+ guiCurrAmountOfDeadRainDrops = 0;
+
+ UpdateRainDropsProperities();
+ UpdateRainDrops();
+ KillOutOfRegionRainDrops();
+ CreateRainDrops();
+
+ BlankRainRenderSurface();
+ RenderRainOnSurface();
+
+ RainClipVideoOverlay();
+
+ if( gfInTalkPanel )
+ {
+ ColorFillVideoSurfaceArea( guiRainRenderSurface, gTalkPanel.sX, gTalkPanel.sY, gTalkPanel.sX + gTalkPanel.usWidth, gTalkPanel.sY + gTalkPanel.usHeight, Get16BPPColor( FROMRGB( 0, 0, 0 ) ) );
+ if ( gTalkPanel.fRenderSubTitlesNow )
+ {
+ if( gPopUpTextBox )
+ 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/Rain.h b/Tactical/Rain.h
new file mode 100644
index 00000000..b22ba4f0
--- /dev/null
+++ b/Tactical/Rain.h
@@ -0,0 +1,7 @@
+#ifndef ___RAIN_H___
+#define ___RAIN_H___
+
+BOOLEAN IsItAllowedToRenderRain();
+void RenderRain();
+
+#endif
\ No newline at end of file
diff --git a/Tactical/Tactical.vcproj b/Tactical/Tactical.vcproj
index 53fd59e8..8afab9f1 100644
--- a/Tactical/Tactical.vcproj
+++ b/Tactical/Tactical.vcproj
@@ -3732,6 +3732,9 @@
BrowseInformation="1"/>
+
+
+
+
diff --git a/Tactical/TeamTurns.cpp b/Tactical/TeamTurns.cpp
index 3cd7fe20..4c21ff0b 100644
--- a/Tactical/TeamTurns.cpp
+++ b/Tactical/TeamTurns.cpp
@@ -361,6 +361,10 @@ void EndTurnEvents( void )
DecayRottingCorpseAIWarnings();
}
+//rain
+BOOLEAN LightningEndOfTurn( UINT8 ubTeam );
+//end rain
+
void BeginTeamTurn( UINT8 ubTeam )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"BeginTeamTurn");
@@ -368,6 +372,11 @@ void BeginTeamTurn( UINT8 ubTeam )
UINT8 ubID;
SOLDIERTYPE *pSoldier;
+ //rain
+ if( !LightningEndOfTurn( ubTeam ) )return;
+ //end rain
+
+
while( 1 )
{
if ( ubTeam > LAST_TEAM )
diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp
index 39406299..380bee5f 100644
--- a/Tactical/Turn Based Input.cpp
+++ b/Tactical/Turn Based Input.cpp
@@ -1513,6 +1513,32 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
}
}
+
+ /// Allow to save everywhere
+ if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == 'l') )
+ {
+ if( InputEvent.usKeyState & ALT_DOWN )
+ {
+ if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
+ {
+ LeaveTacticalScreen( GAME_SCREEN );
+ DoQuickLoad();
+ }
+ }
+ else if( InputEvent.usKeyState & CTRL_DOWN )
+ {
+ if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
+ {
+ gfSaveGame = FALSE;
+ gfCameDirectlyFromGame = TRUE;
+
+ guiPreviousOptionScreen = GAME_SCREEN;
+ LeaveTacticalScreen( SAVE_LOAD_SCREEN );
+ }
+ }
+ }
+
+
// Break of out IN CONV...
if ( CHEATER_CHEAT_LEVEL( ) )
{
@@ -2734,7 +2760,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
#endif
case 'l':
-
+/*
if( fAlt )
{
if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
@@ -2756,16 +2782,16 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
guiPreviousOptionScreen = GAME_SCREEN;
LeaveTacticalScreen( SAVE_LOAD_SCREEN );
}
-/*
+*//*
if ( INFORMATION_CHEAT_LEVEL( ) )
{
*puiNewEvent = I_LEVELNODEDEBUG;
CountLevelNodes();
}
-*/
+*//*
}
else
- {
+*/ {
// nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel
if ( ( gpItemPointer == NULL ) &&
( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ LOOK_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) )
diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp
index e8aaeb45..9ccd0894 100644
--- a/Tactical/Weapons.cpp
+++ b/Tactical/Weapons.cpp
@@ -44,6 +44,12 @@
#include "XML.h"
#endif
+//rain
+#define WEAPON_RELIABILITY_REDUCTION_PER_RAIN_INTENSITY 9
+extern INT8 gbCurrentRainIntensity;
+//end rain
+
+
#define MINCHANCETOHIT 1
#define MAXCHANCETOHIT 99
@@ -1055,6 +1061,10 @@ void AdjustImpactByHitLocation( INT32 iImpact, UINT8 ubHitLocation, INT32 * piNe
// #define TESTGUNJAM
+//rain
+extern INT8 gbCurrentRainIntensity;
+//end rain
+
BOOLEAN CheckForGunJam( SOLDIERTYPE * pSoldier )
{
OBJECTTYPE * pObj;
@@ -1069,7 +1079,12 @@ BOOLEAN CheckForGunJam( SOLDIERTYPE * pSoldier )
if (pObj->bGunAmmoStatus > 0)
{
// gun might jam, figure out the chance
- iChance = (80 - pObj->bGunStatus);
+ //iChance = (80 - pObj->bGunStatus);
+
+ //rain
+ iChance = (80 - 90 - pObj->bGunStatus) + WEAPON_RELIABILITY_REDUCTION_PER_RAIN_INTENSITY * gbCurrentRainIntensity;
+ //end rain
+
// CJC: removed reliability from formula...
@@ -1080,6 +1095,10 @@ BOOLEAN CheckForGunJam( SOLDIERTYPE * pSoldier )
// increased by 20% per negative point...
//iChance = iChance * (10 - Item[pObj->usItem].bReliability * 2) / 10;
+ //rain
+ iChance = iChance * (10 - Item[pObj->usItem].bReliability * 2) / 10;
+ //end rain
+
if (pSoldier->bDoBurst > 1)
{
// if at bullet in a burst after the first, higher chance
@@ -3211,7 +3230,11 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, UINT16 sGridNo, UINT8 ubAimTime
{
//SOLDIERTYPE *vicpSoldier;
SOLDIERTYPE * pTarget;
- INT32 iChance, iRange, iSightRange, iMaxRange, iBonus; //, minRange;
+ //rain
+ //INT32 iChance, iRange, iSightRange, iMaxRange, iBonus; //, minRange;
+ INT32 iChance, iRange, iSightRange, iMaxRange, iScopeBonus, iBonus; //, minRange;
+ //end rain
+
INT32 iGunCondition, iMarksmanship;
INT32 iPenalty;
UINT16 usInHand;
@@ -3472,6 +3495,11 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, UINT16 sGridNo, UINT8 ubAimTime
// // adjust for scope condition, only has full affect at 100%
// iScopeBonus = (iScopeBonus * WEAPON_STATUS_MOD(pInHand->bAttachStatus[bAttachPos])) / 100;
+ //rain
+ // reduce scope effectiveness when it's raining
+ iScopeBonus /= 1 + gbCurrentRainIntensity;
+ //end rain
+
// // reduce effective range by the bonus obtained from the scope
// iSightRange -= iScopeBonus;
// if (iSightRange < 1)
diff --git a/Tactical/opplist.cpp b/Tactical/opplist.cpp
index 38d94e24..692d5caf 100644
--- a/Tactical/opplist.cpp
+++ b/Tactical/opplist.cpp
@@ -44,6 +44,10 @@
#include "SkillCheck.h"
#endif
+//rain
+#define VIS_DIST_DECREASE_PER_RAIN_INTENSITY 20
+//end rain
+
#define WE_SEE_WHAT_MILITIA_SEES_AND_VICE_VERSA
extern void SetSoldierAniSpeed( SOLDIERTYPE *pSoldier );
@@ -255,6 +259,14 @@ UINT8 gubSightFlags = 0;
}
+//rain
+extern INT8 gbCurrentRainIntensity;
+extern BOOLEAN gfLightningInProgress;
+extern BOOLEAN gfHaveSeenSomeone;
+extern UINT8 ubRealAmbientLightLevel;
+//end rain
+
+
INT16 AdjustMaxSightRangeForEnvEffects( SOLDIERTYPE *pSoldier, INT8 bLightLevel, INT16 sDistVisible )
{
INT16 sNewDist = 0;
@@ -264,8 +276,16 @@ INT16 AdjustMaxSightRangeForEnvEffects( SOLDIERTYPE *pSoldier, INT8 bLightLevel,
// Adjust it based on weather...
if ( guiEnvWeather & ( WEATHER_FORECAST_SHOWERS | WEATHER_FORECAST_THUNDERSHOWERS ) )
{
- sNewDist = sNewDist * 70 / 100;
+ //sNewDist = sNewDist * 70 / 100;
+ //rain
+ sNewDist = sNewDist * ( 100 - VIS_DIST_DECREASE_PER_RAIN_INTENSITY * gbCurrentRainIntensity ) / 100;
+ //end rain
}
+
+ //rain
+ if( gfLightningInProgress )
+ sNewDist += sNewDist * ( ubRealAmbientLightLevel ) / 10; // 10% per dark level
+ //end rain
return( sNewDist );
}
@@ -785,6 +805,7 @@ void HandleSight(SOLDIERTYPE *pSoldier, UINT8 ubSightFlags)
pSoldier->bNewOppCnt = 0;
pSoldier->bNeedToLook = FALSE;
+
// Temporary for opplist synching - disable random order radioing
#ifndef RECORDOPPLIST
// if this soldier's NOT on our team (MAY be under our control, though!)
@@ -839,7 +860,6 @@ void HandleSight(SOLDIERTYPE *pSoldier, UINT8 ubSightFlags)
// CJC August 13 2002: at the end of handling sight, reset sight flags to allow interrupts in case an audio cue should
// cause someone to see an enemy
gubSightFlags |= SIGHT_INTERRUPT;
-
}
@@ -1028,7 +1048,6 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir,
//bSubjectDir = atan8(pSoldier->sX,pSoldier->sY,pOpponent->sX,pOpponent->sY);
}
-
if ( !TANK( pSoldier ) && ( bFacingDir == DIRECTION_IRRELEVANT || (pSoldier->uiStatusFlags & SOLDIER_ROBOT) || (pSubject && pSubject->fMuzzleFlash) ) )
{
sDistVisible = MaxDistanceVisible();
@@ -1420,6 +1439,7 @@ void ManLooksForOtherTeams(SOLDIERTYPE *pSoldier)
UINT32 uiLoop;
SOLDIERTYPE *pOpponent;
+
#ifdef TESTOPPLIST
DebugMsg( TOPIC_JA2OPPLIST, DBG_LEVEL_3,
String("MANLOOKSFOROTHERTEAMS ID %d(%S) team %d side %d",pSoldier->ubID,pSoldier->name,pSoldier->bTeam,pSoldier->bSide));
@@ -1457,7 +1477,6 @@ void ManLooksForOtherTeams(SOLDIERTYPE *pSoldier)
}
}
}
-
}
void HandleManNoLongerSeen( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pOpponent, INT8 * pPersOL, INT8 * pbPublOL )
@@ -1550,6 +1569,7 @@ INT16 ManLooksForMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, UINT8 ubCall
INT16 sDistVisible,sDistAway;
INT8 *pPersOL,*pbPublOL;
+
/*
if (ptr->guynum >= NOBODY)
{
@@ -1593,6 +1613,8 @@ INT16 ManLooksForMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, UINT8 ubCall
return(FALSE);
}
+
+
// if we're somehow looking for a guy who is inactive, at base, or already dead
if (!pOpponent->bActive || !pOpponent->bInSector || pOpponent->bLife <= 0 || pOpponent->sGridNo == NOWHERE )
{
@@ -1696,6 +1718,7 @@ INT16 ManLooksForMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, UINT8 ubCall
pPersOL = &(pSoldier->bOppList[pOpponent->ubID]);
pbPublOL = &(gbPublicOpplist[pSoldier->bTeam][pOpponent->ubID]);
+
// if soldier is known about (SEEN or HEARD within last few turns)
if (*pPersOL || *pbPublOL)
{
@@ -1791,6 +1814,8 @@ INT16 ManLooksForMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, UINT8 ubCall
}
+
+
return(bSuccess);
}
@@ -2256,6 +2281,9 @@ else
// then locate to him and set his locator flag
bDoLocate = TRUE;
+ //rain
+ if( gfLightningInProgress ) gfHaveSeenSomeone = TRUE;
+ //end rain
}
// make opponent visible (to us)
@@ -2321,7 +2349,10 @@ else
{
if (!pOpponent->bNeutral && (pSoldier->bSide != pOpponent->bSide))
{
- SlideTo(0,pOpponent->ubID, pSoldier->ubID, SETLOCATOR);
+ //SlideTo(0,pOpponent->ubID, pSoldier->ubID, SETLOCATOR);
+ //rain
+ SlideTo(0,pOpponent->ubID, pSoldier->ubID, SETLOCATORFAST);
+ //end rain
}
}
}
diff --git a/TileEngine/environment.cpp b/TileEngine/environment.cpp
index d46d7c17..81007a62 100644
--- a/TileEngine/environment.cpp
+++ b/TileEngine/environment.cpp
@@ -158,6 +158,10 @@ BOOLEAN gfDoLighting = FALSE;
UINT8 gubDesertTemperature = 0;
UINT8 gubGlobalTemperature = 0;
+//rain
+extern BOOLEAN gfAllowRain;
+//end rain
+
// local prototypes
void EnvDoLightning(void);
@@ -201,12 +205,12 @@ void EnvironmentController( BOOLEAN fCheckForLights )
// ONly do indooors
if( !gfBasement && !gfCaves )
{
-#if 0
+//#if 0 //rain
if ( guiEnvWeather & ( WEATHER_FORECAST_THUNDERSHOWERS | WEATHER_FORECAST_SHOWERS ) )
{
if ( guiRainLoop == NO_SAMPLE )
{
- guiRainLoop = PlayJA2Ambient( RAIN_1, MIDVOLUME, 0 );
+ guiRainLoop = PlayJA2Ambient( RAIN_1, BTNVOLUME, 0 );
}
// Do lightning if we want...
@@ -224,7 +228,7 @@ void EnvironmentController( BOOLEAN fCheckForLights )
guiRainLoop = NO_SAMPLE;
}
}
-#endif
+//#endif //rain
}
if ( gfDoLighting && fCheckForLights )
@@ -236,7 +240,7 @@ void EnvironmentController( BOOLEAN fCheckForLights )
if( !gfBasement && !gfCaves )
{
// Rain storms....
-#if 0
+//#if 0 //rain
if ( guiEnvWeather & ( WEATHER_FORECAST_THUNDERSHOWERS | WEATHER_FORECAST_SHOWERS ) )
{
// Thunder showers.. make darker
@@ -249,7 +253,7 @@ void EnvironmentController( BOOLEAN fCheckForLights )
ubLightAdjustFromWeather = (UINT8)(__min( gubEnvLightValue+1, NORMAL_LIGHTLEVEL_NIGHT ));
}
}
-#endif
+//#endif //rain
}
@@ -355,10 +359,20 @@ void BuildDayAmbientSounds( )
}
- guiRainLoop = NO_SAMPLE;
+ //guiRainLoop = NO_SAMPLE;
+ //rain
+ if ( guiRainLoop != NO_SAMPLE )
+ {
+ SoundStop( guiRainLoop );
+ guiRainLoop = NO_SAMPLE;
+ }
+ //end rain
}
+extern UINT16 gusRainChancePerDay, gusRainMinLength, gusRainMaxLength; //rain
+
+
void ForecastDayEvents( )
{
UINT32 uiOldDay;
@@ -383,6 +397,32 @@ void ForecastDayEvents( )
// ATE: Don't forecast if start of game...
if ( guiEnvDay > 1 )
{
+ //rain
+ if ( Random( 100 ) < gusRainChancePerDay )
+ {
+ // Add rain!
+ // Between 6:00 and 10:00
+ uiStartTime = (UINT32)( Random( 1440 - 1 -gusRainMaxLength ) );
+ // Between 5 - 15 miniutes
+ uiEndTime = uiStartTime + ( gusRainMinLength + Random( gusRainMaxLength - gusRainMinLength ) );
+
+ ubStormIntensity = 0;
+
+ // Randomze for a storm!
+ if ( Random( 10 ) < 5 )
+ {
+ ubStormIntensity = 1;
+ }
+
+ if( 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 )
{
@@ -406,6 +446,7 @@ void ForecastDayEvents( )
//AddSameDayStrategicEvent( EVENT_BEGINRAINSTORM, uiStartTime, ubStormIntensity );
//AddSameDayStrategicEvent( EVENT_ENDRAINSTORM, uiEndTime, 0 );
}
+ */
}
}
@@ -422,6 +463,272 @@ void EnvDisableTOD(void)
}
+
+//rain
+UINT32 guiMinLightningInterval = 5;
+UINT32 guiMaxLightningInterval = 15;
+
+UINT32 guiMinDLInterval = 1;
+UINT32 guiMaxDLInterval = 5;
+
+UINT32 guiProlongLightningIfSeenSomeone = 5;
+UINT32 guiChanceToDoLightningBetweenTurns = 20;
+
+
+ // 60 = 1 second
+#define MIN_LIGHTNING_INTERVAL ( 60 * guiMinLightningInterval )
+#define MAX_LIGHTNING_INTERVAL ( 60 * guiMaxLightningInterval )
+
+#define MAX_DELAYED_SOUNDS 10
+#define NO_DL_SOUND 0xFFFFFFFF
+
+// 1000 = 1 second
+#define MIN_DL_INTERVAL ( 1000 * guiMinDLInterval )
+#define MAX_DL_INTERVAL ( 1000 * guiMaxDLInterval )
+
+#define EXTRA_ADD_VIS_DIST_IF_SEEN_SOMEONE ( 1000 * guiProlongLightningIfSeenSomeone )
+#define CHANCE_TO_DO_LIGHTNING_BETWEEN_TURNS guiChanceToDoLightningBetweenTurns
+
+BOOLEAN gfLightningInProgress = FALSE;
+BOOLEAN gfHaveSeenSomeone = FALSE;
+
+UINT8 ubRealAmbientLightLevel = 0;
+BOOLEAN gfTurnBasedDoLightning = FALSE;
+BOOLEAN gfTurnBasedLightningEnd = FALSE;
+
+BOOLEAN gfWasTurnBasedWhenLightningBegin = FALSE;
+
+UINT8 gubLastTeamLightning;
+
+#define IS_TURNBASED ( gTacticalStatus.uiFlags & TURNBASED && gTacticalStatus.uiFlags & INCOMBAT )
+
+void BeginTeamTurn( UINT8 ubTeam );
+
+
+
+
+void EnvDoLightning(void)
+{
+ static UINT32 uiCount=10, uiIndex=0, uiStrike=0, uiFrameNext=0;
+ static UINT8 ubLevel=0, ubLastLevel=0;
+ static UINT32 uiLastUpdate = 0xFFFFFFFF;
+ static UINT32 uiTurnOffExtraVisDist = 0xFFFFFFFF;
+ static UINT32 pDelayedSounds[ MAX_DELAYED_SOUNDS ];
+ UINT32 uiDSIndex;
+
+ if( GetJA2Clock() < uiLastUpdate )
+ {
+ uiLastUpdate = 0;
+ memset( pDelayedSounds, NO_DL_SOUND, sizeof( UINT32 ) * MAX_DELAYED_SOUNDS );
+ }
+
+ if( GetJA2Clock() < uiLastUpdate + 1000 / 60 )return;
+ else
+ uiLastUpdate = GetJA2Clock();
+
+ if( GetJA2Clock() > uiTurnOffExtraVisDist )
+ {
+ AllTeamsLookForAll( FALSE );
+ uiTurnOffExtraVisDist = 0xFFFFFFFF;
+
+ if( gfTurnBasedLightningEnd )
+ {
+ BeginTeamTurn( gubLastTeamLightning );
+ gfTurnBasedLightningEnd = FALSE;
+ }
+
+ }
+
+ for( uiDSIndex = 0; uiDSIndex < MAX_DELAYED_SOUNDS; ++uiDSIndex )
+ if( GetJA2Clock() > pDelayedSounds[ uiDSIndex ] )
+ {
+ PlayJA2Ambient(LIGHTNING_1+Random(2), HIGHVOLUME, 1);
+ pDelayedSounds[ uiDSIndex ] = NO_DL_SOUND;
+ }
+
+ if ( gfPauseDueToPlayerGamePause )
+ {
+ return;
+ }
+
+ if( IS_TURNBASED && !gfLightningInProgress )
+ {
+ if( !gfTurnBasedDoLightning )
+ {
+ return;
+ }
+ else
+ {
+ gfTurnBasedDoLightning = FALSE;
+ uiFrameNext = 1;
+ uiCount = 0;
+ gfTurnBasedLightningEnd = TRUE;
+ }
+ }
+
+ uiCount++;
+ if(uiCount >= (uiFrameNext+10))
+ {
+ if( gfHaveSeenSomeone && gfWasTurnBasedWhenLightningBegin )
+ uiTurnOffExtraVisDist = GetJA2Clock() + EXTRA_ADD_VIS_DIST_IF_SEEN_SOMEONE;
+ else
+ uiTurnOffExtraVisDist = GetJA2Clock();
+
+ gfLightningInProgress = FALSE;
+ gfHaveSeenSomeone = FALSE;
+
+ uiCount=0;
+ uiIndex=0;
+ ubLevel=0;
+ ubLastLevel=0;
+
+ uiStrike=Random(3);
+ uiFrameNext=MIN_LIGHTNING_INTERVAL+Random(MAX_LIGHTNING_INTERVAL - MIN_LIGHTNING_INTERVAL);
+ }
+ else if(uiCount >= uiFrameNext)
+ {
+ if(uiCount == uiFrameNext)
+ {
+ //EnvStopCrickets();
+// PlayJA2Ambient(LIGHTNING_1+Random(2), HIGHVOLUME, 1);
+ for( uiDSIndex = 0; uiDSIndex < MAX_DELAYED_SOUNDS; ++uiDSIndex )
+ if( pDelayedSounds[ uiDSIndex ] == NO_DL_SOUND )
+ {
+ pDelayedSounds[ uiDSIndex ] = GetJA2Clock() + MIN_DL_INTERVAL+Random(MAX_DL_INTERVAL - MIN_DL_INTERVAL);
+ break;
+ }
+
+ ubRealAmbientLightLevel = ubAmbientLightLevel;
+
+ gfWasTurnBasedWhenLightningBegin = IS_TURNBASED;
+
+ gfLightningInProgress = TRUE;
+ AllTeamsLookForAll( FALSE );
+ }
+
+ while(uiCount > ((UINT32)ubLightningTable[uiStrike][uiIndex][0] + uiFrameNext))
+ uiIndex++;
+
+ ubLastLevel=ubLevel;
+ ubLevel=min( ubRealAmbientLightLevel - 1, ubLightningTable[uiStrike][uiIndex][1] );
+
+/* // ATE: Don't modify if scrolling!
+ if ( gfScrollPending || gfScrollInertia )
+ {
+ }
+ 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( !gfTurnBasedLightningEnd )
+ {
+ gfTurnBasedDoLightning = TRUE;
+ gubLastTeamLightning = ubTeam;
+ EnvDoLightning();
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+UINT8 GetTimeOfDayAmbientLightLevel()
+{
+ if ( SectorTemperature( GetWorldMinutesInDay(), gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) == HOT )
+ {
+ return( HOT_DAY_LIGHTLEVEL );
+ }
+ else
+ {
+ 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;
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Storm started." );
+ }
+ else
+ {
+ guiEnvWeather |= WEATHER_FORECAST_SHOWERS;
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Rain started." );
+ }
+ }
+
+}
+
+void EnvEndRainStorm( )
+{
+ 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, L"Storm ended." );
+ }
+ else
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Rain ended." );
+ }
+
+
+ guiEnvWeather &= (~WEATHER_FORECAST_THUNDERSHOWERS );
+ guiEnvWeather &= (~WEATHER_FORECAST_SHOWERS );
+}
+
+//end rain
+
+
+
+
+
+
+
+
+
+/*
void EnvDoLightning(void)
{
static UINT32 uiCount=0, uiIndex=0, uiStrike=0, uiFrameNext=1000;
@@ -531,6 +838,8 @@ void EnvEndRainStorm( )
guiEnvWeather &= (~WEATHER_FORECAST_THUNDERSHOWERS );
guiEnvWeather &= (~WEATHER_FORECAST_SHOWERS );
}
+*/
+
void TurnOnNightLights()
{
diff --git a/TileEngine/physics.cpp b/TileEngine/physics.cpp
index bc11b48b..2cd67691 100644
--- a/TileEngine/physics.cpp
+++ b/TileEngine/physics.cpp
@@ -670,16 +670,15 @@ BOOLEAN PhysicsHandleCollisions( REAL_OBJECT *pObject, INT32 *piCollisionID, rea
}
}
-
// Check for -ve velocity still...
- //if ( pObject->Velocity.z <= EPSILONV && pObject->Velocity.z >= -EPSILONV &&
- // pObject->Velocity.y <= EPSILONV && pObject->Velocity.y >= -EPSILONV &&
- // pObject->Velocity.x <= EPSILONV && pObject->Velocity.x >= -EPSILONV )
- //{
- //PhysicsDeleteObject( pObject );
- // pObject->fAlive = FALSE;
- // return( FALSE );
- //}
+ /*if ( pObject->Velocity.z <= EPSILONV && pObject->Velocity.z >= -EPSILONV &&
+ pObject->Velocity.y <= EPSILONV && pObject->Velocity.y >= -EPSILONV &&
+ pObject->Velocity.x <= EPSILONV && pObject->Velocity.x >= -EPSILONV )
+ {
+ PhysicsDeleteObject( pObject );
+ pObject->fAlive = FALSE;
+ return( FALSE );
+ }*/
}
return( TRUE );
diff --git a/TileEngine/renderworld.cpp b/TileEngine/renderworld.cpp
index b3857ec1..9eaddcdf 100644
--- a/TileEngine/renderworld.cpp
+++ b/TileEngine/renderworld.cpp
@@ -2800,6 +2800,12 @@ UINT32 cnt = 0;
if ( gfScrollInertia == FALSE || (gRenderFlags&RENDER_FLAG_NOZ ) || (gRenderFlags&RENDER_FLAG_FULL ) || (gRenderFlags&RENDER_FLAG_MARKED ) )
{
RenderDynamicWorld( );
+
+///////////////////////////////////////////////////////////
+
+// ColorFillVideoSurfaceArea( guiSAVEBUFFER, 0, gsVIEWPORT_WINDOW_END_Y, BP_SCREEN_WIDTH_CENTERED, SCREEN_HEIGHT, Get16BPPColor( FROMRGB( 16, 8, 0 ) ) );
+
+///////////////////////////////////////////////////////////
}
if ( gfScrollInertia )
@@ -3504,6 +3510,7 @@ BOOLEAN HandleScrollDirections( UINT32 ScrollFlags, INT16 sScrollXStep, INT16 sS
return( fAGoodMove );
}
+extern BOOLEAN gfNextRefreshFullScreen;
void ScrollWorld( )
{
@@ -3752,6 +3759,8 @@ void ScrollWorld( )
// Now we actually begin our scrolling
HandleScrollDirections( ScrollFlags, sScrollXStep, sScrollYStep, &sTempRenderCenterX, &sTempRenderCenterY, FALSE );
+
+ if( gfNextRefreshFullScreen ) SetRenderFlags( RENDER_FLAG_FULL );
}
}
else
diff --git a/gameloop.cpp b/gameloop.cpp
index 41e3ce9f..7e588321 100644
--- a/gameloop.cpp
+++ b/gameloop.cpp
@@ -29,6 +29,10 @@
#include "HelpScreen.h"
#endif
+// rain
+#include "Rain.h"
+// end rain
+
UINT32 guiCurrentScreen;
UINT32 guiPendingScreen = NO_PENDING_SCREEN;
@@ -162,6 +166,9 @@ void ShutdownGame(void)
// the state of the game (i.e. Main Menu, PC Generation, Combat loop, etc....)
// This function exits constantly and reenters constantly
+// rain
+static BOOLEAN gfSkipFrame = FALSE;
+
void GameLoop(void)
{
// DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"GameLoop");
@@ -309,6 +316,14 @@ void GameLoop(void)
guiCurrentScreen = uiOldScreen;
}
+ // rain
+ RenderRain();
+
+ if( gfSkipFrame )
+ gfSkipFrame = FALSE;
+ else
+ // end rain
+
//DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"GameLoop: refresh screen");
RefreshScreen( NULL );
@@ -339,6 +354,10 @@ void SetPendingNewScreen( UINT32 uiNewScreen )
guiPendingScreen = uiNewScreen;
}
+// rain
+extern UINT32 guiRainLoop;
+// end rain
+
// Gets called when the screen changes, place any needed in code in here
void HandleNewScreenChange( UINT32 uiNewScreen, UINT32 uiOldScreen )
{
@@ -348,6 +367,17 @@ void HandleNewScreenChange( UINT32 uiNewScreen, UINT32 uiOldScreen )
//reset the help screen
NewScreenSoResetHelpScreen( );
}
+
+ //rain
+ if( uiNewScreen == MAP_SCREEN )
+ {
+ if ( guiRainLoop != NO_SAMPLE )
+ {
+ SoundStop( guiRainLoop );
+ guiRainLoop = NO_SAMPLE;
+ }
+ }
+ // end rain
}
void HandleShortCutExitState( void )
diff --git a/local.h b/local.h
index aa78a6d5..09bc6fcc 100644
--- a/local.h
+++ b/local.h
@@ -4,6 +4,13 @@
#include "Screens.h"
+//rain
+#include "NewGameSettings.h"
+//end rain
+
+
+
+
//
// Make sure the application has a name
//