Skip to content

fix(inventory): equip exclusivity gate used slot-name constant where slot index belongs#573

Merged
CoreyRDean merged 1 commit into
developfrom
fix/equip-exclusivity-slot-index
Jun 10, 2026
Merged

fix(inventory): equip exclusivity gate used slot-name constant where slot index belongs#573
CoreyRDean merged 1 commit into
developfrom
fix/equip-exclusivity-slot-index

Conversation

@CoreyRDean

Copy link
Copy Markdown
Collaborator

The bug (player-reachable, runtime-confirmed, found by PR #571's pins)

src/Modules/Inventories.bb:229 gated the race/class exclusivity fork in ActorHasSlot on SlotI < Slot_Backpack — but Slot_Backpack (= 11) is the 1-based slot name constant while SlotI is a slot index (equip indices run 0..13; SlotI_Backpack = 14). Net effect: equip indices 11–13 (Ring4, Amulet1, Amulet2) skipped ExclusiveRace$/ExclusiveClass$ entirely — a wrong-race ring or amulet equipped fine there. The adjacent comment ("If it's an equipped slot") shows the intent was all 14 equip indices.

The fix

One line: SlotI < Slot_BackpackSlotI < SlotI_Backpack. Indices 0–10 and 14+ behave identically before and after; only 11–13 now enter the exclusivity fork as intended.

Plus the deliberate flips of exactly 4 pinned assertions in InventoryEquipRulesTest.bb (the PR #571 pins that documented the bug): wrong-race denial at Ring4/Amulet1/Amulet2 and class-exclusivity denial at Ring4 — each now asserts the correct denial.

Deliberately untouched: the race-match-short-circuits-class behavior at ~:240 (an item matching ExclusiveRace$ skips the ExclusiveClass$ check). That is a separate OR-vs-AND semantics question awaiting a maintainer decision; its pin remains FLAG-FOR-HUMAN.

Blast radius (independent verifier's sweep)

  • All 8 ActorHasSlot call sites audited: 7 pass true slot indices (InventorySwap, server pickup/claim, client auto-equip, drag-drop); client and server both Include Inventories.bb so the tightening lands on both sides simultaneously — no desync.
  • Shipped data/ corroboration (Items.dat parsed, not grepped): 0 items use ExclusiveRace/ExclusiveClass, 0 with slot_type ≥ 11 — no shipped content relied on the bypass.
  • Migration: save/load never calls ActorHasSlot, so an already-equipped now-illegal item stays put on load; it just can't be re-equipped once removed.
  • Pre-existing, out-of-scope observation for a follow-up: BVM_GIVEITEM (ScriptingCommands.bb:2908) passes It\SlotType (a slot-NAME constant, 0–11) where ActorHasSlot expects a slot index — same name-vs-index family, harmless for all shipped data.

Verification (independent verifier ≠ implementer)

  • Diff = 1 engine line + the 4 test flips (-U0 confirmed); no generator-gated files.
  • .\test.bat InventoryEquipRules[PASS] (denials visibly executing); full suite Ran 55 files: 55 passed, 0 failed.; FULL compile.bat (engine + all tools) exit 0.

🤖 Generated with Claude Code

…slot index belongs

ActorHasSlot's race/class exclusivity block was gated on
SlotI < Slot_Backpack, but Slot_Backpack (11) is the 1-based slot NAME
constant while SlotI is a 0-based slot INDEX (equip range 0..13, backpack
starting at SlotI_Backpack = 14). Equip indices 11-13 (Ring4, Amulet1,
Amulet2) therefore skipped the ExclusiveRace$/ExclusiveClass$ checks
entirely: a wrong-race or wrong-class ring/amulet equipped fine in those
three slots while being denied everywhere else. The gate now compares
against SlotI_Backpack, covering all 14 equip indices as the adjacent
'If it's an equipped slot' comment always intended.

The InventoryEquipRulesTest assertions that deliberately pinned the buggy
allows at indices 11-13 (FLAG-FOR-HUMAN items in
testActorHasSlotWrongRaceDenied and testActorHasSlotClassExclusivity) are
flipped to the now-correct denials; the flip is deliberate and paired with
this fix. The separate race-match-short-circuits-class pin is untouched
(still awaiting a maintainer decision).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@CoreyRDean CoreyRDean requested a review from a team as a code owner June 10, 2026 23:28
@CoreyRDean CoreyRDean merged commit ee79caa into develop Jun 10, 2026
1 check passed
@CoreyRDean CoreyRDean deleted the fix/equip-exclusivity-slot-index branch June 10, 2026 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant