Skip to content

Weapon pitch limits are not restored when a save is loaded #3144

Description

@bobtista

A unit whose current weapon set limits its firing pitch stops respecting that limit after a save is loaded. It accepts a target it cannot elevate or depress to, commits to the attack, and then never lands a shot.

The flag that gates the check, WeaponSet::m_hasPitchLimit, is not carried in the save. WeaponSet::xfer writes two bools, and both of them are m_hasDamageWeapon:

https://github.com/TheSuperHackers/GeneralsGameCode/blob/main/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/WeaponSet.cpp#L296-L297

The value does not recover after the load either. updateWeaponSet recomputes the flag only when the weapon template set changes, and the load restores that set, so the comparison at the top of the function is already satisfied and the body never runs. The flag keeps whatever the object was constructed with, which is the default weapon set rather than the saved one.

Only the stale false direction misbehaves. A stale true still runs the per weapon loop in isAnyWithinTargetPitch and reaches the right answer, so the fault appears when the saved weapon set has a pitch limit that the default set does not, such as a set gained through an upgrade, veterancy or a rider.

Repro:

  1. Take an object whose current weapon set has a pitch limit that its default weapon set does not
  2. Save
  3. Load that save
  4. Order it to attack a target outside its firing pitch

isAnyWithinTargetPitch returns true from its first line, the order is accepted, and the unit does not connect. Before the save, the same order is rejected as an invalid shot.

Measured with a probe on the flag, forcing a value at save time that the default weapon set cannot produce, and logging both sides of the transfer with m_hasDamageWeapon as a control:

saved loaded
pitch limit flag 1 0
damage weapon flag (control) 0 0

The control survives the round trip, so the record itself is written and read; only the pitch limit flag is missing from it.

The same two lines are present in Generals at Generals/Code/GameEngine/Source/GameLogic/Object/WeaponSet.cpp#L288-L289.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions