mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-04-28 21:27:58 +03:00
rework assignable tunic/boots to use shipinit and hooks (#4978)
* don't put away items when equipping tunics/boots * vb * don't need that return * ok i guess i'm going down the rabbit hole * more rabbit hole * shipinit and more hooks * clean up * use fewer params, add a missing condition * make the loops make sense
This commit is contained in:
parent
8ae8770db8
commit
11e07a8f9d
3 changed files with 122 additions and 47 deletions
114
soh/soh/Enhancements/AssignableTunicsAndBoots.cpp
Normal file
114
soh/soh/Enhancements/AssignableTunicsAndBoots.cpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
#include "soh/ShipInit.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "macros.h"
|
||||||
|
#include "variables.h"
|
||||||
|
|
||||||
|
extern s32 Player_GetItemOnButton(PlayState*, s32);
|
||||||
|
extern void Inventory_ChangeEquipment(s16, u16);
|
||||||
|
extern void Player_SetEquipmentData(PlayState*, Player*);
|
||||||
|
extern void func_808328EC(Player*, u16);
|
||||||
|
extern PlayState* gPlayState;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u16 sItemButtons[] = { BTN_B, BTN_CLEFT, BTN_CDOWN, BTN_CRIGHT, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT };
|
||||||
|
|
||||||
|
void UseTunicBoots(Player* player, PlayState* play, Input* input) {
|
||||||
|
// Boots and tunics equip despite state
|
||||||
|
if (
|
||||||
|
player->stateFlags1 & (PLAYER_STATE1_INPUT_DISABLED | PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE | PLAYER_STATE1_TALKING | PLAYER_STATE1_DEAD) ||
|
||||||
|
player->stateFlags2 & PLAYER_STATE2_OCARINA_PLAYING
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 item = ITEM_NONE;
|
||||||
|
for (s32 i = 0; i < ARRAY_COUNT(sItemButtons); i++) {
|
||||||
|
if (CHECK_BTN_ALL(input->press.button, sItemButtons[i])) {
|
||||||
|
item = Player_GetItemOnButton(play, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item >= ITEM_TUNIC_KOKIRI && item <= ITEM_BOOTS_HOVER) {
|
||||||
|
if (item >= ITEM_BOOTS_KOKIRI) {
|
||||||
|
u16 bootsValue = item - ITEM_BOOTS_KOKIRI + 1;
|
||||||
|
if (CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) == bootsValue) {
|
||||||
|
Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_KOKIRI);
|
||||||
|
} else {
|
||||||
|
Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, bootsValue);
|
||||||
|
}
|
||||||
|
Player_SetEquipmentData(play, player);
|
||||||
|
func_808328EC(player, CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) == EQUIP_VALUE_BOOTS_IRON ? NA_SE_PL_WALK_HEAVYBOOTS : NA_SE_PL_CHANGE_ARMS);
|
||||||
|
} else {
|
||||||
|
u16 tunicValue = item - ITEM_TUNIC_KOKIRI + 1;
|
||||||
|
if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) == tunicValue) {
|
||||||
|
Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_KOKIRI);
|
||||||
|
} else {
|
||||||
|
Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, tunicValue);
|
||||||
|
}
|
||||||
|
Player_SetEquipmentData(play, player);
|
||||||
|
func_808328EC(player, NA_SE_PL_CHANGE_ARMS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearAssignedTunicsBoots(int32_t unused = 0) {
|
||||||
|
for (int32_t buttonIndex = 0; buttonIndex < 8; buttonIndex++) {
|
||||||
|
int32_t item = gSaveContext.equips.buttonItems[buttonIndex];
|
||||||
|
|
||||||
|
if (item >= ITEM_TUNIC_KOKIRI && item <= ITEM_BOOTS_HOVER) {
|
||||||
|
gSaveContext.equips.buttonItems[buttonIndex] = ITEM_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CVAR_TUNICBOOTS_NAME CVAR_ENHANCEMENT("AssignableTunicsAndBoots")
|
||||||
|
#define CVAR_TUNICBOOTS_DEFAULT 0
|
||||||
|
#define CVAR_TUNICBOOTS_VALUE CVarGetInteger(CVAR_TUNICBOOTS_NAME, CVAR_TUNICBOOTS_DEFAULT)
|
||||||
|
|
||||||
|
void RegisterAssignableTunicsBoots() {
|
||||||
|
// make sure we don't change our held/equipped item when changing tunics/boots
|
||||||
|
COND_VB_SHOULD(VB_CHANGE_HELD_ITEM_AND_USE_ITEM, CVAR_TUNICBOOTS_VALUE != CVAR_TUNICBOOTS_DEFAULT, {
|
||||||
|
int32_t item = va_arg(args, int32_t);
|
||||||
|
|
||||||
|
if (item >= ITEM_TUNIC_KOKIRI && item <= ITEM_BOOTS_HOVER) {
|
||||||
|
*should = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// make sure we don't crash because tunics/boots don't have assoicated item actions
|
||||||
|
COND_VB_SHOULD(VB_ITEM_ACTION_BE_NONE, CVAR_TUNICBOOTS_VALUE != CVAR_TUNICBOOTS_DEFAULT, {
|
||||||
|
int32_t item = va_arg(args, int32_t);
|
||||||
|
|
||||||
|
if (item >= ITEM_TUNIC_KOKIRI && item <= ITEM_BOOTS_HOVER) {
|
||||||
|
*should = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// do something when the player presses a button to use the tunics/boots
|
||||||
|
COND_VB_SHOULD(VB_EXECUTE_PLAYER_ACTION_FUNC, CVAR_TUNICBOOTS_VALUE != CVAR_TUNICBOOTS_DEFAULT, {
|
||||||
|
// if the vanilla condition doesn't want us to run the actionFunc, don't do any of this
|
||||||
|
if (!*should) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Input* input = va_arg(args, Input*);
|
||||||
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
|
|
||||||
|
*should = false;
|
||||||
|
player->actionFunc(player, gPlayState);
|
||||||
|
UseTunicBoots(player, gPlayState, input);
|
||||||
|
});
|
||||||
|
|
||||||
|
// clear out assigned tunics/boots when the enhancement is toggled off
|
||||||
|
if (GameInteractor::IsSaveLoaded(true) && CVAR_TUNICBOOTS_VALUE == CVAR_TUNICBOOTS_DEFAULT) {
|
||||||
|
ClearAssignedTunicsBoots();
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear out assigned tunics/boots when loading a save with enhancement turned off
|
||||||
|
COND_HOOK(OnLoadGame, CVAR_TUNICBOOTS_VALUE == CVAR_TUNICBOOTS_DEFAULT, ClearAssignedTunicsBoots);
|
||||||
|
}
|
||||||
|
|
||||||
|
static RegisterShipInitFunc initFunc(RegisterAssignableTunicsBoots, { CVAR_TUNICBOOTS_NAME });
|
|
@ -532,6 +532,11 @@ typedef enum {
|
||||||
VB_SPAWN_SONG_FAIRY,
|
VB_SPAWN_SONG_FAIRY,
|
||||||
// Opt: *EnGs
|
// Opt: *EnGs
|
||||||
VB_SPAWN_GOSSIP_STONE_FAIRY,
|
VB_SPAWN_GOSSIP_STONE_FAIRY,
|
||||||
|
|
||||||
|
/*** Equippable tunics and boots ***/
|
||||||
|
VB_CHANGE_HELD_ITEM_AND_USE_ITEM,
|
||||||
|
VB_ITEM_ACTION_BE_NONE,
|
||||||
|
VB_EXECUTE_PLAYER_ACTION_FUNC,
|
||||||
} GIVanillaBehavior;
|
} GIVanillaBehavior;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -2244,16 +2244,12 @@ void Player_InitItemActionWithAnim(PlayState* play, Player* this, s8 itemAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
s8 Player_ItemToItemAction(s32 item) {
|
s8 Player_ItemToItemAction(s32 item) {
|
||||||
if (item >= ITEM_NONE_FE) {
|
if (GameInteractor_Should(VB_ITEM_ACTION_BE_NONE, item >= ITEM_NONE_FE, item)) {
|
||||||
return PLAYER_IA_NONE;
|
return PLAYER_IA_NONE;
|
||||||
} else if (item == ITEM_LAST_USED) {
|
} else if (item == ITEM_LAST_USED) {
|
||||||
return PLAYER_IA_SWORD_CS;
|
return PLAYER_IA_SWORD_CS;
|
||||||
} else if (item == ITEM_FISHING_POLE) {
|
} else if (item == ITEM_FISHING_POLE) {
|
||||||
return PLAYER_IA_FISHING_POLE;
|
return PLAYER_IA_FISHING_POLE;
|
||||||
// #region SOH [Enhancement] Added to prevent crashes with assignable equipment
|
|
||||||
} else if (item >= ITEM_TUNIC_KOKIRI && item <= ITEM_BOOTS_HOVER) {
|
|
||||||
return PLAYER_IA_NONE;
|
|
||||||
// #endregion
|
|
||||||
} else {
|
} else {
|
||||||
return sItemActions[item];
|
return sItemActions[item];
|
||||||
}
|
}
|
||||||
|
@ -2572,7 +2568,7 @@ void Player_ProcessItemButtons(Player* this, PlayState* play) {
|
||||||
if ((item < ITEM_NONE_FE) && (Player_ItemToItemAction(item) == this->heldItemAction)) {
|
if ((item < ITEM_NONE_FE) && (Player_ItemToItemAction(item) == this->heldItemAction)) {
|
||||||
sHeldItemButtonIsHeldDown = true;
|
sHeldItemButtonIsHeldDown = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (GameInteractor_Should(VB_CHANGE_HELD_ITEM_AND_USE_ITEM, true, item)) {
|
||||||
this->heldItemButton = i;
|
this->heldItemButton = i;
|
||||||
Player_UseItem(play, this, item);
|
Player_UseItem(play, this, item);
|
||||||
}
|
}
|
||||||
|
@ -11883,45 +11879,6 @@ static Vec3f D_80854814 = { 0.0f, 0.0f, 200.0f };
|
||||||
static f32 sWaterConveyorSpeeds[] = { 2.0f, 4.0f, 7.0f };
|
static f32 sWaterConveyorSpeeds[] = { 2.0f, 4.0f, 7.0f };
|
||||||
static f32 sFloorConveyorSpeeds[] = { 0.5f, 1.0f, 3.0f };
|
static f32 sFloorConveyorSpeeds[] = { 0.5f, 1.0f, 3.0f };
|
||||||
|
|
||||||
void Player_UseTunicBoots(Player* this, PlayState* play) {
|
|
||||||
// Boots and tunics equip despite state
|
|
||||||
if (
|
|
||||||
this->stateFlags1 & (PLAYER_STATE1_INPUT_DISABLED | PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE | PLAYER_STATE1_TALKING | PLAYER_STATE1_DEAD) ||
|
|
||||||
this->stateFlags2 & PLAYER_STATE2_OCARINA_PLAYING
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 i;
|
|
||||||
for (i = 0; i < ARRAY_COUNT(sItemButtons); i++) {
|
|
||||||
if (CHECK_BTN_ALL(sControlInput->press.button, sItemButtons[i])) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s32 item = Player_GetItemOnButton(play, i);
|
|
||||||
if (item >= ITEM_TUNIC_KOKIRI && item <= ITEM_BOOTS_HOVER) {
|
|
||||||
if (item >= ITEM_BOOTS_KOKIRI) {
|
|
||||||
u16 bootsValue = item - ITEM_BOOTS_KOKIRI + 1;
|
|
||||||
if (CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) == bootsValue) {
|
|
||||||
Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_KOKIRI);
|
|
||||||
} else {
|
|
||||||
Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, bootsValue);
|
|
||||||
}
|
|
||||||
Player_SetEquipmentData(play, this);
|
|
||||||
func_808328EC(this, CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) == EQUIP_VALUE_BOOTS_IRON ? NA_SE_PL_WALK_HEAVYBOOTS : NA_SE_PL_CHANGE_ARMS);
|
|
||||||
} else {
|
|
||||||
u16 tunicValue = item - ITEM_TUNIC_KOKIRI + 1;
|
|
||||||
if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) == tunicValue) {
|
|
||||||
Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_KOKIRI);
|
|
||||||
} else {
|
|
||||||
Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, tunicValue);
|
|
||||||
}
|
|
||||||
Player_SetEquipmentData(play, this);
|
|
||||||
func_808328EC(this, NA_SE_PL_CHANGE_ARMS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player_UpdateCommon(Player* this, PlayState* play, Input* input) {
|
void Player_UpdateCommon(Player* this, PlayState* play, Input* input) {
|
||||||
s32 pad;
|
s32 pad;
|
||||||
|
|
||||||
|
@ -12218,9 +12175,8 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) {
|
||||||
sUseHeldItem = sHeldItemButtonIsHeldDown = 0;
|
sUseHeldItem = sHeldItemButtonIsHeldDown = 0;
|
||||||
sSavedCurrentMask = this->currentMask;
|
sSavedCurrentMask = this->currentMask;
|
||||||
|
|
||||||
if (!(this->stateFlags3 & PLAYER_STATE3_PAUSE_ACTION_FUNC)) {
|
if (GameInteractor_Should(VB_EXECUTE_PLAYER_ACTION_FUNC, !(this->stateFlags3 & PLAYER_STATE3_PAUSE_ACTION_FUNC), input)) {
|
||||||
this->actionFunc(this, play);
|
this->actionFunc(this, play);
|
||||||
Player_UseTunicBoots(this, play);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Player_UpdateCamAndSeqModes(play, this);
|
Player_UpdateCamAndSeqModes(play, this);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue