diff --git a/GameSettings.cpp b/GameSettings.cpp index 78f85336d..c527eabfd 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -332,6 +332,53 @@ void LoadGameExternalOptions() gGameExternalOptions.iExpertAPBonus = iniReader.ReadInteger("Options","EXPERT_AP_BONUS",0); gGameExternalOptions.iInsaneAPBonus = iniReader.ReadInteger("Options","INSANE_AP_BONUS",0); + + // System settings + gGameExternalOptions.gubDeadLockDelay = iniReader.ReadInteger("JA2 System Settings","DeadLockDelay",15); + //gGameExternalOptions.gfEnableEmergencyButton_SkipStrategicEvents = iniReader.ReadBoolean("JA2 System Settings","EnableEmergencyButton_NumLock_ToSkipStrategicEvents",0); + + //Video settings + gGameExternalOptions.gfVSync = iniReader.ReadBoolean("JA2 Video Settings","VerticalSync",0); + + //Animation settings + gGameExternalOptions.gubPlayerTurnSpeedUpFactor = iniReader.ReadInteger("JA2 Turnbased Animation Speed Settings","PlayerTurnSpeedUpFactor",1); + gGameExternalOptions.gubEnemyTurnSpeedUpFactor = iniReader.ReadInteger("JA2 Turnbased Animation Speed Settings","EnemyTurnSpeedUpFactor",1); + gGameExternalOptions.gubCreatureTurnSpeedUpFactor = iniReader.ReadInteger("JA2 Turnbased Animation Speed Settings","CreatureTurnSpeedUpFactor",1); + gGameExternalOptions.gubMilitiaTurnSpeedUpFactor = iniReader.ReadInteger("JA2 Turnbased Animation Speed Settings","MilitiaTurnSpeedUpFactor",1); + gGameExternalOptions.gubCivTurnSpeedUpFactor = iniReader.ReadInteger("JA2 Turnbased Animation Speed Settings","CivTurnSpeedUpFactor",1); + + //Sound settings + gGameExternalOptions.guiWeaponSoundEffectsVolume = iniReader.ReadInteger("JA2 Sound Settings","WeaponSoundEffectsVolume",0); + + // Militia Settings + gGameExternalOptions.fAllowTacticalMilitiaCommand = iniReader.ReadBoolean("JA2 Tactical Settings","AllowTacticalMilitiaCommand",1); + + gGameExternalOptions.gfAllowMilitiaGroups = iniReader.ReadBoolean("JA2 Gameplay Settings","AllowMilitiaMobileGroups",1); + gGameExternalOptions.gfAllowReinforcments = iniReader.ReadBoolean("JA2 Gameplay Settings","AllowReinforcments",1); + gGameExternalOptions.gfAllowReinforcmentsOnlyInCity = iniReader.ReadBoolean("JA2 Gameplay Settings","AllowReinforcmentsOnlyInCities",0); + gGameExternalOptions.guiBaseQueenPoolIncrement = iniReader.ReadInteger("JA2 Gameplay Settings","QueenPoolIncrementPerDifficultyLevel",60); + + //Sight range + gGameExternalOptions.ubStraightSightRange = iniReader.ReadInteger("JA2 Tactical Settings","BaseSightRange",13); + + // Maximal search distance for grenades + //gGameExternalOptions.guiMaxTossSearchDist = iniReader.ReadInteger("JA2 Tactical Settings","MaxTossSearchDist",3); + + // Rain settings + gGameExternalOptions.gfAllowRain = iniReader.ReadBoolean("JA2 Rain Settings","ALLOW_RAIN",0); + gGameExternalOptions.gusRainChancePerDay = iniReader.ReadInteger("JA2 Rain Settings","RAIN_CHANCE_PER_DAY",100); + gGameExternalOptions.gusRainMinLength = iniReader.ReadInteger("JA2 Rain Settings","RAIN_MIN_LENGTH_IN_MINUTES",60); + gGameExternalOptions.gusRainMaxLength = iniReader.ReadInteger("JA2 Rain Settings","RAIN_MAX_LENGTH_IN_MINUTES",180); + gGameExternalOptions.guiMaxRainDrops = iniReader.ReadInteger("JA2 Rain Settings","MAX_RAIN_DROPS",80); + + + // Thunder settings + gGameExternalOptions.guiMinLightningInterval = iniReader.ReadInteger("JA2 Thunder Settings","MIN_INTERVAL_BETWEEN_LIGHTNINGS_IN_REAL_TIME_SECONDS",5); + gGameExternalOptions.guiMaxLightningInterval = iniReader.ReadInteger("JA2 Thunder Settings","MAX_INTERVAL_BETWEEN_LIGHTNINGS_IN_REAL_TIME_SECONDS",15); + gGameExternalOptions.guiMinDLInterval = iniReader.ReadInteger("JA2 Thunder Settings","MIN_INTERVAL_BETWEEN_LIGHTNING_AND_THUNDERCLAPS_IN_SECONDS",1); + gGameExternalOptions.guiMaxDLInterval = iniReader.ReadInteger("JA2 Thunder Settings","MAX_INTERVAL_BETWEEN_LIGHTNING_AND_THUNDERCLAPS_IN_SECONDS",5); + gGameExternalOptions.guiProlongLightningIfSeenSomeone = iniReader.ReadInteger("JA2 Thunder Settings","PROLOGNE_DELAY_IF_SEEN_SOMEONE_DURING_LIGHTNING_IN_TURNBASED_IN_SECONDS",5); + gGameExternalOptions.guiChanceToDoLightningBetweenTurns = iniReader.ReadInteger("JA2 Thunder Settings","CHANCE_TO_DO_LIGHTNING_BETWEEN_TURNS",35); } diff --git a/GameSettings.h b/GameSettings.h index 4e379094a..90e393442 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -118,7 +118,7 @@ typedef struct BOOLEAN fTurnTimeLimit; BOOLEAN fIronManMode; UINT8 ubBobbyRay; - UINT8 ubFiller[7]; + UINT8 ubFiller[7]; } GAME_OPTIONS; @@ -178,6 +178,48 @@ typedef struct INT8 iInsaneAPBonus; + // Moved from NewGameSettings.cpp + + //Video settings + UINT8 gubDeadLockDelay; + UINT8 ubStraightSightRange; + + // System settings + BOOLEAN gfVSync; + BOOLEAN gfEnableEmergencyButton_SkipStrategicEvents; + + //Animation settings + UINT8 gubPlayerTurnSpeedUpFactor; + UINT8 gubEnemyTurnSpeedUpFactor; + UINT8 gubCreatureTurnSpeedUpFactor; + UINT8 gubMilitiaTurnSpeedUpFactor; + UINT8 gubCivTurnSpeedUpFactor; + + //Sound settings + UINT32 guiWeaponSoundEffectsVolume; + + // Militia Settings + BOOLEAN fAllowTacticalMilitiaCommand; + + BOOLEAN gfAllowMilitiaGroups; + BOOLEAN gfAllowReinforcments; + BOOLEAN gfAllowReinforcmentsOnlyInCity; + UINT32 guiBaseQueenPoolIncrement; + + // Rain settings + BOOLEAN gfAllowRain; + UINT16 gusRainChancePerDay; + UINT16 gusRainMinLength; + UINT16 gusRainMaxLength; + UINT32 guiMaxRainDrops; + + // Thunder settings + UINT32 guiMinLightningInterval; + UINT32 guiMaxLightningInterval; + UINT32 guiMinDLInterval; + UINT32 guiMaxDLInterval; + UINT32 guiProlongLightningIfSeenSomeone; + UINT32 guiChanceToDoLightningBetweenTurns; } GAME_EXTERNAL_OPTIONS; diff --git a/JA2 Splash.cpp b/JA2 Splash.cpp index 2cde93f06..4da4a2b84 100644 --- a/JA2 Splash.cpp +++ b/JA2 Splash.cpp @@ -12,11 +12,11 @@ extern HVSURFACE ghFrameBuffer; void InitJA2SplashScreen() { UINT32 uiLogoID = 0; - HVSURFACE hVSurface; // unused jonathanl // lalien reenabled for international versions - VSURFACE_DESC VSurfaceDesc; //unused jonathanl // lalien reenabled for international versions INT32 i = 0; #if !defined( ENGLISH ) && defined( JA2TESTVERSION ) + HVSURFACE hVSurface; // unused jonathanl // lalien reenabled for international versions + VSURFACE_DESC VSurfaceDesc; //unused jonathanl // lalien reenabled for international versions memset( &VSurfaceDesc, 0, sizeof( VSURFACE_DESC ) ); VSurfaceDesc.fCreateFlags = VSURFACE_CREATE_FROMFILE | VSURFACE_SYSTEM_MEM_USAGE; sprintf( VSurfaceDesc.ImageFile, "LOADSCREENS\\Notification.sti" ); diff --git a/JA2.vcproj b/JA2.vcproj index 1ddb56abd..e8807e477 100644 --- a/JA2.vcproj +++ b/JA2.vcproj @@ -1924,9 +1924,6 @@ BrowseInformation="1"/> - - - - diff --git a/Standard Gaming Platform/sgp.cpp b/Standard Gaming Platform/sgp.cpp index 989e692c7..58b056f90 100644 --- a/Standard Gaming Platform/sgp.cpp +++ b/Standard Gaming Platform/sgp.cpp @@ -706,7 +706,7 @@ int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR p } //rain - NSLoadSettings(); + //NSLoadSettings(); //NSSaveSettings(); //InitResolution(); diff --git a/Standard Gaming Platform/video.cpp b/Standard Gaming Platform/video.cpp index 21834fe84..823f2798e 100644 --- a/Standard Gaming Platform/video.cpp +++ b/Standard Gaming Platform/video.cpp @@ -1504,7 +1504,7 @@ void ScrollJA2Background(UINT32 uiDirection, INT16 sScrollXIncrement, INT16 sScr //rain -extern BOOLEAN gfVSync; +//extern BOOLEAN gfVSync; BOOLEAN IsItAllowedToRenderRain(); extern UINT32 guiRainRenderSurface; @@ -2178,7 +2178,7 @@ void RefreshScreen(void *DummyVariable) do { - ReturnCode = IDirectDrawSurface_Flip(_gpPrimarySurface, NULL, gfVSync ? DDFLIP_WAIT : 0x00000008l );//DDFLIP_WAIT ); + ReturnCode = IDirectDrawSurface_Flip(_gpPrimarySurface, NULL, gGameExternalOptions.gfVSync ? DDFLIP_WAIT : 0x00000008l );//DDFLIP_WAIT ); // if ((ReturnCode != DD_OK)&&(ReturnCode != DDERR_WASSTILLDRAWING)) if ((ReturnCode != DD_OK)&&(ReturnCode != DDERR_WASSTILLDRAWING)) { diff --git a/Strategic/Assignments.cpp b/Strategic/Assignments.cpp index 13655d01b..6c4da5d05 100644 --- a/Strategic/Assignments.cpp +++ b/Strategic/Assignments.cpp @@ -58,6 +58,7 @@ #include "Strategic Pathing.h" #endif +#include "MilitiaSquads.h" // various reason an assignment can be aborted before completion enum{ @@ -1913,6 +1914,8 @@ void UpdateAssignments() { for( bZ = 0; bZ < 4; bZ++) { + // handle militia squads movings and creating (not an assignment) + if(!bZ && sX < 17 && sY < 17 && sX > 0 && sY > 0)UpdateMilitiaSquads( sX, sY ); // is there anyone in this sector? if( fSectorsWithSoldiers[ sX + sY * MAP_WORLD_X ][ bZ ] == TRUE ) { diff --git a/Strategic/Auto Resolve.cpp b/Strategic/Auto Resolve.cpp index e93089cc1..8e2ccc633 100644 --- a/Strategic/Auto Resolve.cpp +++ b/Strategic/Auto Resolve.cpp @@ -58,15 +58,23 @@ #include "GameSettings.h" #endif +#include "Reinforcement.h" + //#include "vtuneapi.h" //#define INVULNERABILITY +// default = 7 (%) +#define EXP_BONUS 7 + #define MAX_AR_TEAM_SIZE 256 +#define REINFORCMENT_ATTACK_DELAY_PER_SOLDIER_IN_SECTOR 1000 + INT32 giMaxEnemiesToRender = 40; INT32 giMaxMilitiaToRender = 20;//Changes depending on merc amount +extern UINT8 gubReinforcementMinEnemyStaticGroupSize; extern BOOLEAN AutoReload( SOLDIERTYPE *pSoldier ); extern HVSURFACE ghFrameBuffer; @@ -99,7 +107,7 @@ typedef struct SOLDIERCELL UINT16 usFrame; INT16 xp, yp; UINT16 usAttack, usDefence; - UINT16 usNextAttack; + UINT32 usNextAttack; UINT16 usNextHit[3]; UINT16 usHitDamage[3]; struct SOLDIERCELL *pAttacker[3]; @@ -133,10 +141,10 @@ typedef struct AUTORESOLVE_STRUCT SGPRect Rect, ExRect; - UINT16 usPlayerAttack; - UINT16 usPlayerDefence; - UINT16 usEnemyAttack; - UINT16 usEnemyDefence; + UINT32 usPlayerAttack; + UINT32 usPlayerDefence; + UINT32 usEnemyAttack; + UINT32 usEnemyDefence; INT16 sWidth, sHeight; INT16 sCenterStartX; @@ -269,6 +277,7 @@ extern void CreateDestroyMapInvButton(); INT16 gsEnemyGainedControlOfSectorID = -1; INT16 gsCiviliansEatenByMonsters = -1; +BOOLEAN ProcessLoyalty(); //Autoresolve handling -- keyboard input, callbacks void HandleAutoResolveInput(); void PauseButtonCallback( GUI_BUTTON *btn, INT32 reason ); @@ -424,12 +433,12 @@ void EliminateAllEnemies( UINT8 ubSectorX, UINT8 ubSectorY ) { for ( i = 0; i < ubNumEnemies[ ubRankIndex ]; i++ ) { - HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_ENEMY_KILLED, ubSectorX, ubSectorY, 0 ); + if( ProcessLoyalty() )HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_ENEMY_KILLED, ubSectorX, ubSectorY, 0 ); TrackEnemiesKilled( ENEMY_KILLED_IN_AUTO_RESOLVE, RankIndexToSoldierClass( ubRankIndex ) ); } } - HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_BATTLE_WON, ubSectorX, ubSectorY, 0 ); + if( ProcessLoyalty() )HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_BATTLE_WON, ubSectorX, ubSectorY, 0 ); } if( !gpAR || gpAR->ubBattleStatus != BATTLE_IN_PROGRESS ) @@ -560,12 +569,17 @@ void DoTransitionFromPreBattleInterfaceToAutoResolve() //BlitBufferToBuffer( FRAME_BUFFER, guiSAVEBUFFER, 0, 0, 640, 480 ); } +extern UINT8 guiDirNumber; + void EnterAutoResolveMode( UINT8 ubSectorX, UINT8 ubSectorY ) { #ifdef JA2BETAVERSION CountRandomCalls( TRUE ); #endif + + guiDirNumber = 0; + //Set up mapscreen for removal SetPendingNewScreen( AUTORESOLVE_SCREEN ); CreateDestroyMapInvButton(); @@ -730,8 +744,12 @@ void AssociateEnemiesWithStrategicGroups() SECTORINFO *pSector; GROUP *pGroup; UINT8 ubNumAdmins, ubNumTroops, ubNumElites; + UINT8 ubISNumAdmins, ubISNumTroops, ubISNumElites; UINT8 ubNumElitesInGroup, ubNumTroopsInGroup, ubNumAdminsInGroup; INT32 i; + UINT8 pSectors[4]; + UINT8 ubDirAmount; + UINT8 ubCurrSI; if( gubEnemyEncounterCode == CREATURE_ATTACK_CODE ) return; @@ -815,6 +833,97 @@ void AssociateEnemiesWithStrategicGroups() } pGroup = pGroup->next; } + +/////////////////////////////////////////////////////////////////////////// Reinforcement + + pGroup = gpGroupList; + while( pGroup ) + { // Don't process road block. It'll be processed as static + if( pGroup->ubGroupID && !pGroup->fPlayer && IsGroupInARightSectorToReinforce( pGroup, gpAR->ubSectorX, gpAR->ubSectorY ) ) + { + ubNumElitesInGroup = pGroup->pEnemyGroup->ubNumElites; + ubNumTroopsInGroup = pGroup->pEnemyGroup->ubNumTroops; + ubNumAdminsInGroup = pGroup->pEnemyGroup->ubNumAdmins; + for( i = 0; i < gpAR->ubEnemies; i++ ) + { + if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) ) + { + if( ubNumElites && ubNumElitesInGroup ) + { + gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID; + gpEnemies[ i ].uiFlags |= CELL_ASSIGNED; + ubNumElites--; + ubNumElitesInGroup--; + } + else if( ubNumTroops && ubNumTroopsInGroup ) + { + gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID; + gpEnemies[ i ].uiFlags |= CELL_ASSIGNED; + ubNumTroops--; + ubNumTroopsInGroup--; + } + else if( ubNumAdmins && ubNumAdminsInGroup ) + { + gpEnemies[ i ].pSoldier->ubGroupID = pGroup->ubGroupID; + gpEnemies[ i ].uiFlags |= CELL_ASSIGNED; + ubNumAdmins--; + ubNumAdminsInGroup--; + } + } + } + } + pGroup = pGroup->next; + } + + +// Set GroupID = 0 for the rest + ubDirAmount = GetAdjacentSectors( pSectors, gpAR->ubSectorX, gpAR->ubSectorY ); + + for( ubCurrSI = 0; ubCurrSI < ubDirAmount; ubCurrSI++ ) + { + pSector = &SectorInfo[ pSectors[ ubCurrSI ] ]; + + ubISNumAdmins = pSector->ubNumAdmins; + ubISNumTroops = pSector->ubNumTroops; + ubISNumElites = pSector->ubNumElites; + + for( i = 0; i < gpAR->ubEnemies; i++ ) + { + if( ubISNumAdmins + ubISNumTroops + ubISNumElites <= gubReinforcementMinEnemyStaticGroupSize ) break; + + if( !(gpEnemies[ i ].uiFlags & CELL_ASSIGNED) ) + { + if( gpEnemies[ i ].uiFlags & CELL_ELITE && ubISNumElites && ubNumElites ) + { + gpEnemies[ i ].pSoldier->ubGroupID = 0; + gpEnemies[ i ].uiFlags |= CELL_ASSIGNED; + gpEnemies[ i ].pSoldier->sSectorX = SECTORX( pSectors[ ubCurrSI ] ); + gpEnemies[ i ].pSoldier->sSectorY = SECTORY( pSectors[ ubCurrSI ] ); + ubISNumElites--; + ubNumElites--; + } + else if( gpEnemies[ i ].uiFlags & CELL_TROOP && ubISNumTroops && ubNumTroops ) + { + gpEnemies[ i ].pSoldier->ubGroupID = 0; + gpEnemies[ i ].uiFlags |= CELL_ASSIGNED; + gpEnemies[ i ].pSoldier->sSectorX = SECTORX( pSectors[ ubCurrSI ] ); + gpEnemies[ i ].pSoldier->sSectorY = SECTORY( pSectors[ ubCurrSI ] ); + ubISNumTroops--; + ubNumTroops--; + } + else if( gpEnemies[ i ].uiFlags & CELL_ADMIN && ubISNumAdmins && ubNumAdmins ) + { + gpEnemies[ i ].pSoldier->ubGroupID = 0; + gpEnemies[ i ].uiFlags |= CELL_ASSIGNED; + gpEnemies[ i ].pSoldier->sSectorX = SECTORX( pSectors[ ubCurrSI ] ); + gpEnemies[ i ].pSoldier->sSectorY = SECTORY( pSectors[ ubCurrSI ] ); + ubISNumAdmins--; + ubNumAdmins--; + } + } + } + } + } @@ -1710,7 +1819,7 @@ void RenderAutoResolve() { case BATTLE_VICTORY: HandleMoraleEvent( NULL, MORALE_BATTLE_WON, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); - HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_BATTLE_WON, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); + if( ProcessLoyalty() )HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_BATTLE_WON, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); SectorInfo[ SECTOR( gpAR->ubSectorX, gpAR->ubSectorY ) ].bLastKnownEnemies = 0; SetThisSectorAsPlayerControlled( gpAR->ubSectorX, gpAR->ubSectorY, 0, TRUE ); @@ -1733,14 +1842,14 @@ void RenderAutoResolve() } } HandleMoraleEvent( NULL, MORALE_HEARD_BATTLE_LOST, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); - HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_BATTLE_LOST, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); + if( ProcessLoyalty() )HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_BATTLE_LOST, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); SetMusicMode( MUSIC_TACTICAL_DEATH ); gsEnemyGainedControlOfSectorID = (INT16)SECTOR( gpAR->ubSectorX, gpAR->ubSectorY ); break; case BATTLE_DEFEAT: HandleMoraleEvent( NULL, MORALE_HEARD_BATTLE_LOST, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); - HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_BATTLE_LOST, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); + if( ProcessLoyalty() )HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_BATTLE_LOST, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); if( gubEnemyEncounterCode != CREATURE_ATTACK_CODE ) { gsEnemyGainedControlOfSectorID = (INT16)SECTOR( gpAR->ubSectorX, gpAR->ubSectorY ); @@ -1759,7 +1868,7 @@ void RenderAutoResolve() //Tack on 5 minutes for retreat. gpAR->uiTotalElapsedBattleTimeInMilliseconds += 300000; - HandleLoyaltyImplicationsOfMercRetreat( RETREAT_AUTORESOLVE, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); + if( ProcessLoyalty() )HandleLoyaltyImplicationsOfMercRetreat( RETREAT_AUTORESOLVE, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); if( gubEnemyEncounterCode != CREATURE_ATTACK_CODE ) { gsEnemyGainedControlOfSectorID = (INT16)SECTOR( gpAR->ubSectorX, gpAR->ubSectorY ); @@ -1924,9 +2033,9 @@ void CreateAutoResolveInterface() } } - ubEliteMilitia = MilitiaInSectorOfRank( gpAR->ubSectorX, gpAR->ubSectorY, ELITE_MILITIA ); - ubRegMilitia = MilitiaInSectorOfRank( gpAR->ubSectorX, gpAR->ubSectorY, REGULAR_MILITIA ); - ubGreenMilitia = MilitiaInSectorOfRank( gpAR->ubSectorX, gpAR->ubSectorY, GREEN_MILITIA ); + ubEliteMilitia = MilitiaInFiveSectorsOfRank( gpAR->ubSectorX, gpAR->ubSectorY, ELITE_MILITIA ); + ubRegMilitia = MilitiaInFiveSectorsOfRank( gpAR->ubSectorX, gpAR->ubSectorY, REGULAR_MILITIA ); + ubGreenMilitia = MilitiaInFiveSectorsOfRank( gpAR->ubSectorX, gpAR->ubSectorY, GREEN_MILITIA ); while( ubEliteMilitia + ubRegMilitia + ubGreenMilitia < gpAR->ubCivs ) { switch( PreRandom( 3 ) ) @@ -2266,8 +2375,9 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2"); if( fDeleteForGood && gpCivs[ i ].pSoldier->bLife < OKLIFE/2 ) { AddDeadSoldierToUnLoadedSector( gpAR->ubSectorX, gpAR->ubSectorY, 0, gpCivs[ i ].pSoldier, RandomGridNo(), ADD_DEAD_SOLDIER_TO_SWEETSPOT ); - StrategicRemoveMilitiaFromSector( gpAR->ubSectorX, gpAR->ubSectorY, ubCurrentRank, 1 ); - HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_NATIVE_KILLED, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); +// StrategicRemoveMilitiaFromSector( gpAR->ubSectorX, gpAR->ubSectorY, ubCurrentRank, 1 ); + ARRemoveMilitiaMan( gpAR->ubSectorX, gpAR->ubSectorY, ubCurrentRank ); + if( ProcessLoyalty() )HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_NATIVE_KILLED, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); } else { @@ -2309,7 +2419,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2"); if( fDeleteForGood && gpEnemies[ i ].pSoldier->bLife < OKLIFE ) { TrackEnemiesKilled( ENEMY_KILLED_IN_AUTO_RESOLVE, gpEnemies[ i ].pSoldier->ubSoldierClass ); - HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_ENEMY_KILLED, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); + if( ProcessLoyalty() )HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_ENEMY_KILLED, gpAR->ubSectorX, gpAR->ubSectorY, 0 ); ProcessQueenCmdImplicationsOfDeath( gpEnemies[ i ].pSoldier ); AddDeadSoldierToUnLoadedSector( gpAR->ubSectorX, gpAR->ubSectorY, 0, gpEnemies[ i ].pSoldier, RandomGridNo(), ADD_DEAD_SOLDIER_TO_SWEETSPOT ); } @@ -2651,9 +2761,10 @@ void CalculateAutoResolveInfo() if( gubEnemyEncounterCode != CREATURE_ATTACK_CODE ) { - GetNumberOfEnemiesInSector( gpAR->ubSectorX, gpAR->ubSectorY, +// GetNumberOfEnemiesInSector( gpAR->ubSectorX, gpAR->ubSectorY, + GetNumberOfEnemiesInFiveSectors( gpAR->ubSectorX, gpAR->ubSectorY, &gpAR->ubAdmins, &gpAR->ubTroops, &gpAR->ubElites ); - gpAR->ubEnemies = (UINT8)min( gpAR->ubAdmins + gpAR->ubTroops + gpAR->ubElites, MAX_AR_TEAM_SIZE ); + gpAR->ubEnemies = (UINT8)min( gpAR->ubAdmins + gpAR->ubTroops + gpAR->ubElites, MAX_AR_TEAM_SIZE ); } else { @@ -2672,7 +2783,8 @@ void CalculateAutoResolveInfo() gpAR->ubEnemies = (UINT8)min( gpAR->ubYMCreatures + gpAR->ubYFCreatures + gpAR->ubAMCreatures + gpAR->ubAFCreatures, MAX_AR_TEAM_SIZE ); } gfTransferTacticalOppositionToAutoResolve = FALSE; - gpAR->ubCivs = CountAllMilitiaInSector( gpAR->ubSectorX, gpAR->ubSectorY ); +// gpAR->ubCivs = CountAllMilitiaInSector( gpAR->ubSectorX, gpAR->ubSectorY ); + gpAR->ubCivs = CountAllMilitiaInFiveSectors( gpAR->ubSectorX, gpAR->ubSectorY ); gpAR->ubMercs = 0; VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; pGroup = gpGroupList; @@ -3383,6 +3495,24 @@ void ResetNextAttackCounter( SOLDIERCELL *pCell ) } } +FLOAT CalcClassBonusOrPenalty( SOLDIERTYPE *pSoldier ) +{ + switch( pSoldier->ubSoldierClass ) + { + case SOLDIER_CLASS_ELITE: + case SOLDIER_CLASS_ELITE_MILITIA: + return 1.3f; + case SOLDIER_CLASS_ARMY: + case SOLDIER_CLASS_REG_MILITIA: + return 1.0f; + case SOLDIER_CLASS_ADMINISTRATOR: + case SOLDIER_CLASS_GREEN_MILITIA: + return 0.7f; + } + + return 1.0f; +} + void CalculateAttackValues() { INT32 i; @@ -3435,6 +3565,7 @@ void CalculateAttackValues() //bExpLevel adds a bonus of 7% per level after 2, level 1 soldiers get a 7% decrease //usBonus += 7 * (pSoldier->bExpLevel-2); + usBonus += EXP_BONUS * (pSoldier->bExpLevel-5); usBonus += gpAR->ubPlayerDefenceAdvantage; pCell->usAttack = pCell->usAttack * usBonus / 100; pCell->usDefence = pCell->usDefence * usBonus / 100; @@ -3478,10 +3609,14 @@ void CalculateAttackValues() usBonus = 100 + gpAR->ubPlayerLeadership/10;// + sOutnumberBonus; //bExpLevel adds a bonus of 7% per level after 2, level 1 soldiers get a 7% decrease //usBonus += 7 * (pSoldier->bExpLevel-2); + usBonus += EXP_BONUS * (pSoldier->bExpLevel-5); usBonus += gpAR->ubPlayerDefenceAdvantage; pCell->usAttack = pCell->usAttack * usBonus / 100; pCell->usDefence = pCell->usDefence * usBonus / 100; + pCell->usAttack = (UINT16)( pCell->usAttack * CalcClassBonusOrPenalty( pCell->pSoldier ) ); + pCell->usDefence =(UINT16)( pCell->usDefence * CalcClassBonusOrPenalty( pCell->pSoldier ) ); + pCell->usAttack = min( pCell->usAttack, 1000 ); pCell->usDefence = min( pCell->usDefence, 1000 ); @@ -3490,8 +3625,16 @@ void CalculateAttackValues() ResetNextAttackCounter( pCell ); if( i > 6 ) { //Too many militia, delay attack entry of extra mercs. - pCell->usNextAttack += (UINT16)(( i - 4 ) * 2000 ); + pCell->usNextAttack += (UINT32)(( i - 4 ) * 2000 ); } + + + if( i >= CountAllMilitiaInSector( gpAR->ubSectorX, gpAR->ubSectorY ) ) + { //Extra delay if soldier's from reinforcement + pCell->usNextAttack += REINFORCMENT_ATTACK_DELAY_PER_SOLDIER_IN_SECTOR * CountAllMilitiaInSector( gpAR->ubSectorX, gpAR->ubSectorY ); + } + + if( pCell->usNextAttack < usBestAttack ) usBestAttack = pCell->usNextAttack; } @@ -3525,9 +3668,12 @@ void CalculateAttackValues() usBonus = 100 + gpAR->ubPlayerLeadership/10;// + sOutnumberBonus; //bExpLevel adds a bonus of 7% per level after 2, level 1 soldiers get a 7% decrease //usBonus += 7 * (pSoldier->bExpLevel-2); + usBonus += EXP_BONUS * (pSoldier->bExpLevel-5); usBonus += gpAR->ubEnemyDefenceAdvantage; - pCell->usAttack = pCell->usAttack * usBonus / 100; + pCell->usAttack = pCell->usAttack * usBonus / 100; pCell->usDefence = pCell->usDefence * usBonus / 100; + pCell->usAttack = (UINT16)( pCell->usAttack * CalcClassBonusOrPenalty( pCell->pSoldier ) ); + pCell->usDefence = (UINT16)( pCell->usDefence * CalcClassBonusOrPenalty( pCell->pSoldier ) ); pCell->usAttack = min( pCell->usAttack, 1000 ); pCell->usDefence = min( pCell->usDefence, 1000 ); @@ -3538,8 +3684,14 @@ void CalculateAttackValues() if( i > 4 && !(pCell->uiFlags & CELL_CREATURE) ) { //Too many enemies, delay attack entry of extra mercs. - pCell->usNextAttack += (UINT16)( ( i - 4 ) * 1000 ); + pCell->usNextAttack += (UINT32)( ( i - 4 ) * 1000 ); } + + if(i >= NumEnemiesInSector( gpAR->ubSectorX, gpAR->ubSectorY ) && !(pCell->uiFlags & CELL_CREATURE) ) + { //Extra delay if it's a reinforcement + pCell->usNextAttack += REINFORCMENT_ATTACK_DELAY_PER_SOLDIER_IN_SECTOR * NumEnemiesInSector( gpAR->ubSectorX, gpAR->ubSectorY ); + } + if( pCell->usNextAttack < usBestAttack ) usBestAttack = pCell->usNextAttack; @@ -3608,7 +3760,7 @@ SOLDIERCELL* ChooseTarget( SOLDIERCELL *pAttacker ) INT32 index; INT32 iRandom = -1; SOLDIERCELL *pTarget = NULL; - UINT16 usSavedDefence; + UINT32 usSavedDefence; //Determine what team we are attacking if( pAttacker->uiFlags & (CELL_ENEMY | CELL_CREATURE) ) { //enemy team attacking a player @@ -3776,7 +3928,7 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget ) pAttacker->uiFlags |= CELL_FIREDATTARGET | CELL_DIRTY; if( pAttacker->usAttack < 950 ) - usAttack = (UINT16)(pAttacker->usAttack + PreRandom(1000 - pAttacker->usAttack )); + usAttack = (UINT16)(pAttacker->usAttack + PreRandom(2000 - pAttacker->usAttack )); else usAttack = (UINT16)(950 + PreRandom( 50 )); if( pTarget->uiFlags & CELL_RETREATING && !(pAttacker->uiFlags & CELL_FEMALECREATURE) ) @@ -3785,7 +3937,7 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget ) usAttack = usAttack * 7 / 10; } if( pTarget->usDefence < 950 ) - usDefence = (UINT16)(pTarget->usDefence + PreRandom(1000 - pTarget->usDefence )); + usDefence = (UINT16)(pTarget->usDefence + PreRandom(2000 - pTarget->usDefence )); else usDefence = (UINT16)(950 + PreRandom( 50 )); if( pAttacker->uiFlags & CELL_FEMALECREATURE ) @@ -3862,7 +4014,8 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget ) //Attacker hits if( !fMelee ) { - ubImpact = (UINT8) GetDamage(&pAttacker->pSoldier->inv[ pAttacker->bWeaponSlot ]); + //ubImpact = (UINT8) GetDamage(&pAttacker->pSoldier->inv[ pAttacker->bWeaponSlot ]); + ubImpact = Weapon[ pAttacker->pSoldier->inv[ pAttacker->bWeaponSlot ].usItem ].ubImpact; iRandom = PreRandom( 100 ); if( iRandom < 15 ) ubLocation = AIM_SHOT_HEAD; @@ -3887,14 +4040,14 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget ) else { OBJECTTYPE *pItem; - OBJECTTYPE tempItem; + //OBJECTTYPE tempItem; PlayAutoResolveSample( (UINT8)(BULLET_IMPACT_1+PreRandom(3)), RATE_11025, 50, 1, MIDDLEPAN ); if( !pTarget->pSoldier->bLife ) { //Soldier already dead (can't kill him again!) return; } - ubAccuracy = (UINT8)((usAttack - usDefence + PreRandom( usDefence - pTarget->usDefence ) )/10); + ubAccuracy = (UINT8)((usAttack - usDefence + PreRandom( usDefence - pTarget->usDefence ) )/10); //Determine attacking weapon. pAttacker->pSoldier->usAttackingWeapon = 0; @@ -3904,10 +4057,10 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget ) if( Item[ pItem->usItem ].usItemClass & IC_WEAPON ) pAttacker->pSoldier->usAttackingWeapon = pAttacker->pSoldier->inv[ pAttacker->bWeaponSlot ].usItem; } - + //if( pAttacker->bWeaponSlot != HANDPOS ) - //{ //switch items - // memcpy( &tempItem, &pAttacker->pSoldier->inv[ HANDPOS ], sizeof( OBJECTTYPE ) ); + //{ //switch items + // memcpy( &tempItem, &pAttacker->pSoldier->inv[ HANDPOS ], sizeof( OBJECTTYPE ) ); // memcpy( &pAttacker->pSoldier->inv[ HANDPOS ], &pAttacker->pSoldier->inv[ pAttacker->bWeaponSlot ], sizeof( OBJECTTYPE ) ); //CTD // iImpact = HTHImpact( pAttacker->pSoldier, pTarget->pSoldier, ubAccuracy, (BOOLEAN)(fKnife | fClaw) ); // memcpy( &pAttacker->pSoldier->inv[ pAttacker->bWeaponSlot ], &pAttacker->pSoldier->inv[ HANDPOS ], sizeof( OBJECTTYPE ) ); @@ -3917,7 +4070,7 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget ) //{ // iImpact = HTHImpact( pAttacker->pSoldier, pTarget->pSoldier, ubAccuracy, (BOOLEAN)(fKnife || fClaw) ); //} - + iImpact = 0; iNewLife = pTarget->pSoldier->bLife - iImpact; if( pAttacker->uiFlags & CELL_MERC ) @@ -4631,7 +4784,7 @@ void ProcessBattleFrame() iTime -= uiSlice; if( iTime > 0 ) { - pAttacker->usNextAttack = (UINT16)iTime; + pAttacker->usNextAttack = (UINT32)iTime; continue; } else @@ -4661,7 +4814,7 @@ void ProcessBattleFrame() else AttackTarget( pAttacker, pTarget ); ResetNextAttackCounter( pAttacker ); - pAttacker->usNextAttack += (UINT16)iTime; //tack on the remainder + pAttacker->usNextAttack += (UINT32)iTime; //tack on the remainder iAttacksThisFrame++; } } @@ -4766,4 +4919,16 @@ BOOLEAN GetCurrentBattleSectorXYZAndReturnTRUEIfThereIsABattle( INT16 *psSectorX void AutoBandageFinishedCallback( UINT8 ubResult ) { SetupDoneInterface(); -} \ No newline at end of file +} + +BOOLEAN ProcessLoyalty() +{ + if( PlayerMercsInSector( gpAR->ubSectorX, gpAR->ubSectorY, 0 ) ) + return TRUE; + + if( GetTownIdForSector( gpAR->ubSectorX, gpAR->ubSectorY ) != BLANK_SECTOR || + IsThisSectorASAMSector( gpAR->ubSectorX, gpAR->ubSectorY, 0 ) ) + return TRUE; + + return FALSE; +} diff --git a/Strategic/Map Screen Interface Map.cpp b/Strategic/Map Screen Interface Map.cpp index db3e4c594..92077b2ba 100644 --- a/Strategic/Map Screen Interface Map.cpp +++ b/Strategic/Map Screen Interface Map.cpp @@ -6165,7 +6165,7 @@ void DrawTownMilitiaForcesOnMap( void ) // clip blits to mapscreen region ClipBlitsToMapViewRegion( ); - +/* while( pTownNamesList[ iCounter ] != 0 ) { // run through each town sector and plot the icons for the militia forces in the town @@ -6214,20 +6214,22 @@ void DrawTownMilitiaForcesOnMap( void ) } iCounter++; - } + }*/ // now handle militia for sam sectors - for( iCounter = 0; iCounter < NUMBER_OF_SAMS; iCounter++ ) + for( sSectorX = 0; sSectorX < 16 ; ++sSectorX ) + for( sSectorY = 0; sSectorY < 16 ; ++sSectorY ) + //for( iCounter = 0; iCounter < NUMBER_OF_SAMS; iCounter++ ) { - sSectorX = SECTORX( pSamList[ iCounter ] ); - sSectorY = SECTORY( pSamList[ iCounter ] ); +// sSectorX = SECTORX( pSamList[ iCounter ] ); +// sSectorY = SECTORY( pSamList[ iCounter ] ); - if( !StrategicMap[ CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY ) ].fEnemyControlled ) + if( 1)// !StrategicMap[ CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY ) ].fEnemyControlled ) { // get number of each - iNumberOfGreens = SectorInfo[ pSamList[ iCounter ] ].ubNumberOfCivsAtLevel[ GREEN_MILITIA ]; - iNumberOfRegulars = SectorInfo[ pSamList[ iCounter ] ].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ]; - iNumberOfElites = SectorInfo[pSamList[ iCounter ] ].ubNumberOfCivsAtLevel[ ELITE_MILITIA ]; + iNumberOfGreens = SectorInfo[ SECTOR( sSectorX, sSectorY ) ].ubNumberOfCivsAtLevel[ GREEN_MILITIA ]; + iNumberOfRegulars = SectorInfo[ SECTOR( sSectorX, sSectorY ) ].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ]; + iNumberOfElites = SectorInfo[ SECTOR( sSectorX, sSectorY ) ].ubNumberOfCivsAtLevel[ ELITE_MILITIA ]; // ste the total for loop upper bound iTotalNumberOfTroops = iNumberOfGreens + iNumberOfRegulars + iNumberOfElites; diff --git a/Strategic/Queen Command.cpp b/Strategic/Queen Command.cpp index b1043639d..9769c07fd 100644 --- a/Strategic/Queen Command.cpp +++ b/Strategic/Queen Command.cpp @@ -32,6 +32,8 @@ extern BOOLEAN gfClearCreatureQuest; #endif +#include "Reinforcement.h" + //The sector information required for the strategic AI. Contains the number of enemy troops, //as well as intentions, etc. SECTORINFO SectorInfo[256]; @@ -847,14 +849,14 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"QueenCommand"); UINT32 ubTotalEnemies; #endif - if( !IsAutoResolveActive() ) - { +// if( !IsAutoResolveActive() ) +// { pSector = &SectorInfo[ SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ]; - } - else - { - pSector = &SectorInfo[ GetAutoResolveSectorID() ]; - } +// } +// else +// { +// pSector = &SectorInfo[ GetAutoResolveSectorID() ]; +// } #ifdef JA2BETAVERSION ubTotalEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites; @@ -1093,16 +1095,99 @@ void AddPossiblePendingEnemiesToBattle() UINT8 ubSlots, ubNumAvailable; UINT8 ubNumElites, ubNumTroops, ubNumAdmins; GROUP *pGroup; - if( !gfPendingEnemies ) + SECTORINFO *pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ]; + static UINT8 ubPredefinedInsertionCode = 255; + + if( ( !PlayerMercsInSector( gWorldSectorX, gWorldSectorY, 0 ) && !CountAllMilitiaInSector( gWorldSectorX, gWorldSectorY ) ) + || !NumEnemiesInSector( gWorldSectorX, gWorldSectorY ) ) return; + + +/* if( !gfPendingEnemies ) { //Optimization. No point in checking if we know that there aren't any more enemies that can //be added to this battle. This changes whenever a new enemy group arrives at the scene. return; - } + }*/ ubSlots = NumFreeEnemySlots(); if( !ubSlots ) { //no available slots to add enemies to. Try again later... return; } + + if( pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins ) + { + ubNumElites = ubNumTroops = ubNumAdmins = 0; + + ubNumAvailable = pSector->ubNumElites + pSector->ubNumTroops + pSector->ubNumAdmins - pSector->ubElitesInBattle - pSector->ubTroopsInBattle - pSector->ubAdminsInBattle; + while( ubNumAvailable && ubSlots ) + { //This group has enemies waiting for a chance to enter the battle. + if( pSector->ubElitesInBattle < pSector->ubNumElites ) + { //Add an elite troop + pSector->ubElitesInBattle++; + ubNumAvailable--; + ubSlots--; + ubNumElites++; + } + else if( pSector->ubTroopsInBattle < pSector->ubNumTroops ) + { //Add a regular troop. + pSector->ubTroopsInBattle++; + ubNumAvailable--; + ubSlots--; + ubNumTroops++; + } + else if( pSector->ubAdminsInBattle < pSector->ubNumAdmins ) + { //Add an elite troop + pSector->ubAdminsInBattle++; + ubNumAvailable--; + ubSlots--; + ubNumAdmins++; + } + else + { + AssertMsg( 0, "AddPossiblePendingEnemiesToBattle(): Logic Error -- by Kris" ); + } + } + + + if( ubNumAdmins || ubNumTroops || ubNumElites ) + { //This group has contributed forces, then add them now, because different + //groups appear on different sides of the map. + UINT8 ubStrategicInsertionCode = ubPredefinedInsertionCode; + //First, determine which entrypoint to use, based on the travel direction of the group. + + if( ubStrategicInsertionCode == 255 ) + { + if( NumEnemiesInSector( gWorldSectorX + 1, gWorldSectorY ) ) + ubStrategicInsertionCode = INSERTION_CODE_EAST; + else if( NumEnemiesInSector( gWorldSectorX - 1, gWorldSectorY ) ) + ubStrategicInsertionCode = INSERTION_CODE_WEST; + else if( NumEnemiesInSector( gWorldSectorX, gWorldSectorY + 1 ) ) + ubStrategicInsertionCode = INSERTION_CODE_SOUTH; + else if( NumEnemiesInSector( gWorldSectorX, gWorldSectorY - 1 ) ) + ubStrategicInsertionCode = INSERTION_CODE_NORTH; + } + + if( ubStrategicInsertionCode == 255 ) + { + if( !CountAllMilitiaInSector( gWorldSectorX + 1, gWorldSectorY ) ) + ubStrategicInsertionCode = INSERTION_CODE_EAST; + else if( !CountAllMilitiaInSector( gWorldSectorX - 1, gWorldSectorY ) ) + ubStrategicInsertionCode = INSERTION_CODE_WEST; + else if( !CountAllMilitiaInSector( gWorldSectorX, gWorldSectorY + 1 ) ) + ubStrategicInsertionCode = INSERTION_CODE_SOUTH; + else if( !CountAllMilitiaInSector( gWorldSectorX, gWorldSectorY - 1 ) ) + ubStrategicInsertionCode = INSERTION_CODE_NORTH; + } + + if( ubStrategicInsertionCode < INSERTION_CODE_NORTH ||ubStrategicInsertionCode > INSERTION_CODE_WEST ) + ubStrategicInsertionCode = INSERTION_CODE_NORTH + Random( 4 ); + + AddEnemiesToBattle( 0, ubStrategicInsertionCode, ubNumAdmins, ubNumTroops, ubNumElites, FALSE ); + gfPendingEnemies = TRUE; + } + } + + ubPredefinedInsertionCode = 255; + pGroup = gpGroupList; while( pGroup && ubSlots ) { @@ -1112,22 +1197,22 @@ void AddPossiblePendingEnemiesToBattle() ubNumAvailable = pGroup->ubGroupSize - pGroup->pEnemyGroup->ubElitesInBattle - pGroup->pEnemyGroup->ubTroopsInBattle - pGroup->pEnemyGroup->ubAdminsInBattle; while( ubNumAvailable && ubSlots ) { //This group has enemies waiting for a chance to enter the battle. - if( pGroup->pEnemyGroup->ubTroopsInBattle < pGroup->pEnemyGroup->ubNumTroops ) - { //Add a regular troop. - pGroup->pEnemyGroup->ubTroopsInBattle++; - ubNumAvailable--; - ubSlots--; - ubNumTroops++; - } - else if( pGroup->pEnemyGroup->ubElitesInBattle < pGroup->pEnemyGroup->ubNumElites ) + if( pGroup->pEnemyGroup->ubElitesInBattle < pGroup->pEnemyGroup->ubNumElites ) { //Add an elite troop pGroup->pEnemyGroup->ubElitesInBattle++; ubNumAvailable--; ubSlots--; ubNumElites++; } + else if( pGroup->pEnemyGroup->ubTroopsInBattle < pGroup->pEnemyGroup->ubNumTroops ) + { //Add a regular troop. + pGroup->pEnemyGroup->ubTroopsInBattle++; + ubNumAvailable--; + ubSlots--; + ubNumTroops++; + } else if( pGroup->pEnemyGroup->ubAdminsInBattle < pGroup->pEnemyGroup->ubNumAdmins ) - { //Add an elite troop + { //Add an admin troop pGroup->pEnemyGroup->ubAdminsInBattle++; ubNumAvailable--; ubSlots--; @@ -1167,6 +1252,7 @@ void AddPossiblePendingEnemiesToBattle() } //Add the number of each type of troop and place them in the appropriate positions AddEnemiesToBattle( pGroup, ubStrategicInsertionCode, ubNumAdmins, ubNumTroops, ubNumElites, FALSE ); + gfPendingEnemies = TRUE; } } pGroup = pGroup->next; @@ -1175,6 +1261,14 @@ void AddPossiblePendingEnemiesToBattle() { //After going through the process, we have finished with some free slots and no more enemies to add. //So, we can turn off the flag, as this check is no longer needed. gfPendingEnemies = FALSE; + + if( gTacticalStatus.Team[ ENEMY_TEAM ].bAwareOfOpposition == TRUE ) + ubPredefinedInsertionCode = DoReinforcementAsPendingEnemy( gWorldSectorX, gWorldSectorY ); + else + ubPredefinedInsertionCode = 255; + + if( ubPredefinedInsertionCode != 255 ) + AddPossiblePendingEnemiesToBattle(); } } diff --git a/Strategic/Strategic AI.cpp b/Strategic/Strategic AI.cpp index bd94efcb5..efcf687cf 100644 --- a/Strategic/Strategic AI.cpp +++ b/Strategic/Strategic AI.cpp @@ -79,6 +79,7 @@ of the group. If the priority of the group is high, they // values have been externalized into an INI file. Not all of them at this point, // but more will be externalized as time goes on. +#define BASIC_POOL_INCREMENT gGameExternalOptions.guiBaseQueenPoolIncrement //Modifies the number of troops the queen has at the beginning of the game on top //of all of the garrison and patrol groups. Additionally, there are a total of @@ -2956,7 +2957,7 @@ void EvaluateQueenSituation() if( !giReinforcementPool ) { //Queen has run out of reinforcements. Simulate recruiting and training new troops uiOffset *= 10; - giReinforcementPool += 30; + giReinforcementPool += ( BASIC_POOL_INCREMENT * gGameOptions.ubDifficultyLevel ) * ( 100 + CurrentPlayerProgressPercentage() ) / 100 ; AddStrategicEvent( EVENT_EVALUATE_QUEEN_SITUATION, GetWorldTotalMin() + uiOffset, 0 ); return; } diff --git a/Strategic/Strategic Movement.cpp b/Strategic/Strategic Movement.cpp index 097162891..6997f5457 100644 --- a/Strategic/Strategic Movement.cpp +++ b/Strategic/Strategic Movement.cpp @@ -39,6 +39,8 @@ #include "Town Militia.h" #endif +#include "MilitiaSquads.h" + // the delay for a group about to arrive #define ABOUT_TO_ARRIVE_DELAY 5 @@ -1145,6 +1147,15 @@ BOOLEAN CheckConditionsForBattle( GROUP *pGroup ) if( fMilitiaPresent ) { NotifyPlayerOfInvasionByEnemyForces( pGroup->ubSectorX, pGroup->ubSectorY, 0, TriggerPrebattleInterface ); + + if( GetTownIdForSector( pGroup->ubSectorX, pGroup->ubSectorY ) == BLANK_SECTOR) + { +// UINT16 str[ 256 ]; +// UINT16 uiSectorC = L'A' + pGroup->ubSectorY - 1; +// swprintf( str, gpStrategicString[ STR_DIALOG_ENEMIES_ATTACK_MILITIA ], uiSectorC, pGroup->ubSectorX ); +// DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, TriggerPrebattleInterface ); + TriggerPrebattleInterface(1); + } } else { @@ -1163,6 +1174,7 @@ BOOLEAN CheckConditionsForBattle( GROUP *pGroup ) if( pPlayerDialogGroup ) { + if( !pGroup->ubSectorZ )MilitiaHelpFromAdjacentSectors( pGroup->ubSectorX, pGroup->ubSectorY ); PrepareForPreBattleInterface( pPlayerDialogGroup, pGroup ); } return TRUE; @@ -2029,6 +2041,10 @@ void HandleNonCombatGroupArrival( GROUP *pGroup, BOOLEAN fMainGroup, BOOLEAN fNe } } } + + + //MilitiaFollowPlayer( pGroup->ubPrevX, pGroup->ubPrevY, pGroup->ubSectorX, pGroup->ubSectorY ); + // look for NPCs to stop for, anyone is too tired to keep going, if all OK rebuild waypoints & continue movement // NOTE: Only the main group (first group arriving) will stop for NPCs, it's just too much hassle to stop them all PlayerGroupArrivedSafelyInSector( pGroup, fMainGroup ); diff --git a/Strategic/Strategic.vcproj b/Strategic/Strategic.vcproj index 28bc512dc..2fb4944a9 100644 --- a/Strategic/Strategic.vcproj +++ b/Strategic/Strategic.vcproj @@ -1938,6 +1938,9 @@ BrowseInformation="1"/> + + + + + + @@ -3583,6 +3592,9 @@ + + diff --git a/Tactical/Militia Control.cpp b/Tactical/Militia Control.cpp index cf3b55efa..22014f9ed 100644 --- a/Tactical/Militia Control.cpp +++ b/Tactical/Militia Control.cpp @@ -12,10 +12,12 @@ #include "PreBattle Interface.h" #endif +#include "MilitiaSquads.h" BOOLEAN gfStrategicMilitiaChangesMade = FALSE; BOOLEAN fFirstClickInMilitiaControlScreenMask = FALSE; +BOOLEAN gfMSResetMilitia = FALSE; // render pre battle interface? @@ -98,11 +100,19 @@ extern BOOLEAN SoldierCanAffordNewStance( SOLDIERTYPE *pSoldier, UINT8 ubDesired void ResetMilitia() { - if( gfStrategicMilitiaChangesMade || gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) + BOOLEAN fBattleInProgress = FALSE; + + if ( gWorldSectorX !=0 && gWorldSectorY != 0 && NumEnemiesInSector( gWorldSectorX, gWorldSectorY ) ) + fBattleInProgress = TRUE; + + if( ( gfStrategicMilitiaChangesMade && !fBattleInProgress ) || gTacticalStatus.uiFlags & LOADING_SAVED_GAME || gfMSResetMilitia ) { gfStrategicMilitiaChangesMade = FALSE; - RemoveMilitiaFromTactical(); + + if( !gfMSResetMilitia ) + RemoveMilitiaFromTactical(); PrepareMilitiaForTactical(); + gfMSResetMilitia = FALSE; } } @@ -131,7 +141,7 @@ void RemoveMilitiaFromTactical() void PrepareMilitiaForTactical() { SECTORINFO *pSector; -// INT32 i; + INT32 x; UINT8 ubGreen, ubRegs, ubElites; if( gbWorldSectorZ > 0 ) return; @@ -144,16 +154,27 @@ void PrepareMilitiaForTactical() ubGreen = pSector->ubNumberOfCivsAtLevel[ GREEN_MILITIA ]; ubRegs = pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ]; ubElites = pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ]; - AddSoldierInitListMilitia( ubGreen, ubRegs, ubElites ); - /* - for( i = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; i <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; i++ ) - { - if( MercPtrs[ i ]->bInSector ) + + if(guiDirNumber) + for( x = 0 ; x < guiDirNumber ; ++x ) { - MercPtrs[ i ]->bAttitude = AGGRESSIVE; +// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%ld,%ld,%ld,%ld", gpAttackDirs[ x ][ 0 ], gpAttackDirs[ x ][1], gpAttackDirs[ x ][2], gpAttackDirs[ x ][3] ); + if( gpAttackDirs[ x ][ 3 ] != INSERTION_CODE_CENTER ) + AddSoldierInitListMilitiaOnEdge( gpAttackDirs[ x ][ 3 ], gpAttackDirs[ x ][0], gpAttackDirs[ x ][1], gpAttackDirs[ x ][2] ); +// AddSoldierInitListMilitia( gpAttackDirs[ x ][0], gpAttackDirs[ x ][1], gpAttackDirs[ x ][2] ); +// else } - } - */ + else AddSoldierInitListMilitia( ubGreen, ubRegs, ubElites ); + +// for( i = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; i <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; i++ ) +// { +// if( MercPtrs[ i ]->bInSector ) +// { +// MercPtrs[ i ]->bOrders = SEEKENEMY; +//// MercPtrs[ i ]->bAttitude = AGGRESSIVE; +// } +// } + guiDirNumber = 0; } void HandleMilitiaPromotions( void ) diff --git a/Tactical/Overhead Types.h b/Tactical/Overhead Types.h index 0116fb55d..71227e4a7 100644 --- a/Tactical/Overhead Types.h +++ b/Tactical/Overhead Types.h @@ -186,7 +186,7 @@ enum // CHANGE THIS VALUE TO AFFECT TOTAL SIGHT RANGE -#define STRAIGHT_RANGE ubStraightSightRange +#define STRAIGHT_RANGE gGameExternalOptions.ubStraightSightRange // CHANGE THESE VALUES TO ADJUST VARIOUS FOV ANGLES #define STRAIGHT_RATIO 1 //* 1.5 diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index 9bbd62afd..ae55117f1 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -3832,6 +3832,7 @@ void MilitiaChangesSides( void ) { if (pSoldier->bActive && pSoldier->bInSector && pSoldier->bLife) { + if ( (gWorldSectorX ==0 && gWorldSectorY == 0) || !NumEnemiesInSector( gWorldSectorX, gWorldSectorY ) ) MakeCivHostile( pSoldier, 2 ); RecalculateOppCntsDueToNoLongerNeutral( pSoldier ); } @@ -5457,7 +5458,8 @@ void EnterCombatMode( UINT8 ubStartingTeam ) // OK, make sure we have a selected guy // Madd: this was causing a weird crash becuase gusSelectedSoldier was 156 (out of the array bounds) for some reason //if ( MercPtrs[ gusSelectedSoldier ]->bOppCnt == 0 ) - //{ + if ( gusSelectedSoldier != NOBODY && MercPtrs[ gusSelectedSoldier ]->bOppCnt == 0 ) + { DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"EnterCombatMode continuing... nobody selected"); // OK, look through and find one.... for ( cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID, pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++, pTeamSoldier++ ) @@ -5468,7 +5470,7 @@ void EnterCombatMode( UINT8 ubStartingTeam ) SelectSoldier( pTeamSoldier->ubID, FALSE, TRUE ); } } - //} + } DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"EnterCombatMode continuing... calling startplayerteamturn"); StartPlayerTeamTurn( FALSE, TRUE ); @@ -5903,7 +5905,13 @@ void DeathNoMessageTimerCallback( void ) CheckAndHandleUnloadingOfCurrentWorld(); } +void RemoveStaticEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY ) +{ + SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR( sMapX, sMapY ) ] ); + pSectorInfo->ubNumAdmins = pSectorInfo->ubNumTroops = pSectorInfo->ubNumElites = 0; + pSectorInfo->ubAdminsInBattle = pSectorInfo->ubTroopsInBattle = pSectorInfo->ubElitesInBattle = 0; +} //!!!! //IMPORTANT NEW NOTE: @@ -5962,6 +5970,7 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) //It is possible to have more than 20 enemies in a sector. By failing here, //it gives the engine a chance to add these soldiers as reinforcements. This //is naturally handled. + AddPossiblePendingEnemiesToBattle(); if( gfPendingEnemies ) { fBattleWon = FALSE; @@ -6043,6 +6052,10 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) } } + // Kill all enemies. Sometime even after killing all the enemies, there appeares "in battle" enemies in sector info + RemoveStaticEnemiesFromSectorInfo( gWorldSectorX, gWorldSectorY ); + + // If here, the battle has been won! // hurray! a glorious victory! @@ -6168,6 +6181,10 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) ShouldBeginAutoBandage(); } + HandleMilitiaStatusInCurrentMapBeforeLoadingNewMap(); + gfStrategicMilitiaChangesMade = TRUE; + + // Loop through all militia and restore them to peaceful status cnt = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; for ( pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; cnt++,pTeamSoldier++) @@ -6180,10 +6197,10 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated ) pTeamSoldier->ubNoiseVolume = 0; pTeamSoldier->bNewSituation = FALSE; pTeamSoldier->bOrders = STATIONARY; - if ( pTeamSoldier->bLife >= OKLIFE ) - { - pTeamSoldier->bBleeding = 0; - } + if ( pTeamSoldier->bLife < OKLIFE ) + pTeamSoldier->bLife = OKLIFE; + + pTeamSoldier->bBleeding = 0; // let's think, the autobandage was done for the militia too } } gTacticalStatus.Team[ MILITIA_TEAM ].bAwareOfOpposition = FALSE; diff --git a/Tactical/PATHAI.cpp b/Tactical/PATHAI.cpp index de650fcf1..249fa83b0 100644 --- a/Tactical/PATHAI.cpp +++ b/Tactical/PATHAI.cpp @@ -84,7 +84,7 @@ UINT8 gubBuildingInfoToSet; // STANDARD maximums... configurable! #define MAX_SKIPLIST_LEVEL 5 -#define MAX_TRAIL_TREE (4096) +#define MAX_TRAIL_TREE (16384)//(4096) #define MAX_PATHQ (512) INT32 iMaxSkipListLevel = MAX_SKIPLIST_LEVEL; @@ -150,7 +150,7 @@ static INT32 iSkipListLevelLimit[8] = {0, 4, 16, 64, 256, 1024, 4192, 16384 }; //#define ESTIMATEC (((dxusCostSoFar + pCurrPtr->usCostToGo) #define TOTALCOST( ptr ) (ptr->usTotalCost) @@ -2127,12 +2127,19 @@ void GlobalItemsReachableTest( INT16 sStartGridNo1, INT16 sStartGridNo2 ) void RoofReachableTest( INT16 sStartGridNo, UINT8 ubBuildingID ) { SOLDIERTYPE s; + INT16 sGridNo; memset( &s, 0, sizeof( SOLDIERTYPE ) ); s.sGridNo = sStartGridNo; s.bLevel = 1; s.bTeam = 1; + // clearing flags + + for( sGridNo = 0 ; sGridNo < NOWHERE ; ++sGridNo ) + gpWorldLevelData[ sGridNo ].uiFlags &= (~MAPELEMENT_REACHABLE); + + gubBuildingInfoToSet = ubBuildingID; ReconfigurePathAI( ABSMAX_SKIPLIST_LEVEL, ABSMAX_TRAIL_TREE, ABSMAX_PATHQ ); diff --git a/Tactical/Rain.cpp b/Tactical/Rain.cpp index fcde53400..2bdfbc21a 100644 --- a/Tactical/Rain.cpp +++ b/Tactical/Rain.cpp @@ -123,7 +123,7 @@ FLOAT fpMinDropSpeed = 0; extern UINT32 guiCurrentScreen; -extern BOOLEAN gfAllowRain; +//extern BOOLEAN gfAllowRain; extern INT16 gsVIEWPORT_WINDOW_END_Y; extern INT16 gsVIEWPORT_WINDOW_START_Y; @@ -149,7 +149,7 @@ INT8 GetRainIntensityFromEnvWeather() BOOLEAN IsItAllowedToRenderRain() { - if( !gfAllowRain )return FALSE; + if( !gGameExternalOptions.gfAllowRain )return FALSE; if( !( guiEnvWeather & (WEATHER_FORECAST_THUNDERSHOWERS | WEATHER_FORECAST_SHOWERS) ) )return FALSE; diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 5b53432be..a3c716ad9 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -86,14 +86,14 @@ #endif //turnspeed -UINT8 gubPlayerTurnSpeedUpFactor = 1; -UINT8 gubEnemyTurnSpeedUpFactor = 1; -UINT8 gubCreatureTurnSpeedUpFactor = 1; -UINT8 gubMilitiaTurnSpeedUpFactor = 1; -UINT8 gubCivTurnSpeedUpFactor = 1; +//UINT8 gubPlayerTurnSpeedUpFactor = 1; +//UINT8 gubEnemyTurnSpeedUpFactor = 1; +//UINT8 gubCreatureTurnSpeedUpFactor = 1; +//UINT8 gubMilitiaTurnSpeedUpFactor = 1; +//UINT8 gubCivTurnSpeedUpFactor = 1; //turnspeed -extern BOOLEAN fAllowTacticalMilitiaCommand; //lal +//extern BOOLEAN fAllowTacticalMilitiaCommand; //lal extern INT16 DirIncrementer[8]; @@ -5879,18 +5879,17 @@ UINT8 GetSpeedUpFactor( ) switch( gTacticalStatus.ubCurrentTeam ) { case OUR_TEAM: - return gubPlayerTurnSpeedUpFactor; + return gGameExternalOptions.gubPlayerTurnSpeedUpFactor; case ENEMY_TEAM: - return gubEnemyTurnSpeedUpFactor; + return gGameExternalOptions.gubEnemyTurnSpeedUpFactor; case CREATURE_TEAM: - return gubCreatureTurnSpeedUpFactor; + return gGameExternalOptions.gubCreatureTurnSpeedUpFactor; case MILITIA_TEAM: - return gubMilitiaTurnSpeedUpFactor; + return gGameExternalOptions.gubMilitiaTurnSpeedUpFactor; case CIV_TEAM: - return gubCivTurnSpeedUpFactor; + return gGameExternalOptions.gubCivTurnSpeedUpFactor; } - return 1; } @@ -10822,7 +10821,7 @@ BOOLEAN PlayerSoldierStartTalking( SOLDIERTYPE *pSoldier, UINT8 ubTargetID, BOOL if ( GetCivType( pTSoldier ) != CIV_TYPE_NA ) { //lal - if ( ( pTSoldier->bTeam == MILITIA_TEAM ) && ( fAllowTacticalMilitiaCommand == TRUE ) && (pSoldier->bSide == pTSoldier->bSide) ) + if ( ( pTSoldier->bTeam == MILITIA_TEAM ) && ( gGameExternalOptions.fAllowTacticalMilitiaCommand == TRUE ) && (pSoldier->bSide == pTSoldier->bSide) ) { PopupMilitiaControlMenu( pTSoldier ); return( FALSE ); diff --git a/Tactical/Soldier Create.cpp b/Tactical/Soldier Create.cpp index 8dcf14f1b..e25c272b6 100644 --- a/Tactical/Soldier Create.cpp +++ b/Tactical/Soldier Create.cpp @@ -2048,7 +2048,8 @@ SOLDIERTYPE* TacticalCreateAdministrator() if( guiCurrentScreen == AUTORESOLVE_SCREEN && !gfPersistantPBI ) { - return ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_ADMINISTRATOR ); + pSoldier = ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_ADMINISTRATOR ); + if( pSoldier ) return pSoldier; } memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) ); @@ -2081,7 +2082,8 @@ SOLDIERTYPE* TacticalCreateArmyTroop() if( guiCurrentScreen == AUTORESOLVE_SCREEN && !gfPersistantPBI ) { - return ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_ARMY ); + pSoldier = ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_ARMY ); + if( pSoldier ) return pSoldier; } memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) ); @@ -2114,7 +2116,8 @@ SOLDIERTYPE* TacticalCreateEliteEnemy() if( guiCurrentScreen == AUTORESOLVE_SCREEN && !gfPersistantPBI ) { - return ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_ELITE ); + pSoldier = ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_ELITE ); + if( pSoldier ) return pSoldier; } memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) ); @@ -2146,11 +2149,53 @@ SOLDIERTYPE* TacticalCreateEliteEnemy() return( pSoldier ); } +SOLDIERTYPE* ReserveTacticalMilitiaSoldierForAutoresolve( UINT8 ubSoldierClass ) +{ + INT32 i, iStart, iEnd; + SOLDIERTYPE *pSoldier; + + // For description look original ReserveTacticalSoldierForAutoresolve() + + iStart = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; + iEnd = gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; + + for( i = iStart; i <= iEnd; i++ ) + { + if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->bInSector && MercPtrs[ i ]->bLife && MercPtrs[ i ]->sGridNo != NOWHERE ) + { + if( MercPtrs[ i ]->ubSoldierClass == ubSoldierClass ) + { + //reserve this soldier + MercPtrs[ i ]->sGridNo = NOWHERE; + + //Allocate and copy the soldier + pSoldier = (SOLDIERTYPE*)MemAlloc( sizeof( SOLDIERTYPE ) ); + if( !pSoldier ) + return NULL; + memcpy( pSoldier, MercPtrs[ i ], sizeof( SOLDIERTYPE ) ); + + //Assign a bogus ID, then return it + pSoldier->ubID = 255; + return pSoldier; + } + } + } + return NULL; +} + + SOLDIERTYPE* TacticalCreateMilitia( UINT8 ubMilitiaClass ) { BASIC_SOLDIERCREATE_STRUCT bp; SOLDIERCREATE_STRUCT pp; UINT8 ubID; + SOLDIERTYPE * pSoldier; + + if( guiCurrentScreen == AUTORESOLVE_SCREEN && !gfPersistantPBI ) + { + pSoldier = ReserveTacticalMilitiaSoldierForAutoresolve( ubMilitiaClass ); + if( pSoldier ) return pSoldier; + } memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) ); memset( &pp, 0, sizeof( SOLDIERCREATE_STRUCT ) ); @@ -2171,10 +2216,12 @@ SOLDIERTYPE* TacticalCreateCreature( INT8 bCreatureBodyType ) BASIC_SOLDIERCREATE_STRUCT bp; SOLDIERCREATE_STRUCT pp; UINT8 ubID; + SOLDIERTYPE * pSoldier; if( guiCurrentScreen == AUTORESOLVE_SCREEN && !gfPersistantPBI ) { - return ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_CREATURE ); + pSoldier = ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_CREATURE ); + if( pSoldier ) return pSoldier; } memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) ); diff --git a/Tactical/Soldier Init List.cpp b/Tactical/Soldier Init List.cpp index 96dc59d6d..6a03342e0 100644 --- a/Tactical/Soldier Init List.cpp +++ b/Tactical/Soldier Init List.cpp @@ -28,6 +28,7 @@ #include "Font Control.h" #endif +#include "Map Edgepoints.h" BOOLEAN gfOriginalList = TRUE; SOLDIERINITNODE *gSoldierInitHead = NULL; @@ -2326,4 +2327,119 @@ void StripEnemyDetailedPlacementsIfSectorWasPlayerLiberated() curr = curr->next; } -} \ No newline at end of file +} + +//////// +//////// For militia squad attack! +//////// + +#define CENTRAL_GRIDNO 13202 +#define CENTRAL_RADIUS 30 + +void AddSoldierInitListMilitiaOnEdge( UINT8 ubStrategicInsertionCode, UINT8 ubNumGreen, UINT8 ubNumReg, UINT8 ubNumElites ) +{ + SOLDIERTYPE *pSoldier; + MAPEDGEPOINTINFO MapEdgepointInfo; + UINT8 ubCurrSlot; + UINT8 ubTotalSoldiers; + UINT8 bDesiredDirection=0; + switch( ubStrategicInsertionCode ) + { + case INSERTION_CODE_NORTH: bDesiredDirection = SOUTHEAST; break; + case INSERTION_CODE_EAST: bDesiredDirection = SOUTHWEST; break; + case INSERTION_CODE_SOUTH: bDesiredDirection = NORTHWEST; break; + case INSERTION_CODE_WEST: bDesiredDirection = NORTHEAST; break; + default: AssertMsg( 0, "Illegal direction passed to AddSoldierInitListMilitiaOnEdge()" ); break; + } + #ifdef JA2TESTVERSION + ScreenMsg( FONT_RED, MSG_INTERFACE, L"Militia reinforcements have arrived! (%d admins, %d troops, %d elite)", ubNumGreen, ubNumReg, ubNumElites ); + #endif + + ubTotalSoldiers = ubNumGreen + ubNumReg + ubNumElites; + + ChooseMapEdgepoints( &MapEdgepointInfo, ubStrategicInsertionCode, (UINT8)(ubNumGreen + ubNumReg + ubNumElites) ); + ubCurrSlot = 0; + while( ubTotalSoldiers ) + { + if( ubNumElites && Random( ubTotalSoldiers ) < ubNumElites ) + { + ubNumElites--; + ubTotalSoldiers--; + pSoldier = TacticalCreateMilitia(SOLDIER_CLASS_ELITE_MILITIA); + + pSoldier->bOrders = SEEKENEMY; + pSoldier->ubInsertionDirection = bDesiredDirection; + + pSoldier->bAlertStatus = STATUS_YELLOW; + pSoldier->sNoiseGridno = (INT16)(CENTRAL_GRIDNO + ( Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS ) + ( Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS ) * WORLD_COLS); + pSoldier->ubNoiseVolume = MAX_MISC_NOISE_DURATION; + + //Setup the position + if( ubCurrSlot < MapEdgepointInfo.ubNumPoints ) + { //using an edgepoint + pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO; + pSoldier->usStrategicInsertionData = MapEdgepointInfo.sGridNo[ ubCurrSlot++ ]; + } + else + { //no edgepoints left, so put him at the entrypoint. + pSoldier->ubStrategicInsertionCode = ubStrategicInsertionCode; + } + UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, 0 ); + } + else if( ubNumReg && (UINT8)Random( ubTotalSoldiers ) < (UINT8)(ubNumElites + ubNumReg) ) + { + ubNumReg--; + ubTotalSoldiers--; + pSoldier = TacticalCreateMilitia(SOLDIER_CLASS_REG_MILITIA); + + pSoldier->bOrders = SEEKENEMY; + pSoldier->ubInsertionDirection = bDesiredDirection; + + pSoldier->bAlertStatus = STATUS_YELLOW; + pSoldier->sNoiseGridno = (INT16)(CENTRAL_GRIDNO + ( Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS ) + ( Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS ) * WORLD_COLS); + pSoldier->ubNoiseVolume = MAX_MISC_NOISE_DURATION; + + //Setup the position + if( ubCurrSlot < MapEdgepointInfo.ubNumPoints ) + { //using an edgepoint + pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO; + pSoldier->usStrategicInsertionData = MapEdgepointInfo.sGridNo[ ubCurrSlot++ ]; + } + else + { //no edgepoints left, so put him at the entrypoint. + pSoldier->ubStrategicInsertionCode = ubStrategicInsertionCode; + } + UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, 0 ); + } + else if( ubNumGreen && (UINT8)Random( ubTotalSoldiers ) < (UINT8)(ubNumElites + ubNumReg + ubNumGreen) ) + { + ubNumGreen--; + ubTotalSoldiers--; + pSoldier = TacticalCreateMilitia(SOLDIER_CLASS_GREEN_MILITIA); + + pSoldier->bOrders = SEEKENEMY; + pSoldier->ubInsertionDirection = bDesiredDirection; + + pSoldier->bAlertStatus = STATUS_YELLOW; + pSoldier->sNoiseGridno = (INT16)(CENTRAL_GRIDNO + ( Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS ) + ( Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS ) * WORLD_COLS); + pSoldier->ubNoiseVolume = MAX_MISC_NOISE_DURATION; + + +// if ( GetTimeOfDayAmbientLightLevel() < NORMAL_LIGHTLEVEL_DAY + 2 ) +// gTacticalStatus.Team[ ENEMY_TEAM ].bAwareOfOpposition = TRUE; +// gTacticalStatus.Team[ MILITIA_TEAM ].bAwareOfOpposition = TRUE; + + //Setup the position + if( ubCurrSlot < MapEdgepointInfo.ubNumPoints ) + { //using an edgepoint + pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO; + pSoldier->usStrategicInsertionData = MapEdgepointInfo.sGridNo[ ubCurrSlot++ ]; + } + else + { //no edgepoints left, so put him at the entrypoint. + pSoldier->ubStrategicInsertionCode = ubStrategicInsertionCode; + } + UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, 0 ); + } + } +} diff --git a/Tactical/Soldier Init List.h b/Tactical/Soldier Init List.h index 1477a9693..8743f7982 100644 --- a/Tactical/Soldier Init List.h +++ b/Tactical/Soldier Init List.h @@ -45,6 +45,7 @@ void AddSoldierInitListCreatures( BOOLEAN fQueen, UINT8 ubNumLarvae, UINT8 ubNum UINT8 ubNumYoungMales, UINT8 ubNumYoungFemales, UINT8 ubNumAdultMales, UINT8 ubNumAdultFemales ); void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumReg, UINT8 ubNumElites ); +void AddSoldierInitListMilitiaOnEdge( UINT8 ubStrategicInsertionCode, UINT8 ubNumGreen, UINT8 ubNumReg, UINT8 ubNumElites ); void AddSoldierInitListBloodcats(); diff --git a/Tactical/Tactical Turns.cpp b/Tactical/Tactical Turns.cpp index ca1543098..a6f84da92 100644 --- a/Tactical/Tactical Turns.cpp +++ b/Tactical/Tactical Turns.cpp @@ -30,6 +30,8 @@ #include "Soldier macros.h" #endif +#include "Reinforcement.h" + extern void DecayPublicOpplist( INT8 bTeam ); //not in overhead.h! @@ -170,6 +172,8 @@ void HandleTacticalEndTurn( ) //Check for enemy pooling (add enemies if there happens to be more than the max in the //current battle. If one or more slots have freed up, we can add them now. AddPossiblePendingEnemiesToBattle(); + + AddPossiblePendingMilitiaToBattle(); // Loop through each active team and decay public opplist... // May want this done every few times too diff --git a/Tactical/TeamTurns.cpp b/Tactical/TeamTurns.cpp index 701bf6cc2..cd4839943 100644 --- a/Tactical/TeamTurns.cpp +++ b/Tactical/TeamTurns.cpp @@ -43,6 +43,36 @@ #endif #endif +#include "Reinforcement.h" + + +//extern UINT8 gubSpeedUpAnimationFactor; +void SetSoldierAniSpeed( SOLDIERTYPE *pSoldier ); + +void RecalculateSoldiersAniSpeed() +{ + UINT32 uiLoop; + SOLDIERTYPE *pSoldier; + +// if( gubSpeedUpAnimationFactor == 1 )return; + + for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) + { + pSoldier = MercSlots[ uiLoop ]; + + // if this merc is inactive, at base, on assignment, dead, unconscious + if (!pSoldier) + { + continue; // next merc + } + + SetSoldierAniSpeed( pSoldier ); + } + +} + + + extern void DecayPublicOpplist(INT8 bTeam); extern void VerifyAndDecayOpplist(SOLDIERTYPE *pSoldier); void EndInterrupt( BOOLEAN fMarkInterruptOccurred ); @@ -257,6 +287,8 @@ void EndTurn( UINT8 ubNextTeam ) { AddPossiblePendingEnemiesToBattle(); + AddPossiblePendingMilitiaToBattle(); + // InitEnemyUIBar( ); FreezeInterfaceForEnemyTurn(); @@ -430,6 +462,8 @@ void BeginTeamTurn( UINT8 ubTeam ) } + RecalculateSoldiersAniSpeed(); + if (ubTeam == gbPlayerNum ) { // ATE: Check if we are still in a valid battle... diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp index f46cd7a85..15910a5a8 100644 --- a/Tactical/Turn Based Input.cpp +++ b/Tactical/Turn Based Input.cpp @@ -225,7 +225,7 @@ void HandleStealthChangeFromUIKeys( ); UINT8 gubCheatLevel = STARTING_CHEAT_LEVEL; - +extern BOOLEAN CompatibleAmmoForGun( OBJECTTYPE *pTryObject, OBJECTTYPE *pTestObject ); extern void DetermineWhichAssignmentMenusCanBeShown( void ); extern void DetermineWhichMilitiaControlMenusCanBeShown( void ); //lal @@ -2995,10 +2995,73 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) HandleStanceChangeFromUIKeys( ANIM_PRONE ); break; + case 'R': + if (! (gTacticalStatus.uiFlags & INCOMBAT) ) + { + SOLDIERTYPE *pTeamSoldier; + INT8 bLoop; + OBJECTTYPE *pGun, *pAmmo; + + // Search for soldier + for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++) + { + if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) ) + { + + + // Search for gun + for (UINT32 bLoop2 = 0; bLoop2 < NUM_INV_SLOTS; bLoop2++) + { + if (Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass & IC_GUN || Item[pTeamSoldier->inv[bLoop2].usItem].usItemClass == IC_LAUNCHER) + { + pGun = &(pTeamSoldier->inv[bLoop2]); + //magazine is not full + if ( pGun->ubGunShotsLeft < GetMagSize( pGun ) ) + { + + // Search for ammo in sector + for ( UINT32 uiLoop = 0; uiLoop < guiNumWorldItems; uiLoop++ ) + { + if ( gWorldItems[ uiLoop ].fExists) + { + pAmmo = &( gWorldItems[ uiLoop ].o ); + + if ( CompatibleAmmoForGun( pAmmo, pGun ) ) + { + ReloadGun( pTeamSoldier, pGun, pAmmo ); + } + + if (pAmmo->ubShotsLeft[0] == 0) + { + RemoveItemFromPool( gWorldItems[ uiLoop ].sGridNo, uiLoop, gWorldItems[ uiLoop ].ubLevel ); + } + } + } + } + } + } + } + } + } + else + { + SOLDIERTYPE *pTeamSoldier; + INT8 bLoop; + + for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++) + { + if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) ) + { + AutoReload( pTeamSoldier ); + } + } + } + break; + + case 'r': if( gusSelectedSoldier != NO_SOLDIER ) { - if( fAlt ) //reload selected merc's weapon { if ( CHEATER_CHEAT_LEVEL( ) ) @@ -3015,24 +3078,27 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) } else { - if ( !MercInWater( MercPtrs[ gusSelectedSoldier ] ) && !(MercPtrs[ gusSelectedSoldier ]->uiStatusFlags & SOLDIER_ROBOT ) ) - { - //change selected merc to run - if ( MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != WALKING && MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != RUNNING ) - { - UIHandleSoldierStanceChange( (UINT8)gusSelectedSoldier, ANIM_STAND ); - MercPtrs[ gusSelectedSoldier ]->fUIMovementFast = 1; - } - else - { - MercPtrs[ gusSelectedSoldier ]->fUIMovementFast = 1; - MercPtrs[ gusSelectedSoldier ]->usUIMovementMode = RUNNING; - gfPlotNewMovement = TRUE; - } - } + if ( !MercInWater( MercPtrs[ gusSelectedSoldier ] ) && !(MercPtrs[ gusSelectedSoldier ]->uiStatusFlags & SOLDIER_ROBOT ) ) + { + //change selected merc to run + if ( MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != WALKING && MercPtrs[ gusSelectedSoldier ]->usUIMovementMode != RUNNING ) + { + UIHandleSoldierStanceChange( (UINT8)gusSelectedSoldier, ANIM_STAND ); + MercPtrs[ gusSelectedSoldier ]->fUIMovementFast = 1; + } + else + { + MercPtrs[ gusSelectedSoldier ]->fUIMovementFast = 1; + MercPtrs[ gusSelectedSoldier ]->usUIMovementMode = RUNNING; + gfPlotNewMovement = TRUE; + } + } } } break; + + + case 's': if( fCtrl ) @@ -3347,7 +3413,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) // nothing in hand and either not in SM panel, or the matching button is enabled if we are in SM panel if ( ( gpItemPointer == NULL ) ) { - HandleStealthChangeFromUIKeys( ); + HandleStealthChangeFromUIKeys( ); } } break; diff --git a/TacticalAI/AIMain.cpp b/TacticalAI/AIMain.cpp index cd5372441..7b30b8749 100644 --- a/TacticalAI/AIMain.cpp +++ b/TacticalAI/AIMain.cpp @@ -61,10 +61,10 @@ UINT8 gubAICounter; // lots of other stuff, I think // -extern UINT8 gubDeadLockDelay; +//extern UINT8 gubDeadLockDelay; //#define DEADLOCK_DELAY 10000 //Madd - let's see what this does -- orig: 15000 -#define DEADLOCK_DELAY ( gubDeadLockDelay * 1000 ) +#define DEADLOCK_DELAY ( gGameExternalOptions.gubDeadLockDelay * 1000 ) // Very representing if this computer is the host, therefore controlling the ai extern BYTE gfAmIHost; diff --git a/TileEngine/environment.cpp b/TileEngine/environment.cpp index 81007a62b..014587276 100644 --- a/TileEngine/environment.cpp +++ b/TileEngine/environment.cpp @@ -159,7 +159,7 @@ UINT8 gubDesertTemperature = 0; UINT8 gubGlobalTemperature = 0; //rain -extern BOOLEAN gfAllowRain; +//extern BOOLEAN gfAllowRain; //end rain // local prototypes @@ -370,7 +370,7 @@ void BuildDayAmbientSounds( ) //end rain } -extern UINT16 gusRainChancePerDay, gusRainMinLength, gusRainMaxLength; //rain +//extern UINT16 gusRainChancePerDay, gusRainMinLength, gusRainMaxLength; //rain void ForecastDayEvents( ) @@ -398,13 +398,13 @@ void ForecastDayEvents( ) if ( guiEnvDay > 1 ) { //rain - if ( Random( 100 ) < gusRainChancePerDay ) + if ( Random( 100 ) < gGameExternalOptions.gusRainChancePerDay ) { // Add rain! // Between 6:00 and 10:00 - uiStartTime = (UINT32)( Random( 1440 - 1 -gusRainMaxLength ) ); + uiStartTime = (UINT32)( Random( 1440 - 1 - gGameExternalOptions.gusRainMaxLength ) ); // Between 5 - 15 miniutes - uiEndTime = uiStartTime + ( gusRainMinLength + Random( gusRainMaxLength - gusRainMinLength ) ); + uiEndTime = uiStartTime + ( gGameExternalOptions.gusRainMinLength + Random( gGameExternalOptions.gusRainMaxLength - gGameExternalOptions.gusRainMinLength ) ); ubStormIntensity = 0; @@ -414,7 +414,7 @@ void ForecastDayEvents( ) ubStormIntensity = 1; } - if( gfAllowRain ) AddSameDayRangedStrategicEvent( EVENT_RAINSTORM, uiStartTime, uiEndTime - uiStartTime, ubStormIntensity ); + if( gGameExternalOptions.gfAllowRain ) AddSameDayRangedStrategicEvent( EVENT_RAINSTORM, uiStartTime, uiEndTime - uiStartTime, ubStormIntensity ); //AddSameDayStrategicEvent( EVENT_BEGINRAINSTORM, uiStartTime, ubStormIntensity ); //AddSameDayStrategicEvent( EVENT_ENDRAINSTORM, uiEndTime, 0 ); diff --git a/Utils/Sound Control.cpp b/Utils/Sound Control.cpp index 76b3e30fc..4572eaae1 100644 --- a/Utils/Sound Control.cpp +++ b/Utils/Sound Control.cpp @@ -19,7 +19,7 @@ UINT32 MIDVOLUME START_MIDVOLUME; UINT32 HIGHVOLUME START_HIGHVOLUME; */ -extern UINT32 guiWeaponSoundEffectsVolume; +//extern UINT32 guiWeaponSoundEffectsVolume; UINT32 guiSpeechVolume = MIDVOLUME; UINT32 guiSoundEffectsVolume = MIDVOLUME; @@ -453,7 +453,7 @@ UINT32 PlayJA2Sample( UINT32 usNum, UINT32 usRate, UINT32 ubVolume, UINT32 ubLoo } else { - spParms.uiVolume = (UINT32)( ( ubVolume / (FLOAT) HIGHVOLUME ) * guiSoundEffectsVolume +.5 ) * (1 + guiWeaponSoundEffectsVolume / 100); + spParms.uiVolume = (UINT32)( ( ubVolume / (FLOAT) HIGHVOLUME ) * guiSoundEffectsVolume +.5 ) * (1 + gGameExternalOptions.guiWeaponSoundEffectsVolume / 100); } spParms.uiVolume &= 0xFFL; @@ -474,6 +474,7 @@ UINT32 PlayJA2StreamingSample( UINT32 usNum, UINT32 usRate, UINT32 ubVolume, UIN memset(&spParms, 0xff, sizeof(SOUNDPARMS)); spParms.uiSpeed = usRate; + spParms.uiVolume = CalculateSoundEffectsVolume( ubVolume ); spParms.uiLoop = ubLoops; spParms.uiPan = uiPan; @@ -500,7 +501,7 @@ UINT32 PlayJA2SampleFromFile( STR8 szFileName, UINT32 usRate, UINT32 ubVolume, U } else { - spParms.uiVolume = (UINT32)( ( ubVolume / (FLOAT) HIGHVOLUME ) * guiSoundEffectsVolume +.5 ) * (1 + guiWeaponSoundEffectsVolume / 100); + spParms.uiVolume = (UINT32)( ( ubVolume / (FLOAT) HIGHVOLUME ) * guiSoundEffectsVolume +.5 ) * (1 + gGameExternalOptions.guiWeaponSoundEffectsVolume / 100); } spParms.uiLoop = ubLoops; @@ -512,7 +513,6 @@ UINT32 PlayJA2SampleFromFile( STR8 szFileName, UINT32 usRate, UINT32 ubVolume, U return(SoundPlay((STR) szFileName, &spParms)); } - UINT32 PlayJA2StreamingSampleFromFile( STR8 szFileName, UINT32 usRate, UINT32 ubVolume, UINT32 ubLoops, UINT32 uiPan, SOUND_STOP_CALLBACK EndsCallback ) { diff --git a/Utils/Text.h b/Utils/Text.h index 4586254cc..723bb5f61 100644 --- a/Utils/Text.h +++ b/Utils/Text.h @@ -158,6 +158,8 @@ extern STR16 wMapScreenSortButtonHelpText[]; extern STR16 pNewNoiseStr[]; extern STR16 gzLateLocalizedString[]; +extern STR16 gzCWStrings[]; + enum { ANTIHACKERSTR_EXITGAME, diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp index 0cb886ea5..8d5bff468 100644 --- a/Utils/_EnglishText.cpp +++ b/Utils/_EnglishText.cpp @@ -3468,8 +3468,10 @@ STR16 zOptionsScreenHelpText[] = L"When ON, the movement cursor is shown in 3D. ( |Home )", + // Options for 1.13 L"When ON, the the chance to hit is shown on the cursor.", - + L"GL Burst, i dont know what is it :(", + L"Enemy drop all items, when he is dead.", }; @@ -4044,7 +4046,10 @@ STR16 gzLateLocalizedString[] = L"%s fires %d more rounds than intended!" }; +STR16 gzCWStrings[] = +{ + L"Call reinforcements from adjacent sectors?", +}; - -#endif //ENGLISH +#endif //ENGLISH \ No newline at end of file diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index 66ab8c990..76c0972f7 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -3270,7 +3270,11 @@ STR16 zOptionsScreenHelpText[] = L"ANgeschaltet, werden Drahtgitter für verborgene Wände gezeigt (|W).", L"ANgeschaltet, wird der Bewegungs-Cursor in 3D angezeigt. ( |Home )", - + + // Options for 1.13 + L"Die Trefferchance wird beim Cursor angezeigt", + L"GL Burst, was auch immer das bedeutet :(", + L"Gegner lassen bei ihrem Ableben alle Gegenstände zurück.", }; STR16 gzGIOScreenText[] = @@ -3294,11 +3298,11 @@ STR16 gzGIOScreenText[] = L"Ohne Zeitlimit", L"Mit Zeitlimit", L"Option nicht verfügbar", - L"Bobby Ray's Selection", - L"Good", - L"Great", - L"Excellent", - L"Awesome", + L"Bobby Ray's Auswahl", + L"Normal", + L"Groß", + L"Ausgezeichnet", + L"Fantastisch", }; STR16 pDeliveryLocationStrings[] = @@ -3828,4 +3832,9 @@ STR16 gzLateLocalizedString[] = }; +STR16 gzCWStrings[] = +{ + L"Verstärkung von anliegenden Sektoren anfordern?", +}; + #endif //GERMAN diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index 4273e45de..f82d2f2a3 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -4011,6 +4011,10 @@ STR16 gzLateLocalizedString[] = L"Âûêëþ÷àòåëü íàæàò.", }; +STR16 gzCWStrings[] = +{ + L"Íóæíà ëè ïîääåðæêà îïîë÷åíèÿ èç ñîñåäíèõ ñåêòîðîâ?", +};