mirror of
https://github.com/1dot13/source.git
synced 2026-09-02 14:36:06 +02:00
New feature: delayed grenade explosions:
- use transformation menu to change explosion mode - only Normal/Stun/Flashbang type grenades can be delayed - AI soldiers will avoid staying close to armed grenades\explosives - use option DELAYED_GRENADE_EXPLOSION to make all hand\GL grenades work as delayed - new value AP_GRENADE_MODE = 4 in APBPConstants.ini - new item flag DELAYED_GRENADE_EXPLOSION Other changes: - fixed call to sqrt in DrawExplosionWarning() that prevented compiling in VS2010 - correctly update interface after transformations - PATHAI: AI soldiers will skip gassed tiles if not in gas already - InGas check: AI soldiers will avoid mustard gas even when wearing gas mask - Yellow AI: added check to avoid gas/water/bomb using FindNearestUngassedLand - gas/flare grenades will always explode instantly even when in bad state - LegalNPCDestination: locations near armed bombs are not legal - FindBestNearbyCover: avoid locations near armed bombs git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8324 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
+50
-3
@@ -2011,7 +2011,8 @@ INT16 InWaterOrGas(SOLDIERTYPE *pSoldier, INT32 sGridNo)
|
||||
}
|
||||
|
||||
BOOLEAN InGas( SOLDIERTYPE *pSoldier, INT32 sGridNo )
|
||||
{//WarmSteel - One square away from gas is still considered in gas, because it could expand any moment.
|
||||
{
|
||||
//WarmSteel - One square away from gas is still considered in gas, because it could expand any moment.
|
||||
//Note: this only works for gas that expands with one tile, but hey it's better than nothing!
|
||||
int iNeighbourGridNo;
|
||||
for(int iDir = 0; iDir < NUM_WORLD_DIRECTIONS; ++iDir)
|
||||
@@ -2020,12 +2021,13 @@ BOOLEAN InGas( SOLDIERTYPE *pSoldier, INT32 sGridNo )
|
||||
if(!TileIsOutOfBounds(iNeighbourGridNo))
|
||||
{
|
||||
// tear/mustard gas
|
||||
if((gpWorldLevelData[iNeighbourGridNo].ubExtFlags[pSoldier->pathing.bLevel] & (MAPELEMENT_EXT_TEARGAS|MAPELEMENT_EXT_MUSTARDGAS)) && !DoesSoldierWearGasMask(pSoldier))//dnl ch40 200909
|
||||
if((gpWorldLevelData[iNeighbourGridNo].ubExtFlags[pSoldier->pathing.bLevel] & (MAPELEMENT_EXT_TEARGAS)) && !DoesSoldierWearGasMask(pSoldier))//dnl ch40 200909
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
// sevenfm: avoid mustard gas even when wearing gas mask
|
||||
// fire/creature gas
|
||||
if(gpWorldLevelData[iNeighbourGridNo].ubExtFlags[pSoldier->pathing.bLevel] & (MAPELEMENT_EXT_BURNABLEGAS|MAPELEMENT_EXT_CREATUREGAS))//dnl ch62 240813
|
||||
if(gpWorldLevelData[iNeighbourGridNo].ubExtFlags[pSoldier->pathing.bLevel] & (MAPELEMENT_EXT_MUSTARDGAS|MAPELEMENT_EXT_BURNABLEGAS|MAPELEMENT_EXT_CREATUREGAS))//dnl ch62 240813
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
@@ -3979,3 +3981,48 @@ UINT8 CountTeamSeeSoldier( INT8 bTeam, SOLDIERTYPE *pSoldier )
|
||||
|
||||
return ubFriends;
|
||||
}
|
||||
|
||||
BOOLEAN FindBombNearby( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubDistance )
|
||||
{
|
||||
UINT32 uiBombIndex;
|
||||
INT32 sCheckGridno;
|
||||
OBJECTTYPE *pObj;
|
||||
|
||||
INT16 sMaxLeft, sMaxRight, sMaxUp, sMaxDown, sXOffset, sYOffset;
|
||||
|
||||
// determine maximum horizontal limits
|
||||
sMaxLeft = min( ubDistance, (sGridNo % MAXCOL));
|
||||
sMaxRight = min( ubDistance, MAXCOL - ((sGridNo % MAXCOL) + 1));
|
||||
|
||||
// determine maximum vertical limits
|
||||
sMaxUp = min( ubDistance, (sGridNo / MAXROW));
|
||||
sMaxDown = min( ubDistance, MAXROW - ((sGridNo / MAXROW) + 1));
|
||||
|
||||
for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++)
|
||||
{
|
||||
for (sXOffset = -sMaxLeft; sXOffset <= sMaxRight; sXOffset++)
|
||||
{
|
||||
sCheckGridno = sGridNo + sXOffset + (MAXCOL * sYOffset);
|
||||
|
||||
if( TileIsOutOfBounds(sCheckGridno) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// search all bombs that we can see
|
||||
for (uiBombIndex = 0; uiBombIndex < guiNumWorldBombs; uiBombIndex++)
|
||||
{
|
||||
if (gWorldBombs[ uiBombIndex ].fExists &&
|
||||
gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].sGridNo == sCheckGridno &&
|
||||
gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].ubLevel == pSoldier->pathing.bLevel &&
|
||||
gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].bVisible == VISIBLE &&
|
||||
gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].usFlags & WORLD_ITEM_ARMED_BOMB )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1084,7 +1084,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
|
||||
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen: get out of water and gas"));
|
||||
|
||||
if (bInWater || bInGas)
|
||||
if (bInWater || bInGas || FindBombNearby(pSoldier, pSoldier->sGridNo, DAY_VISION_RANGE/8))
|
||||
{
|
||||
pSoldier->aiData.usActionData = FindNearestUngassedLand(pSoldier);
|
||||
|
||||
@@ -1543,11 +1543,11 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
|
||||
BOOLEAN fReachable;
|
||||
#ifdef DEBUGDECISIONS
|
||||
STR16 tempstr;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Flugente: to prevent an accidental call
|
||||
if ( pSoldier->IsZombie() )
|
||||
return( ZombieDecideActionYellow(pSoldier) );
|
||||
return( ZombieDecideActionYellow(pSoldier) );
|
||||
|
||||
if (fCivilian || (gGameExternalOptions.fAllNamedNpcsDecideAction && pSoldier->ubProfile != NO_PROFILE))
|
||||
{
|
||||
@@ -1602,6 +1602,20 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// WHEN IN GAS, GO TO NEAREST REACHABLE SPOT OF UNGASSED LAND
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if ( InGas(pSoldier, pSoldier->sGridNo) || DeepWater( pSoldier->sGridNo, pSoldier->pathing.bLevel ) || FindBombNearby(pSoldier, pSoldier->sGridNo, DAY_VISION_RANGE/8) )
|
||||
{
|
||||
pSoldier->aiData.usActionData = FindNearestUngassedLand(pSoldier);
|
||||
|
||||
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
|
||||
{
|
||||
return(AI_ACTION_LEAVE_WATER_GAS);
|
||||
}
|
||||
}
|
||||
|
||||
// determine the most important noise heard, and its relative value
|
||||
sNoiseGridNo = MostImportantNoiseHeard(pSoldier,&iNoiseValue, &fClimb, &fReachable);
|
||||
//NumMessage("iNoiseValue = ",iNoiseValue);
|
||||
@@ -2537,7 +2551,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
|
||||
// WHEN IN GAS, GO TO NEAREST REACHABLE SPOT OF UNGASSED LAND
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (bInGas && ubCanMove)
|
||||
if (ubCanMove && (bInGas || FindBombNearby(pSoldier, pSoldier->sGridNo, DAY_VISION_RANGE/8)))
|
||||
{
|
||||
pSoldier->aiData.usActionData = FindNearestUngassedLand(pSoldier);
|
||||
|
||||
@@ -4712,7 +4726,7 @@ INT16 ubMinAPCost;
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// if soldier in water/gas has enough APs left to move at least 1 square
|
||||
if ( ( bInDeepWater || bInGas ) && ubCanMove)
|
||||
if ( ( bInDeepWater || bInGas || FindBombNearby(pSoldier, pSoldier->sGridNo, DAY_VISION_RANGE/8) ) && ubCanMove)
|
||||
{
|
||||
pSoldier->aiData.usActionData = FindNearestUngassedLand(pSoldier);
|
||||
|
||||
|
||||
@@ -987,6 +987,12 @@ INT32 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB
|
||||
continue;
|
||||
}
|
||||
|
||||
// sevenfm: avoid tiles near bombs
|
||||
if( FindBombNearby(pSoldier, sGridNo, DAY_VISION_RANGE / 8))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
iPathCost = gubAIPathCosts[AI_PATHCOST_RADIUS + sXOffset][AI_PATHCOST_RADIUS + sYOffset];
|
||||
/*
|
||||
// water is OK, if the only good hiding place requires us to get wet, OK
|
||||
|
||||
+13
-22
@@ -59,28 +59,19 @@ int LegalNPCDestination(SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubPathMode,
|
||||
// skip mercs if turnbased and adjacent AND not doing an IGNORE_PATH check (which is used almost exclusively by GoAsFarAsPossibleTowards)
|
||||
fSkipTilesWithMercs = (gfTurnBasedAI && ubPathMode != IGNORE_PATH && SpacesAway( pSoldier->sGridNo, sGridNo ) == 1 );
|
||||
|
||||
// if this gridno is an OK destination
|
||||
// AND the gridno is NOT in a tear-gassed tile when we have no gas mask
|
||||
// AND someone is NOT already standing there
|
||||
// AND we're NOT already standing at that gridno
|
||||
// AND the gridno hasn't been black-listed for us
|
||||
|
||||
// Nov 28 98: skip people in destination tile if in turnbased
|
||||
if ( ( NewOKDestination(pSoldier, sGridNo, fSkipTilesWithMercs, pSoldier->pathing.bLevel ) ) &&
|
||||
( !InGas( pSoldier, sGridNo ) ) &&
|
||||
( sGridNo != pSoldier->sGridNo ) &&
|
||||
( sGridNo != pSoldier->pathing.sBlackList ) )
|
||||
/*
|
||||
if ( ( NewOKDestination(pSoldier, sGridno, FALSE, pSoldier->pathing.bLevel ) ) &&
|
||||
( !(gpWorldLevelData[ sGridno ].ubExtFlags[0] & (MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS)) || ( pSoldier->inv[ HEAD1POS ].usItem == GASMASK || pSoldier->inv[ HEAD2POS ].usItem == GASMASK ) ) &&
|
||||
( sGridno != pSoldier->sGridNo ) &&
|
||||
( sGridno != pSoldier->pathing.sBlackList ) )*/
|
||||
/*
|
||||
if ( ( NewOKDestination(pSoldier,sGridno,ALLPEOPLE, pSoldier->pathing.bLevel ) ) &&
|
||||
( !(gpWorldLevelData[ sGridno ].ubExtFlags[0] & (MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS)) || ( pSoldier->inv[ HEAD1POS ].usItem == GASMASK || pSoldier->inv[ HEAD2POS ].usItem == GASMASK ) ) &&
|
||||
( sGridno != pSoldier->sGridNo ) &&
|
||||
( sGridno != pSoldier->pathing.sBlackList ) )
|
||||
*/
|
||||
// if this gridno is an OK destination
|
||||
// AND the gridno is NOT in a tear-gassed tile when we have no gas mask
|
||||
// AND someone is NOT already standing there
|
||||
// AND we're NOT already standing at that gridno
|
||||
// AND the gridno hasn't been black-listed for us
|
||||
|
||||
// Nov 28 98: skip people in destination tile if in turnbased
|
||||
// sevenfm: also check for bomb nearby
|
||||
if ( NewOKDestination(pSoldier, sGridNo, fSkipTilesWithMercs, pSoldier->pathing.bLevel ) &&
|
||||
!InGas( pSoldier, sGridNo ) &&
|
||||
!FindBombNearby(pSoldier, sGridNo, DAY_VISION_RANGE/8 ) &&
|
||||
sGridNo != pSoldier->sGridNo &&
|
||||
sGridNo != pSoldier->pathing.sBlackList )
|
||||
{
|
||||
// if water's a problem, and gridno is in a water tile (bridges are OK)
|
||||
if (!ubWaterOK && Water(sGridNo, pSoldier->pathing.bLevel))
|
||||
|
||||
@@ -295,6 +295,8 @@ INT8 CalcMoraleNew(SOLDIERTYPE *pSoldier);
|
||||
BOOLEAN ProneSightCoverAtSpot( SOLDIERTYPE *pSoldier, INT32 sSpot );
|
||||
BOOLEAN SightCoverAtSpot( SOLDIERTYPE *pSoldier, INT32 sSpot );
|
||||
|
||||
BOOLEAN FindBombNearby( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubDistance );
|
||||
|
||||
#define MAX_FLANKS_RED 25
|
||||
#define MAX_FLANKS_YELLOW 25
|
||||
|
||||
|
||||
Reference in New Issue
Block a user