Skip to content

Incorrect movement cost calculation when using pathing waypoints #1561

@Iridar

Description

@Iridar

The game does not correctly calculate the cost of movement when using waypoints. The actual calculation happens in native X2ReachableTilesCache::GetPathCostToTile(TTile Destination), so exact logic is unknown, but presumably the way it works is it builds a path from the unit's current tile location to the specified Destination tile and calculates the length of that path.

The function is called by XComTacticalController::CreatePathDataForPathTiles() here.

This method works fine for normal movement, but things break if the actual planned path of the unit's movement includes waypoints.

A couple screenshots with some log output.

First, regular dash. Note the moment at tile 9 when the move cost increase happens.

Image

[0233.86] MOVE_FIX: CreatePathDataForPathTiles Sally Johnson Soldier Mobility:'12'
[0233.86] MOVE_FIX: Tile: 0 -> 19 0 1 Path cost to tile: 0.0000 > 12 * 1 : False
[0233.86] MOVE_FIX: Tile: 1 -> 19 1 1 Path cost to tile: 1.5000 > 12 * 1 : False
[0233.86] MOVE_FIX: Tile: 2 -> 19 2 1 Path cost to tile: 3.0000 > 12 * 1 : False
[0233.86] MOVE_FIX: Tile: 3 -> 19 3 1 Path cost to tile: 4.5000 > 12 * 1 : False
[0233.86] MOVE_FIX: Tile: 4 -> 19 4 1 Path cost to tile: 6.0000 > 12 * 1 : False
[0233.87] MOVE_FIX: Tile: 5 -> 19 5 1 Path cost to tile: 7.5000 > 12 * 1 : False
[0233.87] MOVE_FIX: Tile: 6 -> 19 6 1 Path cost to tile: 9.0000 > 12 * 1 : False
[0233.87] MOVE_FIX: Tile: 7 -> 19 7 1 Path cost to tile: 10.5000 > 12 * 1 : False
[0233.87] MOVE_FIX: Tile: 8 -> 19 8 1 Path cost to tile: 12.0000 > 12 * 1 : False
[0233.87] MOVE_FIX: Tile: 9 -> 19 9 1 Path cost to tile: 13.5000 > 12 * 1 : True
[0233.87] MOVE_FIX: Increasing move cost
[0233.87] MOVE_FIX: Tile: 10 -> 19 10 1 Path cost to tile: 15.0000 > 12 * 2 : False
[0233.87] MOVE_FIX: Tile: 11 -> 19 11 1 Path cost to tile: 16.5000 > 12 * 2 : False
[0233.87] MOVE_FIX: Tile: 12 ->19 12 1 Path cost to tile: 18.0000 > 12 * 2 : False
[0233.87] MOVE_FIX: Tile: 13 -> 19 13 1 Path cost to tile: 19.5000 > 12 * 2 : False
[0233.87] MOVE_FIX: Tile: 14 -> 19 14 1 Path cost to tile: 21.0000 > 12 * 2 : False
[0233.87] MOVE_FIX: Tile: 15 -> 19 15 1 Path cost to tile: 22.5000 > 12 * 2 : False
[0233.87] MOVE_FIX: Tile: 16 -> 19 16 1 Path cost to tile: 24.0000 > 12 * 2 : False

Second - dash forward and then back, with a waypoint. Note that move cost doesn't increase here, which means the dash move here costs only one action point.

Image

[0259.04] MOVE_FIX: CreatePathDataForPathTiles Sally Johnson Soldier Mobility:'12'
[0259.04] MOVE_FIX: Tile: 0 -> 19 0 1 Path cost to tile: 0.0000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 1 -> 19 1 1 Path cost to tile: 1.5000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 2 -> 19 2 1 Path cost to tile: 3.0000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 3 -> 19 3 1 Path cost to tile: 4.5000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 4 -> 19 4 1 Path cost to tile: 6.0000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 5 -> 19 5 1 Path cost to tile: 7.5000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 6 -> 19 6 1 Path cost to tile: 9.0000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 7 -> 19 7 1 Path cost to tile: 10.5000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 8 -> 19 8 1 Path cost to tile: 12.0000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 9 -> 19 7 1 Path cost to tile: 10.5000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 10 -> 19 6 1 Path cost to tile: 9.0000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 11 -> 19 5 1 Path cost to tile: 7.5000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 12 -> 19 4 1 Path cost to tile: 6.0000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 13 -> 19 3 1 Path cost to tile: 4.5000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 14 -> 19 2 1 Path cost to tile: 3.0000 > 12 * 1 : False
[0259.04] MOVE_FIX: Tile: 15 -> 18 1 1 Path cost to tile: 2.1213 > 12 * 1 : False

Technically, this bug is relatively harmless, as all it does, at best, is gives the player some extra action points. It can be purposefully abused if the player knows about it, but that's hardly a concern for a single player game. That's more of an issue for multiplayer.

This exploit has been known for a long time, but I thought it would be nice to highlight the offending code.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions