Skip to content

Commit

Permalink
Arrow Switching: Move some code to dedicated header
Browse files Browse the repository at this point in the history
  • Loading branch information
lilDavid committed Nov 23, 2024
1 parent e5eb84f commit 046b56f
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 48 deletions.
1 change: 0 additions & 1 deletion soh/include/functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,6 @@ s32 Player_ActionToBottle(Player* player, s32 actionParam);
s32 Player_GetBottleHeld(Player* player);
s32 Player_ActionToExplosive(Player* player, s32 actionParam);
s32 Player_GetExplosiveHeld(Player* player);
bool Player_CanSwitchArrows(Player* player);
s32 func_8008F2BC(Player* player, s32 actionParam);
s32 Player_GetEnvironmentalHazard(PlayState* play);
void Player_DrawImpl(PlayState* play, void** skeleton, Vec3s* jointTable, s32 dListCount, s32 lod, s32 tunic,
Expand Down
53 changes: 53 additions & 0 deletions soh/soh/Enhancements/arrow-switching/arrow_switching.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "arrow_switching.h"

#include <macros.h>
#include <variables.h>


s32 func_808351D4(Player* this, PlayState* play); // Arrow nocked
s32 func_808353D8(Player* this, PlayState* play); // Aiming in first person

typedef struct {
u8 asArrow;
u8 asBowArrow;
} ArrowItems;

static ArrowItems arrowTypeToItem[] = {
/* normal arrows */ { ITEM_BOW, ITEM_BOW },
/* fire arrows */ { ITEM_ARROW_FIRE, ITEM_BOW_ARROW_FIRE },
/* ice arrows */ { ITEM_ARROW_ICE, ITEM_BOW_ARROW_ICE },
/* light arrows */ { ITEM_ARROW_LIGHT, ITEM_BOW_ARROW_LIGHT },
/* unused arrow types are excluded from cycling */
};

// Returns true if the player is in a state where they can switch arrows.
// Specifically, the gArrowSwitching CVar is enabled, the player is holding the
// bow with normal, fire, ice, or light arrows, and they're either aiming or
// have an arrow notched.
bool ArrowSwitching_CanSwitch(Player* player) {
if (!CVarGetInteger("gArrowSwitching", 0)) {
return false;
}

if (player->heldItemAction < PLAYER_IA_BOW || player->heldItemAction > PLAYER_IA_BOW_LIGHT) {
return false;
}

return player->func_82C == func_808351D4 || player->func_82C == func_808353D8;
}

bool ArrowSwitching_Next(u8 currentItemAction, u8* item, u8* itemAction) {
const u8 arrowCount = ARRAY_COUNT(arrowTypeToItem);
u8 heldArrowIA = currentItemAction - PLAYER_IA_BOW;
u8 i;
for (i = 1; i < arrowCount; i++) {
u8 arrowIA = (heldArrowIA + i) % arrowCount;
ArrowItems items = arrowTypeToItem[arrowIA];
if (INV_CONTENT(items.asArrow) != ITEM_NONE) {
*item = items.asBowArrow;
*itemAction = PLAYER_IA_BOW + arrowIA;
break;
}
}
return i != arrowCount;
}
9 changes: 9 additions & 0 deletions soh/soh/Enhancements/arrow-switching/arrow_switching.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef ENHANCEMENTS_ARROW_SWITCHING_H
#define ENHANCEMENTS_ARROW_SWITCHING_H

#include <z64.h>

bool ArrowSwitching_CanSwitch(Player*);
bool ArrowSwitching_Next(u8 currentItemAction, u8* item, u8* itemAction);

#endif
3 changes: 2 additions & 1 deletion soh/src/code/z_map_exp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "textures/parameter_static/parameter_static.h"
#include "textures/map_i_static/map_i_static.h"
#include "textures/map_grand_static/map_grand_static.h"
#include "soh/Enhancements/arrow-switching/arrow_switching.h"
#include <assert.h>

MapData* gMapData;
Expand Down Expand Up @@ -964,7 +965,7 @@ void Minimap_Draw(PlayState* play) {
}

u16 minimapButton = BTN_L;
if (Player_CanSwitchArrows(GET_PLAYER(play))) {
if (ArrowSwitching_CanSwitch(GET_PLAYER(play))) {
minimapButton &= ~CVarGetInteger("gArrowSwitchBtnMap", BTN_R);
}
if (minimapButton && CHECK_BTN_ALL(play->state.input[0].press.button, minimapButton) && !Play_InCsMode(play) && enableMapToggle) {
Expand Down
54 changes: 8 additions & 46 deletions soh/src/overlays/actors/ovl_player_actor/z_player.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "objects/object_link_child/object_link_child.h"
#include "textures/icon_item_24_static/icon_item_24_static.h"
#include <soh/Enhancements/custom-message/CustomMessageTypes.h>
#include "soh/Enhancements/arrow-switching/arrow_switching.h"
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
Expand Down Expand Up @@ -2218,36 +2219,8 @@ s32 func_80834380(PlayState* play, Player* this, s32* itemPtr, s32* typePtr) {
}
}

typedef struct {
u8 asArrow;
u8 asBowArrow;
} ArrowItems;

static ArrowItems arrowTypeToItem[] = {
/* normal arrows */ { ITEM_BOW, ITEM_BOW },
/* fire arrows */ { ITEM_ARROW_FIRE, ITEM_BOW_ARROW_FIRE },
/* ice arrows */ { ITEM_ARROW_ICE, ITEM_BOW_ARROW_ICE },
/* light arrows */ { ITEM_ARROW_LIGHT, ITEM_BOW_ARROW_LIGHT },
/* unused arrow types are excluded from cycling */
};

static bool gSwitchingArrow = false;

// Returns true if the player is in a state where they can switch arrows.
// Specifically, the gArrowSwitching CVar is enabled, the player is holding the
// bow with normal, fire, ice, or light arrows, and they're either aiming or
// have an arrow notched.
bool Player_CanSwitchArrows(Player* this) {
if (!CVarGetInteger("gArrowSwitching", 0)) {
return false;
}

if (this->heldItemAction < PLAYER_IA_BOW || this->heldItemAction > PLAYER_IA_BOW_LIGHT) {
return false;
}

return this->func_82C == func_808351D4 || this->func_82C == func_808353D8;
}

bool Player_SwitchArrowsIfEnabled(Player* this) {
if (!CVarGetInteger("gArrowSwitching", 0)) {
Expand All @@ -2260,19 +2233,8 @@ bool Player_SwitchArrowsIfEnabled(Player* this) {
return false;
}

u8 i, newItem, newItemAction;
const u8 arrowCount = ARRAY_COUNT(arrowTypeToItem);
u8 heldArrowAP = this->heldItemAction - PLAYER_IA_BOW;
for (i = 1; i < arrowCount; i++) {
u8 arrowAP = (heldArrowAP + i) % arrowCount;
ArrowItems items = arrowTypeToItem[arrowAP];
if (INV_CONTENT(items.asArrow) != ITEM_NONE) {
newItem = items.asBowArrow;
newItemAction = PLAYER_IA_BOW + arrowAP;
break;
}
}
if (i == arrowCount) {
u8 newItem, newItemAction;
if (!ArrowSwitching_Next(this->heldItemAction, &newItem, &newItemAction)) {
return false;
}

Expand Down Expand Up @@ -2334,7 +2296,7 @@ s32 func_8083442C(Player* this, PlayState* play) {
if (this->unk_860 >= 0) {
if ((magicArrowType >= 0) && (magicArrowType <= 2) &&
!Magic_RequestChange(play, sMagicArrowCosts[magicArrowType],
CVarGetInteger("gArrowSwitching", 0) ? 4 : MAGIC_CONSUME_NOW)) {
CVarGetInteger("gArrowSwitching", 0) ? MAGIC_CONSUME_WAIT_PREVIEW : MAGIC_CONSUME_NOW)) {
arrowType = ARROW_NORMAL;
}

Expand Down Expand Up @@ -2401,7 +2363,7 @@ s32 func_80834758(PlayState* play, Player* this) {
if (!(this->stateFlags1 & (PLAYER_STATE1_SHIELDING | PLAYER_STATE1_ON_HORSE | PLAYER_STATE1_IN_CUTSCENE)) &&
(play->shootingGalleryStatus == 0) && (this->heldItemAction == this->itemAction) &&
(this->currentShield != PLAYER_SHIELD_NONE) && !Player_IsChildWithHylianShield(this) && func_80833BCC(this) &&
!Player_CanSwitchArrows(this) && CHECK_BTN_ALL(sControlInput->cur.button, BTN_R)) {
!ArrowSwitching_CanSwitch(this) && CHECK_BTN_ALL(sControlInput->cur.button, BTN_R)) {

anim = func_808346C4(play, this);
frame = Animation_GetLastFrame(anim);
Expand Down Expand Up @@ -2647,7 +2609,7 @@ s32 func_808350A4(PlayState* play, Player* this) {
if (CVarGetInteger("gArrowSwitching", 0) &&
arrowType >= ARROW_FIRE && arrowType <= ARROW_LIGHT
&& this->heldActor->child != NULL) {
gSaveContext.magicState = 0;
gSaveContext.magicState = MAGIC_STATE_IDLE;
Magic_RequestChange(play, sMagicArrowCosts[arrowType - ARROW_FIRE], MAGIC_CONSUME_NOW);
}
}
Expand Down Expand Up @@ -5328,7 +5290,7 @@ s32 func_8083B644(Player* this, PlayState* play) {
}

u16 naviButton = CVarGetInteger("gNaviOnL", 0) ? BTN_L : BTN_CUP;
if (Player_CanSwitchArrows(this)) {
if (ArrowSwitching_CanSwitch(this)) {
naviButton &= ~CVarGetInteger("gArrowSwitchBtnMap", BTN_R);
}
if (!(naviButton && CHECK_BTN_ALL(sControlInput->press.button, naviButton)) &&
Expand Down Expand Up @@ -11716,7 +11678,7 @@ void func_8084B1D8(Player* this, PlayState* play) {
itemButtons |= BTN_DUP | BTN_DDOWN | BTN_DLEFT | BTN_DRIGHT;
}
u16 returnButtons = BTN_A | BTN_B | BTN_R;
if (Player_CanSwitchArrows(this)) {
if (ArrowSwitching_CanSwitch(this)) {
itemButtons &= ~CVarGetInteger("gArrowSwitchBtnMap", BTN_R);
returnButtons &= ~CVarGetInteger("gArrowSwitchBtnMap", BTN_R);
}
Expand Down

0 comments on commit 046b56f

Please sign in to comment.