mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
- AI controlled soldiers can now jump through windows
- new ini option allows to jump through closed windows, smashing them while doing so git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5682 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -1205,6 +1205,7 @@ void LoadGameExternalOptions()
|
||||
|
||||
//legion by Jazz
|
||||
gGameExternalOptions.fCanJumpThroughWindows = iniReader.ReadBoolean("Tactical Gameplay Settings","CAN_JUMP_THROUGH_WINDOWS", FALSE);
|
||||
gGameExternalOptions.fCanJumpThroughClosedWindows = iniReader.ReadBoolean("Tactical Gameplay Settings","CAN_JUMP_THROUGH_CLOSED_WINDOWS", TRUE);
|
||||
gGameExternalOptions.fCanClimbOnWalls = iniReader.ReadBoolean("Tactical Gameplay Settings","CAN_CLIMB_ON_WALLS", FALSE);
|
||||
|
||||
//legion by Jazz
|
||||
@@ -1395,6 +1396,7 @@ void LoadGameExternalOptions()
|
||||
gGameExternalOptions.fZombieSpawnWaves = iniReader.ReadInteger("Tactical Zombie Settings", "ZOMBIE_SPAWN_WAVES", FALSE);
|
||||
gGameExternalOptions.sZombieRiseWaveFrequency = iniReader.ReadInteger("Tactical Zombie Settings", "ZOMBIE_RISE_WAVE_FREQUENCY", 30, 0, 100);
|
||||
gGameExternalOptions.fZombieCanClimb = iniReader.ReadBoolean("Tactical Zombie Settings", "ZOMBIE_CAN_CLIMB", TRUE);
|
||||
gGameExternalOptions.fZombieCanJumpWindows = iniReader.ReadBoolean("Tactical Zombie Settings", "ZOMBIE_CAN_JUMP_WINDOWS", TRUE);
|
||||
gGameExternalOptions.fZombieExplodingCivs = iniReader.ReadBoolean("Tactical Zombie Settings", "ZOMBIE_EXPLODING_CIVS", FALSE);
|
||||
gGameExternalOptions.sEnemyZombieDamageResistance = iniReader.ReadInteger("Tactical Zombie Settings", "ZOMBIE_DAMAGE_RESISTANCE", 0, -50, 95);
|
||||
gGameExternalOptions.sEnemyZombieBreathDamageResistance = iniReader.ReadInteger("Tactical Zombie Settings", "ZOMBIE_BREATH_DAMAGE_RESISTANCE", 0, -50, 95);
|
||||
|
||||
@@ -377,6 +377,7 @@ typedef struct
|
||||
BOOLEAN fZombieSpawnWaves;
|
||||
INT8 sZombieRiseWaveFrequency;
|
||||
BOOLEAN fZombieCanClimb;
|
||||
BOOLEAN fZombieCanJumpWindows;
|
||||
BOOLEAN fZombieExplodingCivs;
|
||||
INT8 sEnemyZombieDamageResistance;
|
||||
INT8 sEnemyZombieBreathDamageResistance;
|
||||
@@ -1068,6 +1069,7 @@ typedef struct
|
||||
|
||||
//legion by Jazz
|
||||
BOOLEAN fCanJumpThroughWindows;
|
||||
BOOLEAN fCanJumpThroughClosedWindows;
|
||||
BOOLEAN fCanClimbOnWalls;
|
||||
|
||||
//legion by Jazz
|
||||
|
||||
@@ -8912,7 +8912,7 @@ void SOLDIERTYPE::BeginSoldierClimbUpRoof( void )
|
||||
this->ubPendingDirection = bNewDirection;
|
||||
//this->usPendingAnimation = CLIMBUPROOF;
|
||||
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
// Flugente: In case an animation is missing (zombies with bodytype of civilians), we TELEPORT instead
|
||||
if ( IsAnimationValidForBodyType( this, CLIMBUPROOF ) == FALSE )
|
||||
{
|
||||
@@ -8990,8 +8990,43 @@ void SOLDIERTYPE::BeginSoldierClimbWindow( void )
|
||||
EVENT_InternalSetSoldierDesiredDirection( this, bDirection, FALSE, this->usAnimState );
|
||||
this->flags.fTurningUntilDone = TRUE;
|
||||
// ATE: Reset flag to go back to prone...
|
||||
|
||||
// Flugente: In case an animation is missing (civilian bodytypes), we TELEPORT instead
|
||||
if ( IsAnimationValidForBodyType( this, JUMPWINDOWS ) == FALSE )
|
||||
{
|
||||
TeleportSoldier( this, this->sTempNewGridNo, TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
this->flags.bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
|
||||
this->usPendingAnimation = JUMPWINDOWS; //HOPFENCE;
|
||||
this->usPendingAnimation = JUMPWINDOWS;
|
||||
}
|
||||
|
||||
// Flugente: if an AI guy, end turn (weird endless clock syndrome)
|
||||
if ( this->bTeam != OUR_TEAM )
|
||||
EndAIGuysTurn( this);
|
||||
|
||||
// Flugente: if we are jumping through an intact window, smash it during our animation
|
||||
if ( gGameExternalOptions.fCanJumpThroughClosedWindows )
|
||||
{
|
||||
INT32 sNewGridNo = sGridNo;
|
||||
if (this->ubDirection == NORTH || this->ubDirection == WEST)
|
||||
sNewGridNo = NewGridNo( sGridNo, (UINT16)DirectionInc( (UINT8)this->ubDirection ) );
|
||||
|
||||
// is there really an intact window that we jump through?
|
||||
if ( IsJumpableWindowPresentAtGridNo( sNewGridNo, this->ubDirection, TRUE ) && !IsJumpableWindowPresentAtGridNo( sNewGridNo, this->ubDirection, FALSE ) )
|
||||
{
|
||||
STRUCTURE * pStructure = FindStructure( sNewGridNo, STRUCTURE_WALLNWINDOW );
|
||||
if ( pStructure && !( pStructure->fFlags & STRUCTURE_OPEN ) )
|
||||
{
|
||||
// intact window found. Smash it!
|
||||
WindowHit( sNewGridNo, pStructure->usStructureID, (this->ubDirection == SOUTH || this->ubDirection == EAST), TRUE );
|
||||
|
||||
// we get a bit of damage for jumping through a window
|
||||
this->SoldierTakeDamage( 0, 1, 0, 1000, TAKE_DAMAGE_ELECTRICITY, NOBODY, sNewGridNo, 0, TRUE );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "worlddef.h"
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include "GameSettings.h" // added by Flugente
|
||||
|
||||
#define PTR_CIVILIAN (pSoldier->bTeam == CIV_TEAM)
|
||||
#define PTR_CROUCHED (gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_CROUCH)
|
||||
|
||||
+11
-10
@@ -21,7 +21,7 @@ extern BOOLEAN DoesSAMExistHere( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ,
|
||||
|
||||
//----------------legion by Jazz
|
||||
|
||||
BOOLEAN IsJumpableWindowPresentAtGridNo( INT32 sGridNo, INT8 direction2 )
|
||||
BOOLEAN IsJumpableWindowPresentAtGridNo( INT32 sGridNo, INT8 direction2, BOOLEAN fIntactWindowsAlso )
|
||||
{
|
||||
STRUCTURE * pStructure;
|
||||
|
||||
@@ -29,16 +29,17 @@ BOOLEAN IsJumpableWindowPresentAtGridNo( INT32 sGridNo, INT8 direction2 )
|
||||
|
||||
if ( pStructure )
|
||||
{
|
||||
|
||||
if ( ( direction2 == SOUTH || direction2 == NORTH ) && (pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT || pStructure->ubWallOrientation == INSIDE_TOP_LEFT ) && pStructure->fFlags & STRUCTURE_WALLNWINDOW && !(pStructure->fFlags & STRUCTURE_SPECIAL) && ( pStructure->fFlags & STRUCTURE_OPEN ) )
|
||||
{
|
||||
return( TRUE );
|
||||
}
|
||||
if ( ( direction2 == SOUTH || direction2 == NORTH ) && (pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT || pStructure->ubWallOrientation == INSIDE_TOP_LEFT ) && pStructure->fFlags & STRUCTURE_WALLNWINDOW && !(pStructure->fFlags & STRUCTURE_SPECIAL) )
|
||||
{
|
||||
if ( fIntactWindowsAlso || ( pStructure->fFlags & STRUCTURE_OPEN ) )
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
if ( ( direction2 == EAST || direction2 == WEST ) && ( pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT || pStructure->ubWallOrientation == INSIDE_TOP_RIGHT ) && pStructure->fFlags & STRUCTURE_WALLNWINDOW && !(pStructure->fFlags & STRUCTURE_SPECIAL) && ( pStructure->fFlags & STRUCTURE_OPEN ) )
|
||||
{
|
||||
return( TRUE );
|
||||
}
|
||||
if ( ( direction2 == EAST || direction2 == WEST ) && ( pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT || pStructure->ubWallOrientation == INSIDE_TOP_RIGHT ) && pStructure->fFlags & STRUCTURE_WALLNWINDOW && !(pStructure->fFlags & STRUCTURE_SPECIAL) )
|
||||
{
|
||||
if ( fIntactWindowsAlso || ( pStructure->fFlags & STRUCTURE_OPEN ) )
|
||||
return( TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
return( FALSE );
|
||||
|
||||
@@ -50,7 +50,7 @@ BOOLEAN IsCorpseAtGridNo( INT32 sGridNo, UINT8 ubLevel );
|
||||
BOOLEAN SetOpenableStructureToClosed( INT32 sGridNo, UINT8 ubLevel );
|
||||
|
||||
//Legion by Jazz
|
||||
BOOLEAN IsJumpableWindowPresentAtGridNo( INT32 sGridNo , INT8 direction2 ); //legion 2 Windows
|
||||
BOOLEAN IsJumpableWindowPresentAtGridNo( INT32 sGridNo , INT8 direction2, BOOLEAN fIntactWindowsAlso ); //legion 2 Windows
|
||||
BOOLEAN IsLegionWallPresentAtGridno( INT32 sGridNo ); //legion 2 Fence
|
||||
|
||||
#endif
|
||||
@@ -177,11 +177,11 @@ void CreatureDecideAlertStatus( SOLDIERTYPE *pCreature );
|
||||
// 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);
|
||||
#endif
|
||||
|
||||
// a variant of ClosestSeenOpponent(...), that allows to find enemies on a roof
|
||||
INT32 ClosestSeenOpponentWithRoof(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel);
|
||||
|
||||
INT8 CrowDecideAction( SOLDIERTYPE * pSoldier );
|
||||
void DecideAlertStatus( SOLDIERTYPE *pSoldier );
|
||||
INT8 DecideAutoBandage( SOLDIERTYPE * pSoldier );
|
||||
|
||||
@@ -2845,6 +2845,11 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
|
||||
}
|
||||
break;
|
||||
|
||||
case AI_ACTION_JUMP_WINDOW:
|
||||
{
|
||||
pSoldier->BeginSoldierClimbWindow();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef BETAVERSION
|
||||
|
||||
+85
-80
@@ -578,6 +578,14 @@ BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier)
|
||||
//bMinPointsNeeded = GetAPsToStealItem( pSoldier, NULL, pSoldier->aiData.usActionData );;
|
||||
break;
|
||||
|
||||
case AI_ACTION_JUMP_WINDOW:
|
||||
if((UsingNewInventorySystem() == true) && pSoldier->inv[BPACKPOCKPOS].exists() == true)
|
||||
bMinPointsNeeded = GetAPsToJumpThroughWindows( pSoldier, TRUE );
|
||||
else
|
||||
bMinPointsNeeded = GetAPsToJumpFence( pSoldier, FALSE );
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef BETAVERSION
|
||||
//NumMessage("AffordableAction - Illegal action type = ",pSoldier->aiData.bAction);
|
||||
@@ -1299,101 +1307,98 @@ INT32 ClosestSeenOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLeve
|
||||
}
|
||||
|
||||
|
||||
// special variant with a minor twist for the zombie AI
|
||||
#ifdef ENABLE_ZOMBIES
|
||||
INT32 ClosestSeenOpponentforZombie(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel)
|
||||
// special variant with a minor twist
|
||||
INT32 ClosestSeenOpponentWithRoof(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++)
|
||||
{
|
||||
INT32 sGridNo, sClosestOpponent = NOWHERE;
|
||||
UINT32 uiLoop;
|
||||
INT32 iRange, iClosestRange = 1500;
|
||||
INT8 *pbPersOL;
|
||||
INT8 bLevel, bClosestLevel;
|
||||
SOLDIERTYPE * pOpp;
|
||||
pOpp = MercSlots[ uiLoop ];
|
||||
|
||||
bClosestLevel = -1;
|
||||
|
||||
// look through this man's personal & public opplists for opponents known
|
||||
for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++)
|
||||
// if this merc is inactive, at base, on assignment, or dead
|
||||
if (!pOpp)
|
||||
{
|
||||
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;
|
||||
}
|
||||
continue; // next merc
|
||||
}
|
||||
|
||||
#ifdef DEBUGDECISIONS
|
||||
if (!TileIsOutOfBounds(sClosestOpponent))
|
||||
// if this merc is neutral/on same side, he's not an opponent
|
||||
if ( CONSIDERED_NEUTRAL( pSoldier, pOpp ) || (pSoldier->bSide == pOpp->bSide))
|
||||
{
|
||||
AINumMessage("CLOSEST OPPONENT is at gridno ",sClosestOpponent);
|
||||
continue; // next merc
|
||||
}
|
||||
#endif
|
||||
|
||||
if (psGridNo)
|
||||
// Special stuff for Carmen the bounty hunter
|
||||
if (pSoldier->aiData.bAttitude == ATTACKSLAYONLY && pOpp->ubProfile != 64)
|
||||
{
|
||||
*psGridNo = sClosestOpponent;
|
||||
continue; // next opponent
|
||||
}
|
||||
if (pbLevel)
|
||||
|
||||
pbPersOL = pSoldier->aiData.bOppList + pOpp->ubID;
|
||||
|
||||
// if this opponent is not seen personally
|
||||
if (*pbPersOL != SEEN_CURRENTLY)
|
||||
{
|
||||
*pbLevel = bClosestLevel;
|
||||
continue; // next merc
|
||||
}
|
||||
return( sClosestOpponent );
|
||||
|
||||
// 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);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (psGridNo)
|
||||
{
|
||||
*psGridNo = sClosestOpponent;
|
||||
}
|
||||
if (pbLevel)
|
||||
{
|
||||
*pbLevel = bClosestLevel;
|
||||
}
|
||||
return( sClosestOpponent );
|
||||
}
|
||||
|
||||
INT32 ClosestPC( SOLDIERTYPE *pSoldier, INT32 * psDistance )
|
||||
{
|
||||
|
||||
+145
-2
@@ -5300,6 +5300,106 @@ INT16 ubMinAPCost;
|
||||
return( AI_ACTION_NONE );
|
||||
}
|
||||
|
||||
// get the location of the closest reachable opponent
|
||||
/* Flugente 22.02.2012 - A few clarifications: I changed ClosestSeenOpponent so that for zombies, this function also returns an opponent if he is on the
|
||||
* roof of a building, we are not, but our GridNo belongs to that same building.
|
||||
* If that is the case, it is clear that we have to get on that roof. However, we cannot do that in BlackState. If, by pure chance, we can still see our
|
||||
* enemy, we cannot climb (there is no climbing option in BlackState sofar).
|
||||
* So, I changed the code so that now we will climb the roof.
|
||||
*/
|
||||
INT32 targetGridNo = -1;
|
||||
INT8 targetbLevel = 0;
|
||||
sClosestOpponent = ClosestSeenOpponentWithRoof(pSoldier, &targetGridNo, &targetbLevel);
|
||||
if (!TileIsOutOfBounds(sClosestOpponent) && ! ( (targetbLevel != pSoldier->pathing.bLevel) && SameBuilding( pSoldier->sGridNo, targetGridNo ) ) )
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// GO DIRECTLY TOWARDS CLOSEST KNOWN OPPONENT
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// try to move towards him
|
||||
pSoldier->aiData.usActionData = GoAsFarAsPossibleTowards(pSoldier,sClosestOpponent,AI_ACTION_GET_CLOSER);
|
||||
|
||||
// if it's possible
|
||||
if (!TileIsOutOfBounds(sClosestOpponent))
|
||||
{
|
||||
if (targetbLevel != pSoldier->pathing.bLevel )
|
||||
return(AI_ACTION_MOVE_TO_CLIMB);
|
||||
else
|
||||
{
|
||||
// Flugente: if on the same level and there is a jumpable window here, jump through it
|
||||
if ( gGameExternalOptions.fCanJumpThroughWindows && targetbLevel == pSoldier->pathing.bLevel && targetbLevel == 0 )
|
||||
{
|
||||
// determine if there is a jumpable window in the direction to our target
|
||||
// if yes, and we are not facing it, face it now
|
||||
// if yes, and we are facing it, jump
|
||||
// if no, go on, nothing to see here
|
||||
// determine direction of our target
|
||||
INT8 targetdirection = GetDirectionToGridNoFromGridNo(pSoldier->sGridNo, sClosestOpponent);
|
||||
|
||||
// determine if there is a jumpable window here, in the direction of our target
|
||||
// store old direction for this check
|
||||
INT tmpdirection = pSoldier->ubDirection;
|
||||
pSoldier->ubDirection = targetdirection;
|
||||
|
||||
INT8 windowdirection = DIRECTION_IRRELEVANT;
|
||||
if ( FindWindowJumpDirection(pSoldier, pSoldier->sGridNo, pSoldier->ubDirection, &windowdirection) && targetdirection == windowdirection )
|
||||
{
|
||||
pSoldier->ubDirection = tmpdirection;
|
||||
|
||||
// are we already looking in that direction?
|
||||
if ( pSoldier->ubDirection == targetdirection )
|
||||
{
|
||||
// jump through the window
|
||||
return(AI_ACTION_JUMP_WINDOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
// look into that direction
|
||||
if ( pSoldier->InternalIsValidStance( targetdirection, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) )
|
||||
{
|
||||
pSoldier->aiData.usActionData = targetdirection;
|
||||
return(AI_ACTION_CHANGE_FACING);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pSoldier->ubDirection = tmpdirection;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// The situation mentioned above happens...
|
||||
else if ( (targetbLevel != pSoldier->pathing.bLevel) && SameBuilding( pSoldier->sGridNo, targetGridNo ) )
|
||||
{
|
||||
if ( 1 )//gGameExternalOptions.fZombieCanClimb )
|
||||
{
|
||||
if (!TileIsOutOfBounds(targetGridNo) )
|
||||
{
|
||||
// need to climb AND have enough APs to get there this turn
|
||||
BOOLEAN fUp = TRUE;
|
||||
if (pSoldier->pathing.bLevel > 0 )
|
||||
fUp = FALSE;
|
||||
|
||||
if ( pSoldier->bActionPoints > GetAPsToClimbRoof ( pSoldier, fUp ) )
|
||||
{
|
||||
pSoldier->aiData.usActionData = targetGridNo;//FindClosestClimbPoint(pSoldier, fUp );
|
||||
|
||||
// Necessary test: can we climb up at this position? It might happen that our target is directly above us, then we'll have to move
|
||||
INT8 newdirection;
|
||||
if ( ( fUp && FindHeigherLevel( pSoldier, pSoldier->sGridNo, pSoldier->ubDirection, &newdirection ) ) || ( !fUp && FindLowerLevel( pSoldier, pSoldier->sGridNo, pSoldier->ubDirection, &newdirection ) ) )
|
||||
{
|
||||
return( AI_ACTION_CLIMB_ROOF );
|
||||
}
|
||||
else
|
||||
{
|
||||
return(AI_ACTION_SEEK_OPPONENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// try to make boxer close if possible
|
||||
if (pSoldier->flags.uiStatusFlags & SOLDIER_BOXER )
|
||||
{
|
||||
@@ -7853,7 +7953,7 @@ void DecideAlertStatus( SOLDIERTYPE *pSoldier )
|
||||
*/
|
||||
INT32 targetGridNo = -1;
|
||||
INT8 targetbLevel = 0;
|
||||
sClosestOpponent = ClosestSeenOpponentforZombie(pSoldier, &targetGridNo, &targetbLevel);
|
||||
sClosestOpponent = ClosestSeenOpponentWithRoof(pSoldier, &targetGridNo, &targetbLevel);
|
||||
if ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ZOMBIE )
|
||||
{
|
||||
if (!TileIsOutOfBounds(sClosestOpponent) && ! ( (targetbLevel != pSoldier->pathing.bLevel) && SameBuilding( pSoldier->sGridNo, targetGridNo ) ) )
|
||||
@@ -7866,14 +7966,57 @@ void DecideAlertStatus( SOLDIERTYPE *pSoldier )
|
||||
pSoldier->aiData.usActionData = GoAsFarAsPossibleTowards(pSoldier,sClosestOpponent,AI_ACTION_GET_CLOSER);
|
||||
|
||||
// if it's possible
|
||||
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
||||
if (!TileIsOutOfBounds(sClosestOpponent))
|
||||
{
|
||||
if (targetbLevel != pSoldier->pathing.bLevel && gGameExternalOptions.fZombieCanClimb )
|
||||
return(AI_ACTION_MOVE_TO_CLIMB);
|
||||
else
|
||||
{
|
||||
// Flugente: if on the same level and there is a jumpable window here, jump through it
|
||||
if ( gGameExternalOptions.fZombieCanJumpWindows && targetbLevel == pSoldier->pathing.bLevel && targetbLevel == 0 )
|
||||
{
|
||||
// determine if there is a jumpable window in the direction to our target
|
||||
// if yes, and we are not facing it, face it now
|
||||
// if yes, and we are facing it, jump
|
||||
// if no, go on, nothing to see here
|
||||
// determine direction of our target
|
||||
INT8 targetdirection = GetDirectionToGridNoFromGridNo(pSoldier->sGridNo, sClosestOpponent);
|
||||
|
||||
// determine if there is a jumpable window here, in the direction of our target
|
||||
// store old direction for this check
|
||||
INT tmpdirection = pSoldier->ubDirection;
|
||||
pSoldier->ubDirection = targetdirection;
|
||||
|
||||
INT8 windowdirection = DIRECTION_IRRELEVANT;
|
||||
if ( FindWindowJumpDirection(pSoldier, pSoldier->sGridNo, pSoldier->ubDirection, &windowdirection) && targetdirection == windowdirection )
|
||||
{
|
||||
pSoldier->ubDirection = tmpdirection;
|
||||
|
||||
// are we already looking in that direction?
|
||||
if ( pSoldier->ubDirection == targetdirection )
|
||||
{
|
||||
// jump through the window
|
||||
return(AI_ACTION_JUMP_WINDOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
// look into that direction
|
||||
if ( pSoldier->InternalIsValidStance( targetdirection, gAnimControl[ pSoldier->usAnimState ].ubEndHeight ) )
|
||||
{
|
||||
pSoldier->aiData.usActionData = targetdirection;
|
||||
return(AI_ACTION_CHANGE_FACING);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pSoldier->ubDirection = tmpdirection;
|
||||
}
|
||||
|
||||
return(AI_ACTION_SEEK_OPPONENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
// The situation mentioned above happens...
|
||||
else if ( (targetbLevel != pSoldier->pathing.bLevel) && SameBuilding( pSoldier->sGridNo, targetGridNo ) )
|
||||
{
|
||||
|
||||
@@ -100,6 +100,8 @@ typedef enum
|
||||
AI_ACTION_STEAL_MOVE, // added by SANDRO
|
||||
|
||||
AI_ACTION_RELOAD_GUN,
|
||||
|
||||
AI_ACTION_JUMP_WINDOW, // added by Flugente: jump through a window
|
||||
} ActionType;
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "overhead.h"
|
||||
#include "Random.h"
|
||||
#include "Pathai.h"
|
||||
#include "GameSettings.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
|
||||
@@ -210,7 +211,7 @@ BOOLEAN FindWindowJumpDirection( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bSta
|
||||
if (direction2 == NORTH || direction2 == WEST)
|
||||
{
|
||||
// IF there is a fence in this gridno, return false!
|
||||
if ( IsJumpableWindowPresentAtGridNo( sGridNo, direction2 ) )
|
||||
if ( IsJumpableWindowPresentAtGridNo( sGridNo, direction2, gGameExternalOptions.fCanJumpThroughClosedWindows ) )
|
||||
{
|
||||
return( FALSE );
|
||||
}
|
||||
@@ -241,7 +242,7 @@ BOOLEAN FindWindowJumpDirection( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bSta
|
||||
// ATE: Check if there is somebody waiting here.....
|
||||
|
||||
// Check if we have a fence here
|
||||
if ( IsJumpableWindowPresentAtGridNo( sNewGridNo , direction2) )
|
||||
if ( IsJumpableWindowPresentAtGridNo( sNewGridNo , direction2, gGameExternalOptions.fCanJumpThroughClosedWindows) )
|
||||
{
|
||||
fFound = TRUE;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user