From d05295aad2ca6601228764f53bb85d33de7bdcec Mon Sep 17 00:00:00 2001 From: TheLegendOfLame <55961603+TheLegendOfLame@users.noreply.github.com> Date: Mon, 25 Jul 2022 05:36:06 -0500 Subject: [PATCH] Adds new features to the Equipment menu Link (#806) * All features are for the equipment menu: Added ability to use the right stick for rotate Link enhancement. Added ability to have analog control on rotating Link. Added ability to zoom into Link with right stick. Added ability to have Link do random animations Idle only. * Added RotationSpeed as a multiplier rather than a hardcoded 2.5 -Allows for more custom control -Also gives purpose for the slider to still be present w/ RStick * Specifically for the RStick, divided RotationSpeed by 150 -Even at RotationSpeed 1 it was way too fast * Added logic to play animations based on what Link has equipped & his age - If has sword and shield, all animations - Unless he's a kid with the Hylian shield equipped - If has sword no shield, all anims but shield anim - If has shield no sword, all anims but sword anim - Unless he's a kid with the Hylian shield equipped - If he has no sword or shield equipped no sword or shield anims * Casted RotationSpeed to float for RStick and divded by 600.0f - Did this instead of dividing by 150, as at RotationSpeed of 20 the rotation was so fast it was almost nauseating. I noticed at RotationSpeed of 5, it was still very quick. Logically, another division of 4 was necessary. * Changed the spacing --- libultraship/libultraship/ImGuiImpl.cpp | 4 + soh/src/code/z_player_lib.c | 86 ++++++++++++++++++- .../ovl_kaleido_scope/z_kaleido_equipment.c | 16 +++- 3 files changed, 102 insertions(+), 4 deletions(-) diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index 7285c368b..129561366 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -1136,6 +1136,8 @@ namespace SohImGui { Tooltip("Allow you to rotate Link on the Equipment menu with the DPAD\nUse DPAD-Up or DPAD-Down to reset Link's rotation"); EnhancementRadioButton("Rotate Link with C-buttons", "gPauseLiveLinkRotation", 2); Tooltip("Allow you to rotate Link on the Equipment menu with the C-buttons\nUse C-Up or C-Down to reset Link's rotation"); + EnhancementRadioButton("Rotate Link with Right Stick", "gPauseLiveLinkRotation", 3); + Tooltip("Allow you to rotate Link on the Equipment menu with the Right Stick\nYou can zoom in by pointing up and reset Link's rotation by pointing down"); if (CVar_GetS32("gPauseLiveLinkRotation", 0) != 0) { EnhancementSliderInt("Rotation Speed: %d", "##MinRotationSpeed", "gPauseLiveLinkRotationSpeed", 1, 20, ""); @@ -1163,6 +1165,8 @@ namespace SohImGui { Tooltip("Randomize the animation played each time you open the menu"); EnhancementRadioButton("Random cycle", "gPauseLiveLink", 16); Tooltip("Randomize the animation played on the menu after a certain time"); + EnhancementRadioButton("Random cycle (Idle)", "gPauseLiveLink", 17); + Tooltip("Randomize the animation played on the menu after a certain time (Idle animations only)"); if (CVar_GetS32("gPauseLiveLink", 0) >= 16) { EnhancementSliderInt("Frame to wait: %d", "##MinFrameCount", "gMinFrameCount", 1, 1000, "", 0, true); } diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index 239a1e1a9..470cec354 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -763,7 +763,7 @@ void func_8008F470(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, color->r = CVar_GetS32("gTunic_Zora_R", sTunicColors[PLAYER_TUNIC_ZORA].r); color->g = CVar_GetS32("gTunic_Zora_G", sTunicColors[PLAYER_TUNIC_ZORA].g); color->b = CVar_GetS32("gTunic_Zora_B", sTunicColors[PLAYER_TUNIC_ZORA].b); - } else if (!CVar_GetS32("gUseTunicsCol",0)){ + } else if (!CVar_GetS32("gUseTunicsCol",0)) { if (tunic >= 3) { color->r = sOriginalTunicColors[0].r; color->g = sOriginalTunicColors[0].g; @@ -1712,7 +1712,6 @@ void func_8009214C(GlobalContext* globalCtx, u8* segment, SkelAnime* skelAnime, // Link is idle so revert to 0 EquipedStance = 0; } - if (SelectedMode == 16) { // Apply Random function s16 SwitchAtFrame = 0; @@ -1749,6 +1748,89 @@ void func_8009214C(GlobalContext* globalCtx, u8* segment, SkelAnime* skelAnime, anim = PauseMenuAnimSet[SelectedAnim][EquipedStance]; } FrameCountSinceLastAnim++; + } else if (SelectedMode == 17) { + // Apply Random function + s16 SwitchAtFrame = 0; + s16 CurAnimDuration = 0; + s16 LastAnim; + if (FrameCountSinceLastAnim == 0) { + // When opening Kaleido this will be passed one time + SelectedAnim = (rand() % (6 - 1 + 1)) + 1; + if (SelectedAnim == 0) { + // prevent loading 0 that would result to a crash. + SelectedAnim = 1; + } + } else if (FrameCountSinceLastAnim >= 1) { + SwitchAtFrame = Animation_GetLastFrame(PauseMenuAnimSet[SelectedAnim][EquipedStance]); + CurAnimDuration = Animation_GetLastFrame(PauseMenuAnimSet[SelectedAnim][EquipedStance]); + if (SwitchAtFrame < MinFrameCount) { + // Animation frame count is lower than minimal wait time then we wait for another round. + // This will be looped to always add current animation time if that still lower than minimum time + while (SwitchAtFrame < MinFrameCount) { + SwitchAtFrame = SwitchAtFrame + CurAnimDuration; + } + } else if (CurAnimDuration >= MinFrameCount) { + // Since we have more (or same) animation time than min duration we set the wait time to animation + // time. + SwitchAtFrame = CurAnimDuration; + } + if (FrameCountSinceLastAnim >= SwitchAtFrame) { + LastAnim = SelectedAnim; + if (LastAnim==1) { + if ((CUR_EQUIP_VALUE(EQUIP_SWORD)!=PLAYER_SWORD_NONE) && (CUR_EQUIP_VALUE(EQUIP_SHIELD)!= PLAYER_SHIELD_NONE)) { // if the player has a sword and shield equipped + if ((LINK_AGE_IN_YEARS == YEARS_ADULT) || (CUR_EQUIP_VALUE(EQUIP_SHIELD) == PLAYER_SHIELD_DEKU)) { // if he's an adult or a kid with the deku shield + SelectedAnim = (rand() % (6 - 2 + 1)) + 2; // select any 5 animations that aren't the default standing anim + } else { //else if he's a child with a shield that isn't the deku shield + s16 randval = (rand() % (5 - 2 + 1)) + 2; // 4 animations + if (randval==4) { //if its the shield anim + SelectedAnim==6; // set to yawn anim + } else { + SelectedAnim=randval; + } + } + } else if ((CUR_EQUIP_VALUE(EQUIP_SWORD) != PLAYER_SWORD_NONE) && (CUR_EQUIP_VALUE(EQUIP_SHIELD)==PLAYER_SHIELD_NONE)) { // if the player has a sword equipped but no shield + s16 randval = (rand() % (5 - 2 + 1)) + 2; // 4 animations + if (randval==4) { //if its the shield anim + SelectedAnim==6; // set to yawn anim + } else { + SelectedAnim=randval; + } + } else if ((CUR_EQUIP_VALUE(EQUIP_SWORD) == PLAYER_SWORD_NONE) && (CUR_EQUIP_VALUE(EQUIP_SHIELD)!=PLAYER_SHIELD_NONE)) { //if the player has a shield equipped but no sword + if ((LINK_AGE_IN_YEARS == YEARS_ADULT) || (CUR_EQUIP_VALUE(EQUIP_SHIELD) == PLAYER_SHIELD_DEKU)) {// if he's an adult or a kid with the deku shield + s16 randval = (rand() % (5 - 2 + 1)) + 2; // 4 animations + if (randval==5) { //if its the sword anim + SelectedAnim==6; // set to yawn anim + } else { + SelectedAnim=randval; + } + } else { + s16 randval = (rand() % (4 - 2 + 1)) + 2; // 3 animations + if (randval==4) { //if its the shield anim + SelectedAnim==6; // set to yawn anim + } else { + SelectedAnim=randval; + } + } + } else if ((CUR_EQUIP_VALUE(EQUIP_SWORD) == PLAYER_SWORD_NONE) && (CUR_EQUIP_VALUE(EQUIP_SHIELD)==PLAYER_SHIELD_NONE)) { // if the player has no sword or shield equipped + s16 randval = (rand() % (4 - 2 + 1)) + 2; // 3 animations + if (randval==4) { //if its the shield anim + SelectedAnim==6; // set to yawn anim + } else { + SelectedAnim=randval; + } + } + } else { + SelectedAnim = 1; + } + if (SelectedAnim == 0) { + // prevent loading 0 that would result to a crash. Also makes sure default idle is every other anim + SelectedAnim = 1; + } + FrameCountSinceLastAnim = 1; + } + anim = PauseMenuAnimSet[SelectedAnim][EquipedStance]; + } + FrameCountSinceLastAnim++; } else if (SelectedMode == 15) { // When opening Kaleido this will be passed one time if (FrameCountSinceLastAnim < 1) { diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c index 863c8ef4a..edcc21c07 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c @@ -98,9 +98,11 @@ void KaleidoScope_DrawPlayerWork(GlobalContext* globalCtx) { f32 scale; Input* input = &globalCtx->state.input[0]; s16 RotationSpeed = 150 * CVar_GetS32("gPauseLiveLinkRotationSpeed", 0); + u8 AllowStickRotation = (CVar_GetS32("gPauseLiveLinkRotation", 0) == 3) ? true : false; u8 AllowCRotation = (CVar_GetS32("gPauseLiveLinkRotation", 0) == 2) ? true : false; u8 AllowDPadRotation = (CVar_GetS32("gPauseLiveLinkRotation", 0) == 1) ? true : false; + if (LINK_AGE_IN_YEARS == YEARS_CHILD) { pos.x = 2.0f; pos.y = -130.0f; @@ -120,22 +122,32 @@ void KaleidoScope_DrawPlayerWork(GlobalContext* globalCtx) { link_kaleido_rot.x = link_kaleido_rot.z = 0; - if ((AllowDPadRotation && CHECK_BTN_ALL(input->cur.button, BTN_DLEFT)) || + if ((AllowDPadRotation && CHECK_BTN_ALL(input->cur.button, BTN_DLEFT)) || // rotate (AllowCRotation && CHECK_BTN_ALL(input->cur.button, BTN_CLEFT))) { link_kaleido_rot.y = link_kaleido_rot.y - RotationSpeed; } else if ((AllowDPadRotation && CHECK_BTN_ALL(input->cur.button, BTN_DRIGHT)) || (AllowCRotation && CHECK_BTN_ALL(input->cur.button, BTN_CRIGHT))) { link_kaleido_rot.y = link_kaleido_rot.y + RotationSpeed; + } else if(AllowStickRotation && input->cur.cam_x != 0){ + link_kaleido_rot.y = link_kaleido_rot.y + (input->cur.cam_x*(((f32)RotationSpeed)/600.0f)); } - if ((AllowDPadRotation && CHECK_BTN_ALL(input->press.button, BTN_DUP)) || + if ((AllowDPadRotation && CHECK_BTN_ALL(input->press.button, BTN_DUP)) || // reset rotation (AllowDPadRotation && CHECK_BTN_ALL(input->press.button, BTN_DDOWN))) { link_kaleido_rot.y = 32300; } else if ((AllowCRotation && CHECK_BTN_ALL(input->press.button, BTN_CUP)) || (AllowCRotation && CHECK_BTN_ALL(input->press.button, BTN_CDOWN))) { link_kaleido_rot.y = 32300; + } else if (AllowStickRotation && input->cur.cam_y < -1200) { + link_kaleido_rot.y = 32300; } + if (AllowStickRotation && input->cur.cam_y>0) { // Zoom in + scale = scale + input->cur.cam_y*.00005; + pos.y = pos.y - input->cur.cam_y*.25; + } + + link_kaleido_rot.x = 0; extern int fbTest;