- 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:
Wanne
2012-07-04 10:30:13 +00:00
parent e8027d6663
commit f40e7fb118
42 changed files with 2827 additions and 2479 deletions
+9 -5
View File
@@ -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 );
+11
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -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 ) );