1--- a/third-party/c/zbanks-alttp/ap_map.c 2+++ b/third-party/c/zbanks-alttp/ap_map.c 3@@ -437,21 +437,32 @@ 4 5 // Carried patch (jev): raw tile ids are reused for different things in 6 // different rooms - ap_snes.h's own entry for 0x27 already notes this 7-// ("hammer peg (was also fence; remapped to 0x01)"). Dungeon room $010B 8-// (the Dam's block-puzzle room) reuses 0x27 for its push blocks, not a 9-// hammer peg: hammering does nothing to them, but upstream's flat, 10-// room-agnostic ap_tile_attrs[] has no way to say so, so ap_pathfind_local 11-// scored it "liftable" (cost 20, not a wall) and ap_follow_targets swung 12-// the hammer at it - Link stood there mashing Y forever, one pixel from a 13-// solid block. Evidence: research/zbanks-alttp.md, "The Dam Chest push 14-// block". 15+// ("hammer peg (was also fence; remapped to 0x01)"). Originally fixed only 16+// for the Dam's block-puzzle room ($010B, whose push blocks reuse 0x27), 17+// generalized here: indoors, the real game (zelda3 dungeon.c's 18+// HandleItemTileAction_Dungeon, 81dabb) never treats raw 0x27 as a hammer 19+// peg at all - a real peg is always the "replacement object" family 20+// (raw attribute 0x70-0x7F, a slot index `attr & 0xf` into 21+// dung_replacement_tile_state[]), and RoomDraw_HammerPegSingle 22+// (dungeon.c:81b493) is what writes 0x4040 into that slot for one; a pot 23+// writes 0x1010 (RevealPotItem's caller) and a plain pushable block 24+// (DrawObjects_PushableBlock, 81b4d6) writes 0. Raw 0x27 indoors is 25+// therefore never a peg by the game's own rule - it is a plain solid tile 26+// reused per-tileset (a push block's floor in $010B, a floor tile in 27+// Sahasrahla's hut) - so this strips TILE_ATTR_HMMR from it unconditionally 28+// indoors, with no room number anywhere. Outdoors is untouched: there, 29+// raw 0x27 (TileBehavior_Hookshottables) genuinely is how the game marks a 30+// hammer/hookshot peg, and ap_map_attr_from_ram's own fence carve-out 31+// already handles that ambiguity. Evidence: research/zbanks-alttp.md, 32+// "The hammer swings at bare floor". 33 static uint16_t 34 ap_tile_attrs_here(uint8_t raw_tile) 35 { 36- if (raw_tile == 0x27 && *ap_ram.dungeon_room == 0x010B) { 37- return 0; 38+ uint16_t attrs = ap_tile_attrs[raw_tile]; 39+ if (*ap_ram.in_building && (attrs & TILE_ATTR_HMMR)) { 40+ attrs &= ~(uint16_t) TILE_ATTR_HMMR; 41 } 42- return ap_tile_attrs[raw_tile]; 43+ return attrs; 44 } 45 46 static uint16_t