From de4e0d3dc76c18bb1f40bc9b584e97a9f5f8d5b8 Mon Sep 17 00:00:00 2001 From: "Marco Antonio J. Costa" Date: Sun, 2 Aug 2026 19:01:54 -0300 Subject: [PATCH] Thread previous-tile movement mode into ActionPointCost Add an ActionPointCost overload taking the previous tile's movement mode explicitly, used to charge the one-time start-run penalty. The existing 4-arg overload forwards the soldier's live anim state, so real per-step movement and every other caller are unchanged. This lets a path-cost estimator - which does not move the soldier - supply its simulated prior mode instead of reading a frozen live anim state, so the estimate and the real deduction can share one cost function. Co-Authored-By: Claude Opus 4.8 --- Tactical/Points.cpp | 9 ++++++++- Tactical/Points.h | 7 +++++++ 2 files changed, 15 insertions(+), 1 deletion(-) 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( );