mirror of
https://github.com/izzy2lost/2ship2harkinian-Android.git
synced 2026-06-19 01:20:08 -07:00
[Enhancement] Two-handed sword spin attacks (#679)
* Enhancement to enable magic for 2-handed swords Create a new magic charge size for the two-handed swords Add utility method for determining if the held item's button is being pressed, not just B * Clean up two-handed sword spin attacks Add hook for thunder matrix transformation, move that logic into TwoHandedSwordSpinAttack Move held item button press function into TwoHandedSwordSpinAttack.cpp Add enhancement to the searchable menu Clean up logic for magic spin attack form check Use variadic args for hooks * Remove redundant includes from TwoHandedSwordSpinAttack.cpp * Use extern on TwoHandedSwordSpinAttack structs
This commit is contained in:
@@ -578,6 +578,9 @@ void DrawEnhancementsMenu() {
|
||||
{ .tooltip =
|
||||
"Pressing B will instantly recall the fin boomerang back to Zora Link after they are thrown." });
|
||||
|
||||
UIWidgets::CVarCheckbox(
|
||||
"Two-Handed Sword Spin Attack", "gEnhancements.Equipment.TwoHandedSwordSpinAttack",
|
||||
{ .tooltip = "Enables magic spin attacks for the Fierce Deity Sword and Great Fairy's Sword." });
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
|
||||
@@ -1027,6 +1027,9 @@ void AddEnhancements() {
|
||||
"Removes the animation for equipping Magic Arrows.", WIDGET_CVAR_CHECKBOX },
|
||||
{ "Instant Fin Boomerangs Recall", "gEnhancements.PlayerActions.InstantRecall",
|
||||
"Pressing B will instantly recall the fin boomerang back to Zora Link after they are thrown.",
|
||||
WIDGET_CVAR_CHECKBOX },
|
||||
{ "Two-Handed Sword Spin Attack", "gEnhancements.Equipment.TwoHandedSwordSpinAttack",
|
||||
"Enables magic spin attacks for the Fierce Deity Sword and Great Fairy's Sword.",
|
||||
WIDGET_CVAR_CHECKBOX } },
|
||||
{ { .widgetName = "Modes", .widgetType = WIDGET_SEPARATOR_TEXT },
|
||||
{ "Play as Kafei", "gModes.PlayAsKafei", "Requires scene reload to take effect.", WIDGET_CVAR_CHECKBOX },
|
||||
|
||||
@@ -34,6 +34,7 @@ void InitEnhancements() {
|
||||
|
||||
// Fixes
|
||||
RegisterFierceDeityZTargetMovement();
|
||||
RegisterTwoHandedSwordSpinAttack();
|
||||
|
||||
// Graphics
|
||||
RegisterDisableBlackBars();
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
|
||||
void RegisterInstantRecall();
|
||||
void RegisterSkipMagicArrowEquip();
|
||||
void RegisterTwoHandedSwordSpinAttack();
|
||||
|
||||
#endif // EQUIPMENT_H
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
#include <libultraship/bridge.h>
|
||||
#include "2s2h/GameInteractor/GameInteractor.h"
|
||||
#include "overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.h"
|
||||
|
||||
extern "C" {
|
||||
extern PlayState* gPlayState;
|
||||
extern Input* sPlayerControlInput;
|
||||
}
|
||||
|
||||
void RegisterTwoHandedSwordSpinAttack() {
|
||||
|
||||
REGISTER_VB_SHOULD(VB_CHECK_HELD_ITEM_BUTTON_PRESS, {
|
||||
if (CVarGetInteger("gEnhancements.Equipment.TwoHandedSwordSpinAttack", 0)) {
|
||||
// Instead of checking B only, check whichever button is assigned to the currently held item. This allows
|
||||
// the Great Fairy Sword, a C button item, to be held for charged spin attacks.
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
u16* sDpadItemButtons = va_arg(args, u16*);
|
||||
u16* sPlayerItemButtons = va_arg(args, u16*);
|
||||
|
||||
if (player->heldItemButton < 0) {
|
||||
*should = false;
|
||||
} else {
|
||||
uint16_t buttonToCheck;
|
||||
if (IS_HELD_DPAD(player->heldItemButton)) {
|
||||
buttonToCheck = sDpadItemButtons[HELD_ITEM_TO_DPAD(player->heldItemButton)];
|
||||
} else {
|
||||
buttonToCheck = sPlayerItemButtons[player->heldItemButton];
|
||||
}
|
||||
*should = CHECK_BTN_ALL(sPlayerControlInput->cur.button, buttonToCheck);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
REGISTER_VB_SHOULD(VB_MAGIC_SPIN_ATTACK_CHECK_FORM, {
|
||||
if (CVarGetInteger("gEnhancements.Equipment.TwoHandedSwordSpinAttack", 0)) {
|
||||
// Additionally allow the Fierce Deity form to use charged spin attacks
|
||||
PlayerTransformation form = va_arg(args, PlayerTransformation);
|
||||
if (form == PLAYER_FORM_FIERCE_DEITY) {
|
||||
*should = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
REGISTER_VB_SHOULD(VB_TRANSFORM_THUNDER_MATRIX, {
|
||||
if (CVarGetInteger("gEnhancements.Equipment.TwoHandedSwordSpinAttack", 0)) {
|
||||
EnMThunder* enMThunder = va_arg(args, EnMThunder*);
|
||||
// Define new thunder matrix transformation for two-handed sword magic. Applies to both the GFS and the
|
||||
// Fierce Deity sword.
|
||||
if (enMThunder->type == ENMTHUNDER_TYPE_GREAT_FAIRYS_SWORD) {
|
||||
Matrix_Translate(0.0f, 220.0f, 0.0f, MTXMODE_APPLY);
|
||||
Matrix_Scale(-1.7f, -1.0f, -0.6f, MTXMODE_APPLY);
|
||||
Matrix_RotateXS(0x4000, MTXMODE_APPLY);
|
||||
*should = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -69,6 +69,9 @@ typedef enum {
|
||||
VB_SHOULD_PUTAWAY,
|
||||
VB_ELEGY_CHECK_SCENE,
|
||||
VB_NEED_SCARECROW_SONG,
|
||||
VB_CHECK_HELD_ITEM_BUTTON_PRESS,
|
||||
VB_MAGIC_SPIN_ATTACK_CHECK_FORM,
|
||||
VB_TRANSFORM_THUNDER_MATRIX,
|
||||
} GIVanillaBehavior;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "z64rumble.h"
|
||||
#include "overlays/actors/ovl_Eff_Dust/z_eff_dust.h"
|
||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
#include "2s2h/GameInteractor/GameInteractor.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_10)
|
||||
|
||||
@@ -543,14 +544,16 @@ void EnMThunder_Draw(Actor* thisx, PlayState* play2) {
|
||||
|
||||
Matrix_Mult(&player->leftHandMf, MTXMODE_NEW);
|
||||
|
||||
if (this->type == ENMTHUNDER_TYPE_GILDED_SWORD) {
|
||||
Matrix_Translate(0.0f, 220.0f, 0.0f, MTXMODE_APPLY);
|
||||
Matrix_Scale(-1.2f, -0.8f, -0.6f, MTXMODE_APPLY);
|
||||
Matrix_RotateXS(0x4000, MTXMODE_APPLY);
|
||||
} else {
|
||||
Matrix_Translate(0.0f, 220.0f, 0.0f, MTXMODE_APPLY);
|
||||
Matrix_Scale(-0.7f, -0.6f, -0.4f, MTXMODE_APPLY);
|
||||
Matrix_RotateXS(0x4000, MTXMODE_APPLY);
|
||||
if (GameInteractor_Should(VB_TRANSFORM_THUNDER_MATRIX, true, this)) {
|
||||
if (this->type == ENMTHUNDER_TYPE_GILDED_SWORD) {
|
||||
Matrix_Translate(0.0f, 220.0f, 0.0f, MTXMODE_APPLY);
|
||||
Matrix_Scale(-1.2f, -0.8f, -0.6f, MTXMODE_APPLY);
|
||||
Matrix_RotateXS(0x4000, MTXMODE_APPLY);
|
||||
} else {
|
||||
Matrix_Translate(0.0f, 220.0f, 0.0f, MTXMODE_APPLY);
|
||||
Matrix_Scale(-0.7f, -0.6f, -0.4f, MTXMODE_APPLY);
|
||||
Matrix_RotateXS(0x4000, MTXMODE_APPLY);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->unk1B0 >= 0.85f) {
|
||||
|
||||
@@ -5268,7 +5268,9 @@ void func_808332A0(PlayState* play, Player* this, s32 magicCost, s32 isSwordBeam
|
||||
}
|
||||
|
||||
this->stateFlags1 |= PLAYER_STATE1_1000;
|
||||
if ((this->actor.id == ACTOR_PLAYER) && (isSwordBeam || (this->transformation == PLAYER_FORM_HUMAN))) {
|
||||
if ((this->actor.id == ACTOR_PLAYER) &&
|
||||
(isSwordBeam || (GameInteractor_Should(VB_MAGIC_SPIN_ATTACK_CHECK_FORM,
|
||||
this->transformation == PLAYER_FORM_HUMAN, this->transformation)))) {
|
||||
s16 pitch = 0;
|
||||
Actor* thunder;
|
||||
|
||||
@@ -8192,13 +8194,16 @@ s32 func_8083A4A4(Player* this, f32* arg1, s16* arg2, f32 arg3) {
|
||||
}
|
||||
|
||||
void func_8083A548(Player* this) {
|
||||
if ((this->unk_ADC > 0) && !CHECK_BTN_ALL(sPlayerControlInput->cur.button, BTN_B)) {
|
||||
if ((this->unk_ADC > 0) &&
|
||||
!GameInteractor_Should(VB_CHECK_HELD_ITEM_BUTTON_PRESS, CHECK_BTN_ALL(sPlayerControlInput->cur.button, BTN_B),
|
||||
sDpadItemButtons, sPlayerItemButtons)) {
|
||||
this->unk_ADC = -this->unk_ADC;
|
||||
}
|
||||
}
|
||||
|
||||
s32 Player_ActionChange_8(Player* this, PlayState* play) {
|
||||
if (CHECK_BTN_ALL(sPlayerControlInput->cur.button, BTN_B)) {
|
||||
if (GameInteractor_Should(VB_CHECK_HELD_ITEM_BUTTON_PRESS, CHECK_BTN_ALL(sPlayerControlInput->cur.button, BTN_B),
|
||||
sDpadItemButtons, sPlayerItemButtons)) {
|
||||
if (!(this->stateFlags1 & PLAYER_STATE1_400000) &&
|
||||
(Player_GetMeleeWeaponHeld(this) != PLAYER_MELEEWEAPON_NONE)) {
|
||||
if ((this->unk_ADC > 0) && (((this->transformation == PLAYER_FORM_ZORA)) ||
|
||||
@@ -10462,7 +10467,9 @@ s32 func_80840A30(PlayState* play, Player* this, f32* arg2, f32 arg3) {
|
||||
s32 func_80840CD4(Player* this, PlayState* play) {
|
||||
if (Player_StartCsAction(play, this)) {
|
||||
this->stateFlags2 |= PLAYER_STATE2_20000;
|
||||
} else if (!CHECK_BTN_ALL(sPlayerControlInput->cur.button, BTN_B)) {
|
||||
} else if (!GameInteractor_Should(VB_CHECK_HELD_ITEM_BUTTON_PRESS,
|
||||
CHECK_BTN_ALL(sPlayerControlInput->cur.button, BTN_B), sDpadItemButtons,
|
||||
sPlayerItemButtons)) {
|
||||
PlayerMeleeWeaponAnimation meleeWeaponAnim;
|
||||
|
||||
if ((this->unk_B08 >= 0.85f) || func_808333CC(this)) {
|
||||
@@ -14561,7 +14568,9 @@ void Player_Action_12(Player* this, PlayState* play) {
|
||||
if (!func_80847880(play, this)) {
|
||||
if (!Player_TryActionChangeList(play, this, sPlayerActionChangeList7, false) ||
|
||||
(Player_Action_12 == this->actionFunc)) {
|
||||
if (!CHECK_BTN_ALL(sPlayerControlInput->cur.button, BTN_B)) {
|
||||
if (!GameInteractor_Should(VB_CHECK_HELD_ITEM_BUTTON_PRESS,
|
||||
CHECK_BTN_ALL(sPlayerControlInput->cur.button, BTN_B), sDpadItemButtons,
|
||||
sPlayerItemButtons)) {
|
||||
func_80839E74(this, play);
|
||||
}
|
||||
}
|
||||
@@ -15246,7 +15255,9 @@ void Player_Action_30(Player* this, PlayState* play) {
|
||||
if (this->unk_B08 >= 0.1f) {
|
||||
this->unk_ADD = 0;
|
||||
this->av2.actionVar2 = 1;
|
||||
} else if (!CHECK_BTN_ALL(sPlayerControlInput->cur.button, BTN_B)) {
|
||||
} else if (!GameInteractor_Should(VB_CHECK_HELD_ITEM_BUTTON_PRESS,
|
||||
CHECK_BTN_ALL(sPlayerControlInput->cur.button, BTN_B), sDpadItemButtons,
|
||||
sPlayerItemButtons)) {
|
||||
func_80840E5C(this, play);
|
||||
}
|
||||
} else if (!func_80840CD4(this, play)) {
|
||||
|
||||
Reference in New Issue
Block a user