jevsnes.git / third-party / c / patches / 0013-big-chest-needs-the-big-key.patch
0013-big-chest-needs-the-big-key.patch29 lines · 1.5 KB · raw
1diff --git a/third-party/c/zbanks-alttp/ap_plan.c b/third-party/c/zbanks-alttp/ap_plan.c
2index 03f78390..34cd5c0e 100644
3--- a/third-party/c/zbanks-alttp/ap_plan.c
4+++ b/third-party/c/zbanks-alttp/ap_plan.c
5@@ -788,6 +788,24 @@ ap_goal_score(struct ap_goal * goal, int max_score)
6         if (room_state & (1 << (attr - 0x58 + 4))) {
7             return GOAL_SCORE_COMPLETE;
8         }
9+        // Carried patch (jev): a big chest needs its dungeon's big key.
10+        // ap_node_islocked's own DOOR_ATTR_BKEY branch (ap_map.c) checks
11+        // this bit correctly, but only for locked DOORS - it is never
12+        // consulted for NODE_CHEST, and NODE_CHEST's own lock check (same
13+        // function, "0x27: opened chest") only ever asks whether the chest
14+        // is still closed, never whether it can legally be opened. So the
15+        // bot walked straight up to a keyless big chest every time and got
16+        // "Eh? It's locked! If you had the Big Key..." - a wasted attempt
17+        // that fed the given-up/retry ping-pong between it and whatever
18+        // else the bot then tried. Evidence: research/zbanks-alttp.md,
19+        // "The Eastern Palace big chest".
20+        if (goal->node->chest_type == 1) {
21+            assert_bp(goal->node->screen->dungeon_id < 16);
22+            uint16_t bkey_bit = 1 << (15 - goal->node->screen->dungeon_id);
23+            if (!(*ap_ram.sram_dungeon_bigkeys & bkey_bit)) {
24+                return GOAL_SCORE_UNSATISFIABLE;
25+            }
26+        }
27         break;
28     case GOAL_NPC:
29         //score += 1000;