mirror of
https://github.com/1dot13/source.git
synced 2026-08-26 14:30:26 +02:00
- New Feature: enemy assassins disguise as militia and can ambush player mercs
- Fix: invalid GridNo for mounting weapons git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5753 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -1459,6 +1459,59 @@ INT32 ClosestPC( SOLDIERTYPE *pSoldier, INT32 * psDistance )
|
||||
return( sGridNo );
|
||||
}
|
||||
|
||||
// Flugente: like ClosestPC(...), but does not account for covert or not visible mercs
|
||||
INT32 ClosestUnDisguisedPC( SOLDIERTYPE *pSoldier, INT32 * psDistance )
|
||||
{
|
||||
// used by NPCs... find the closest PC
|
||||
// NOTE: skips EPCs!
|
||||
|
||||
UINT8 ubLoop;
|
||||
SOLDIERTYPE *pTargetSoldier;
|
||||
INT32 sMinDist = WORLD_MAX;
|
||||
INT32 sDist;
|
||||
INT32 sGridNo = NOWHERE;
|
||||
|
||||
// Loop through all mercs on player team
|
||||
ubLoop = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
|
||||
for ( ; ubLoop <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ubLoop++)
|
||||
{
|
||||
pTargetSoldier = Menptr + ubLoop;
|
||||
|
||||
if (!pTargetSoldier->bActive || !pTargetSoldier->bInSector)
|
||||
continue;
|
||||
|
||||
// if not conscious, skip him
|
||||
if (pTargetSoldier->stats.bLife < OKLIFE)
|
||||
continue;
|
||||
|
||||
if ( AM_AN_EPC( pTargetSoldier ) )
|
||||
continue;
|
||||
|
||||
if ( pTargetSoldier->bSoldierFlagMask & (SOLDIER_COVERT_CIV|SOLDIER_COVERT_SOLDIER) )
|
||||
continue;
|
||||
|
||||
sDist = PythSpacesAway(pSoldier->sGridNo,pTargetSoldier->sGridNo);
|
||||
|
||||
// if this PC is not visible to the soldier, then add a penalty to the distance
|
||||
// so that we weight in favour of visible mercs
|
||||
if ( pTargetSoldier->bTeam != pSoldier->bTeam && pSoldier->aiData.bOppList[ ubLoop ] != SEEN_CURRENTLY )
|
||||
continue;
|
||||
|
||||
if (sDist < sMinDist)
|
||||
{
|
||||
sMinDist = sDist;
|
||||
sGridNo = pTargetSoldier->sGridNo;
|
||||
}
|
||||
}
|
||||
|
||||
if ( psDistance )
|
||||
{
|
||||
*psDistance = sMinDist;
|
||||
}
|
||||
|
||||
return( sGridNo );
|
||||
}
|
||||
|
||||
INT32 FindClosestClimbPointAvailableToAI( SOLDIERTYPE * pSoldier, INT32 sStartGridNo, INT32 sDesiredGridNo, BOOLEAN fClimbUp )
|
||||
{
|
||||
INT32 sGridNo;
|
||||
|
||||
@@ -440,7 +440,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns
|
||||
//NumMessage("SHOT AttackValue = ",iAttackValue / 1000);
|
||||
|
||||
// special stuff for assassins to ignore militia more
|
||||
if ( pSoldier->ubProfile >= JIM && pSoldier->ubProfile <= TYRONE && pOpponent->bTeam == MILITIA_TEAM )
|
||||
if ( pSoldier->IsAssassin() && pOpponent->bTeam == MILITIA_TEAM )
|
||||
{
|
||||
iAttackValue /= 2;
|
||||
}
|
||||
|
||||
+61
-19
@@ -662,14 +662,8 @@ INT8 DecideActionNamedNPC( SOLDIERTYPE * pSoldier )
|
||||
}
|
||||
}
|
||||
|
||||
switch( pSoldier->ubProfile )
|
||||
if ( pSoldier->IsAssassin() )
|
||||
{
|
||||
case JIM:
|
||||
case JACK:
|
||||
case OLAF:
|
||||
case RAY:
|
||||
case OLGA:
|
||||
case TYRONE:
|
||||
sDesiredMercLoc = ClosestPC( pSoldier, &sDesiredMercDist );
|
||||
|
||||
if (!TileIsOutOfBounds(sDesiredMercLoc))
|
||||
@@ -691,9 +685,6 @@ INT8 DecideActionNamedNPC( SOLDIERTYPE * pSoldier )
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return( AI_ACTION_NONE );
|
||||
@@ -838,9 +829,36 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
|
||||
}
|
||||
}
|
||||
|
||||
if (pSoldier->ubProfile != NO_PROFILE)
|
||||
if ( pSoldier->ubProfile != NO_PROFILE || pSoldier->IsAssassin() )
|
||||
{
|
||||
pSoldier->aiData.bAction = DecideActionNamedNPC( pSoldier );
|
||||
if ( pSoldier->ubProfile != NO_PROFILE )
|
||||
pSoldier->aiData.bAction = DecideActionNamedNPC( pSoldier );
|
||||
else
|
||||
{
|
||||
INT32 sDesiredMercDist;
|
||||
INT32 sDesiredMercLoc = ClosestUnDisguisedPC( pSoldier, &sDesiredMercDist );
|
||||
|
||||
if (!TileIsOutOfBounds(sDesiredMercLoc))
|
||||
{
|
||||
if ( sDesiredMercDist <= NPC_TALK_RADIUS * 2 )
|
||||
{
|
||||
AddToShouldBecomeHostileOrSayQuoteList( pSoldier->ubID );
|
||||
// now wait a bit!
|
||||
pSoldier->aiData.usActionData = 5000;
|
||||
pSoldier->aiData.bAction = AI_ACTION_WAIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSoldier->aiData.usActionData = GoAsFarAsPossibleTowards( pSoldier, sDesiredMercLoc, AI_ACTION_APPROACH_MERC );
|
||||
|
||||
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
||||
{
|
||||
pSoldier->aiData.bAction = AI_ACTION_APPROACH_MERC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( pSoldier->aiData.bAction != AI_ACTION_NONE )
|
||||
{
|
||||
return( pSoldier->aiData.bAction );
|
||||
@@ -852,9 +870,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
|
||||
}
|
||||
// turn off counter so we don't check it again
|
||||
pSoldier->uiTimeSinceLastSpoke = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// if not in the way, do nothing most of the time
|
||||
@@ -1440,18 +1456,44 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
|
||||
// ******************
|
||||
// REAL TIME NPC CODE
|
||||
// ******************
|
||||
if (pSoldier->ubProfile != NO_PROFILE)
|
||||
if (pSoldier->ubProfile != NO_PROFILE || pSoldier->IsAssassin() )
|
||||
{
|
||||
pSoldier->aiData.bAction = DecideActionNamedNPC( pSoldier );
|
||||
if ( pSoldier->ubProfile != NO_PROFILE )
|
||||
pSoldier->aiData.bAction = DecideActionNamedNPC( pSoldier );
|
||||
else
|
||||
{
|
||||
INT32 sDesiredMercDist;
|
||||
INT32 sDesiredMercLoc = ClosestUnDisguisedPC( pSoldier, &sDesiredMercDist );
|
||||
|
||||
// Flugente: if this guy is disguised, do not consider him
|
||||
|
||||
if (!TileIsOutOfBounds(sDesiredMercLoc))
|
||||
{
|
||||
if ( sDesiredMercDist <= NPC_TALK_RADIUS * 2 )
|
||||
{
|
||||
AddToShouldBecomeHostileOrSayQuoteList( pSoldier->ubID );
|
||||
// now wait a bit!
|
||||
pSoldier->aiData.usActionData = 5000;
|
||||
pSoldier->aiData.bAction = AI_ACTION_WAIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSoldier->aiData.usActionData = GoAsFarAsPossibleTowards( pSoldier, sDesiredMercLoc, AI_ACTION_APPROACH_MERC );
|
||||
|
||||
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
||||
{
|
||||
pSoldier->aiData.bAction = AI_ACTION_APPROACH_MERC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( pSoldier->aiData.bAction != AI_ACTION_NONE )
|
||||
{
|
||||
return( pSoldier->aiData.bAction );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// determine the most important noise heard, and its relative value
|
||||
|
||||
@@ -162,6 +162,7 @@ INT8 ClosestPanicTrigger( SOLDIERTYPE * pSoldier );
|
||||
|
||||
INT32 ClosestKnownOpponent(SOLDIERTYPE *pSoldier, INT32 * psGridNo, INT8 * pbLevel);
|
||||
INT32 ClosestPC( SOLDIERTYPE *pSoldier, INT32 * psDistance );
|
||||
INT32 ClosestUnDisguisedPC( SOLDIERTYPE *pSoldier, INT32 * psDistance ); // Flugente: like ClosestPC(...), but does not account for covert or not visible mercs
|
||||
BOOLEAN CanAutoBandage( BOOLEAN fDoFullCheck );
|
||||
|
||||
void DebugAI( STR szOutput );
|
||||
|
||||
Reference in New Issue
Block a user