exodus122

OoT - Equip Swap explained

Apr 21st, 2022 (edited)
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.94 KB | None | 0 0
  1. Below is a simplified version of the code which runs each frame that the item subscreen is open. It updates the position of the cursor in the inventory, keeps track of the current slot and item selected, and equips items to C. Look below the code for explanations of the variables.
  2.  
  3.  
  4. moveCursorResult = 0
  5. cursorItem = pauseCtx->cursorItem[PAUSE_ITEM];
  6. cursorSlot = pauseCtx->cursorSlot[PAUSE_ITEM];
  7.  
  8. if(detected left/right control stick input):
  9. if(found a filled item slot to move to):
  10. move the cursor to that slot
  11. moveCursorResult = 1
  12. if(cursor was moved from an item slot to another item slot):
  13. // this notably does not run if the cursor was moved from Z/R to an item slot
  14. cursorItem = item in that slot
  15. else:
  16. no slot was found, move the cursor to the R or Z icon
  17. moveCursorResult = 2
  18.  
  19. if(cursor is not on the R or Z icon):
  20. if(cursorItem != PAUSE_ITEM_NONE):
  21. if(detected up/down control stick input):
  22. if(found a filled item slot to move to):
  23. move the cursor to that slot
  24. moveCursorResult = 1
  25. else:
  26. no slot was found, do not move the cursor up or down
  27. moveCursorResult = 2
  28.  
  29. cursorSlot gets updated if the cursor moved
  30. if (moveCursorResult != 2):
  31. cursorItem = the item in that new slot
  32.  
  33. pauseCtx->cursorItem[PAUSE_ITEM] = cursorItem;
  34. pauseCtx->cursorSlot[PAUSE_ITEM] = cursorSlot;
  35.  
  36. else:
  37. pauseCtx->cursorItem[PAUSE_ITEM] = PAUSE_ITEM_NONE;
  38.  
  39. if(c-button input detected && pauseCtx->cursorItem[PAUSE_ITEM] != PAUSE_ITEM_NONE):
  40. equip "pauseCtx->cursorItem[PAUSE_ITEM]" to C and assign it to this slot: "pauseCtx->cursorSlot[PAUSE_ITEM]"
  41.  
  42.  
  43.  
  44.  
  45. Variables explained:
  46.  
  47. "moveCursorResult" is a temporary variable which starts at 0, and gets set to either 1 or 2 if a left/right/up/down input is detected. 1 means the cursor successfully moved to a new item slot. 2 means the cursor was not able to move to a new item slot.
  48.  
  49. "cursorItem" is a temporary variable which is used to update "pauseCtx->cursorItem[PAUSE_ITEM]".
  50.  
  51. "pauseCtx->cursorItem[PAUSE_ITEM]" keeps track of the item which the cursor was most recently on, when on the item subscreen. It can also be set to PAUSE_ITEM_NONE, which signifies being on the Z or R icon, and disables moving the cursor up/down and also disallows equipping items. It keeps its value when you switch to another subscreen, which is important for Equip Swap.
  52.  
  53. "cursorSlot" is a temporary variable which is used to update "pauseCtx->cursorSlot[PAUSE_ITEM]".
  54.  
  55. "pauseCtx->cursorSlot[PAUSE_ITEM]" keeps track of the slot which the cursor is currently on, when on the item subscreen
  56.  
  57.  
  58.  
  59.  
  60.  
  61. Below are 3 scenarios explaining how left/right and up/down inputs affect the cursorItem and cursorSlot variables when moving to the item subscreen from another subscreen.
  62.  
  63.  
  64. Scenario 1: Switching to the item screen without a left/right input:
  65. -the cursor starts on the Z or R icon (depending on which subscreen you came from)
  66. -no left/right input is detected, so skip that block
  67. -the cursor is on the Z/R button, so skip the next block
  68. -set cursorItem to PAUSE_ITEM_NONE. this disables up/down and c-button inputs as long as the cursor remains on Z or R.
  69.  
  70.  
  71.  
  72.  
  73. Scenario 2: Switching to the item subscreen with a left/right input but without an up/down input:
  74. -the cursor starts on the Z or R icon (depending on which subscreen you came from)
  75. -a left/right input is detected, so find the non-empty column which is closest to the Z/R icon, then move the cursor to the topmost item in that column. set moveCursorResult to 1.
  76. -the cursor is no longer on the Z/R icon, so go into the next block (line 19)
  77. -cursorSlot gets updated because the cursor moved
  78. -moveCursorResult is 1, so the cursorItem gets updated as well
  79. -if a c-button is also pressed on this frame, cursorItem gets equipped and assigned to cursorSlot.
  80.  
  81.  
  82.  
  83. Scenario 3: Switching to the item subscreen with both a left/right input and an up/down input:
  84. -the cursor starts on the Z or R icon (depending on which subscreen you came from)
  85. -a left/right input is detected, so find the non-empty column which is closest to the Z/R icon, then move the cursor to the topmost item in that column. set moveCursorResult to 1.
  86. -the cursor is no longer on the Z/R icon, so go into the next block (line 19)
  87. -(cursorItem is not PAUSE_ITEM_NONE because the cursor moved from the Z/R button before it could be set, so up/down inputs are not disabled on this first frame)
  88. -an up/down input is detected, so try to move the cursor to an item above or below the cursor.
  89.  
  90. Now 3 different things can happen:
  91. 1. if an up input is detected, the cursor is unable to move upward because it is already on the topmost item in this column, so moveCursorResult gets set to 2.
  92. 2. if a down input is detected, and there is no item below the cursor, it will fail to move downward and moveCursorResult gets set to 2.
  93. 3. if a down input is detected, and there is an item below the cursor, it will move downward and moveCursorResult gets set to 1.
  94.  
  95. If moveCursorResult was set to 2, cursorSlot gets updated, but cursorItem does not. If a c-button is also pressed on this frame, the stale cursorItem will be equipped and assigned to the newly updated cursorSlot. This is known as Equip Swap.
  96.  
  97. If moveCursorResult is set to 1, the cursor moves to the item below the topmost item in the non-empty column which is closest to the Z/R icon. If a c-button is also pressed on this frame, the updated cursorItem gets equipped and assigned to cursorSlot. This is why you cannot use a diagonal down input to equip swap if you have more than one item in the non-empty column which is closest to the Z/R icon.
  98.  
  99.  
  100.  
  101. Other notes:
  102.  
  103. Equip swap is frame perfect because the inputs must be detected on the first frame this code runs. If the inputs are a frame late, pauseCtx->cursorItem[PAUSE_ITEM] gets set to PAUSE_ITEM_NONE, because the cursor is on the Z or R icon. This overwrites the stale value which is necessary for Equip Swap.
  104.  
  105. As for why you cannot simply hold the diagonal input early and time the c button press, the pause menu starts ignoring control stick inputs if you hold them for more than one frame. For example, if you begin holding left, it will detect it on the next frame, but will be ignored for the next several frames. This is so the cursor does not move too quickly through the menu. You can see this ingame if you start holding a direction on the item screen, it will move once immediately, then stay still for several frames, then move again, then stay still for a few frames, then move again, etc.
  106.  
  107. So if the cursor getting moved left/right then failing to move up/down causes equip swap, why doesn't equip swap happen with an upleft/upright input when the cursor is on an item slot in the top row? The answer is on line 13 of this pastebin. cursorItem gets updated when moving from one item slot to another, but not when moving from Z/R to an item slot.
Add Comment
Please, Sign In to add comment