mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
- Made the "Zombie MOD" optional, so we can decide if we like to build an executable with/without the appearance of zombies
o See: builddefines.h: #define ENABLE_ZOMBIES (then you can turn on/off Zombies in the ingame option screen) o Poison system is still in the code and not combined with the option "Zombie MOD" o Gamers reported on the Bears Pit, that an executable compiled WITH the Zombies mod enabled makes the game unplayable slow in tactical screen after a few minutes in turn based/realtime git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5356 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
+9
-1
@@ -254,7 +254,9 @@ BOOLEAN LoadGameSettings()
|
||||
gGameSettings.fOptions[TOPTION_AUTO_FAST_FORWARD_MODE] = FALSE;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
gGameSettings.fOptions[TOPTION_ZOMBIES] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_ZOMBIES" , FALSE );
|
||||
#endif
|
||||
|
||||
gGameSettings.fOptions[NUM_ALL_GAME_OPTIONS] = iniReader.ReadBoolean("JA2 Game Settings","NUM_ALL_GAME_OPTIONS" , FALSE );
|
||||
|
||||
@@ -417,7 +419,10 @@ BOOLEAN SaveGameSettings()
|
||||
settings << "TOPTION_AUTO_FAST_FORWARD_MODE = " << (gGameSettings.fOptions[TOPTION_AUTO_FAST_FORWARD_MODE] ? "TRUE" : "FALSE" ) << endl;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
settings << "TOPTION_ZOMBIES = " << (gGameSettings.fOptions[TOPTION_ZOMBIES] ? "TRUE" : "FALSE" ) << endl;
|
||||
#endif
|
||||
|
||||
settings << "TOPTION_CHEAT_MODE_OPTIONS_HEADER = " << (gGameSettings.fOptions[TOPTION_CHEAT_MODE_OPTIONS_HEADER] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_FORCE_BOBBY_RAY_SHIPMENTS = " << (gGameSettings.fOptions[TOPTION_FORCE_BOBBY_RAY_SHIPMENTS] ? "TRUE" : "FALSE" ) << endl;
|
||||
settings << "TOPTION_CHEAT_MODE_OPTIONS_END = " << (gGameSettings.fOptions[TOPTION_CHEAT_MODE_OPTIONS_END] ? "TRUE" : "FALSE" ) << endl;
|
||||
@@ -549,8 +554,9 @@ void InitGameSettings()
|
||||
gGameSettings.fOptions[ TOPTION_AUTO_FAST_FORWARD_MODE ] = FALSE;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
gGameSettings.fOptions[ TOPTION_ZOMBIES ] = FALSE; // Flugente Zombies 1.0
|
||||
|
||||
#endif
|
||||
|
||||
// arynn: Cheat/Debug Menu
|
||||
gGameSettings.fOptions[ TOPTION_CHEAT_MODE_OPTIONS_HEADER ] = FALSE;
|
||||
@@ -1357,6 +1363,7 @@ void LoadGameExternalOptions()
|
||||
gGameExternalOptions.iCooldownModificatorLonelyBarrel = iniReader.ReadFloat ("Tactical Weapon Overheating Settings","OVERHEATING_COOLDOWN_MODIFICATOR_LONELYBARREL", 1.15f, 1.0f, 10.0f);
|
||||
gGameExternalOptions.fSetZeroUponNewSector = iniReader.ReadBoolean("Tactical Weapon Overheating Settings","OVERHEATING_SET_ZERO_UPON_NEW_SECTOR",TRUE);
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
//################# Tactical Zombie Settings ##################
|
||||
gGameExternalOptions.sZombieRiseBehaviour = iniReader.ReadInteger("Tactical Zombie Settings", "ZOMBIE_RISE_BEHAVIOUR", 0, 0, 3);
|
||||
gGameExternalOptions.fZombieSpawnWaves = iniReader.ReadInteger("Tactical Zombie Settings", "ZOMBIE_SPAWN_WAVES", FALSE);
|
||||
@@ -1368,6 +1375,7 @@ void LoadGameExternalOptions()
|
||||
gGameExternalOptions.fZombieOnlyHeadshotsWork = iniReader.ReadBoolean("Tactical Zombie Settings", "ZOMBIE_ONLY_HEADSHOTS_WORK", FALSE);
|
||||
gGameExternalOptions.sZombieDifficultyLevel = iniReader.ReadInteger("Tactical Zombie Settings", "ZOMBIE_DIFFICULTY_LEVEL", 2, 1, 4);
|
||||
gGameExternalOptions.fZombieRiseWithArmour = iniReader.ReadBoolean("Tactical Zombie Settings", "ZOMBIE_RISE_WITH_ARMOUR", TRUE);
|
||||
#endif
|
||||
|
||||
//################# Tactical Poison Settings ##################
|
||||
gGameExternalOptions.ubPoisonBaseMedicalSkillToCure = iniReader.ReadInteger("Tactical Poison Settings", "POISON_BASE_MEDICAL_SKILL_TO_CURE", 50, 1, 100);
|
||||
|
||||
@@ -95,7 +95,9 @@ enum
|
||||
TOPTION_AUTO_FAST_FORWARD_MODE, // automatically fast forward through AI turns
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
TOPTION_ZOMBIES, // Flugente Zombies 1.0: allow zombies
|
||||
#endif
|
||||
|
||||
// arynn: Debug/Cheat
|
||||
TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
@@ -369,6 +371,7 @@ typedef struct
|
||||
//Video settings
|
||||
BOOLEAN gfVSync;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: zombie settings
|
||||
INT8 sZombieRiseBehaviour;
|
||||
BOOLEAN fZombieSpawnWaves;
|
||||
@@ -380,6 +383,7 @@ typedef struct
|
||||
BOOLEAN fZombieOnlyHeadshotsWork;
|
||||
INT8 sZombieDifficultyLevel;
|
||||
BOOLEAN fZombieRiseWithArmour;
|
||||
#endif
|
||||
|
||||
// Flugente: poison settings
|
||||
INT32 ubPoisonBaseMedicalSkillToCure;
|
||||
|
||||
@@ -4959,7 +4959,12 @@ void DisplayDepartedCharStats(INT32 iId, INT32 iSlot, INT32 iState)
|
||||
case 14:
|
||||
// kills
|
||||
mprintf((INT16)(pPersonnelScreenPoints[20].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[20].y - 12),pPersonnelScreenStrings[PRSNL_TXT_KILLS]);
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
swprintf(sString, L"%d",(gMercProfiles[iId].records.usKillsElites + gMercProfiles[iId].records.usKillsRegulars + gMercProfiles[iId].records.usKillsAdmins + gMercProfiles[iId].records.usKillsHostiles + gMercProfiles[iId].records.usKillsCreatures + gMercProfiles[iId].records.usKillsZombies + gMercProfiles[iId].records.usKillsTanks + gMercProfiles[iId].records.usKillsOthers));
|
||||
#else
|
||||
swprintf(sString, L"%d",(gMercProfiles[iId].records.usKillsElites + gMercProfiles[iId].records.usKillsRegulars + gMercProfiles[iId].records.usKillsAdmins + gMercProfiles[iId].records.usKillsHostiles + gMercProfiles[iId].records.usKillsCreatures + gMercProfiles[iId].records.usKillsTanks + gMercProfiles[iId].records.usKillsOthers));
|
||||
#endif
|
||||
FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[20].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
|
||||
mprintf(sX,(pPersonnelScreenPoints[20].y - 12),sString);
|
||||
|
||||
@@ -6828,7 +6833,12 @@ DEF:3/19/99:
|
||||
case 14:
|
||||
// kills
|
||||
mprintf((INT16)(pPersonnelScreenPoints[20].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[20].y - 12),pPersonnelScreenStrings[PRSNL_TXT_KILLS]);
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
swprintf(sString, L"%d",(gMercProfiles[Menptr[iId].ubProfile].records.usKillsElites + gMercProfiles[Menptr[iId].ubProfile].records.usKillsRegulars + gMercProfiles[Menptr[iId].ubProfile].records.usKillsAdmins + gMercProfiles[Menptr[iId].ubProfile].records.usKillsHostiles + gMercProfiles[Menptr[iId].ubProfile].records.usKillsCreatures + gMercProfiles[Menptr[iId].ubProfile].records.usKillsZombies + gMercProfiles[Menptr[iId].ubProfile].records.usKillsTanks + gMercProfiles[Menptr[iId].ubProfile].records.usKillsOthers));
|
||||
#else
|
||||
swprintf(sString, L"%d",(gMercProfiles[Menptr[iId].ubProfile].records.usKillsElites + gMercProfiles[Menptr[iId].ubProfile].records.usKillsRegulars + gMercProfiles[Menptr[iId].ubProfile].records.usKillsAdmins + gMercProfiles[Menptr[iId].ubProfile].records.usKillsHostiles + gMercProfiles[Menptr[iId].ubProfile].records.usKillsCreatures + gMercProfiles[Menptr[iId].ubProfile].records.usKillsTanks + gMercProfiles[Menptr[iId].ubProfile].records.usKillsOthers));
|
||||
#endif
|
||||
FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[20].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
|
||||
mprintf(sX,(pPersonnelScreenPoints[20].y - 12),sString);
|
||||
|
||||
@@ -8239,6 +8249,8 @@ void AssignPersonnelKillsHelpText( INT32 IMercId )
|
||||
swprintf(atStr, pPersonnelRecordsHelpTexts[ 6 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsOthers );
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if (gGameSettings.fOptions[TOPTION_ZOMBIES] )
|
||||
{
|
||||
if (gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsZombies > 0 || fShowRecordsIfZero)
|
||||
@@ -8247,6 +8259,7 @@ void AssignPersonnelKillsHelpText( INT32 IMercId )
|
||||
wcscat( apStr, atStr );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set region help text
|
||||
SetRegionFastHelpText( &(gSkillTraitHelpTextRegion[7]), apStr );
|
||||
|
||||
Binary file not shown.
@@ -4598,9 +4598,11 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
|
||||
case SOLDIER_CLASS_CREATURE :
|
||||
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsCreatures++;
|
||||
break;
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
case SOLDIER_CLASS_ZOMBIE :
|
||||
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsZombies++;
|
||||
break;
|
||||
#endif
|
||||
default :
|
||||
if ( CREATURE_OR_BLOODCAT( pTarget->pSoldier ) )
|
||||
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsCreatures++;
|
||||
@@ -4789,9 +4791,11 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index )
|
||||
case SOLDIER_CLASS_CREATURE :
|
||||
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsCreatures++;
|
||||
break;
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
case SOLDIER_CLASS_ZOMBIE :
|
||||
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsZombies++;
|
||||
break;
|
||||
#endif
|
||||
default :
|
||||
if ( CREATURE_OR_BLOODCAT( pTarget->pSoldier ) )
|
||||
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsCreatures++;
|
||||
|
||||
@@ -820,7 +820,10 @@ void EndMeanwhile( )
|
||||
{
|
||||
// We leave this sector open for our POWs to escape!
|
||||
// Set music mode to enemy present!
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
UseCreatureMusic(HostileZombiesPresent());
|
||||
#endif
|
||||
|
||||
SetMusicMode( MUSIC_TACTICAL_ENEMYPRESENT );
|
||||
|
||||
// ATE: Restore people to saved positions...
|
||||
|
||||
@@ -867,7 +867,10 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
|
||||
//Disable the options button when the auto resolve screen comes up
|
||||
EnableDisAbleMapScreenOptionsButton( FALSE );
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
UseCreatureMusic(HostileZombiesPresent());
|
||||
#endif
|
||||
|
||||
SetMusicMode( MUSIC_TACTICAL_ENEMYPRESENT );
|
||||
|
||||
#ifdef JA2UB
|
||||
|
||||
@@ -959,7 +959,10 @@ void PrepareForPreBattleInterface( GROUP *pPlayerDialogGroup, GROUP *pInitiating
|
||||
}
|
||||
|
||||
//Set music
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
UseCreatureMusic(HostileZombiesPresent());
|
||||
#endif
|
||||
|
||||
SetMusicMode( MUSIC_TACTICAL_ENEMYPRESENT );
|
||||
|
||||
if( gfTacticalTraversal && pInitiatingBattleGroup == gpTacticalTraversalGroup ||
|
||||
|
||||
@@ -1035,9 +1035,11 @@ void StartEnemyTaunt( SOLDIERTYPE *pCiv, INT8 iTauntType )
|
||||
VIDEO_OVERLAY_DESC VideoOverlayDesc;
|
||||
CHAR16 gzTauntQuote[ 320 ];
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: zombies don't talk
|
||||
if ( pCiv->IsZombie() )
|
||||
return;
|
||||
#endif
|
||||
|
||||
// if we have a different quote on, return, this one is not important
|
||||
if ( gCivQuoteData.bActive )
|
||||
|
||||
@@ -1926,13 +1926,8 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
|
||||
}
|
||||
}
|
||||
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] ) // Flugente Zombies
|
||||
{
|
||||
//////////////////// POISON PERCENTAGE
|
||||
{
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 4 ] );
|
||||
}
|
||||
}
|
||||
//////////////////// POISON PERCENTAGE
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 4 ] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3864,10 +3859,11 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//#ifdef ENABLE_ZOMBIES
|
||||
// Flugente Zombies
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] )
|
||||
{
|
||||
//if ( gGameSettings.fOptions[TOPTION_ZOMBIES] )
|
||||
//{
|
||||
if(!cnt) cnt += 2;
|
||||
|
||||
if (cnt >= sFirstLine && cnt < sLastLine)
|
||||
@@ -3908,7 +3904,8 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
//}
|
||||
//#endif
|
||||
|
||||
gubDescBoxTotalAdvLines = (UINT8)cnt;
|
||||
}
|
||||
@@ -4304,13 +4301,15 @@ void DrawAmmoStats( OBJECTTYPE * gpItemDescObject )
|
||||
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 16, gItemDescGenRegions[3][0].sLeft+sOffsetX, gItemDescGenRegions[3][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
}
|
||||
}
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] ) // Flugente Zombies
|
||||
{
|
||||
//#ifdef ENABLE_ZOMBIES
|
||||
//if ( gGameSettings.fOptions[TOPTION_ZOMBIES] ) // Flugente Zombies
|
||||
//{
|
||||
//////////////// POISON PERCENTAGE
|
||||
{
|
||||
//{
|
||||
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWH40KIcon, 6, gItemDescGenRegions[4][0].sLeft+sOffsetX, gItemDescGenRegions[4][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
}
|
||||
}
|
||||
//}
|
||||
//}
|
||||
//#endif
|
||||
|
||||
DrawSecondaryStats( gpItemDescObject );
|
||||
}
|
||||
@@ -5198,9 +5197,10 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject )
|
||||
}
|
||||
}
|
||||
|
||||
//#ifdef ENABLE_ZOMBIES
|
||||
// Flugente Zombies
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] )
|
||||
{
|
||||
// if ( gGameSettings.fOptions[TOPTION_ZOMBIES] )
|
||||
// {
|
||||
if(!cnt) cnt += 2;
|
||||
|
||||
++cnt; // for the new index-line
|
||||
@@ -5215,7 +5215,8 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject )
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
//}
|
||||
//#endif
|
||||
}
|
||||
|
||||
void DrawMiscStats( OBJECTTYPE * gpItemDescObject )
|
||||
@@ -7597,8 +7598,9 @@ void DrawAmmoValues( OBJECTTYPE * gpItemDescObject, int shotsLeft )
|
||||
mprintf( usX, usY, pStr );
|
||||
}
|
||||
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] ) // Flugente Zombies
|
||||
{
|
||||
//#ifdef ENABLE_ZOMBIES
|
||||
// if ( gGameSettings.fOptions[TOPTION_ZOMBIES] ) // Flugente Zombies
|
||||
// {
|
||||
///////////////////// POISON PERCENTAGE
|
||||
// Set line to draw into
|
||||
ubNumLine = 4;
|
||||
@@ -7648,7 +7650,8 @@ void DrawAmmoValues( OBJECTTYPE * gpItemDescObject, int shotsLeft )
|
||||
swprintf( pStr, L"%d", finalvalue );
|
||||
FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
|
||||
mprintf( usX, usY, pStr );
|
||||
}
|
||||
// }
|
||||
//#endif
|
||||
}
|
||||
else if (gubDescBoxPage == 2)
|
||||
{
|
||||
@@ -11170,8 +11173,9 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
|
||||
}
|
||||
|
||||
// Flugente Zombies
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] )
|
||||
{
|
||||
//#ifdef USE_ZOMBIES
|
||||
// if ( gGameSettings.fOptions[TOPTION_ZOMBIES] )
|
||||
//{
|
||||
///////////////////////////////////////////////////// INDEXES
|
||||
if(!cnt) cnt += 2;
|
||||
|
||||
@@ -11252,7 +11256,8 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
//}
|
||||
//#endif
|
||||
}
|
||||
|
||||
void DrawMiscValues( OBJECTTYPE * gpItemDescObject )
|
||||
|
||||
@@ -2211,6 +2211,7 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( pSoldier->IsZombie() )
|
||||
{
|
||||
swprintf(NameStr, pSoldier->name);
|
||||
@@ -2225,6 +2226,7 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
|
||||
gprintfdirty( sX, sY, NameStr );
|
||||
mprintf( sX, sY, NameStr );
|
||||
}
|
||||
#endif
|
||||
//------------
|
||||
}
|
||||
}
|
||||
|
||||
@@ -847,9 +847,11 @@ void GenerateRandomEquipment( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass, INT8
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
case SOLDIER_CLASS_ZOMBIE:
|
||||
// zombies get no items at all...
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
for ( i = 0; i < pp->Inv.size(); i++ )
|
||||
@@ -1056,8 +1058,11 @@ void ChooseWeaponForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bWeaponC
|
||||
bStatus += (INT8)(HighestPlayerProgressPercentage() / 10);
|
||||
bStatus = (INT8)min( 100, bStatus );
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
case SOLDIER_CLASS_ZOMBIE:
|
||||
bStatus = (INT8)(1); // if a zombie gets anything, it'll be broken
|
||||
#endif
|
||||
default:
|
||||
bStatus = (INT8)(50 + Random( 51 ) );
|
||||
break;
|
||||
@@ -2111,8 +2116,11 @@ void ChooseFaceGearForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp )
|
||||
break;
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_GREEN_MILITIA:
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
case SOLDIER_CLASS_ZOMBIE:
|
||||
#endif
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -907,8 +907,12 @@ void HandleFirstHeliDropOfGame( )
|
||||
{
|
||||
// Say quote.....
|
||||
SayQuoteFromAnyBodyInSector( QUOTE_ENEMY_PRESENCE );
|
||||
|
||||
// Start music
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
UseCreatureMusic(HostileZombiesPresent());
|
||||
#endif
|
||||
|
||||
SetMusicMode( MUSIC_TACTICAL_ENEMYPRESENT );
|
||||
}
|
||||
else
|
||||
|
||||
+50
-32
@@ -6186,7 +6186,10 @@ void ExitCombatMode( )
|
||||
// unused
|
||||
//gfForceMusicToTense = TRUE;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
UseCreatureMusic(HostileZombiesPresent());
|
||||
#endif
|
||||
|
||||
SetMusicMode( MUSIC_TACTICAL_ENEMYPRESENT );
|
||||
|
||||
BetweenTurnsVisibilityAdjustments();
|
||||
@@ -6245,7 +6248,11 @@ void SetEnemyPresence( )
|
||||
|
||||
#endif
|
||||
{
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
UseCreatureMusic(HostileZombiesPresent());
|
||||
#endif
|
||||
|
||||
SetMusicMode( MUSIC_TACTICAL_ENEMYPRESENT );
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("SetEnemyPresence: warnings = false"));
|
||||
sniperwarning = FALSE;
|
||||
@@ -6583,7 +6590,10 @@ BOOLEAN CheckForEndOfCombatMode( BOOLEAN fIncrementTurnsNotSeen )
|
||||
// Begin tense music....
|
||||
// unused
|
||||
//gfForceMusicToTense = TRUE;
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
UseCreatureMusic(HostileZombiesPresent());
|
||||
#endif
|
||||
|
||||
SetMusicMode( MUSIC_TACTICAL_ENEMYPRESENT );
|
||||
|
||||
return( TRUE );
|
||||
@@ -6682,8 +6692,10 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated )
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( HostileZombiesPresent() ) //Madd: got tired of the victory music playing right after the zombies arose
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
// OK, this is to releave infinate looping...becasue we can kill guys in this function
|
||||
if ( gfKillingGuysForLosingBattle )
|
||||
@@ -7267,25 +7279,27 @@ UINT8 NumEnemyInSector( )
|
||||
|
||||
}
|
||||
|
||||
UINT8 NumZombiesInSector( )
|
||||
{
|
||||
SOLDIERTYPE *pTeamSoldier;
|
||||
INT32 cnt = 0;
|
||||
UINT8 ubNumZombies = 0;
|
||||
|
||||
for ( pTeamSoldier = Menptr, cnt = 0; cnt < TOTAL_SOLDIERS; ++pTeamSoldier, ++cnt )
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
UINT8 NumZombiesInSector( )
|
||||
{
|
||||
if ( pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->stats.bLife > 0 )
|
||||
SOLDIERTYPE *pTeamSoldier;
|
||||
INT32 cnt = 0;
|
||||
UINT8 ubNumZombies = 0;
|
||||
|
||||
for ( pTeamSoldier = Menptr, cnt = 0; cnt < TOTAL_SOLDIERS; ++pTeamSoldier, ++cnt )
|
||||
{
|
||||
if ( pTeamSoldier->IsZombie() )
|
||||
if ( pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->stats.bLife > 0 )
|
||||
{
|
||||
++ubNumZombies;
|
||||
if ( pTeamSoldier->IsZombie() )
|
||||
{
|
||||
++ubNumZombies;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return( ubNumZombies );
|
||||
}
|
||||
return( ubNumZombies );
|
||||
}
|
||||
#endif
|
||||
|
||||
UINT8 NumEnemyInSectorExceptCreatures()
|
||||
{
|
||||
@@ -7799,9 +7813,11 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker )
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("HandleSuppressionFire: loop = %d, numslots = %d ",uiLoop, guiNumMercSlots));
|
||||
pSoldier = MercSlots[uiLoop];
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: zombies do not receive any suppression at all!
|
||||
if ( pSoldier != NULL && pSoldier->IsZombie() )
|
||||
continue;
|
||||
#endif
|
||||
|
||||
// Has this character received any Suppression Points since the last attack?
|
||||
// HEADROCK: Suppression Points accumulate by bullets flying near the character. It includes
|
||||
@@ -9286,28 +9302,30 @@ BOOLEAN HostileBloodcatsPresent( void )
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
BOOLEAN HostileZombiesPresent( void )
|
||||
{
|
||||
INT32 iLoop;
|
||||
SOLDIERTYPE * pSoldier;
|
||||
|
||||
if ( gTacticalStatus.Team[ CREATURE_TEAM ].bTeamActive == FALSE )
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
BOOLEAN HostileZombiesPresent( void )
|
||||
{
|
||||
INT32 iLoop;
|
||||
SOLDIERTYPE * pSoldier;
|
||||
|
||||
if ( gTacticalStatus.Team[ CREATURE_TEAM ].bTeamActive == FALSE )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
for ( iLoop = gTacticalStatus.Team[ CREATURE_TEAM ].bFirstID; iLoop <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID; iLoop++ )
|
||||
{
|
||||
pSoldier = MercPtrs[ iLoop ];
|
||||
|
||||
if ( pSoldier->bActive && pSoldier->bInSector && pSoldier->stats.bLife > 0 && pSoldier->IsZombie() )
|
||||
{
|
||||
return( TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
for ( iLoop = gTacticalStatus.Team[ CREATURE_TEAM ].bFirstID; iLoop <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID; iLoop++ )
|
||||
{
|
||||
pSoldier = MercPtrs[ iLoop ];
|
||||
|
||||
if ( pSoldier->bActive && pSoldier->bInSector && pSoldier->stats.bLife > 0 && pSoldier->IsZombie() )
|
||||
{
|
||||
return( TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
return( FALSE );
|
||||
}
|
||||
#endif
|
||||
|
||||
void HandleCreatureTenseQuote( )
|
||||
{
|
||||
|
||||
+9
-3
@@ -362,7 +362,10 @@ void DoPOWPathChecks( void );
|
||||
BOOLEAN HostileCiviliansWithGunsPresent( void );
|
||||
BOOLEAN HostileCiviliansPresent( void );
|
||||
BOOLEAN HostileBloodcatsPresent( void );
|
||||
BOOLEAN HostileZombiesPresent( void );
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
BOOLEAN HostileZombiesPresent( void );
|
||||
#endif
|
||||
|
||||
UINT8 NumPCsInSector( void );
|
||||
|
||||
@@ -396,6 +399,9 @@ BOOLEAN WillAirRaidBeStopped( INT16 sSectorX, INT16 sSectorY );
|
||||
// HEADROCK HAM 3.5: Externalized for First Arrival enemy check
|
||||
extern UINT8 NumEnemyInSector();
|
||||
|
||||
// Flugente
|
||||
extern UINT8 NumZombiesInSector();
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente
|
||||
extern UINT8 NumZombiesInSector();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+395
-383
@@ -44,8 +44,7 @@
|
||||
#include "qarray.h"
|
||||
#include "Interface.h"
|
||||
#include "Music Control.h"
|
||||
#include "Campaign Types.h"
|
||||
//#include "Queen Command.h"
|
||||
#include "Campaign Types.h"
|
||||
#include "text.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
@@ -584,9 +583,11 @@ INT32 AddRottingCorpse( ROTTING_CORPSE_DEFINITION *pCorpseDef )
|
||||
pCorpse->pAniTile->uiUserData = iIndex;
|
||||
pCorpse->iID = iIndex;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// copy name of corpse definition...
|
||||
memcpy( &(pCorpse->name), &(pCorpseDef->name), sizeof(CHAR16) * 10 );
|
||||
pCorpse->name[9] = '\0';
|
||||
#endif
|
||||
|
||||
pCorpse->fActivated = TRUE;
|
||||
|
||||
@@ -861,6 +862,7 @@ BOOLEAN TurnSoldierIntoCorpse( SOLDIERTYPE *pSoldier, BOOLEAN fRemoveMerc, BOOLE
|
||||
Corpse.usFlags |= ROTTING_CORPSE_USE_SNOW_CAMO_PALETTE;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente Zombies: Determine if a zombie can rise from this corpse
|
||||
switch ( gGameExternalOptions.sZombieRiseBehaviour )
|
||||
{
|
||||
@@ -891,6 +893,7 @@ BOOLEAN TurnSoldierIntoCorpse( SOLDIERTYPE *pSoldier, BOOLEAN fRemoveMerc, BOOLE
|
||||
// Flugente: copy name of soldier...
|
||||
memcpy( &(Corpse.name), &(pSoldier->name), sizeof(CHAR16) * 10 );
|
||||
Corpse.name[9] = '\0';
|
||||
#endif
|
||||
|
||||
// Determine corpse type!
|
||||
ubType = (UINT8)gubAnimSurfaceCorpseID[ pSoldier->ubBodyType][ pSoldier->usAnimState ];
|
||||
@@ -2085,436 +2088,445 @@ UINT8 GetNearestRottingCorpseAIWarning( INT32 sGridNo )
|
||||
return( ubHighestWarning );
|
||||
}
|
||||
|
||||
// Flugente Zombies: resurrect zombies
|
||||
void RaiseZombies( void )
|
||||
{
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] )
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente Zombies: resurrect zombies
|
||||
void RaiseZombies( void )
|
||||
{
|
||||
// if gGameExternalOptions.fZombieSpawnWaves is true, zombies will spawn from all corpses (while there is still room for more), creating a wave of zombies. with lots of bodies lying around, this can be a lot.
|
||||
// if GameExternalOptions.fZombieSpawnWaves is false, each zombie can spawn randomly, you will get zombies on msot turns, but they won't spawn a whole horde at once
|
||||
if ( ( gGameExternalOptions.fZombieSpawnWaves && (INT8) ( Random( 100 ) ) > 100 - gGameExternalOptions.sZombieRiseWaveFrequency ) || !gGameExternalOptions.fZombieSpawnWaves )
|
||||
if ( gGameSettings.fOptions[TOPTION_ZOMBIES] )
|
||||
{
|
||||
ROTTING_CORPSE * pCorpse;
|
||||
BOOLEAN zombieshaverisen = FALSE;
|
||||
|
||||
SECTORINFO *pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ];
|
||||
|
||||
for ( INT32 cnt = giNumRottingCorpse - 1; cnt >= 0; --cnt )
|
||||
// if gGameExternalOptions.fZombieSpawnWaves is true, zombies will spawn from all corpses (while there is still room for more), creating a wave of zombies. with lots of bodies lying around, this can be a lot.
|
||||
// if GameExternalOptions.fZombieSpawnWaves is false, each zombie can spawn randomly, you will get zombies on msot turns, but they won't spawn a whole horde at once
|
||||
if ( ( gGameExternalOptions.fZombieSpawnWaves && (INT8) ( Random( 100 ) ) > 100 - gGameExternalOptions.sZombieRiseWaveFrequency ) || !gGameExternalOptions.fZombieSpawnWaves )
|
||||
{
|
||||
if ( pSector->ubNumCreatures < gGameExternalOptions.ubGameMaximumNumberOfCreatures ) // ... if there is still room for more zombies (zombies count as creatures until a separate ZOMBIE_TEAM is implemented)...
|
||||
ROTTING_CORPSE * pCorpse;
|
||||
BOOLEAN zombieshaverisen = FALSE;
|
||||
|
||||
SECTORINFO *pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ];
|
||||
|
||||
for ( INT32 cnt = giNumRottingCorpse - 1; cnt >= 0; --cnt )
|
||||
{
|
||||
pCorpse = &(gRottingCorpse[ cnt ] );
|
||||
|
||||
// if zombies should spawn individually, roll for every corpse individually
|
||||
if ( gGameExternalOptions.fZombieSpawnWaves || ( !gGameExternalOptions.fZombieSpawnWaves && (INT8) ( Random( 100 ) ) > 100 - gGameExternalOptions.sZombieRiseWaveFrequency ) )
|
||||
if ( pSector->ubNumCreatures < gGameExternalOptions.ubGameMaximumNumberOfCreatures ) // ... if there is still room for more zombies (zombies count as creatures until a separate ZOMBIE_TEAM is implemented)...
|
||||
{
|
||||
if ( pCorpse->fActivated && pCorpse->def.fHeadTaken == FALSE ) // ... if corpse is active, and still has a head ...
|
||||
pCorpse = &(gRottingCorpse[ cnt ] );
|
||||
|
||||
// if zombies should spawn individually, roll for every corpse individually
|
||||
if ( gGameExternalOptions.fZombieSpawnWaves || ( !gGameExternalOptions.fZombieSpawnWaves && (INT8) ( Random( 100 ) ) > 100 - gGameExternalOptions.sZombieRiseWaveFrequency ) )
|
||||
{
|
||||
if ( !(pCorpse->def.usFlags & ROTTING_CORPSE_NEVER_RISE_AGAIN) ) // ... if corpse is already that of a zombie, don't create zombie again ...
|
||||
if ( pCorpse->fActivated && pCorpse->def.fHeadTaken == FALSE ) // ... if corpse is active, and still has a head ...
|
||||
{
|
||||
if ( !TileIsOutOfBounds(pCorpse->def.sGridNo) ) // ... if corpse is on existing coordinates ...
|
||||
{
|
||||
if ( WhoIsThere2( pCorpse->def.sGridNo, pCorpse->def.bLevel ) == NOBODY ) // ... if nobody else is on that position ...
|
||||
{
|
||||
UINT16 recanimstate = STANDING;
|
||||
if ( !(pCorpse->def.usFlags & ROTTING_CORPSE_NEVER_RISE_AGAIN) ) // ... if corpse is already that of a zombie, don't create zombie again ...
|
||||
{
|
||||
if ( !TileIsOutOfBounds(pCorpse->def.sGridNo) ) // ... if corpse is on existing coordinates ...
|
||||
{
|
||||
if ( WhoIsThere2( pCorpse->def.sGridNo, pCorpse->def.bLevel ) == NOBODY ) // ... if nobody else is on that position ...
|
||||
{
|
||||
UINT16 recanimstate = STANDING;
|
||||
|
||||
if ( CorpseOkToSpawnZombie( pCorpse, &recanimstate ) ) // ... a zombie can be created from this corpse, in the corresponding animstate ...
|
||||
{
|
||||
zombieshaverisen = TRUE;
|
||||
CreateZombiefromCorpse( pCorpse, recanimstate );
|
||||
if ( CorpseOkToSpawnZombie( pCorpse, &recanimstate ) ) // ... a zombie can be created from this corpse, in the corresponding animstate ...
|
||||
{
|
||||
zombieshaverisen = TRUE;
|
||||
CreateZombiefromCorpse( pCorpse, recanimstate );
|
||||
|
||||
//++pSector->ubNumZombies;
|
||||
//++pSector->ubZombiesInBattle;
|
||||
//++pSector->ubNumZombies;
|
||||
//++pSector->ubZombiesInBattle;
|
||||
|
||||
RemoveCorpse( cnt );
|
||||
RemoveCorpse( cnt );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if there is no more room, we can skip this
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if ( zombieshaverisen )
|
||||
{
|
||||
// if there is no more room, we can skip this
|
||||
break;
|
||||
SetRenderFlags( RENDER_FLAG_FULL );
|
||||
|
||||
#ifdef JA2TESTVERSION
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"A wave of zombies is created");
|
||||
#endif
|
||||
// Play sound
|
||||
PlayJA2SampleFromFile( "Sounds\\zombie1.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN );
|
||||
|
||||
UseCreatureMusic(TRUE); // Madd: music when zombies rise
|
||||
SetMusicMode( MUSIC_TACTICAL_ENEMYPRESENT );
|
||||
}
|
||||
}
|
||||
|
||||
if ( zombieshaverisen )
|
||||
{
|
||||
SetRenderFlags( RENDER_FLAG_FULL );
|
||||
|
||||
#ifdef JA2TESTVERSION
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"A wave of zombies is created");
|
||||
#endif
|
||||
// Play sound
|
||||
PlayJA2SampleFromFile( "Sounds\\zombie1.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN );
|
||||
|
||||
UseCreatureMusic(TRUE); // Madd: music when zombies rise
|
||||
SetMusicMode( MUSIC_TACTICAL_ENEMYPRESENT );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente Zombies 1.0: create a zombie from a corpse
|
||||
void CreateZombiefromCorpse( ROTTING_CORPSE * pCorpse, UINT16 usAnimState )
|
||||
{
|
||||
SOLDIERCREATE_STRUCT MercCreateStruct;
|
||||
|
||||
MercCreateStruct.ubProfile = NO_PROFILE;
|
||||
MercCreateStruct.bTeam = CREATURE_TEAM; // should be ZOMBIE_TEAM, once that is properly implemented
|
||||
MercCreateStruct.sInsertionGridNo = pCorpse->def.sGridNo;
|
||||
MercCreateStruct.sSectorX = gWorldSectorX;
|
||||
MercCreateStruct.sSectorY = gWorldSectorY;
|
||||
MercCreateStruct.bSectorZ = gbWorldSectorZ;
|
||||
MercCreateStruct.bBodyType = pCorpse->def.ubBodyType;
|
||||
MercCreateStruct.ubDirection = pCorpse->def.ubDirection;
|
||||
MercCreateStruct.fOnRoof = pCorpse->def.bLevel > 0 ? TRUE : FALSE;
|
||||
|
||||
// add important stats according to difficulty level
|
||||
// bLife is actually lower than bLifeMax. Because zombies have poison absorption, they can and will heal themselves over time, thereby gaining more life if they are not put down fast
|
||||
switch( gGameExternalOptions.sZombieDifficultyLevel )
|
||||
// Flugente Zombies 1.0: create a zombie from a corpse
|
||||
void CreateZombiefromCorpse( ROTTING_CORPSE * pCorpse, UINT16 usAnimState )
|
||||
{
|
||||
case 4:
|
||||
MercCreateStruct.bLifeMax = (INT8)( 70 + Random( 30 ) );
|
||||
MercCreateStruct.bLife = MercCreateStruct.bLifeMax - (INT8)(10 + Random(15));
|
||||
MercCreateStruct.bAgility = (INT8)( 50 + Random( 10 ) );
|
||||
MercCreateStruct.bDexterity = (INT8)( 60 + Random( 15 ) );
|
||||
MercCreateStruct.bStrength = (INT8)( 80 + Random( 20 ) );
|
||||
break;
|
||||
SOLDIERCREATE_STRUCT MercCreateStruct;
|
||||
|
||||
MercCreateStruct.ubProfile = NO_PROFILE;
|
||||
MercCreateStruct.bTeam = CREATURE_TEAM; // should be ZOMBIE_TEAM, once that is properly implemented
|
||||
MercCreateStruct.sInsertionGridNo = pCorpse->def.sGridNo;
|
||||
MercCreateStruct.sSectorX = gWorldSectorX;
|
||||
MercCreateStruct.sSectorY = gWorldSectorY;
|
||||
MercCreateStruct.bSectorZ = gbWorldSectorZ;
|
||||
MercCreateStruct.bBodyType = pCorpse->def.ubBodyType;
|
||||
MercCreateStruct.ubDirection = pCorpse->def.ubDirection;
|
||||
MercCreateStruct.fOnRoof = pCorpse->def.bLevel > 0 ? TRUE : FALSE;
|
||||
|
||||
case 3:
|
||||
MercCreateStruct.bLifeMax = (INT8)( 60 + Random( 20 ) );
|
||||
MercCreateStruct.bLife = MercCreateStruct.bLifeMax - (INT8)(10 + Random(10));
|
||||
MercCreateStruct.bAgility = (INT8)( 40 + Random( 10 ) );
|
||||
MercCreateStruct.bDexterity = (INT8)( 45 + Random( 10 ) );
|
||||
MercCreateStruct.bStrength = (INT8)( 60 + Random( 20 ) );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
MercCreateStruct.bLifeMax = (INT8)( 45 + Random( 15 ) );
|
||||
MercCreateStruct.bLife = MercCreateStruct.bLifeMax - (INT8)(5 + Random(10));
|
||||
MercCreateStruct.bAgility = (INT8)( 30 + Random( 5 ) );
|
||||
MercCreateStruct.bDexterity = (INT8)( 30 + Random( 10 ) );
|
||||
MercCreateStruct.bStrength = (INT8)( 45 + Random( 20 ) );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
default:
|
||||
MercCreateStruct.bLifeMax = (INT8)( 35 + Random( 10 ) );
|
||||
MercCreateStruct.bLife = MercCreateStruct.bLifeMax - (INT8)(5 + Random(5));
|
||||
MercCreateStruct.bAgility = (INT8)( 15 + Random( 5 ) );
|
||||
MercCreateStruct.bDexterity = (INT8)( 15 + Random( 5 ) );
|
||||
MercCreateStruct.bStrength = (INT8)( 30 + Random( 20 ) );
|
||||
break;
|
||||
}
|
||||
|
||||
// FIX: something's wrong with the FATCIV-bodytype when dying... this is to ensure they die absolutely fast
|
||||
//if ( MercCreateStruct.bBodyType == FATCIV )
|
||||
//MercCreateStruct.bLifeMax = OKLIFE;
|
||||
|
||||
MercCreateStruct.bExpLevel = 1;
|
||||
MercCreateStruct.bMarksmanship = 1;
|
||||
MercCreateStruct.bMedical = 1;
|
||||
MercCreateStruct.bMechanical = 1;
|
||||
MercCreateStruct.bExplosive = 1;
|
||||
MercCreateStruct.bLeadership = 1;
|
||||
MercCreateStruct.bWisdom = 1;
|
||||
MercCreateStruct.bMorale = 90;
|
||||
MercCreateStruct.bAIMorale = MORALE_FEARLESS;
|
||||
|
||||
SET_PALETTEREP_ID ( MercCreateStruct.HeadPal, pCorpse->def.HeadPal );
|
||||
SET_PALETTEREP_ID ( MercCreateStruct.PantsPal, pCorpse->def.PantsPal );
|
||||
SET_PALETTEREP_ID ( MercCreateStruct.VestPal, pCorpse->def.VestPal );
|
||||
SET_PALETTEREP_ID ( MercCreateStruct.SkinPal, pCorpse->def.SkinPal );
|
||||
|
||||
MercCreateStruct.fVisible = TRUE;
|
||||
|
||||
INT8 iNewIndex;
|
||||
if ( TacticalCreateSoldier( &MercCreateStruct, (UINT8 *)&iNewIndex ) )
|
||||
{
|
||||
/* certain values have to be set afterwards - the alternative would be to edit each and every function that gets called from TacticalCreateSoldier() subsequently and
|
||||
* make an exception for zombies every time...
|
||||
*/
|
||||
SOLDIERTYPE* pNewSoldier = MercPtrs[ (UINT8)iNewIndex ];
|
||||
|
||||
pNewSoldier->bActionPoints = 60;
|
||||
pNewSoldier->bInitialActionPoints = 60;
|
||||
pNewSoldier->sBreathRed = 0;
|
||||
|
||||
pNewSoldier->ubInsertionDirection = pCorpse->def.ubDirection;
|
||||
|
||||
//pNewSoldier->sHeightAdjustment = pCorpse->def.sHeightAdjustment;
|
||||
pNewSoldier->sDesiredHeight = 3;
|
||||
|
||||
pNewSoldier->ubDesiredHeight = 3; // this forces pNewSoldier to rise up to crouching position
|
||||
|
||||
pNewSoldier->ubSoldierClass = SOLDIER_CLASS_ZOMBIE;
|
||||
pNewSoldier->aiData.bOrders = SEEKENEMY;
|
||||
pNewSoldier->aiData.bAttitude = AGGRESSIVE;
|
||||
|
||||
////////////// stuff for poisoning ///////////////////////////////////
|
||||
// this is important - by declaring the gap between bLife and bLifeMax as bBleeding, the zombies will bleed (even more if they are damaged)
|
||||
// all their lifepoints are also poisoned. Thereby all bleeding damage will be poisoned bleeding damage
|
||||
// as they have bPoisonAbsorption of at least 200%, they will absorp this poison damage
|
||||
// This leads to them GAINING life through bleeding
|
||||
// They can thereby regain their health in battle (although not very fast)
|
||||
pNewSoldier->bBleeding = pNewSoldier->stats.bLifeMax - pNewSoldier->stats.bLife;
|
||||
|
||||
pNewSoldier->bPoisonSum = pNewSoldier->stats.bLifeMax;
|
||||
pNewSoldier->bPoisonLife = pNewSoldier->stats.bLife;
|
||||
pNewSoldier->bPoisonBleeding = pNewSoldier->bPoisonSum - pNewSoldier->bPoisonLife;
|
||||
// zombies get 200% poison absorption, but no resistance to it, as it would reduce their healing
|
||||
pNewSoldier->bPoisonResistance = 0;
|
||||
pNewSoldier->bPoisonAbsorption = 200 + Random(100);
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
if ( !memcmp( pCorpse->name, TacticalStr[ CIV_TEAM_MINER_NAME ], sizeof(pCorpse->name) )
|
||||
|| !memcmp( pCorpse->name, TacticalStr[ MILITIA_TEAM_MERC_NAME ], sizeof(pCorpse->name) )
|
||||
|| !memcmp( pCorpse->name, TacticalStr[ CREATURE_TEAM_MERC_NAME ], sizeof(pCorpse->name) )
|
||||
|| !memcmp( pCorpse->name, TacticalStr[ CIV_TEAM_MERC_NAME ], sizeof(pCorpse->name) )
|
||||
|| !memcmp( pCorpse->name, TacticalStr[ ZOMBIE_TEAM_MERC_NAME ], sizeof(pCorpse->name) )
|
||||
|| !memcmp( pCorpse->name, TacticalStr[ ENEMY_TEAM_MERC_NAME ], sizeof(pCorpse->name) ) )
|
||||
{
|
||||
swprintf( pNewSoldier->name, TacticalStr[ ZOMBIE_TEAM_MERC_NAME ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy( &(pNewSoldier->name), &(pCorpse->name), sizeof(CHAR16) * 10 );
|
||||
pNewSoldier->name[9] = '\0';
|
||||
}
|
||||
|
||||
// add skills according to difficulty level
|
||||
// add important stats according to difficulty level
|
||||
// bLife is actually lower than bLifeMax. Because zombies have poison absorption, they can and will heal themselves over time, thereby gaining more life if they are not put down fast
|
||||
switch( gGameExternalOptions.sZombieDifficultyLevel )
|
||||
{
|
||||
case 4:
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = MARTIAL_ARTS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = MARTIAL_ARTS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[2] = ATHLETICS_NT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = HANDTOHAND_OT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = MARTIALARTS_OT;
|
||||
}
|
||||
MercCreateStruct.bLifeMax = (INT8)( 70 + Random( 30 ) );
|
||||
MercCreateStruct.bLife = MercCreateStruct.bLifeMax - (INT8)(10 + Random(15));
|
||||
MercCreateStruct.bAgility = (INT8)( 50 + Random( 10 ) );
|
||||
MercCreateStruct.bDexterity = (INT8)( 60 + Random( 15 ) );
|
||||
MercCreateStruct.bStrength = (INT8)( 80 + Random( 20 ) );
|
||||
break;
|
||||
|
||||
|
||||
case 3:
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = MARTIAL_ARTS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = ATHLETICS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[2] = NO_SKILLTRAIT_NT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = HANDTOHAND_OT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_OT;
|
||||
}
|
||||
MercCreateStruct.bLifeMax = (INT8)( 60 + Random( 20 ) );
|
||||
MercCreateStruct.bLife = MercCreateStruct.bLifeMax - (INT8)(10 + Random(10));
|
||||
MercCreateStruct.bAgility = (INT8)( 40 + Random( 10 ) );
|
||||
MercCreateStruct.bDexterity = (INT8)( 45 + Random( 10 ) );
|
||||
MercCreateStruct.bStrength = (INT8)( 60 + Random( 20 ) );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = MARTIAL_ARTS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[2] = NO_SKILLTRAIT_NT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = NO_SKILLTRAIT_OT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_OT;
|
||||
}
|
||||
MercCreateStruct.bLifeMax = (INT8)( 45 + Random( 15 ) );
|
||||
MercCreateStruct.bLife = MercCreateStruct.bLifeMax - (INT8)(5 + Random(10));
|
||||
MercCreateStruct.bAgility = (INT8)( 30 + Random( 5 ) );
|
||||
MercCreateStruct.bDexterity = (INT8)( 30 + Random( 10 ) );
|
||||
MercCreateStruct.bStrength = (INT8)( 45 + Random( 20 ) );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
default:
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = NO_SKILLTRAIT_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[2] = NO_SKILLTRAIT_NT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = NO_SKILLTRAIT_OT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_OT;
|
||||
}
|
||||
MercCreateStruct.bLifeMax = (INT8)( 35 + Random( 10 ) );
|
||||
MercCreateStruct.bLife = MercCreateStruct.bLifeMax - (INT8)(5 + Random(5));
|
||||
MercCreateStruct.bAgility = (INT8)( 15 + Random( 5 ) );
|
||||
MercCreateStruct.bDexterity = (INT8)( 15 + Random( 5 ) );
|
||||
MercCreateStruct.bStrength = (INT8)( 30 + Random( 20 ) );
|
||||
break;
|
||||
}
|
||||
|
||||
AddSoldierToSectorNoCalculateDirectionUseAnimation( iNewIndex, usAnimState, 0 );
|
||||
|
||||
// If this corpse has camo, use palette from hvobject
|
||||
if ( pCorpse->def.ubType == ROTTING_STAGE2 )
|
||||
{
|
||||
memcpy( pNewSoldier->p8BPPPalette, gpTileCache[ pCorpse->iCachedTileID ].pImagery->vo->pPaletteEntry, sizeof( pCorpse->p8BPPPalette ) * 256 );
|
||||
}
|
||||
else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_CAMO_PALETTE )
|
||||
{
|
||||
pNewSoldier->bCamo = 60;
|
||||
pNewSoldier->wornCamo = 60;
|
||||
}
|
||||
else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_URBAN_CAMO_PALETTE )
|
||||
{
|
||||
pNewSoldier->urbanCamo = 60;
|
||||
pNewSoldier->wornUrbanCamo = 60;
|
||||
}
|
||||
else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_DESERT_CAMO_PALETTE )
|
||||
{
|
||||
pNewSoldier->desertCamo = 60;
|
||||
pNewSoldier->wornDesertCamo = 60;
|
||||
}
|
||||
else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_SNOW_CAMO_PALETTE )
|
||||
{
|
||||
pNewSoldier->snowCamo = 60;
|
||||
pNewSoldier->wornSnowCamo = 60;
|
||||
}
|
||||
// FIX: something's wrong with the FATCIV-bodytype when dying... this is to ensure they die absolutely fast
|
||||
//if ( MercCreateStruct.bBodyType == FATCIV )
|
||||
//MercCreateStruct.bLifeMax = OKLIFE;
|
||||
|
||||
MercCreateStruct.bExpLevel = 1;
|
||||
MercCreateStruct.bMarksmanship = 1;
|
||||
MercCreateStruct.bMedical = 1;
|
||||
MercCreateStruct.bMechanical = 1;
|
||||
MercCreateStruct.bExplosive = 1;
|
||||
MercCreateStruct.bLeadership = 1;
|
||||
MercCreateStruct.bWisdom = 1;
|
||||
MercCreateStruct.bMorale = 90;
|
||||
MercCreateStruct.bAIMorale = MORALE_FEARLESS;
|
||||
|
||||
SET_PALETTEREP_ID ( MercCreateStruct.HeadPal, pCorpse->def.HeadPal );
|
||||
SET_PALETTEREP_ID ( MercCreateStruct.PantsPal, pCorpse->def.PantsPal );
|
||||
SET_PALETTEREP_ID ( MercCreateStruct.VestPal, pCorpse->def.VestPal );
|
||||
SET_PALETTEREP_ID ( MercCreateStruct.SkinPal, pCorpse->def.SkinPal );
|
||||
|
||||
MercCreateStruct.fVisible = TRUE;
|
||||
|
||||
// Reload palettes....
|
||||
if ( pNewSoldier->bInSector )
|
||||
INT8 iNewIndex;
|
||||
if ( TacticalCreateSoldier( &MercCreateStruct, (UINT8 *)&iNewIndex ) )
|
||||
{
|
||||
pNewSoldier->CreateSoldierPalettes( );
|
||||
}
|
||||
/* certain values have to be set afterwards - the alternative would be to edit each and every function that gets called from TacticalCreateSoldier() subsequently and
|
||||
* make an exception for zombies every time...
|
||||
*/
|
||||
SOLDIERTYPE* pNewSoldier = MercPtrs[ (UINT8)iNewIndex ];
|
||||
|
||||
pNewSoldier->bActionPoints = 60;
|
||||
pNewSoldier->bInitialActionPoints = 60;
|
||||
pNewSoldier->sBreathRed = 0;
|
||||
|
||||
// Set a pending animation to change stance first...
|
||||
//SendChangeSoldierStanceEvent( pNewSoldier, ANIM_CROUCH );
|
||||
pNewSoldier->ubInsertionDirection = pCorpse->def.ubDirection;
|
||||
|
||||
// search for armour and equip if found
|
||||
if ( gGameExternalOptions.fZombieRiseWithArmour )
|
||||
{
|
||||
BOOLEAN fHelmetFound = FALSE;
|
||||
BOOLEAN fVestFound = FALSE;
|
||||
BOOLEAN fPantsFound = FALSE;
|
||||
//pNewSoldier->sHeightAdjustment = pCorpse->def.sHeightAdjustment;
|
||||
pNewSoldier->sDesiredHeight = 3;
|
||||
|
||||
ITEM_POOL * pItemPool, * pItemPoolNext;
|
||||
pNewSoldier->ubDesiredHeight = 3; // this forces pNewSoldier to rise up to crouching position
|
||||
|
||||
GetItemPool( pCorpse->def.sGridNo, &pItemPool, pCorpse->def.bLevel );
|
||||
pNewSoldier->ubSoldierClass = SOLDIER_CLASS_ZOMBIE;
|
||||
pNewSoldier->aiData.bOrders = SEEKENEMY;
|
||||
pNewSoldier->aiData.bAttitude = AGGRESSIVE;
|
||||
|
||||
while( pItemPool && ( !fHelmetFound || !fVestFound ||!fPantsFound ) )
|
||||
////////////// stuff for poisoning ///////////////////////////////////
|
||||
// this is important - by declaring the gap between bLife and bLifeMax as bBleeding, the zombies will bleed (even more if they are damaged)
|
||||
// all their lifepoints are also poisoned. Thereby all bleeding damage will be poisoned bleeding damage
|
||||
// as they have bPoisonAbsorption of at least 200%, they will absorp this poison damage
|
||||
// This leads to them GAINING life through bleeding
|
||||
// They can thereby regain their health in battle (although not very fast)
|
||||
pNewSoldier->bBleeding = pNewSoldier->stats.bLifeMax - pNewSoldier->stats.bLife;
|
||||
|
||||
pNewSoldier->bPoisonSum = pNewSoldier->stats.bLifeMax;
|
||||
pNewSoldier->bPoisonLife = pNewSoldier->stats.bLife;
|
||||
pNewSoldier->bPoisonBleeding = pNewSoldier->bPoisonSum - pNewSoldier->bPoisonLife;
|
||||
// zombies get 200% poison absorption, but no resistance to it, as it would reduce their healing
|
||||
pNewSoldier->bPoisonResistance = 0;
|
||||
pNewSoldier->bPoisonAbsorption = 200 + Random(100);
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( !memcmp( pCorpse->name, TacticalStr[ CIV_TEAM_MINER_NAME ], sizeof(pCorpse->name) )
|
||||
|| !memcmp( pCorpse->name, TacticalStr[ MILITIA_TEAM_MERC_NAME ], sizeof(pCorpse->name) )
|
||||
|| !memcmp( pCorpse->name, TacticalStr[ CREATURE_TEAM_MERC_NAME ], sizeof(pCorpse->name) )
|
||||
|| !memcmp( pCorpse->name, TacticalStr[ CIV_TEAM_MERC_NAME ], sizeof(pCorpse->name) )
|
||||
|| !memcmp( pCorpse->name, TacticalStr[ ZOMBIE_TEAM_MERC_NAME ], sizeof(pCorpse->name) )
|
||||
|| !memcmp( pCorpse->name, TacticalStr[ ENEMY_TEAM_MERC_NAME ], sizeof(pCorpse->name) ) )
|
||||
{
|
||||
pItemPoolNext = pItemPool->pNext;
|
||||
|
||||
OBJECTTYPE* pObj = &(gWorldItems[ pItemPool->iItemIndex ].object);
|
||||
|
||||
if ( Item[ pObj->usItem ].usItemClass == IC_ARMOUR )
|
||||
{
|
||||
switch (Armour[Item[pObj->usItem].ubClassIndex].ubArmourClass)
|
||||
{
|
||||
case ARMOURCLASS_HELMET:
|
||||
{
|
||||
if( !fHelmetFound && AutoPlaceObject(pNewSoldier, pObj, FALSE))
|
||||
{
|
||||
// remove item from the ground
|
||||
RemoveItemFromPool( pCorpse->def.sGridNo, pItemPool->iItemIndex, pCorpse->def.bLevel );
|
||||
fHelmetFound = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ARMOURCLASS_VEST:
|
||||
{
|
||||
if( !fVestFound && AutoPlaceObject(pNewSoldier, pObj, FALSE))
|
||||
{
|
||||
// remove item from the ground
|
||||
RemoveItemFromPool( pCorpse->def.sGridNo, pItemPool->iItemIndex, pCorpse->def.bLevel );
|
||||
fVestFound = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ARMOURCLASS_LEGGINGS:
|
||||
{
|
||||
if( !fPantsFound && AutoPlaceObject(pNewSoldier, pObj, FALSE))
|
||||
{
|
||||
// remove item from the ground
|
||||
RemoveItemFromPool( pCorpse->def.sGridNo, pItemPool->iItemIndex, pCorpse->def.bLevel );
|
||||
fPantsFound = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pItemPool = pItemPoolNext;
|
||||
swprintf( pNewSoldier->name, TacticalStr[ ZOMBIE_TEAM_MERC_NAME ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy( &(pNewSoldier->name), &(pCorpse->name), sizeof(CHAR16) * 10 );
|
||||
pNewSoldier->name[9] = '\0';
|
||||
}
|
||||
#else
|
||||
memcpy( &(pNewSoldier->name), &(pCorpse->name), sizeof(CHAR16) * 10 );
|
||||
pNewSoldier->name[9] = '\0';
|
||||
#endif
|
||||
|
||||
// add skills according to difficulty level
|
||||
switch( gGameExternalOptions.sZombieDifficultyLevel )
|
||||
{
|
||||
case 4:
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = MARTIAL_ARTS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = MARTIAL_ARTS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[2] = ATHLETICS_NT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = HANDTOHAND_OT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = MARTIALARTS_OT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = MARTIAL_ARTS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = ATHLETICS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[2] = NO_SKILLTRAIT_NT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = HANDTOHAND_OT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_OT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = MARTIAL_ARTS_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[2] = NO_SKILLTRAIT_NT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = NO_SKILLTRAIT_OT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_OT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
default:
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = NO_SKILLTRAIT_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_NT;
|
||||
pNewSoldier->stats.ubSkillTraits[2] = NO_SKILLTRAIT_NT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewSoldier->stats.ubSkillTraits[0] = NO_SKILLTRAIT_OT;
|
||||
pNewSoldier->stats.ubSkillTraits[1] = NO_SKILLTRAIT_OT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
AddSoldierToSectorNoCalculateDirectionUseAnimation( iNewIndex, usAnimState, 0 );
|
||||
|
||||
// If this corpse has camo, use palette from hvobject
|
||||
if ( pCorpse->def.ubType == ROTTING_STAGE2 )
|
||||
{
|
||||
memcpy( pNewSoldier->p8BPPPalette, gpTileCache[ pCorpse->iCachedTileID ].pImagery->vo->pPaletteEntry, sizeof( pCorpse->p8BPPPalette ) * 256 );
|
||||
}
|
||||
else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_CAMO_PALETTE )
|
||||
{
|
||||
pNewSoldier->bCamo = 60;
|
||||
pNewSoldier->wornCamo = 60;
|
||||
}
|
||||
else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_URBAN_CAMO_PALETTE )
|
||||
{
|
||||
pNewSoldier->urbanCamo = 60;
|
||||
pNewSoldier->wornUrbanCamo = 60;
|
||||
}
|
||||
else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_DESERT_CAMO_PALETTE )
|
||||
{
|
||||
pNewSoldier->desertCamo = 60;
|
||||
pNewSoldier->wornDesertCamo = 60;
|
||||
}
|
||||
else if ( pCorpse->def.usFlags & ROTTING_CORPSE_USE_SNOW_CAMO_PALETTE )
|
||||
{
|
||||
pNewSoldier->snowCamo = 60;
|
||||
pNewSoldier->wornSnowCamo = 60;
|
||||
}
|
||||
|
||||
// Reload palettes....
|
||||
if ( pNewSoldier->bInSector )
|
||||
{
|
||||
pNewSoldier->CreateSoldierPalettes( );
|
||||
}
|
||||
|
||||
// Set a pending animation to change stance first...
|
||||
//SendChangeSoldierStanceEvent( pNewSoldier, ANIM_CROUCH );
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// search for armour and equip if found
|
||||
if ( gGameExternalOptions.fZombieRiseWithArmour )
|
||||
{
|
||||
BOOLEAN fHelmetFound = FALSE;
|
||||
BOOLEAN fVestFound = FALSE;
|
||||
BOOLEAN fPantsFound = FALSE;
|
||||
|
||||
ITEM_POOL * pItemPool, * pItemPoolNext;
|
||||
|
||||
GetItemPool( pCorpse->def.sGridNo, &pItemPool, pCorpse->def.bLevel );
|
||||
|
||||
while( pItemPool && ( !fHelmetFound || !fVestFound ||!fPantsFound ) )
|
||||
{
|
||||
pItemPoolNext = pItemPool->pNext;
|
||||
|
||||
OBJECTTYPE* pObj = &(gWorldItems[ pItemPool->iItemIndex ].object);
|
||||
|
||||
if ( Item[ pObj->usItem ].usItemClass == IC_ARMOUR )
|
||||
{
|
||||
switch (Armour[Item[pObj->usItem].ubClassIndex].ubArmourClass)
|
||||
{
|
||||
case ARMOURCLASS_HELMET:
|
||||
{
|
||||
if( !fHelmetFound && AutoPlaceObject(pNewSoldier, pObj, FALSE))
|
||||
{
|
||||
// remove item from the ground
|
||||
RemoveItemFromPool( pCorpse->def.sGridNo, pItemPool->iItemIndex, pCorpse->def.bLevel );
|
||||
fHelmetFound = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ARMOURCLASS_VEST:
|
||||
{
|
||||
if( !fVestFound && AutoPlaceObject(pNewSoldier, pObj, FALSE))
|
||||
{
|
||||
// remove item from the ground
|
||||
RemoveItemFromPool( pCorpse->def.sGridNo, pItemPool->iItemIndex, pCorpse->def.bLevel );
|
||||
fVestFound = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ARMOURCLASS_LEGGINGS:
|
||||
{
|
||||
if( !fPantsFound && AutoPlaceObject(pNewSoldier, pObj, FALSE))
|
||||
{
|
||||
// remove item from the ground
|
||||
RemoveItemFromPool( pCorpse->def.sGridNo, pItemPool->iItemIndex, pCorpse->def.bLevel );
|
||||
fPantsFound = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pItemPool = pItemPoolNext;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Change to standing,unless we can getup with an animation
|
||||
pNewSoldier->EVENT_InitNewSoldierAnim( STANDING, 0, TRUE );
|
||||
pNewSoldier->BeginSoldierGetup( );
|
||||
|
||||
// So we can see them!
|
||||
AllTeamsLookForAll(ALLOW_INTERRUPTS);
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente Zombies: returns true if a zombie can be raised from this corpse, and returns the correct pAnimState for the new zombie
|
||||
BOOLEAN CorpseOkToSpawnZombie( ROTTING_CORPSE * pCorpse, UINT16* pAnimState )
|
||||
{
|
||||
BOOLEAN canbezombie = FALSE;
|
||||
*pAnimState = FALLBACKHIT_STOP;
|
||||
|
||||
switch ( pCorpse->def.ubType )
|
||||
{
|
||||
case SMERC_BCK:
|
||||
case SMERC_DHD:
|
||||
case SMERC_FALL:
|
||||
case MMERC_BCK:
|
||||
case MMERC_DHD:
|
||||
case MMERC_FALL:
|
||||
case FMERC_BCK:
|
||||
case FMERC_DHD:
|
||||
case FMERC_FALL:
|
||||
case ROTTING_STAGE2:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = FALLBACKHIT_STOP;
|
||||
break;
|
||||
|
||||
case SMERC_FWD:
|
||||
case SMERC_PRN:
|
||||
case SMERC_FALLF:
|
||||
case MMERC_FWD:
|
||||
case MMERC_PRN:
|
||||
case MMERC_FALLF:
|
||||
case FMERC_FWD:
|
||||
case FMERC_PRN:
|
||||
case FMERC_FALLF:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = FALLFORWARD_HITDEATH_STOP;
|
||||
break;
|
||||
|
||||
case M_DEAD1:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = GENERIC_HIT_DEATH;
|
||||
break;
|
||||
|
||||
case M_DEAD2:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = CIV_DIE2;
|
||||
|
||||
case H_DEAD1:
|
||||
case K_DEAD1:
|
||||
case FT_DEAD1:
|
||||
case S_DEAD1:
|
||||
case W_DEAD1:
|
||||
case C_DEAD1:
|
||||
case H_DEAD2:
|
||||
case K_DEAD2:
|
||||
case FT_DEAD2:
|
||||
case S_DEAD2:
|
||||
case W_DEAD2:
|
||||
case C_DEAD2:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = STANDING;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
// Change to standing,unless we can getup with an animation
|
||||
pNewSoldier->EVENT_InitNewSoldierAnim( STANDING, 0, TRUE );
|
||||
pNewSoldier->BeginSoldierGetup( );
|
||||
|
||||
// So we can see them!
|
||||
AllTeamsLookForAll(ALLOW_INTERRUPTS);
|
||||
return( canbezombie );
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente Zombies: returns true if a zombie can be raised from this corpse, and returns the correct pAnimState for the new zombie
|
||||
BOOLEAN CorpseOkToSpawnZombie( ROTTING_CORPSE * pCorpse, UINT16* pAnimState )
|
||||
{
|
||||
BOOLEAN canbezombie = FALSE;
|
||||
*pAnimState = FALLBACKHIT_STOP;
|
||||
|
||||
switch ( pCorpse->def.ubType )
|
||||
{
|
||||
case SMERC_BCK:
|
||||
case SMERC_DHD:
|
||||
case SMERC_FALL:
|
||||
case MMERC_BCK:
|
||||
case MMERC_DHD:
|
||||
case MMERC_FALL:
|
||||
case FMERC_BCK:
|
||||
case FMERC_DHD:
|
||||
case FMERC_FALL:
|
||||
case ROTTING_STAGE2:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = FALLBACKHIT_STOP;
|
||||
break;
|
||||
|
||||
case SMERC_FWD:
|
||||
case SMERC_PRN:
|
||||
case SMERC_FALLF:
|
||||
case MMERC_FWD:
|
||||
case MMERC_PRN:
|
||||
case MMERC_FALLF:
|
||||
case FMERC_FWD:
|
||||
case FMERC_PRN:
|
||||
case FMERC_FALLF:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = FALLFORWARD_HITDEATH_STOP;
|
||||
break;
|
||||
|
||||
case M_DEAD1:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = GENERIC_HIT_DEATH;
|
||||
break;
|
||||
|
||||
case M_DEAD2:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = CIV_DIE2;
|
||||
|
||||
case H_DEAD1:
|
||||
case K_DEAD1:
|
||||
case FT_DEAD1:
|
||||
case S_DEAD1:
|
||||
case W_DEAD1:
|
||||
case C_DEAD1:
|
||||
case H_DEAD2:
|
||||
case K_DEAD2:
|
||||
case FT_DEAD2:
|
||||
case S_DEAD2:
|
||||
case W_DEAD2:
|
||||
case C_DEAD2:
|
||||
canbezombie = TRUE;
|
||||
*pAnimState = STANDING;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
return( canbezombie );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -84,7 +84,10 @@ enum RottingCorpseDefines
|
||||
#define ROTTING_CORPSE_USE_URBAN_CAMO_PALETTE 0x100 //We use urban palette here....
|
||||
#define ROTTING_CORPSE_USE_DESERT_CAMO_PALETTE 0x200 //We use desert palette here....
|
||||
#define ROTTING_CORPSE_USE_SNOW_CAMO_PALETTE 0x400 //We use snow palette here....
|
||||
#define ROTTING_CORPSE_NEVER_RISE_AGAIN 0x800 //a zombie cannot be created from this corpse (if not set, it'll eventually rise again )
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
#define ROTTING_CORPSE_NEVER_RISE_AGAIN 0x800 //a zombie cannot be created from this corpse (if not set, it'll eventually rise again )
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
@@ -116,8 +119,10 @@ typedef struct
|
||||
|
||||
UINT8 ubFiller[ 12 ];
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: added name so we can display individual name if corpse gets resurrected...
|
||||
CHAR16 name[ 10 ];
|
||||
#endif
|
||||
|
||||
} ROTTING_CORPSE_DEFINITION;
|
||||
|
||||
@@ -140,8 +145,10 @@ typedef struct
|
||||
BOOLEAN fAttractCrowsOnlyWhenOnScreen;
|
||||
INT32 iID;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: added name so we can display individual name if corpse gets resurrected...
|
||||
CHAR16 name[ 10 ];
|
||||
#endif
|
||||
|
||||
} ROTTING_CORPSE;
|
||||
|
||||
@@ -200,13 +207,15 @@ INT32 GetGridNoOfCorpseGivenProfileID( UINT8 ubProfileID );
|
||||
void DecayRottingCorpseAIWarnings( void );
|
||||
UINT8 GetNearestRottingCorpseAIWarning( INT32 sGridNo );
|
||||
|
||||
// Flugente: Raise zombies
|
||||
void RaiseZombies( void );
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: Raise zombies
|
||||
void RaiseZombies( void );
|
||||
|
||||
// Flugente: create a zombie from a corpse
|
||||
void CreateZombiefromCorpse( ROTTING_CORPSE * pCorpse, UINT16 usAnimState );
|
||||
// Flugente: create a zombie from a corpse
|
||||
void CreateZombiefromCorpse( ROTTING_CORPSE * pCorpse, UINT16 usAnimState );
|
||||
|
||||
// Flugente: returns true if a zombie can be raised from this corpse, and returns the correct pAnimState for the new zombie
|
||||
BOOLEAN CorpseOkToSpawnZombie( ROTTING_CORPSE * pCorpse, UINT16* pAnimState );
|
||||
// Flugente: returns true if a zombie can be raised from this corpse, and returns the correct pAnimState for the new zombie
|
||||
BOOLEAN CorpseOkToSpawnZombie( ROTTING_CORPSE * pCorpse, UINT16* pAnimState );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -3485,9 +3485,11 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse )
|
||||
case SOLDIER_CLASS_CREATURE :
|
||||
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsCreatures++;
|
||||
break;
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
case SOLDIER_CLASS_ZOMBIE :
|
||||
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsZombies++;
|
||||
break;
|
||||
#endif
|
||||
default :
|
||||
if ( CREATURE_OR_BLOODCAT( pSoldier ) )
|
||||
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsCreatures++;
|
||||
|
||||
@@ -137,8 +137,10 @@ extern INT16 DirIncrementer[8];
|
||||
#define MIN_SUBSEQUENT_SNDS_DELAY 2000
|
||||
#include "connect.h"
|
||||
|
||||
extern void TeleportSelectedSoldier( void );
|
||||
extern BOOLEAN AddSoldierToSectorNoCalculateDirectionUseAnimation( UINT8 ubID, UINT16 usAnimState, UINT16 usAnimCode );
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
extern void TeleportSelectedSoldier( void );
|
||||
extern BOOLEAN AddSoldierToSectorNoCalculateDirectionUseAnimation( UINT8 ubID, UINT16 usAnimState, UINT16 usAnimCode );
|
||||
#endif
|
||||
|
||||
|
||||
// Enumerate extended directions
|
||||
@@ -1349,7 +1351,11 @@ MERCPROFILESTRUCT& MERCPROFILESTRUCT::operator=(const OLD_MERCPROFILESTRUCT_101&
|
||||
this->records.usKillsAdmins = (src.usKills/4);
|
||||
this->records.usKillsHostiles = 0;
|
||||
this->records.usKillsCreatures = 0;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
this->records.usKillsZombies = 0;
|
||||
#endif
|
||||
|
||||
this->records.usKillsTanks = 0;
|
||||
this->records.usKillsOthers = 0;
|
||||
this->records.usAssistsMercs = (src.usAssists*3/4);
|
||||
@@ -8673,6 +8679,7 @@ void SOLDIERTYPE::BeginSoldierClimbUpRoof( void )
|
||||
this->ubPendingDirection = bNewDirection;
|
||||
//this->usPendingAnimation = CLIMBUPROOF;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: In case an animation is missing (zombies with bodytype of civilians), we TELEPORT instead
|
||||
if ( IsAnimationValidForBodyType( this, CLIMBUPROOF ) == FALSE )
|
||||
{
|
||||
@@ -8682,6 +8689,9 @@ void SOLDIERTYPE::BeginSoldierClimbUpRoof( void )
|
||||
}
|
||||
else
|
||||
this->EVENT_InitNewSoldierAnim( CLIMBUPROOF, 0 , FALSE );
|
||||
#else
|
||||
this->EVENT_InitNewSoldierAnim( CLIMBUPROOF, 0 , FALSE );
|
||||
#endif
|
||||
|
||||
this->InternalReceivingSoldierCancelServices( FALSE );
|
||||
this->InternalGivingSoldierCancelServices( FALSE );
|
||||
@@ -9276,7 +9286,11 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sPo
|
||||
// ATE: Put some logic in here to allow enemies to die quicker.....
|
||||
// Are we an enemy?
|
||||
// zombies don't die suddenly, as they regenerate health by bloodloss and poison. You have to make sure they die!
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( this->bSide != gbPlayerNum && !this->aiData.bNeutral && this->ubProfile == NO_PROFILE && !this->IsZombie() )
|
||||
#else
|
||||
if ( this->bSide != gbPlayerNum && !this->aiData.bNeutral && this->ubProfile == NO_PROFILE)
|
||||
#endif
|
||||
{
|
||||
// ATE: Give them a chance to fall down...
|
||||
if ( this->stats.bLife > 0 && this->stats.bLife < ( OKLIFE - 1 ) )
|
||||
@@ -9310,12 +9324,15 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sPo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
else if ( this->IsZombie() && this->stats.bLife > 0 && this->stats.bLife < OKLIFE )
|
||||
{
|
||||
// a zombie doesn't automatically die, so he would normally stand up again after being hit.
|
||||
// We don't want that, because he is dying, so we manually skip that animation
|
||||
this->usPendingAnimation = NO_PENDING_ANIMATION;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( fShowDamage )
|
||||
{
|
||||
@@ -9988,6 +10005,7 @@ BOOLEAN SOLDIERTYPE::InternalDoMercBattleSound( UINT8 ubBattleSoundID, INT8 bSpe
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
else if ( pSoldier->IsZombie() ) // Madd: add zombie sounds
|
||||
{
|
||||
if ( ubSoundID == BATTLE_SOUND_DIE1 )
|
||||
@@ -10007,6 +10025,7 @@ BOOLEAN SOLDIERTYPE::InternalDoMercBattleSound( UINT8 ubBattleSoundID, INT8 bSpe
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
if ( ubSoundID == BATTLE_SOUND_DIE1 )
|
||||
@@ -10265,6 +10284,7 @@ void SOLDIERTYPE::BeginSoldierClimbDownRoof( void )
|
||||
|
||||
this->ubPendingDirection = bNewDirection;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: In case an animation is missing (zombies with bodytype of civilians), we TELEPORT instead
|
||||
if ( IsAnimationValidForBodyType( this, JUMPDOWNWALL ) == FALSE )
|
||||
{
|
||||
@@ -10274,6 +10294,9 @@ void SOLDIERTYPE::BeginSoldierClimbDownRoof( void )
|
||||
}
|
||||
else
|
||||
this->EVENT_InitNewSoldierAnim( JUMPDOWNWALL, 0 , FALSE );
|
||||
#else
|
||||
this->EVENT_InitNewSoldierAnim( JUMPDOWNWALL, 0 , FALSE );
|
||||
#endif
|
||||
|
||||
this->InternalReceivingSoldierCancelServices( FALSE );
|
||||
this->InternalGivingSoldierCancelServices( FALSE );
|
||||
@@ -11505,7 +11528,13 @@ void SOLDIERTYPE::EVENT_SoldierBeginPunchAttack( INT32 sGridNo, UINT8 ubDirectio
|
||||
#if (defined JA2UB || defined JA113NODEMO)
|
||||
if ( fMartialArtist && !Item[usItem].crowbar && this->ubBodyType == REGMALE)
|
||||
#else
|
||||
if ( fMartialArtist && !AreInMeanwhile( ) && !Item[usItem].crowbar && this->ubBodyType == REGMALE && !IsZombie() ) // SANDRO - added check for body type
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( fMartialArtist && !AreInMeanwhile( ) && !Item[usItem].crowbar && this->ubBodyType == REGMALE && !IsZombie() ) // SANDRO - added check for body type
|
||||
#else
|
||||
if ( fMartialArtist && !AreInMeanwhile( ) && !Item[usItem].crowbar && this->ubBodyType == REGMALE ) // SANDRO - added check for body type
|
||||
#endif
|
||||
|
||||
#endif
|
||||
{
|
||||
// Are we in attack mode yet?
|
||||
@@ -11520,6 +11549,7 @@ void SOLDIERTYPE::EVENT_SoldierBeginPunchAttack( INT32 sGridNo, UINT8 ubDirectio
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: civilians can be zombies too, but they do not have a 'punch' animation. Simple fix: They 'attack' without animation...
|
||||
// CHECK IF WE CAN DO THIS ANIMATION!
|
||||
if ( this->IsZombie() && IsAnimationValidForBodyType( this, PUNCH ) == FALSE )
|
||||
@@ -11589,6 +11619,7 @@ void SOLDIERTYPE::EVENT_SoldierBeginPunchAttack( INT32 sGridNo, UINT8 ubDirectio
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
// Look at stance of target
|
||||
switch( gAnimControl[ pTSoldier->usAnimState ].ubEndHeight )
|
||||
{
|
||||
@@ -11649,7 +11680,10 @@ void SOLDIERTYPE::EVENT_SoldierBeginPunchAttack( INT32 sGridNo, UINT8 ubDirectio
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13402,6 +13436,8 @@ INT32 SOLDIERTYPE::GetDamageResistance(BOOLEAN fAutoResolve, BOOLEAN fCalcBreath
|
||||
resistance += gGameExternalOptions.sEnemyRegularDamageResistance;
|
||||
else if (this->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteDamageResistance != 0)
|
||||
resistance += gGameExternalOptions.sEnemyEliteDamageResistance;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
else if (IsZombie())
|
||||
{
|
||||
if ( fCalcBreathLoss )
|
||||
@@ -13409,6 +13445,7 @@ INT32 SOLDIERTYPE::GetDamageResistance(BOOLEAN fAutoResolve, BOOLEAN fCalcBreath
|
||||
else
|
||||
resistance += gGameExternalOptions.sEnemyZombieDamageResistance;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -13463,10 +13500,13 @@ INT16 SOLDIERTYPE::GetSoldierCriticalDamageBonus( void )
|
||||
return val;
|
||||
}
|
||||
|
||||
BOOLEAN SOLDIERTYPE::IsZombie( void )
|
||||
{
|
||||
return( ubSoldierClass == SOLDIER_CLASS_ZOMBIE );
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
BOOLEAN SOLDIERTYPE::IsZombie( void )
|
||||
{
|
||||
return( ubSoldierClass == SOLDIER_CLASS_ZOMBIE );
|
||||
}
|
||||
#endif
|
||||
|
||||
INT16 SOLDIERTYPE::GetPoisonResistance( void )
|
||||
{
|
||||
@@ -13497,9 +13537,11 @@ INT16 SOLDIERTYPE::GetPoisonDamagePercentage( void )
|
||||
// Flugente: this percentage has to be between 0% and 100%
|
||||
INT16 val = 0;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// zombies poison damage percentage is externalised
|
||||
if ( IsZombie() )
|
||||
val += gGameExternalOptions.sZombiePoisonDamagePercentage;
|
||||
#endif
|
||||
|
||||
if ( this->usAttackingWeapon )
|
||||
{
|
||||
|
||||
@@ -310,7 +310,9 @@ enum
|
||||
SOLDIER_CLASS_ELITE_MILITIA,
|
||||
SOLDIER_CLASS_CREATURE,
|
||||
SOLDIER_CLASS_MINER,
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
SOLDIER_CLASS_ZOMBIE,
|
||||
#endif
|
||||
};
|
||||
|
||||
#define SOLDIER_CLASS_ENEMY( bSoldierClass ) ( ( bSoldierClass >= SOLDIER_CLASS_ADMINISTRATOR ) && ( bSoldierClass <= SOLDIER_CLASS_ARMY ) )
|
||||
@@ -1358,8 +1360,10 @@ public:
|
||||
|
||||
INT16 GetSoldierCriticalDamageBonus( void ); // Flugente: determines critical damage bonus depending on class, skill, etc.
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: Zombies
|
||||
BOOLEAN IsZombie( void );
|
||||
#endif
|
||||
|
||||
// Flugente: poison system
|
||||
// These functions might one day be modified by traits etc. We'll keep that in these functions and not clutter the rest of the code
|
||||
|
||||
+53
-30
@@ -1729,10 +1729,12 @@ BOOLEAN TacticalCopySoldierFromCreateStruct( SOLDIERTYPE *pSoldier, SOLDIERCREAT
|
||||
{
|
||||
swprintf( pSoldier->name, gzLateLocalizedString[ 36 ] );
|
||||
}
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
else if ( pSoldier->IsZombie() )
|
||||
{
|
||||
swprintf( pSoldier->name, TacticalStr[ ZOMBIE_TEAM_MERC_NAME ] );
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
swprintf( pSoldier->name, TacticalStr[ CREATURE_TEAM_MERC_NAME ] ); break;
|
||||
@@ -2176,7 +2178,9 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
|
||||
switch( ubSoldierClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
case SOLDIER_CLASS_ZOMBIE:
|
||||
#endif
|
||||
pp->bExpLevel = (INT8) 2 + bExpLevelModifier;
|
||||
break;
|
||||
case SOLDIER_CLASS_ARMY:
|
||||
@@ -2294,7 +2298,11 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
|
||||
//If it is a detailed placement, don't do this yet, as detailed placements may have their
|
||||
//own equipment.
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CreateDetailedPlacementGivenBasicPlacementInfo: generate random equipment"));
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if( !bp->fDetailedPlacement && ubSoldierClass != SOLDIER_CLASS_NONE && ubSoldierClass != SOLDIER_CLASS_CREATURE && ubSoldierClass != SOLDIER_CLASS_MINER && ubSoldierClass != SOLDIER_CLASS_ZOMBIE )
|
||||
#else
|
||||
if( !bp->fDetailedPlacement && ubSoldierClass != SOLDIER_CLASS_NONE && ubSoldierClass != SOLDIER_CLASS_CREATURE && ubSoldierClass != SOLDIER_CLASS_MINER )
|
||||
#endif
|
||||
GenerateRandomEquipment( pp, ubSoldierClass, bp->bRelativeEquipmentLevel);
|
||||
|
||||
DecideToAssignSniperOrders(pp);
|
||||
@@ -2462,7 +2470,12 @@ void CreateDetailedPlacementGivenStaticDetailedPlacementAndBasicPlacementInfo(
|
||||
//{
|
||||
// ReplaceExtendedGuns( pp, bp->ubSoldierClass );
|
||||
//}
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if( bp->ubSoldierClass != SOLDIER_CLASS_NONE && bp->ubSoldierClass != SOLDIER_CLASS_CREATURE && bp->ubSoldierClass != SOLDIER_CLASS_MINER && bp->ubSoldierClass != SOLDIER_CLASS_ZOMBIE )
|
||||
#else
|
||||
if( bp->ubSoldierClass != SOLDIER_CLASS_NONE && bp->ubSoldierClass != SOLDIER_CLASS_CREATURE && bp->ubSoldierClass != SOLDIER_CLASS_MINER )
|
||||
#endif
|
||||
{
|
||||
GenerateRandomEquipment( pp, bp->ubSoldierClass, bp->bRelativeEquipmentLevel);
|
||||
DecideToAssignSniperOrders(pp);
|
||||
@@ -2657,7 +2670,11 @@ SOLDIERTYPE* ReserveTacticalSoldierForAutoresolve( UINT8 ubSoldierClass )
|
||||
//returns the pointer to that soldier. This is used when copying the exact status of
|
||||
//all remaining enemy troops (or creatures) to finish the battle in autoresolve. To
|
||||
//signify that the troop has already been reserved, we simply set their gridno to NOWHERE.
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if( ubSoldierClass != SOLDIER_CLASS_CREATURE && ubSoldierClass != SOLDIER_CLASS_ZOMBIE )
|
||||
#else
|
||||
if( ubSoldierClass != SOLDIER_CLASS_CREATURE )
|
||||
#endif
|
||||
{ //use the enemy team
|
||||
iStart = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID;
|
||||
iEnd = gTacticalStatus.Team[ ENEMY_TEAM ].bLastID;
|
||||
@@ -2799,39 +2816,41 @@ SOLDIERTYPE* TacticalCreateEliteEnemy()
|
||||
return( pSoldier );
|
||||
}
|
||||
|
||||
//USED BY STRATEGIC AI and AUTORESOLVE
|
||||
SOLDIERTYPE* TacticalCreateZombie()
|
||||
{
|
||||
BASIC_SOLDIERCREATE_STRUCT bp;
|
||||
SOLDIERCREATE_STRUCT pp;
|
||||
UINT8 ubID;
|
||||
SOLDIERTYPE * pSoldier;
|
||||
|
||||
if( guiCurrentScreen == AUTORESOLVE_SCREEN && !gfPersistantPBI )
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
//USED BY STRATEGIC AI and AUTORESOLVE
|
||||
SOLDIERTYPE* TacticalCreateZombie()
|
||||
{
|
||||
pSoldier = ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_ZOMBIE );
|
||||
if( pSoldier ) return pSoldier;
|
||||
}
|
||||
BASIC_SOLDIERCREATE_STRUCT bp;
|
||||
SOLDIERCREATE_STRUCT pp;
|
||||
UINT8 ubID;
|
||||
SOLDIERTYPE * pSoldier;
|
||||
|
||||
memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) );
|
||||
RandomizeRelativeLevel( &( bp.bRelativeAttributeLevel ), SOLDIER_CLASS_ZOMBIE );
|
||||
RandomizeRelativeLevel( &( bp.bRelativeEquipmentLevel ), SOLDIER_CLASS_ZOMBIE );
|
||||
bp.bTeam = CREATURE_TEAM;//ZOMBIE_TEAM;
|
||||
bp.bOrders = SEEKENEMY;
|
||||
bp.bAttitude = AGGRESSIVE;
|
||||
bp.bBodyType = -1;
|
||||
bp.ubSoldierClass = SOLDIER_CLASS_ZOMBIE;
|
||||
CreateDetailedPlacementGivenBasicPlacementInfo( &pp, &bp );
|
||||
pSoldier = TacticalCreateSoldier( &pp, &ubID );
|
||||
if ( pSoldier )
|
||||
{
|
||||
// send soldier to centre of map, roughly
|
||||
pSoldier->aiData.sNoiseGridno = (CENTRAL_GRIDNO + ( Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS ) + ( Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS ) * WORLD_COLS);
|
||||
pSoldier->aiData.ubNoiseVolume = MAX_MISC_NOISE_DURATION;
|
||||
}
|
||||
if( guiCurrentScreen == AUTORESOLVE_SCREEN && !gfPersistantPBI )
|
||||
{
|
||||
pSoldier = ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_ZOMBIE );
|
||||
if( pSoldier ) return pSoldier;
|
||||
}
|
||||
|
||||
return( pSoldier );
|
||||
}
|
||||
memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) );
|
||||
RandomizeRelativeLevel( &( bp.bRelativeAttributeLevel ), SOLDIER_CLASS_ZOMBIE );
|
||||
RandomizeRelativeLevel( &( bp.bRelativeEquipmentLevel ), SOLDIER_CLASS_ZOMBIE );
|
||||
bp.bTeam = CREATURE_TEAM;//ZOMBIE_TEAM;
|
||||
bp.bOrders = SEEKENEMY;
|
||||
bp.bAttitude = AGGRESSIVE;
|
||||
bp.bBodyType = -1;
|
||||
bp.ubSoldierClass = SOLDIER_CLASS_ZOMBIE;
|
||||
CreateDetailedPlacementGivenBasicPlacementInfo( &pp, &bp );
|
||||
pSoldier = TacticalCreateSoldier( &pp, &ubID );
|
||||
if ( pSoldier )
|
||||
{
|
||||
// send soldier to centre of map, roughly
|
||||
pSoldier->aiData.sNoiseGridno = (CENTRAL_GRIDNO + ( Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS ) + ( Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS ) * WORLD_COLS);
|
||||
pSoldier->aiData.ubNoiseVolume = MAX_MISC_NOISE_DURATION;
|
||||
}
|
||||
|
||||
return( pSoldier );
|
||||
}
|
||||
#endif
|
||||
|
||||
SOLDIERTYPE* ReserveTacticalMilitiaSoldierForAutoresolve( UINT8 ubSoldierClass )
|
||||
{
|
||||
@@ -4236,8 +4255,10 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
iChance = 10 + ubProgress/4; // 10-35% chance
|
||||
else if( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
iChance = ubProgress/4; // 0-25% chance
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
else if (ubSolClass == SOLDIER_CLASS_ZOMBIE )
|
||||
iChance = 100; // 100% chance
|
||||
#endif
|
||||
|
||||
if( foundHtH ) // if found brass knuckless, increase the chance (doesn't happen often)
|
||||
iChance += 35;
|
||||
@@ -4281,8 +4302,10 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
iChance = 25 + ubProgress*2/5; // 25-65% chance
|
||||
else if( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
iChance = 10 + ubProgress*2/5; // 10-50% chance
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
else if (ubSolClass == SOLDIER_CLASS_ZOMBIE )
|
||||
iChance = 100; // 100% chance
|
||||
#endif
|
||||
|
||||
// modify the chance by preset ini setting
|
||||
if( gGameExternalOptions.bAssignedTraitsRarity != 0 )
|
||||
|
||||
@@ -420,7 +420,9 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
|
||||
SOLDIERTYPE* TacticalCreateAdministrator();
|
||||
SOLDIERTYPE* TacticalCreateEliteEnemy();
|
||||
SOLDIERTYPE* TacticalCreateArmyTroop();
|
||||
SOLDIERTYPE* TacticalCreateZombie(); // Flugente Zombies
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
SOLDIERTYPE* TacticalCreateZombie(); // Flugente Zombies
|
||||
#endif
|
||||
SOLDIERTYPE* TacticalCreateMilitia( UINT8 ubMilitiaClass );
|
||||
SOLDIERTYPE* TacticalCreateCreature( INT8 bCreatureBodyType );
|
||||
|
||||
|
||||
@@ -275,11 +275,14 @@ void HandleTacticalEndTurn( )
|
||||
|
||||
// Flugente: Cool down all items not in a soldier's inventory
|
||||
CoolDownWorldItems( FALSE );
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: raise zombies if in gamescreen and option set
|
||||
if ( guiCurrentScreen == GAME_SCREEN )
|
||||
{
|
||||
RaiseZombies();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -464,11 +464,14 @@ void EndTurnEvents( void )
|
||||
|
||||
// Flugente: Cool down all items not in a soldier's inventory
|
||||
CoolDownWorldItems( FALSE );
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: raise zombies if in gamescreen and option set
|
||||
if ( guiCurrentScreen == GAME_SCREEN )
|
||||
{
|
||||
RaiseZombies();
|
||||
}
|
||||
#endif
|
||||
|
||||
// decay AI warning values from corpses
|
||||
DecayRottingCorpseAIWarnings();
|
||||
|
||||
@@ -8635,12 +8635,14 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
|
||||
INT8 bStatLoss = 0;
|
||||
UINT8 ubAmmoType;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( pTarget->IsZombie() && gGameExternalOptions.fZombieOnlyHeadshotsWork )
|
||||
{
|
||||
// if bullet does not hits anything other than the head, it doesn't do any damage
|
||||
if ( ubHitLocation != AIM_SHOT_HEAD )
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// NOTE: reduction of bullet impact due to range and obstacles is handled
|
||||
// in MoveBullet.
|
||||
|
||||
@@ -4764,7 +4764,11 @@ void DebugSoldierPage4( )
|
||||
case SOLDIER_CLASS_REG_MILITIA: gprintf( 320, LINE_HEIGHT * ubLine, L"(Reg Militia)" ); break;
|
||||
case SOLDIER_CLASS_ELITE_MILITIA: gprintf( 320, LINE_HEIGHT * ubLine, L"(Elite Militia)" ); break;
|
||||
case SOLDIER_CLASS_MINER: gprintf( 320, LINE_HEIGHT * ubLine, L"(Miner)" ); break;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
case SOLDIER_CLASS_ZOMBIE: gprintf( 320, LINE_HEIGHT * ubLine, L"(Zombie)" ); break;
|
||||
#endif
|
||||
|
||||
default: break; //don't care (don't write anything)
|
||||
}
|
||||
ubLine++;
|
||||
|
||||
@@ -172,12 +172,14 @@ void CreatureCall( SOLDIERTYPE * pCaller );
|
||||
INT8 CreatureDecideAction( SOLDIERTYPE * pCreature );
|
||||
void CreatureDecideAlertStatus( SOLDIERTYPE *pCreature );
|
||||
|
||||
// Flugente: Zombie AI
|
||||
INT8 ZombieDecideAction( SOLDIERTYPE * pZombie );
|
||||
void ZombieDecideAlertStatus( SOLDIERTYPE *pZombie );
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: Zombie AI
|
||||
INT8 ZombieDecideAction( SOLDIERTYPE * pZombie );
|
||||
void ZombieDecideAlertStatus( SOLDIERTYPE *pZombie );
|
||||
|
||||
// a variant of ClosestSeenOpponent(...), that allows zombies
|
||||
INT32 ClosestSeenOpponentforZombie(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel);
|
||||
// a variant of ClosestSeenOpponent(...), that allows zombies
|
||||
INT32 ClosestSeenOpponentforZombie(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel);
|
||||
#endif
|
||||
|
||||
INT8 CrowDecideAction( SOLDIERTYPE * pSoldier );
|
||||
void DecideAlertStatus( SOLDIERTYPE *pSoldier );
|
||||
@@ -241,9 +243,11 @@ INT8 FindDirectionForClimbing( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel
|
||||
|
||||
// HEADROCK HAM B2.7: Functions to assist group AI
|
||||
// WANNE: Headrock informed me that I should disable these 3 functions in code, because they need a lot of CPU during AI calculation.
|
||||
/*
|
||||
INT16 AssessTacticalSituation( INT8 bSide );
|
||||
BOOLEAN TeamSeesOpponent( INT8 bSide, SOLDIERTYPE * pOpponent );
|
||||
INT32 CalcStraightThreatValue( SOLDIERTYPE *pEnemy );
|
||||
*/
|
||||
|
||||
// SANDRO - added following functions
|
||||
BOOLEAN DoctorIsPresent( SOLDIERTYPE * pPatient, BOOLEAN fOnDoctorAssignmentCheck );
|
||||
|
||||
@@ -1616,6 +1616,8 @@ fprintf(NetDebugFile,"\tNPC %d, dtctLvl %d, marking mine at gridno %d, gridCost
|
||||
|
||||
void TurnBasedHandleNPCAI(SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
|
||||
// added by Flugente: static pointers, used to break out of an endless circles (currently only used for zombie AI)
|
||||
static SOLDIERTYPE* pLastDecisionSoldier = NULL;
|
||||
static INT16 lastdecisioncount = 0;
|
||||
@@ -1642,6 +1644,7 @@ void TurnBasedHandleNPCAI(SOLDIERTYPE *pSoldier)
|
||||
pLastDecisionSoldier = pSoldier;
|
||||
lastdecisioncount = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
if (Status.gamePaused)
|
||||
@@ -1930,11 +1933,15 @@ void TurnBasedHandleNPCAI(SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
if (!(gTacticalStatus.uiFlags & ENGAGED_IN_CONV))
|
||||
{
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( pSoldier->IsZombie() )
|
||||
{
|
||||
pSoldier->aiData.bAction = ZombieDecideAction(pSoldier);
|
||||
}
|
||||
else if (CREATURE_OR_BLOODCAT( pSoldier ))
|
||||
#else
|
||||
if (CREATURE_OR_BLOODCAT( pSoldier ))
|
||||
#endif
|
||||
{
|
||||
pSoldier->aiData.bAction = CreatureDecideAction( pSoldier );
|
||||
}
|
||||
@@ -2000,7 +2007,9 @@ void TurnBasedHandleNPCAI(SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
// turn based... abort this guy's turn
|
||||
EndAIGuysTurn( pSoldier );
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
lastdecisioncount = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2281,8 +2290,10 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
|
||||
StartEnemyTaunt( pSoldier, TAUNT_SEEK_NOISE );
|
||||
else if (pSoldier->aiData.bAction == AI_ACTION_RUN_AWAY )
|
||||
StartEnemyTaunt( pSoldier, TAUNT_RUN_AWAY );
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
else if ( pSoldier->IsZombie() ) // Madd: Zombies randomly moan...
|
||||
pSoldier->DoMercBattleSound( (INT8)( BATTLE_SOUND_LAUGH1 ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
case AI_ACTION_APPROACH_MERC: // walk up to someone to talk
|
||||
|
||||
+83
-79
@@ -1296,98 +1296,100 @@ INT32 ClosestSeenOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLeve
|
||||
|
||||
|
||||
// special variant with a minor twist for the zombie AI
|
||||
INT32 ClosestSeenOpponentforZombie(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel)
|
||||
{
|
||||
INT32 sGridNo, sClosestOpponent = NOWHERE;
|
||||
UINT32 uiLoop;
|
||||
INT32 iRange, iClosestRange = 1500;
|
||||
INT8 *pbPersOL;
|
||||
INT8 bLevel, bClosestLevel;
|
||||
SOLDIERTYPE * pOpp;
|
||||
|
||||
bClosestLevel = -1;
|
||||
|
||||
// look through this man's personal & public opplists for opponents known
|
||||
for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++)
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
INT32 ClosestSeenOpponentforZombie(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel)
|
||||
{
|
||||
pOpp = MercSlots[ uiLoop ];
|
||||
INT32 sGridNo, sClosestOpponent = NOWHERE;
|
||||
UINT32 uiLoop;
|
||||
INT32 iRange, iClosestRange = 1500;
|
||||
INT8 *pbPersOL;
|
||||
INT8 bLevel, bClosestLevel;
|
||||
SOLDIERTYPE * pOpp;
|
||||
|
||||
// if this merc is inactive, at base, on assignment, or dead
|
||||
if (!pOpp)
|
||||
bClosestLevel = -1;
|
||||
|
||||
// look through this man's personal & public opplists for opponents known
|
||||
for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++)
|
||||
{
|
||||
continue; // next merc
|
||||
pOpp = MercSlots[ uiLoop ];
|
||||
|
||||
// if this merc is inactive, at base, on assignment, or dead
|
||||
if (!pOpp)
|
||||
{
|
||||
continue; // next merc
|
||||
}
|
||||
|
||||
// if this merc is neutral/on same side, he's not an opponent
|
||||
if ( CONSIDERED_NEUTRAL( pSoldier, pOpp ) || (pSoldier->bSide == pOpp->bSide))
|
||||
{
|
||||
continue; // next merc
|
||||
}
|
||||
|
||||
// Special stuff for Carmen the bounty hunter
|
||||
if (pSoldier->aiData.bAttitude == ATTACKSLAYONLY && pOpp->ubProfile != 64)
|
||||
{
|
||||
continue; // next opponent
|
||||
}
|
||||
|
||||
pbPersOL = pSoldier->aiData.bOppList + pOpp->ubID;
|
||||
|
||||
// if this opponent is not seen personally
|
||||
if (*pbPersOL != SEEN_CURRENTLY)
|
||||
{
|
||||
continue; // next merc
|
||||
}
|
||||
|
||||
// since we're dealing with seen people, use exact gridnos
|
||||
sGridNo = pOpp->sGridNo;
|
||||
bLevel = pOpp->pathing.bLevel;
|
||||
|
||||
// if we are standing at that gridno(!, obviously our info is old...)
|
||||
if (sGridNo == pSoldier->sGridNo)
|
||||
{
|
||||
continue; // next merc
|
||||
}
|
||||
|
||||
// special: allow zombies to also find opponents on a roof
|
||||
// otherwise they have will never decide to climb a roof while they are seeing an enemy
|
||||
// this function is used only for turning towards closest opponent or changing stance
|
||||
// as such, if they AI is in a building,
|
||||
// we should ignore people who are on the roof of the same building as the AI
|
||||
if ( !pSoldier->IsZombie() && (bLevel != pSoldier->pathing.bLevel) && SameBuilding( pSoldier->sGridNo, sGridNo ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// I hope this will be good enough; otherwise we need a fractional/world-units-based 2D distance function
|
||||
//sRange = PythSpacesAway( pSoldier->sGridNo, sGridNo);
|
||||
iRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sGridNo );
|
||||
|
||||
if (iRange < iClosestRange)
|
||||
{
|
||||
iClosestRange = iRange;
|
||||
sClosestOpponent = sGridNo;
|
||||
bClosestLevel = bLevel;
|
||||
}
|
||||
}
|
||||
|
||||
// if this merc is neutral/on same side, he's not an opponent
|
||||
if ( CONSIDERED_NEUTRAL( pSoldier, pOpp ) || (pSoldier->bSide == pOpp->bSide))
|
||||
#ifdef DEBUGDECISIONS
|
||||
if (!TileIsOutOfBounds(sClosestOpponent))
|
||||
{
|
||||
continue; // next merc
|
||||
AINumMessage("CLOSEST OPPONENT is at gridno ",sClosestOpponent);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Special stuff for Carmen the bounty hunter
|
||||
if (pSoldier->aiData.bAttitude == ATTACKSLAYONLY && pOpp->ubProfile != 64)
|
||||
if (psGridNo)
|
||||
{
|
||||
continue; // next opponent
|
||||
*psGridNo = sClosestOpponent;
|
||||
}
|
||||
|
||||
pbPersOL = pSoldier->aiData.bOppList + pOpp->ubID;
|
||||
|
||||
// if this opponent is not seen personally
|
||||
if (*pbPersOL != SEEN_CURRENTLY)
|
||||
if (pbLevel)
|
||||
{
|
||||
continue; // next merc
|
||||
*pbLevel = bClosestLevel;
|
||||
}
|
||||
|
||||
// since we're dealing with seen people, use exact gridnos
|
||||
sGridNo = pOpp->sGridNo;
|
||||
bLevel = pOpp->pathing.bLevel;
|
||||
|
||||
// if we are standing at that gridno(!, obviously our info is old...)
|
||||
if (sGridNo == pSoldier->sGridNo)
|
||||
{
|
||||
continue; // next merc
|
||||
}
|
||||
|
||||
// special: allow zombies to also find opponents on a roof
|
||||
// otherwise they have will never decide to climb a roof while they are seeing an enemy
|
||||
// this function is used only for turning towards closest opponent or changing stance
|
||||
// as such, if they AI is in a building,
|
||||
// we should ignore people who are on the roof of the same building as the AI
|
||||
if ( !pSoldier->IsZombie() && (bLevel != pSoldier->pathing.bLevel) && SameBuilding( pSoldier->sGridNo, sGridNo ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// I hope this will be good enough; otherwise we need a fractional/world-units-based 2D distance function
|
||||
//sRange = PythSpacesAway( pSoldier->sGridNo, sGridNo);
|
||||
iRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sGridNo );
|
||||
|
||||
if (iRange < iClosestRange)
|
||||
{
|
||||
iClosestRange = iRange;
|
||||
sClosestOpponent = sGridNo;
|
||||
bClosestLevel = bLevel;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUGDECISIONS
|
||||
if (!TileIsOutOfBounds(sClosestOpponent))
|
||||
{
|
||||
AINumMessage("CLOSEST OPPONENT is at gridno ",sClosestOpponent);
|
||||
return( sClosestOpponent );
|
||||
}
|
||||
#endif
|
||||
|
||||
if (psGridNo)
|
||||
{
|
||||
*psGridNo = sClosestOpponent;
|
||||
}
|
||||
if (pbLevel)
|
||||
{
|
||||
*pbLevel = bClosestLevel;
|
||||
}
|
||||
return( sClosestOpponent );
|
||||
}
|
||||
|
||||
|
||||
INT32 ClosestPC( SOLDIERTYPE *pSoldier, INT32 * psDistance )
|
||||
{
|
||||
@@ -2581,9 +2583,11 @@ UINT8 SoldierDifficultyLevel( SOLDIERTYPE * pSoldier )
|
||||
bDifficulty = 4;
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
case SOLDIER_CLASS_ZOMBIE:
|
||||
bDifficulty = bDifficultyBase;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
if (pSoldier->bTeam == CREATURE_TEAM)
|
||||
@@ -2733,7 +2737,7 @@ void AINameMessage(SOLDIERTYPE * pSoldier,const STR8 str,INT32 num)
|
||||
// friendlies. The idea is to return a value called "TacticalSituation" which can tell a combatant
|
||||
// whether he should try to undertake a smarter course of action.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
INT16 AssessTacticalSituation( INT8 bTeam )
|
||||
{
|
||||
UINT16 ubFriendlyTeamTacticalValue = 0;
|
||||
@@ -2815,7 +2819,7 @@ INT16 AssessTacticalSituation( INT8 bTeam )
|
||||
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// HEADROCK: Function to check whether a team can see the specified soldier.
|
||||
BOOLEAN TeamSeesOpponent( INT8 bTeam, SOLDIERTYPE * pOpponent )
|
||||
|
||||
+1918
-1905
File diff suppressed because it is too large
Load Diff
@@ -27,10 +27,12 @@ INT8 RTPlayerDecideAction( SOLDIERTYPE * pSoldier )
|
||||
{
|
||||
bAction = DecideAutoBandage( pSoldier );
|
||||
}
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
else if ( pSoldier->IsZombie() )
|
||||
{
|
||||
bAction = ZombieDecideAction( pSoldier );
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
bAction = DecideAction( pSoldier );
|
||||
@@ -51,10 +53,12 @@ INT8 RTDecideAction(SOLDIERTYPE *pSoldier)
|
||||
{
|
||||
return( CreatureDecideAction( pSoldier ) );
|
||||
}
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
else if ( pSoldier->IsZombie() )
|
||||
{
|
||||
return( ZombieDecideAction( pSoldier ) );
|
||||
}
|
||||
#endif
|
||||
else if (pSoldier->ubBodyType == CROW)
|
||||
{
|
||||
return( CrowDecideAction( pSoldier ) );
|
||||
|
||||
@@ -1582,8 +1582,25 @@ BOOLEAN DamageSoldierFromBlast( UINT8 ubPerson, UINT8 ubOwner, INT32 sBombGridNo
|
||||
sNewWoundAmt = max( 1, (INT16)(sNewWoundAmt * (100 - gSkillTraitValues.ubBBDamageResistance) / 100));
|
||||
|
||||
// Flugente: moved the damage calculation into a separate function
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( pSoldier->GetDamageResistance(FALSE, FALSE) > 0 )
|
||||
sNewWoundAmt -= ((sNewWoundAmt * pSoldier->GetDamageResistance(FALSE, FALSE)) /100);
|
||||
#else
|
||||
// Damage resistance for Militia
|
||||
if (pSoldier->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.bGreenMilitiaDamageResistance != 0)
|
||||
sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.bGreenMilitiaDamageResistance) /100);
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.bRegularMilitiaDamageResistance != 0)
|
||||
sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.bRegularMilitiaDamageResistance) /100);
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.bVeteranMilitiaDamageResistance != 0)
|
||||
sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.bVeteranMilitiaDamageResistance) /100);
|
||||
// bonus for enemy too
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminDamageResistance != 0)
|
||||
sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.sEnemyAdminDamageResistance) /100);
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularDamageResistance != 0)
|
||||
sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.sEnemyRegularDamageResistance) /100);
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteDamageResistance != 0)
|
||||
sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.sEnemyEliteDamageResistance) /100);
|
||||
#endif
|
||||
|
||||
// we can loose stats due to being hit by the blast
|
||||
else if ( gGameOptions.fNewTraitSystem && Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_NORMAL &&
|
||||
@@ -1782,6 +1799,38 @@ BOOLEAN DamageSoldierFromBlast( UINT8 ubPerson, UINT8 ubOwner, INT32 sBombGridNo
|
||||
sNewWoundAmt = max(1, sNewWoundAmt);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Nothing to do here
|
||||
#else
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// SANDRO - option to make special NPCs stronger - damage resistance
|
||||
if (gGameExternalOptions.usSpecialNPCStronger > 0)
|
||||
{
|
||||
switch( pSoldier->ubProfile )
|
||||
{
|
||||
case CARMEN:
|
||||
case QUEEN:
|
||||
case JOE:
|
||||
case ANNIE:
|
||||
case CHRIS:
|
||||
case KINGPIN:
|
||||
case TIFFANY:
|
||||
case T_REX:
|
||||
case DRUGGIST:
|
||||
case GENERAL:
|
||||
case JACK:
|
||||
case OLAF:
|
||||
case RAY:
|
||||
case OLGA:
|
||||
case TYRONE:
|
||||
case MIKE:
|
||||
sNewWoundAmt -= (sNewWoundAmt * gGameExternalOptions.usSpecialNPCStronger / 200);
|
||||
sNewWoundAmt = max( 1, sNewWoundAmt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// SANDRO - new merc records - times wounded (blasted by explosion)
|
||||
if ( ( sNewWoundAmt > 1 || sBreathAmt > 1000 ) && pSoldier->ubProfile != NO_PROFILE )
|
||||
@@ -1882,7 +1931,11 @@ BOOLEAN DishOutGasDamage( SOLDIERTYPE * pSoldier, EXPLOSIVETYPE * pExplosive, IN
|
||||
if ( pExplosive->ubType == EXPLOSV_TEARGAS )
|
||||
{
|
||||
// zombies and robots are unaffected by tear gas
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
if ( AM_A_ROBOT( pSoldier ) || pSoldier->IsZombie() )
|
||||
#else
|
||||
if ( AM_A_ROBOT( pSoldier ) )
|
||||
#endif
|
||||
{
|
||||
return( fRecompileMovementCosts );
|
||||
}
|
||||
@@ -1896,8 +1949,12 @@ BOOLEAN DishOutGasDamage( SOLDIERTYPE * pSoldier, EXPLOSIVETYPE * pExplosive, IN
|
||||
}
|
||||
else if ( pExplosive->ubType == EXPLOSV_MUSTGAS )
|
||||
{
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// zombies and robots are unaffected by mustard gas
|
||||
if ( AM_A_ROBOT( pSoldier ) || pSoldier->IsZombie() )
|
||||
#else
|
||||
if ( AM_A_ROBOT( pSoldier ) )
|
||||
#endif
|
||||
{
|
||||
return( fRecompileMovementCosts );
|
||||
}
|
||||
|
||||
@@ -5115,7 +5115,10 @@ STR16 zOptionsToggleText[] =
|
||||
L"自动加速敌军回合", // Automatic fast forward through AI turns
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"Allow Zombies", // TODO.Translate
|
||||
#endif
|
||||
|
||||
L"--作弊模式选项--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"强制 Bobby Ray 送货", // force all pending Bobby Ray shipments
|
||||
L"-----------------", // TOPTION_CHEAT_MODE_OPTIONS_END
|
||||
@@ -5228,7 +5231,10 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"打开时,敌军回合将被大幅加速。",
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
#endif
|
||||
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"强制 Bobby Ray 出货",
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_END",
|
||||
|
||||
@@ -5114,7 +5114,10 @@ STR16 zOptionsToggleText[] =
|
||||
L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"Allow Zombies", // TODO.Translate
|
||||
#endif
|
||||
|
||||
L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments
|
||||
L"-----------------", // TOPTION_CHEAT_MODE_OPTIONS_END
|
||||
@@ -5227,7 +5230,10 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"When ON, AI turns will be much faster.", // TODO.Translate
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
#endif
|
||||
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"Force all pending Bobby Ray shipments",
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_END",
|
||||
|
||||
@@ -5113,7 +5113,10 @@ STR16 zOptionsToggleText[] =
|
||||
L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"Allow Zombies", // Flugente Zombies 1.0
|
||||
#endif
|
||||
|
||||
L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments
|
||||
L"-----------------", // TOPTION_CHEAT_MODE_OPTIONS_END
|
||||
@@ -5226,7 +5229,10 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"When ON, AI turns will be much faster.",
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"When ON, zombies will spawn. Be aware!", // allow zombies
|
||||
#endif
|
||||
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"Force all pending Bobby Ray shipments",
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_END",
|
||||
|
||||
@@ -5104,7 +5104,10 @@ STR16 zOptionsToggleText[] =
|
||||
L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"Allow Zombies", // Flugente Zombies 1.0
|
||||
#endif
|
||||
|
||||
L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Forcer envois Bobby Ray", // force all pending Bobby Ray shipments
|
||||
L"-----------------", // TOPTION_CHEAT_MODE_OPTIONS_END
|
||||
@@ -5217,7 +5220,10 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"When ON, AI turns will be much faster.", // TODO.Translate
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
#endif
|
||||
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"Forcer tous les envois en attente de Bobby Ray",
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_END",
|
||||
|
||||
@@ -4962,7 +4962,10 @@ STR16 zOptionsToggleText[] =
|
||||
L"Autom. schnelle Gegner-Züge", // Automatic fast forward through AI turns
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"Allow Zombies", // Flugente Zombies 1.0
|
||||
#endif
|
||||
|
||||
L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Erzwinge BR Lieferung", // force all pending Bobby Ray shipments
|
||||
L"-----------------", // TOPTION_CHEAT_MODE_OPTIONS_END
|
||||
@@ -5075,7 +5078,10 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"Wenn diese Funktion aktiviert ist, werden gegnerische Züge schneller durchgeführt.",
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
#endif
|
||||
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"Force all pending Bobby Ray shipments",
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_END",
|
||||
|
||||
@@ -5099,7 +5099,10 @@ STR16 zOptionsToggleText[] =
|
||||
L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"Allow Zombies", // Flugente Zombies 1.0
|
||||
#endif
|
||||
|
||||
L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments
|
||||
L"-----------------", // TOPTION_CHEAT_MODE_OPTIONS_END
|
||||
@@ -5212,7 +5215,10 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"When ON, AI turns will be much faster.", // TODO.Translate
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
#endif
|
||||
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"Force all pending Bobby Ray shipments",
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_END",
|
||||
|
||||
@@ -5111,7 +5111,10 @@ STR16 zOptionsToggleText[] =
|
||||
L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"Allow Zombies", // Flugente Zombies 1.0
|
||||
#endif
|
||||
|
||||
L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments
|
||||
L"-----------------", // TOPTION_CHEAT_MODE_OPTIONS_END
|
||||
@@ -5224,7 +5227,10 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"When ON, AI turns will be much faster.", // TODO.Translate
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
#endif
|
||||
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"WymuŚ wszystkie oczekiwane dostawy od Bobby Ray's.",
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_END",
|
||||
|
||||
@@ -5094,7 +5094,10 @@ STR16 zOptionsToggleText[] =
|
||||
L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"Allow Zombies", // Flugente Zombies 1.0
|
||||
#endif
|
||||
|
||||
L"--Читерские настройки--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Ускорить доставку Бобби Рэя", // force all pending Bobby Ray shipments
|
||||
L"-----------------", // TOPTION_CHEAT_MODE_OPTIONS_END
|
||||
@@ -5207,7 +5210,10 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"When ON, AI turns will be much faster.", // TODO.Translate
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
#endif
|
||||
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"Выберите этот пункт чтобы груз Бобби Рэя прибыл немедленно.",
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_END",
|
||||
|
||||
@@ -5115,7 +5115,10 @@ STR16 zOptionsToggleText[] =
|
||||
L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"Allow Zombies", // Flugente Zombies 1.0
|
||||
#endif
|
||||
|
||||
L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER,
|
||||
L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments
|
||||
L"-----------------", // TOPTION_CHEAT_MODE_OPTIONS_END
|
||||
@@ -5228,7 +5231,10 @@ STR16 zOptionsScreenHelpText[] =
|
||||
L"When ON, AI turns will be much faster.", // TODO.Translate
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate
|
||||
#endif
|
||||
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER",
|
||||
L"Force all pending Bobby Ray shipments",
|
||||
L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_END",
|
||||
|
||||
+13
-1
@@ -3,10 +3,22 @@
|
||||
|
||||
#include "Language Defines.h"
|
||||
|
||||
// -----------------------------
|
||||
// *****************************
|
||||
// WANNE: Enable this define, to build an executable where you can enable/disable zombies in tactical (ingame option screen).
|
||||
// It seems, that executables compiled with this zombie option turned on, causes slowdown in tactical.
|
||||
//#define ENABLE_ZOMBIES
|
||||
// -----------------------------
|
||||
// *****************************
|
||||
|
||||
// -----------------------------
|
||||
// *****************************
|
||||
// WANNE: Enable this define, to build the gameloop with the highspeed timer. To use the highspeed timer, you also have to set the HIGHSPEED_TIMER = TRUE in ja2.ini
|
||||
// CAUTION: A lot of games reported, when the exe is compiled with the highspeed timer on, the game runs very slowly in strategy map screen when doing repair, ..
|
||||
// This is the reason, why I made a compilation define, where we can turn on/off the highspeed timer.
|
||||
//#define USE_HIGHSPEED_GAMELOOP_TIMER
|
||||
#define USE_HIGHSPEED_GAMELOOP_TIMER
|
||||
// -----------------------------
|
||||
// *****************************
|
||||
|
||||
// -----------------------------
|
||||
// *****************************
|
||||
|
||||
Reference in New Issue
Block a user