Crusader_Decomp/docs/removed_items.md
2026-03-30 00:19:01 +02:00

15 KiB

Removed And Suspicious Item Shapes

This note collects the current evidence for several old or suspicious No Remorse item shapes that still appear in map data.

The working split is:

  • 0343 is a real surviving Remorse usecode class with limited behavior.
  • 034E, 034F, and 0350 are strongly evidenced as leftover grenade-family map/catalog entries, and the retail executable still preserves their exact display names.
  • 0548 is now tied to the live inventory UI fallback path: retail DTable_GetNameForShapeNo returns the INVALID string for unmapped entries, and Weasel_OnPaint uses that same lookup.
  • 0110 and 0112 are present in old maps, but are not yet tied to any confirmed Remorse pickup/use behavior.
  • The broader retail explosive-name table also contains LAND MINE, BLAST PAC, and FUSION PAC, but those are not newly found removed items in Remorse; they line up with live Remorse explosive classes.

Primary Sources

  • Remorse shape catalog: Crusader_Decomp_Public/map_renderer/Catalogs/usecode_shape_catalog_remorse.csv
  • Remorse cached scene exports: Crusader_Decomp_Public/map_renderer/.cache/scene-cache/remorse/**/scene.json
  • Remorse usecode export: Crusader_Decomp_Public/USECODE_REMORSE/**
  • Regret usecode export: Crusader_Decomp_Public/USECODE_REGRET/** for comparison only
  • Retail disassembly export: Crusader_Decomp/exports/CRUSADER.EXE.xml
  • Generated retail dtable dump: Crusader_Decomp/tools/dump_dtable_names.py -> Crusader_Decomp/out/dtable_get_name_dump.json plus companion CSVs
  • Generated Regret dtable dump: Crusader_Decomp/tools/dump_dtable_names.py regret -> Crusader_Decomp/out/regret_dtable_get_name_dump.json plus companion CSVs

High-Level Conclusions

0x0343 - old grenade

  • The Remorse shape catalog already labels 0x0343 as ITEM_GRENADE_REMOVED_0343 with description Old grenade, cannot be picked up.
  • Cached Remorse scene exports show 0343 placed on multiple maps including 2, 6, 26, 64, 69, 116, 170, 245, 246, 251, and 255.
  • The cached shape metadata for those map instances marks it as kind: terrain, solid: true, land: true, draw: false, invitem: false.
  • Unlike the other removed grenade-family shapes, 0343 is a real Remorse usecode class: GRENADE, class id 0x0343.
  • The recovered GRENADE class does not currently expose meaningful look, use, or inventory-facing handlers. The only non-empty exported handlers are hit and gotHit.
  • GRENADE::hit writes info 0x020B and excludes the process; GRENADE::gotHit writes info 0x020C and excludes the process.
  • Two Pepsi dispenser families in Remorse still explicitly try to create shape 0x0343, so this is not just dead catalog metadata. PEPSINS::use and PEPSIEW::use both call Item.legalCreateAtPoint(..., 0x0343, item).

Current best read: 0343 is a surviving but heavily stripped grenade-family object. It is still known to the Remorse scripting layer, but not as a normal player-facing inventory grenade.

0x034E, 0x034F, 0x0350 - removed grenade variants

  • The Remorse shape catalog labels them as:
    • 0x034E = UNUSED_GRENADE_CONCUSSION_034E
    • 0x034F = UNUSED_GRENADE_NERVE_034F
    • 0x0350 = UNUSED_GRENADE_EMP_0350
  • Cached scene exports show these shapes placed on old Remorse maps alongside 0343, especially on 245 and 246, and workspace-wide scene-cache searches also turned up placements across several other maps.
  • The cached map metadata for these shapes matches 0343: terrain-like placement, solid, land, draw: false, invitem: false.
  • Exact Remorse usecode searches did not recover separate classes for 034E, 034F, or 0350.
  • That matters because it separates them from 0343: they still exist in map/catalog data, but they do not currently have the same direct evidence of a surviving scripted class in Remorse.
  • The retail executable evidence is now stronger too. Live CRUSADER.EXE segment 1118 contains the already-named DTable_GetNameForShapeNo, and its backing name array at 1478:22BC includes the exact explosive strings:
    • GRENADE
    • CONCUSSION GRENADE
    • NERVE GAS GRENADE
    • EMP GRENADE
    • SPIDER BOMB
    • LAND MINE
    • BLAST PAC
    • FUSION PAC
  • The repeated INVALID placeholders inside that same array are also informative: the verified retail dump from tools/dump_dtable_names.py shows 1478:22BC is a char *[41] table whose global slots 0, 14, 26, and 32 all point to the same INVALID string. The removed grenade names then occupy bomb-family slots 33..40 as GRENADE, CONCUSSION GRENADE, NERVE GAS GRENADE, EMP GRENADE, SPIDER BOMB, LAND MINE, BLAST PAC, and FUSION PAC.
  • This means the removed grenade family is not just a renderer/catalog naming artifact. The retail executable still knows those display strings even though the distinct Remorse scripted classes appear to be gone.

Current best read: these are old grenade-family placements left in maps and editor-era data whose exact inventory/display names still survive in the retail executable, but whose distinct Remorse behavior has likely been removed or collapsed away before retail. The user-observed behavior where some can be forced into inventory but do nothing is consistent with a leftover shape/name path surviving after the actual item logic was cut.

0x0548 - Invalid

  • The Remorse shape catalog labels 0x0548 as ITEM_INVALID_0548 with description Cannot be picked up with S but can be picked with G, shows up a Medkit icon with text "Invalid".
  • Cached scene searches found 0548 on at least map 255.
  • The executable-side confirmation is now materially stronger than the first pass suggested:
    • retail 1118:056A is already identified as DTable_GetNameForShapeNo
    • its fallback branch at 1118:05D5 returns DS:238C, which is the string INVALID
    • Weasel_OnPaint at 13E0:0932 calls DTable_GetNameForShapeNo, so this is a real inventory/display UI path rather than an isolated dead string helper
  • The backing data segment confirms the same model. In segment 1478, the item-name table at 1478:22BC is a char *[41] array whose placeholder slots point at the INVALID string at 1478:238C.
  • The verified dump also closes one open point: 0x0548 does not appear in the resolved dtable category tables at all. Its visible in-game Invalid label is therefore best explained as a plain DTable_GetNameForShapeNo fallback for an unmapped shape, not as a dedicated 0548 name-table entry.

Current best read: 0548 is a real leftover item-like record that still resolves through at least one executable-side text/name path, but no meaningful use behavior has been recovered yet.

0x0110 and 0x0112 - suspicious non-pickup shapes

  • The Remorse shape catalog labels them only generically:
    • 0x0110 = ITEM_UNKNOWN_REMOVED_0110
    • 0x0112 = ITEM_UNKNOWN_REMOVED_0112
  • Cached scene searches found 0110 on old Remorse maps including 64 and 255.
  • Cached scene searches found 0112 on old Remorse maps including 47, 69, and 255.
  • No direct Remorse usecode class for 0110 or 0112 was recovered in this pass.
  • The class-event index does contain many incidental 0110 and 0112 hits, but those are body offsets or event-window bounds in unrelated classes, not proof that either shape is a real scripted item class.
  • Regret comparison material does show many incidental 0110/0112 hits too, which reinforces that numeric grep matches for these IDs are noisy and should not be promoted into behavioral claims.

Current best read: 0110 and 0112 are present in map data, but they remain unidentified map objects rather than recovered cut inventory items.

Additional DTable Findings

The retail name table behind DTable_GetNameForShapeNo was useful beyond the original target list because it shows which explosive-family names are still present in the executable and which ones are only suspicious if you stop at the catalog layer.

Active explosive items, not newly found cut items

  • LAND MINE, BLAST PAC, and FUSION PAC all appear in the same retail name table block as the removed grenade variants.
  • In Remorse usecode, these are not dead names:
    • LANDMINE is a live class with class id 0x039A
    • BLASTPAC is a live class with class id 0x039B
    • FUSPAC is a live class with class id 0x039C
  • The map-renderer catalog still underlabels two of those shapes:
    • 0x039A is currently unlabeled in the Remorse catalog
    • 0x039B is labeled ITEM_BLASTPACK_039B
    • 0x039C is currently unlabeled in the Remorse catalog
  • Cached Remorse scenes place 039A/039B/039C on normal gameplay maps including 1, 2, 14, 64, 170, 246, 251, and 255.

Current best read: these are active explosive inventory objects, not additional removed-item discoveries. The current catalog simply does not label all of them clearly.

Reusable dump status

  • The retail DTable_GetNameForShapeNo mapping is now exported in reusable form for downstream tooling:
    • out/dtable_get_name_dump.json
    • out/dtable_global_name_slots.csv
    • out/dtable_category_entries.csv
    • out/dtable_resolved_shapes.csv
  • That dump is generated by tools/dump_dtable_names.py directly from retail CRUSADER.EXE bytes plus exports/CRUSADER.EXE.xml relocations, so it is suitable for feeding the map renderer and shape catalogs without keeping the mapping only in prose notes.

Regret-side DTable comparison

  • The same dumper now also supports live REGRET.EXE, with the recovered helper at 1130:056a and the Regret dtable island in segment 1480.
  • The Regret dump closes the shifted layout directly from raw bytes even without a local REGRET.EXE.xml export: pointer table 1480:2856, string pool 1480:2926, and category tables at 1480:2590 (ammo), 1480:2614 (weapons), 1480:2792 (misc items), and 1480:27DE (bombs).
  • Regret also repeats a single INVALID string through four global slots, but at a different expanded layout: indices 0, 17, 36, and 44 all point back to 1480:2926.
  • That expanded Regret table preserves several names that do not appear in the earlier Remorse dump, including weapons BK-16, LNR-81, XP-5; items IONIC SHIELD, PLASMA SHIELD, DISRUPTER, SPIDER MINE, DATA PICK, MINE DET, PORTABLE BETTY, RADIATION SHIELD, and VIR IMAGER; and ammo BK-16 CLIP, LNR-81 CLIP.
  • The resolved Regret bomb rows are also narrower than a naive string scan suggests: 0x0343 = GRENADE, 0x0350 = EMP GRENADE, 0x0560 = SPIDER BOMB, 0x039A = LAND MINE, and 0x039C = FUSION PAC.
  • BLAST PAC is notably absent from the recovered Regret dtable output. In other words, the Regret executable still carries LAND MINE and FUSION PAC, but not a BLAST PAC bomb-table slot analogous to the Remorse block.

Current best read: the Regret comparison strengthens the claim that these explosive names come from a real retail inventory/display lookup family rather than renderer-only catalog text, but it also shows that the two games do not preserve the exact same bomb/item naming inventory.

Spider bomb: stronger Regret-side evidence than Remorse-side evidence

  • The same retail name table includes SPIDER BOMB.
  • I have not yet recovered a matching Remorse catalog entry, Remorse scene placement, or Remorse usecode class for that name.
  • Comparative Regret evidence is real, though: REGRET has a concrete CSPID class with class id 0x0584, and existing Regret-side notes already identify that as spider bomb.

Current best read: SPIDER BOMB is probably a legitimate series-level explosive item name rather than random dtable noise, but in this batch it remains a Regret-backed comparative lead, not a closed Remorse removed-item finding.

Other Unused-Looking Remorse Shapes

The broader Remorse catalog does contain more unused-looking or obviously non-retail shapes, but most of them are not good fits for the same "pickup-able inert item" bucket as the removed grenade family.

Placeholder cube family

  • The strongest additional item-adjacent candidates from the catalog/scene pass are placeholder cube entries:
    • 0x0251 = PLACEHOLDER_KEY_CUBE
    • 0x0318 = PLACEHOLDER_CUBE
    • 0x0337 = PLACEHOLDER_CUBE_BIG
    • 0x0361 = PLACEHOLDER_CUBE_RED_BLACK
  • Cached Remorse scenes place these on multiple maps, so they are not catalog-only artifacts.
  • Their current labels and kinds point more toward editor/UI/test content than toward cut inventory explosives.

Current best read: these are real leftover placeholder objects worth a future dedicated note, but they are a separate category from the grenade/inventory leftovers.

Editor-only and invisible-wall leftovers

  • The same scan found many Editor Object and invisible-wall entries such as 005A/005B/005C, 0066..0069, 0290, 0336, and many later one-off editor shapes.
  • These are clearly useful for understanding old map construction and hidden geometry, but they do not currently look like removed inventory items.

Regret comparison note for 0548

  • A useful cross-game contrast showed up too: in the current Regret catalog, 0x0548 is labeled as an editor/invisible-wall shape, not as an Invalid pickup-like leftover.
  • That makes the Remorse-side 0548 behavior more interesting, because it suggests this shape slot drifted significantly between the two games rather than preserving one stable item identity.

Evidence Notes

  • The strongest positive Remorse evidence in this batch is for 0343: it has a named exported class (GRENADE) and explicit spawn attempts from two other live Remorse classes.
  • The strongest positive executable-side evidence in this batch is the now-closed DTable_GetNameForShapeNo path: retail Weasel_OnPaint uses the same lookup family that falls back to INVALID, and the backing 1478:22BC name array preserves the removed grenade names inline.
  • The grenade-family map metadata (draw: false, invitem: false) is important because it suggests these were no longer treated as normal visible inventory pickups by the map/render metadata layer, even though alternate pickup/debug paths may still pull some of them into inventory.
  • Ghidra database notes were added in the live CRUSADER.EXE session at 1118:056A and 1118:05D5 to preserve the DTable_GetNameForShapeNo / INVALID fallback interpretation.

Open Questions

  1. What code path allows 0548 and similar bad/unmapped shapes to reach the inventory/display UI if they are not direct entries in the retail 1478:22BC dtable mapping?
  2. Do 034E, 034F, and 0350 still have dead executable-side item-definition records even though no separate Remorse usecode classes were recovered?
  3. Is the observed forced-pickup behavior using a generic item acquisition path that bypasses normal invitem rules and therefore reaches the DTable_GetNameForShapeNo fallback path?
  4. What are 0110 and 0112 visually or functionally in the old maps, beyond being non-pickup leftovers?
  5. Does Remorse still contain a spider-bomb shape or handler that has simply not been recognized yet, or is SPIDER BOMB dtable-only in Remorse while remaining live in Regret (CSPID)?
  6. Are there raw-build, beta, Pentagram, or ScummVM sources that preserve a cleaner shape-to-dtable mapping for the removed grenade family?