diff --git a/Tactical/Points.cpp b/Tactical/Points.cpp index 4c0ac1fce..b6a8c1153 100644 --- a/Tactical/Points.cpp +++ b/Tactical/Points.cpp @@ -391,6 +391,13 @@ INT16 TerrainBreathPoints(SOLDIERTYPE * pSoldier, INT32 sGridNo, INT8 bDir, UINT INT16 ActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, UINT16 usMovementMode ) +{ + // Real, per-step movement: the soldier is physically at his current stance, so his + // live anim state IS the previous tile's mode. + return ActionPointCost( pSoldier, sGridNo, bDir, usMovementMode, pSoldier->usAnimState ); +} + +INT16 ActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, UINT16 usMovementMode, UINT16 usPrevMovementMode ) { INT16 sTileCost, sSwitchValue; FLOAT sPoints = 0; @@ -535,7 +542,7 @@ INT16 ActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, UINT16 u sPoints = max(1.0f, ( sPoints * (100 - (FLOAT)gSkillTraitValues.ubATAPsMovementReduction) / 100.0f ) ); } - if (usMovementMode == RUNNING && pSoldier->usAnimState != RUNNING) + if (usMovementMode == RUNNING && usPrevMovementMode != RUNNING) { // CHRISL if ((UsingNewInventorySystem() == true) && FindBackpackOnSoldier(pSoldier) != ITEM_NOT_FOUND) diff --git a/Tactical/Points.h b/Tactical/Points.h index 9bf9dec9f..ce3833522 100644 --- a/Tactical/Points.h +++ b/Tactical/Points.h @@ -282,6 +282,13 @@ INT16 BaseAPsToShootOrStabNoModifier( INT16 bAPs, INT16 bAimSkill, OBJECTTYPE * INT16 BaseAPsToShootOrStabNoModifier( INT16 bAPs, INT16 bAimSkill, OBJECTTYPE * pObj ); INT16 TerrainActionPoints( SOLDIERTYPE *pSoldier, INT32 sGridno, INT8 bDir, INT8 bLevel ); +// Per-tile movement AP cost - the single source of truth for what a step costs. +// usPrevMovementMode is the mode the soldier was in on the PREVIOUS tile, used to +// charge the one-time "spin up to run" penalty exactly once. Real movement passes +// the soldier's live anim state; a path estimator must pass its simulated prior mode, +// because the soldier doesn't actually move while the path is being summed. +INT16 ActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, UINT16 usMovementMode, UINT16 usPrevMovementMode ); +// Convenience overload: prev mode = the soldier's current anim state (correct for real, per-step movement). INT16 ActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, UINT16 usMovementMode ); INT16 EstimateActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, UINT16 usMovementMode, INT8 bPathIndex, INT8 bPathLength ); BOOLEAN SelectedMercCanAffordMove( );