jevsnes.git / third-party / c / patches / 0007-talk-to-an-npc-until-it-gives.patch
0007-talk-to-an-npc-until-it-gives.patch69 lines · 3.4 KB · raw
1diff --git a/third-party/c/zbanks-alttp/ap_plan.c b/third-party/c/zbanks-alttp/ap_plan.c
2--- a/third-party/c/zbanks-alttp/ap_plan.c
3+++ b/third-party/c/zbanks-alttp/ap_plan.c
4@@ -489,17 +489,39 @@
5         break;
6     case TASK_TALK_NPC:
7         LOG("timeout: %d; state: %d; recving: %x; push: %x; item_recv_method: %x; link_state: %x; recving_item: %#x", task->timeout, task->state, *ap_ram.recving_item, *ap_ram.push_timer, *ap_ram.item_recv_method, *ap_ram.link_state, *ap_ram.recving_item);
8+        // Carried patch (jev): what Link has, $7EF340-$7EF35F, to tell that
9+        // the NPC gave him something. $02D8 cannot: it keeps the last item
10+        // Link was given long after, and an NPC's gift is received while
11+        // Link holds it up, when ap_tick does not evaluate tasks at all -
12+        // by the time this runs again it is 0 (Sahasrahla's boots).
13+        static uint32_t talk_items;
14+        uint32_t items = 0;
15+        for (size_t i = 1; i <= 0x20; i++) {
16+            if (i != 4) items = items * 31 + ap_ram.inventory_base[i]; // not $7EF343, the bomb count
17+        }
18         switch (task->state) {
19         case 0:
20             task->timeout = 64;
21+            task->item = *ap_ram.recving_item;
22+            talk_items = items;
23             task->state++;
24         case 1:
25             JOYPAD_SET(UP);
26             JOYPAD_MASH(A, 1);
27-            if (*ap_ram.link_state == LINK_STATE_RECVING_ITEM || *ap_ram.link_state == LINK_STATE_RECVING_ITEM2 || *ap_ram.recving_item) {
28+            // Carried patch (jev): while the NPC's text box is up (module
29+            // 0x0E) the talk is not over, however long it is - Sahasrahla's
30+            // outlasts 64 frames, and a goal failed mid-text leaves the box
31+            // open with nothing pressing A.
32+            if (*ap_ram.module_index == 0x0E && task->timeout < 2) {
33+                task->timeout = 2;
34+            }
35+            if (*ap_ram.link_state == LINK_STATE_RECVING_ITEM || *ap_ram.link_state == LINK_STATE_RECVING_ITEM2 ||
36+                    items != talk_items) {
37                 // Holding item (uncle)
38                 LOGB("holding item");
39-                ap_item_loc_set_raw(task->node->item_loc, *ap_ram.recving_item);
40+                if (*ap_ram.recving_item != 0 && *ap_ram.recving_item != task->item) {
41+                    ap_item_loc_set_raw(task->node->item_loc, *ap_ram.recving_item);
42+                }
43                 task->timeout = 128;
44                 task->state++;
45             }
46@@ -510,10 +532,21 @@
47             break;
48         case 2:
49             JOYPAD_CLEAR(UP);
50-            if (*ap_ram.link_state != LINK_STATE_RECVING_ITEM && *ap_ram.link_state != LINK_STATE_RECVING_ITEM2) {
51-                return RC_DONE;
52+            if (*ap_ram.link_state != LINK_STATE_RECVING_ITEM && *ap_ram.link_state != LINK_STATE_RECVING_ITEM2 &&
53+                    *ap_ram.module_index != 0x0E) {
54+                // Carried patch (jev): once the text is done, step back down
55+                // off the NPC. Talking pressed up into it, and a path that
56+                // starts with a sidestep along a solid NPC's body goes
57+                // nowhere (Sahasrahla).
58+                task->state = 3;
59+                task->timeout = 20;
60             }
61             break;
62+        case 3:
63+            JOYPAD_CLEAR(UP);
64+            JOYPAD_SET(DOWN);
65+            if (task->timeout <= 1) return RC_DONE;
66+            break;
67         }
68         break;
69     case TASK_LIFT_POT: