CalcTargetMovementOffset: better integer calculation for max tiles penalty.

SOLDIERTYPE::initialize: initialize additional data.
EVENT_FireSoldierWeapon: if shooting soldier is invisible, locate screen to target spot.
CancelAIAction: reset next AI action.
FindBestPath: improved gas avoiding code.
InGas: improved code, also check the spot itself.
LegalNPCDestination: disabled additional checks to prevent AI deadlock.

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8695 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Sevenfm
2019-10-03 16:49:04 +00:00
parent 54e7c1e24d
commit 30df6c350a
7 changed files with 83 additions and 29 deletions
+3 -1
View File
@@ -9098,7 +9098,9 @@ void CalcTargetMovementOffset( SOLDIERTYPE *pShooter, SOLDIERTYPE *pTarget, OBJE
// Again, if the shooter is skilled, this will occur after fewer tiles have been moved.
// If the target moves *more* tiles than this, the movement penalty will begin to diminish. That's our shooter
// beginning to compensate for the target's speed, pointing the gun ahead of the target ("Leading the target").
INT16 uiTilesForMaxPenalty = (INT16)((100-uiCombinedSkill) / (100 / gGameCTHConstants.MOVEMENT_TRACKING_DIFFICULTY));
// sevenfm: better integer calculation
//INT16 uiTilesForMaxPenalty = (INT16)((100-uiCombinedSkill) / (100 / gGameCTHConstants.MOVEMENT_TRACKING_DIFFICULTY));
INT16 uiTilesForMaxPenalty = (INT16)((100 - uiCombinedSkill) * gGameCTHConstants.MOVEMENT_TRACKING_DIFFICULTY / 100);
UINT8 stance = gAnimControl[ pShooter->usAnimState ].ubEndHeight;
+4 -3
View File
@@ -62,6 +62,7 @@ extern UINT16 gubAnimSurfaceIndex[ TOTALBODYTYPES ][ NUMANIMATIONSTATES ];
// sevenfm:
extern BOOLEAN InGas( SOLDIERTYPE *pSoldier, INT32 sGridNo );
extern BOOLEAN InGasSpot(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel);
//extern UINT8 gubDiagCost[20];
// skiplist has extra level of pointers every 4 elements, so a level 5is optimized for
@@ -3144,9 +3145,9 @@ if(!GridNoOnVisibleWorldTile(iDestination))
}
// sevenfm: skip gas if not in gas already
if( !(s->flags.uiStatusFlags & SOLDIER_PC) &&
InGas(s, newLoc) &&
!InGas(s, s->sGridNo) )
if (!(s->flags.uiStatusFlags & SOLDIER_PC) &&
InGasSpot(s, newLoc, ubLevel) &&
!InGasSpot(s, s->sGridNo, ubLevel))
{
goto NEXTDIR;
}
+27 -5
View File
@@ -1114,6 +1114,19 @@ void SOLDIERTYPE::initialize( )
memset( &newdrugs, 0, sizeof(DRUGS) );
memset( &stats, 0, sizeof(STRUCT_Statistics) );
memset( &pathing, 0, sizeof(STRUCT_Pathing) );
// sevenfm:initialize additional data
this->ubLastShock = 0;
this->ubLastSuppression = 0;
this->ubLastAP = 0;
this->ubLastMorale = 0;
this->ubLastShockFromHit = 0;
this->ubLastMoraleFromHit = 0;
this->ubLastAPFromHit = 0;
this->iLastBulletImpact = 0;
this->iLastArmourProtection = 0;
this->usQuickItemId = 0;
this->ubQuickItemSlot = 0;
}
bool SOLDIERTYPE::exists( )
@@ -5084,12 +5097,21 @@ void SOLDIERTYPE::EVENT_FireSoldierWeapon( INT32 sTargetGridNo )
}
else
{
// Set flag indicating we are about to shoot once destination direction is hit
this->flags.fTurningToShoot = TRUE;
if ( this->bTeam != gbPlayerNum && this->bVisible != -1 )
if (this->bTeam != gbPlayerNum)
{
LocateSoldier( this->ubID, DONTSETLOCATOR );
if (this->bVisible != -1)
{
LocateSoldier(this->ubID, DONTSETLOCATOR);
}
else if (!TileIsOutOfBounds(sTargetGridNo) && !GridNoOnScreen(sTargetGridNo))
{
INT16 sNewCenterWorldX = CenterX(sTargetGridNo);
INT16 sNewCenterWorldY = CenterY(sTargetGridNo);
SetRenderCenter(sNewCenterWorldX, sNewCenterWorldY);
// Plot new path!
gfPlotNewMovement = TRUE;
}
}
}
}
+1
View File
@@ -243,6 +243,7 @@ INT8 HeadForTheStairCase( SOLDIERTYPE * pSoldier );
BOOLEAN InGas( SOLDIERTYPE *pSoldier, INT32 sGridNo );
BOOLEAN InGasOrSmoke( SOLDIERTYPE *pSoldier, INT32 sGridNo );
BOOLEAN InWaterGasOrSmoke( SOLDIERTYPE *pSoldier, INT32 sGridNo );
BOOLEAN InGasSpot(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel);
INT32 InternalGoAsFarAsPossibleTowards(SOLDIERTYPE *pSoldier, INT32 sDesGrid, INT16 bReserveAPs, INT8 bAction, INT8 fFlags );
+5
View File
@@ -1250,6 +1250,11 @@ void CancelAIAction(SOLDIERTYPE *pSoldier, UINT8 ubForce)
pSoldier->aiData.bBypassToGreen = FALSE;
ActionDone(pSoldier);
// sevenfm: reset next action
pSoldier->aiData.bNextAction = AI_ACTION_NONE;
pSoldier->aiData.usNextActionData = 0;
pSoldier->aiData.bNextTargetLevel = 0;
}
+38 -15
View File
@@ -2010,27 +2010,50 @@ INT16 InWaterOrGas(SOLDIERTYPE *pSoldier, INT32 sGridNo)
return (INT16)InGas( pSoldier, sGridNo );
}
BOOLEAN InGas( SOLDIERTYPE *pSoldier, INT32 sGridNo )
BOOLEAN InGasSpot(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel)
{
CHECKF(pSoldier);
if (TileIsOutOfBounds(sGridNo))
return FALSE;
// tear gas
if ((gpWorldLevelData[sGridNo].ubExtFlags[bLevel] & MAPELEMENT_EXT_TEARGAS) &&
!DoesSoldierWearGasMask(pSoldier))
{
return(TRUE);
}
// fire/creature/mustard gas
// sevenfm: avoid mustard gas even when wearing gas mask
if (gpWorldLevelData[sGridNo].ubExtFlags[bLevel] & (MAPELEMENT_EXT_BURNABLEGAS | MAPELEMENT_EXT_CREATUREGAS | MAPELEMENT_EXT_MUSTARDGAS))
{
return(TRUE);
}
return FALSE;
}
BOOLEAN InGas(SOLDIERTYPE *pSoldier, INT32 sGridNo)
{
CHECKF(pSoldier);
if (TileIsOutOfBounds(sGridNo))
return FALSE;
if (InGasSpot(pSoldier, sGridNo, pSoldier->pathing.bLevel))
{
return TRUE;
}
//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)
{
for (int iDir = 0; iDir < NUM_WORLD_DIRECTIONS; ++iDir)
{
iNeighbourGridNo = sGridNo + DirectionInc(iDir);
if(!TileIsOutOfBounds(iNeighbourGridNo))
if (!TileIsOutOfBounds(iNeighbourGridNo) && InGasSpot(pSoldier, iNeighbourGridNo, pSoldier->pathing.bLevel))
{
// tear/mustard gas
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_MUSTARDGAS|MAPELEMENT_EXT_BURNABLEGAS|MAPELEMENT_EXT_CREATUREGAS))//dnl ch62 240813
{
return(TRUE);
}
return TRUE;
}
}
+5 -5
View File
@@ -66,10 +66,10 @@ int LegalNPCDestination(SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubPathMode,
// 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
// sevenfm: disabled additional checks to prevent AI deadlock
if ( NewOKDestination(pSoldier, sGridNo, fSkipTilesWithMercs, pSoldier->pathing.bLevel ) &&
!InGas( pSoldier, sGridNo ) &&
!FindBombNearby(pSoldier, sGridNo, DAY_VISION_RANGE/8 ) &&
//!InGas( pSoldier, sGridNo ) &&
//!FindBombNearby(pSoldier, sGridNo, DAY_VISION_RANGE/8 ) &&
sGridNo != pSoldier->sGridNo &&
sGridNo != pSoldier->pathing.sBlackList )
{
@@ -78,7 +78,7 @@ int LegalNPCDestination(SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubPathMode,
return(FALSE);
//Madd: added to prevent people from running into gas and fire
if ( (gpWorldLevelData[sGridNo].ubExtFlags[pSoldier->pathing.bLevel] & (MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS)) &&
/*if ( (gpWorldLevelData[sGridNo].ubExtFlags[pSoldier->pathing.bLevel] & (MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS)) &&
!DoesSoldierWearGasMask( pSoldier ) )
{
return( FALSE );
@@ -87,7 +87,7 @@ int LegalNPCDestination(SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubPathMode,
if ( gpWorldLevelData[sGridNo].ubExtFlags[pSoldier->pathing.bLevel] & MAPELEMENT_EXT_BURNABLEGAS )
{
return( FALSE );
}
}*/
// passed all checks, now try to make sure we can get there!
switch (ubPathMode)