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 //