Deed placement (ObjectActionMsgHandler, PlaceAssetMsgHandler) reads
deed_structure_id from DeedTemplate._deeds. The deed, employment
contract and charter type checks (PlaceAssetMsgHandler,
ActivateNPCMsgHandler, GuildCreationFinalizeHandler, UseCharterMsg,
Item.serialize) read item_type through the cache template bridge.
Charters go through the shared getter rather than _deeds because
template 545 "Charter" is a CHARTER in the ITEM folder.
Parity (offline, static_item_templates vs COBJECTS, scripts/p13.py,
881 templates: all 880 DEED plus ITEM 545): 0 differences in
item_type and deed_structure_id. Every DB DEED, EMPLOYMENTCONTRACT,
PETTOTEM and FURNITUREDEED id is in the DEED folder. No value changes
expected. No pet totem or furniture deed consumer reads template
fields, so neither changes.
JSON-Refactor-Plan Task 1.3.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moves the warehouse-only check into validateBuildingPlacement, which every
city asset placement except siege equipment and trees passes through.
Matches client error 74, "Only buildings of war may be placed during a bane".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Placing a new warehouse discards the destroyed warehouse's rubble loot,
so defenders could deny attackers the loot by rebuilding mid-siege.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
destroyOrDerank nulled city.warehouse on destruction, so the loot click
found no warehouse and returned silently. The destroyed Warehouse is now
held in Warehouse.destroyedWarehouses keyed by the rubble building UUID
until it is looted empty, the rubble is destroyed, or the city places a
new warehouse. Contents are not persisted across a reboot.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>