- Connect aMoveToCommandZone to cmMoveToCommandZone; the menu item was
added, shown, and shortcut-bound but never wired, so it did nothing
- Extract evaluateModifyCounter() and route cmdIncCounter/cmdSetCounter
through it, replacing isCommandZoneCounterBlocked; reject inc/set on
an inactive tax counter so a hidden counter cannot accumulate value
- Reject reserved tax counter names in cmdCreateCounter to prevent a
client from spoofing a system tax counter via a user-created counter
- Route AbstractCounter::valueChanged through the virtual setValue() so
CommanderTaxCounter clamps and refreshes its tooltip on value changes
- Deduplicate actPlayAndIncreaseTax/actPlayAndIncreasePartnerTax into a
single playAndIncreaseTax(counterId) helper
- Move MINIMUM_STACKING_HEIGHT from CommandZone to the PlayerGraphicsItem
layout code, its only consumer
- Remove unused AbstractCounter forward declaration from player_logic.h
- Add EvaluateModifyCounter tests and PartnerTax cases for
evaluateSetCounterActive
- Pin the FirstUserId floor in new_counter_id_test using ids 3 and 5 so
a naive "highest id + 1" regression fails the test
- Sync command zone visibility in the PlayerGraphicsItem constructor in case processPlayerInfo runs before the signal is connected.
- Emit CommandZone::effectiveHeightChanged() when a minimized zone's height changes so the stack zone repositions.
- Make AbstractCounter::setActive() the sole owner of counter visibility; document the contract.
- Drop the redundant setVisible() from CommandZone::rearrangeTaxCounters(); it now only lays out by isActive().
- Format tax log lines with a single atomic 4-arg arg() instead of mixing string and int overloads.
Pull the pure guard logic out of cmdDelCounter and cmdSetCounterActive
into static evaluateDelCounter/evaluateSetCounterActive methods, leaving
the handlers as thin shells over the decision. Add command_zone_tests
covering every authorization branch of both evaluators.
- Initialize commandZoneGraphicsItem to nullptr so the pervasive null
checks have defined behavior before initializeZones() runs
- Remove unused getTaxCounterWidgets()
- Enforce the "reset tax to 0 before deactivating" invariant server-side
in cmdSetCounterActive, not just in the UI
- Hide tax increment/decrement menu actions at their bounds (0 and
MAX_COUNTER_VALUE) to avoid sending no-op commands
- Drop redundant/inconsistent toggle labels from CommandZoneMenu::
retranslateUi(); updateTaxCounterActionStates() owns them
- Add default=-1 to Event_SetCounterActive.counter_id for parity with
Command_SetCounterActive
In non-Commander games, newCounterId() could return 8 or 9, colliding
with reserved commander tax counter IDs. A malicious client could
exploit this via cmd_set_counter_active. Now user counters always
start at ID 10+.