jevsnes.git / third-party / c / patches / 0030-hammer-peg-indoors-general.patch
0030-hammer-peg-indoors-general.patch46 lines · 2.4 KB · raw
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