diff --git a/Tactical/Inventory Choosing.cpp b/Tactical/Inventory Choosing.cpp index a8537e3b..c6e50596 100644 --- a/Tactical/Inventory Choosing.cpp +++ b/Tactical/Inventory Choosing.cpp @@ -1164,12 +1164,16 @@ void ChooseGrenadesForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bGrena // return here in any case if (itemMortar > 0 ) { - usItem = PickARandomLaunchable ( itemMortar ); - if ( usItem > 0 ) + // sevenfm: more variety for mortar shells + for (int i = 0; i < bGrenades; i++) { - CreateItems( usItem, (INT8) (80 + Random(21)), bGrenades, &gTempObject ); - gTempObject.fFlags |= OBJECT_UNDROPPABLE; - PlaceObjectInSoldierCreateStruct( pp, &gTempObject ); + usItem = PickARandomLaunchable(itemMortar); + if (usItem > 0) + { + CreateItems(usItem, (INT8)(80 + Random(21)), 1, &gTempObject); + gTempObject.fFlags |= OBJECT_UNDROPPABLE; + PlaceObjectInSoldierCreateStruct(pp, &gTempObject); + } } } @@ -1214,9 +1218,7 @@ void ChooseGrenadesForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bGrena //do this for every 1-2 grenades so that we can get more variety while ( bGrenades > 0 ) { - count = Random(3); - if ( count > bGrenades ) - count = bGrenades; + count = min(1 + Random(2), bGrenades); usItem = PickARandomLaunchable ( itemGrenadeLauncher ); if ( usItem > 0 && count > 0 ) @@ -1236,9 +1238,7 @@ void ChooseGrenadesForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bGrena //do this for every 1-2 grenades so that we can get more variety while ( bGrenades > 0 ) { - count = Random(3); - if ( count > bGrenades ) - count = bGrenades; + count = min(1 + Random(2), bGrenades); usItem = PickARandomItem ( GRENADE, pp->ubSoldierClass, bGrenadeClass, FALSE ); if ( usItem > 0 && count > 0 ) diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index 3f4244bd..4d223706 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -5343,12 +5343,17 @@ BOOLEAN IsLocationSittable( INT32 iMapIndex, BOOLEAN fOnRoof ) { STRUCTURE *pStructure; INT16 sDesiredLevel; + if( WhoIsThere2( iMapIndex, 0 ) != NOBODY ) return FALSE; + //Locations on roofs without a roof is not possible, so //we convert the onroof intention to ground. - if( fOnRoof && !FlatRoofAboveGridNo( iMapIndex ) ) - fOnRoof = FALSE; + // sevenfm: return FALSE if location on roof does not exist + if (fOnRoof && !FlatRoofAboveGridNo(iMapIndex)) + return FALSE; + //fOnRoof = FALSE; + // Check structure database if( gpWorldLevelData[ iMapIndex ].pStructureHead ) { @@ -5373,8 +5378,11 @@ BOOLEAN IsLocationSittableExcludingPeople( INT32 iMapIndex, BOOLEAN fOnRoof ) //Locations on roofs without a roof is not possible, so //we convert the onroof intention to ground. - if( fOnRoof && !FlatRoofAboveGridNo( iMapIndex ) ) - fOnRoof = FALSE; + // sevenfm: return FALSE if location on roof does not exist + if (fOnRoof && !FlatRoofAboveGridNo(iMapIndex)) + return FALSE; + //fOnRoof = FALSE; + // Check structure database if( gpWorldLevelData[ iMapIndex ].pStructureHead ) { diff --git a/Tactical/PATHAI.cpp b/Tactical/PATHAI.cpp index 922c85e9..112eee68 100644 --- a/Tactical/PATHAI.cpp +++ b/Tactical/PATHAI.cpp @@ -3159,7 +3159,7 @@ if(!GridNoOnVisibleWorldTile(iDestination)) } // sevenfm: skip gas if not in gas already - if (!(s->flags.uiStatusFlags & SOLDIER_PC) && + if ((!(s->flags.uiStatusFlags & SOLDIER_PC) || gTacticalStatus.fAutoBandageMode || s->flags.uiStatusFlags & SOLDIER_PCUNDERAICONTROL) && InGasSpot(s, newLoc, bLevel) && !InGasSpot(s, s->sGridNo, bLevel)) { diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index faa52c56..9739fa57 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -2027,7 +2027,11 @@ void PlayWeaponSound(SOLDIERTYPE *pSoldier, OBJECTTYPE *pObjHand, OBJECTTYPE *pO bTerrainType = FLAT_FLOOR; if (pSector) ubSectorType = pSector->ubTraversability[THROUGH_STRATEGIC_MOVE]; - if (InARoom(pSoldier->sGridNo, NULL) && pSoldier->pathing.bLevel == 0 && bTerrainType == FLAT_FLOOR && CheckRoof(pSoldier->sGridNo)) + if (InARoom(pSoldier->sGridNo, NULL) && + pSoldier->pathing.bLevel == 0 && + bTerrainType == FLAT_FLOOR && + CheckRoof(pSoldier->sGridNo) && + pSoldier->bDoBurst <= 1) fRoom = TRUE; if (pSoldier->ubAttackingHand == HANDPOS) fMainHand = TRUE; diff --git a/TacticalAI/AIUtils.cpp b/TacticalAI/AIUtils.cpp index e6ef7acb..adbfe711 100644 --- a/TacticalAI/AIUtils.cpp +++ b/TacticalAI/AIUtils.cpp @@ -1913,8 +1913,10 @@ INT16 EstimatePathCostToLocation( SOLDIERTYPE * pSoldier, INT32 sDestGridNo, INT { // on ground or same building... normal! sPathCost = EstimatePlotPath( pSoldier, sDestGridNo, FALSE, FALSE, FALSE, WALKING, FALSE, FALSE, 0); - *pfClimbingNecessary = FALSE; - *psClimbGridNo = NOWHERE; + if (pfClimbingNecessary) + *pfClimbingNecessary = FALSE; + if (psClimbGridNo) + *psClimbGridNo = NOWHERE; } else { @@ -1945,8 +1947,10 @@ INT16 EstimatePathCostToLocation( SOLDIERTYPE * pSoldier, INT32 sDestGridNo, INT // add in an estimate of getting there after climbing down, *but not on top of roof* sPathCost += (APBPConstants[AP_MOVEMENT_FLAT] + APBPConstants[AP_MODIFIER_WALK]) * PythSpacesAway( sClimbGridNo, sDestGridNo ) / 2; } - *pfClimbingNecessary = TRUE; - *psClimbGridNo = sClimbGridNo; + if (pfClimbingNecessary) + *pfClimbingNecessary = TRUE; + if (psClimbGridNo) + *psClimbGridNo = sClimbGridNo; } } } @@ -2001,8 +2005,10 @@ INT16 EstimatePathCostToLocation( SOLDIERTYPE * pSoldier, INT32 sDestGridNo, INT // estimate walk cost sPathCost += (APBPConstants[AP_MOVEMENT_FLAT] + APBPConstants[AP_MODIFIER_WALK]) * PythSpacesAway( sClimbGridNo, sDestGridNo ); } - *pfClimbingNecessary = TRUE; - *psClimbGridNo = sClimbGridNo; + if (pfClimbingNecessary) + *pfClimbingNecessary = TRUE; + if (psClimbGridNo) + *psClimbGridNo = sClimbGridNo; } } } diff --git a/TacticalAI/DecideAction.cpp b/TacticalAI/DecideAction.cpp index 0cda6a2b..1e10adc6 100644 --- a/TacticalAI/DecideAction.cpp +++ b/TacticalAI/DecideAction.cpp @@ -2752,16 +2752,35 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier) // try behind us, see if there's room to move back sCheckGridNo = NewGridNo(pSoldier->sGridNo, DirectionInc(gOppositeDirection[ubOpponentDir])); if (OKFallDirection(pSoldier, sCheckGridNo, pSoldier->pathing.bLevel, gOppositeDirection[ubOpponentDir], pSoldier->usAnimState)) - //FindBestPath(pSoldier, sCheckGridNo, pSoldier->pathing.bLevel, DetermineMovementMode(pSoldier, AI_ACTION_GET_CLOSER), COPYROUTE, 0)) { // sevenfm: check if we can reach this gridno INT32 iPathCost = EstimatePlotPath(pSoldier, sCheckGridNo, FALSE, FALSE, FALSE, DetermineMovementMode(pSoldier, AI_ACTION_GET_CLOSER), pSoldier->bStealthMode, FALSE, 0); - if(iPathCost !=0 && iPathCost <= pSoldier->bActionPoints) + if (iPathCost != 0 && iPathCost + BestThrow.ubAPCost + GetAPsToLook(pSoldier) + GetAPsCrouch(pSoldier, FALSE) <= pSoldier->bActionPoints) { + DebugAI(AI_MSG_INFO, pSoldier, String("moving backwards to have more room to deploy mortar")); pSoldier->aiData.usActionData = sCheckGridNo; + + DebugAI(AI_MSG_INFO, pSoldier, String("prepare next action throw at spot %d level %d aimtime %d", BestThrow.sTarget, BestThrow.bTargetLevel, BestThrow.ubAimTime)); + + // if necessary, swap the usItem + if (BestThrow.bWeaponIn != HANDPOS) + { + DebugAI(AI_MSG_INFO, pSoldier, String("rearrange pocket")); + RearrangePocket(pSoldier, HANDPOS, BestThrow.bWeaponIn, FOREVER); + } + + pSoldier->aiData.usNextActionData = BestThrow.sTarget; + pSoldier->aiData.bNextTargetLevel = BestThrow.bTargetLevel; + pSoldier->aiData.bAimTime = BestThrow.ubAimTime; + + pSoldier->aiData.bNextAction = AI_ACTION_TOSS_PROJECTILE; + return AI_ACTION_GET_CLOSER; } } + + // can't fire! + BestThrow.ubPossible = FALSE; } } @@ -2770,7 +2789,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier) { DebugAI(AI_MSG_INFO, pSoldier, String("prepare throw at spot %d level %d aimtime %d", BestThrow.sTarget, BestThrow.bTargetLevel, BestThrow.ubAimTime)); - // if necessary, swap the usItem from holster into the hand position + // if necessary, swap the usItem if (BestThrow.bWeaponIn != HANDPOS) { DebugAI(AI_MSG_INFO, pSoldier, String("rearrange pocket")); @@ -3856,11 +3875,11 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier) // modify RED movement tendencies according to morale switch (pSoldier->aiData.bAIMorale) { - case MORALE_HOPELESS: bSeekPts = -99; bHelpPts = -99; bHidePts = +2; bWatchPts = -99; break; + case MORALE_HOPELESS: bSeekPts = -99; bHelpPts = -99; bHidePts += +2; bWatchPts = -99; break; case MORALE_WORRIED: bSeekPts += -2; bHelpPts += 0; bHidePts += +2; bWatchPts += 1; break; case MORALE_NORMAL: bSeekPts += 0; bHelpPts += 0; bHidePts += 0; bWatchPts += 0; break; case MORALE_CONFIDENT: bSeekPts += +1; bHelpPts += 0; bHidePts += -1; bWatchPts += 0; break; - case MORALE_FEARLESS: bSeekPts += +1; bHelpPts += 0; bHidePts = -1; bWatchPts += 0; break; + case MORALE_FEARLESS: bSeekPts += +1; bHelpPts += 0; bHidePts += -1; bWatchPts += 0; break; } // modify tendencies according to orders @@ -5490,15 +5509,15 @@ INT16 ubMinAPCost; if ( OKFallDirection( pSoldier, sCheckGridNo, pSoldier->pathing.bLevel, gOppositeDirection[ ubOpponentDir ], pSoldier->usAnimState ) ) { // sevenfm: check if we can reach this gridno - INT32 iPathCost = EstimatePlotPath(pSoldier, sCheckGridNo, FALSE, FALSE, FALSE, DetermineMovementMode(pSoldier, AI_ACTION_GET_CLOSER), pSoldier->bStealthMode, FALSE, 0); - if (iPathCost != 0 && iPathCost <= pSoldier->bActionPoints) - { + INT32 iPathCost = EstimatePlotPath(pSoldier, sCheckGridNo, FALSE, FALSE, FALSE, DetermineMovementMode(pSoldier, AI_ACTION_GET_CLOSER), pSoldier->bStealthMode, FALSE, 0); + if (iPathCost != 0 && iPathCost <= pSoldier->bActionPoints) + { pSoldier->aiData.usActionData = sCheckGridNo; return AI_ACTION_GET_CLOSER; - } } } } + } if ( BestThrow.ubPossible ) { @@ -6481,23 +6500,23 @@ L_NEWAIM: if (IsGrenadeLauncherAttached(&pSoldier->inv[HANDPOS])) //dnl ch63 240813 { DebugAI(AI_MSG_INFO, pSoldier, String("using attached GL")); - pSoldier->bWeaponMode = WM_ATTACHED_GL; - } + pSoldier->bWeaponMode = WM_ATTACHED_GL; + } - // stand up before throwing if needed - if (gAnimControl[pSoldier->usAnimState].ubEndHeight < BestAttack.ubStance && - pSoldier->InternalIsValidStance(AIDirection(pSoldier->sGridNo, BestAttack.sTarget), BestAttack.ubStance)) - { - pSoldier->aiData.usActionData = BestAttack.ubStance; - pSoldier->aiData.bNextAction = AI_ACTION_TOSS_PROJECTILE; - pSoldier->aiData.usNextActionData = BestAttack.sTarget; - pSoldier->aiData.bNextTargetLevel = BestAttack.bTargetLevel; - return AI_ACTION_CHANGE_STANCE; - } - else - { - pSoldier->aiData.usActionData = BestAttack.sTarget; - pSoldier->bTargetLevel = BestAttack.bTargetLevel; + // stand up before throwing if needed + if (gAnimControl[pSoldier->usAnimState].ubEndHeight < BestAttack.ubStance && + pSoldier->InternalIsValidStance(AIDirection(pSoldier->sGridNo, BestAttack.sTarget), BestAttack.ubStance)) + { + pSoldier->aiData.usActionData = BestAttack.ubStance; + pSoldier->aiData.bNextAction = AI_ACTION_TOSS_PROJECTILE; + pSoldier->aiData.usNextActionData = BestAttack.sTarget; + pSoldier->aiData.bNextTargetLevel = BestAttack.bTargetLevel; + return AI_ACTION_CHANGE_STANCE; + } + else + { + pSoldier->aiData.usActionData = BestAttack.sTarget; + pSoldier->bTargetLevel = BestAttack.bTargetLevel; return(AI_ACTION_TOSS_PROJECTILE); } }