diff options
| author | Anghelo Carvajal <angheloalf95@gmail.com> | 2023-04-18 23:01:05 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-18 23:01:05 -0400 |
| commit | 543c38ae06d68ce2aa603144dbbe76262d00ddb6 (patch) | |
| tree | 4abbf85ab801a2ce740535c49132e390ac357f96 /src/code | |
| parent | f9c638117c0b5f9559ee8952fe459cac178bc73c (diff) | |
`z_player_lib`: Dawn of the final PR (#1142)
* Player_GetMask and Player_RemoveMask
* some comments
* Player_ActionToBottle and Player_GetBottleHeld
* Player_DrawGetItemImpl and Player_DrawGetItem
* func_80123420 OK
* Decompile a few more functions
* Decompile a few more functions
* func_80122760
* func_80122868, func_801229A0 and func_801229EC
* func_80122F28
* func_8012301C
* func_801242B4
* func_801242DC
* func_80124420 nonmatching
* func_80126440
* func_801240C8 and func_801240DC
* func_8012405C and func_80124088
* func_80124020
* Player_IsBurningStickInRange
* func_8012754C
* func_80125318 and func_80125CE0
* func_801229FC
* func_80127B64
* func_80127488
* func_80122D44
* func_80122BA4
* func_80122C20 attempt
* func_80122EEC
* func_80122F9C
* func_80122FCC and func_8012300C
* func_80123448
* func_801234D4
* func_801235DC
* func_80123960
* func_80123BD4
* func_80123AA4
* func_801239AC
* func_801241B4
* func_80123C58 and func_80123C90
* func_80123D50 and func_80123DA4
* func_80123DC0, func_80123E90 and func_80123F14
* func_80124110 and func_80124148
* func_80124168 and func_80124190
* func_80124278
* func_80124F18 non_equivalent
* func_80125340 and func_8012536C
* func_801263FC
* func_801265C8
* func_8012669C
* func_80128B74
* func_80123140
* func_801246F4
* func_801253A4 NON_MATCHING
* func_801262C8
* func_80126AB4
* func_80126B8C
* func_80127438
* func_801278F8 NON_MATCHING
* Fix data split
* cleanup externs
* func_80128BD0 compiles...
* Rename Player_SetEquipmentData
* fix merge issues
* Fix types
* Improvement? Worse? I don't know at this point
* func_80128640 attempt
* func_80127BE8
* func_80127A60
* func_80127594 attempt
* func_801271B0
* func_8012364C NON_MATCHING
* func_80124618
* func_80124CC4 non matching
* func_801251C4
* func_80125580 non equivalent
* func_80128388
* cleanup
* remove some hardcoded pointers
* object symbol cleanup
* func_80124870 NON_EQUIVALENT
* name overridlimbdraw arguments
* func_80125D4C NON_EQUIVALENT
* func_80126BD0 NON_MATCHING
* Match func_80126BD0 thanks to anon58
* func_80127DA4 NON_EQUIVALENT
* fix merge issues
* some stealing from OoT
* small rename pass and cleanup
* Improve some
* CLAMP and fix warnings
* func_80125580 matched by mzx
* cleanup func_80128BD0 a bit
* import data
* func_80124CC4
* Rename objectFileTable to gObjectTable
* Improve func_80124FF0 thanks to maide
* fix renames
* Match func_80124FF0 thanks to Maide
* cleanup
* More cleaning up
* import bss
* Add PLAYER_STATE macros
* a bit more of cleanup
* run formatter
* func_80128BD0 a bit more deecent
* Add player limb enum
* Use limb enum
* cleanup and format
* Use symbols for player dlists groups
* A bunch more of pointers
* more object pointers
* Change the remaining object pointers
* Add a few missing dlist in link_child
* Small rename
* whoops
* Work on NON_MATCHINGs
* Cleanup
* Steal OoT renames from "sword" to "meleeWeapon"
* Fix some symbols
* Match func_80127594 and format
* Match func_80127DA4
* Matched func_801284A0
* Annotate D_801F59AC
* Matched func_80128640
* Some cleanup
* format
* stuffs
* some cleanups
* import stuff from pr
* swords and shields
* fixes
* bss
* cleanup Player_OverrideLimbDrawGameplayCommon
* progress on func_80125D4C
* PlayerMeleeWeapon enum
* Player_BButtonSwordFromAP
* GET_B_SWORD_FROM_AP
* GET_MELEE_WEAPON_FROM_AP
* PlayerBottle
* PlayerExplosive and PlayerSword
* misc fixes
* Various changes fromplayer_actor
* z64player.h stuff from player_actor
* Fixes
* skelanime stuff
* placeholders on z64item.h, save macros and ther cleanups
* <= PLAYER_AP_MINUS1
* Player_UpdateBunnyEarsKinematics
Co-authored-by: EllipticEllipsis <elliptic.ellipsis@gmail.com>
* cleanup
* bodyPartsPos
* comment
* sizeof(u16)
* typo
* merge fixes
* fix
* fixes
* format
* fix merge
* fix merge
* func_80125D4C
Co-authored-by: engineer124 <engineer124engineer124@gmail.com>
* func_80128BD0 improvement
* minor renames
* format
* whoops
* small cleanup
* Update src/code/z_player_lib.c
Co-authored-by: EllipticEllipsis <elliptic.ellipsis@gmail.com>
* review
Co-authored-by: EllipticEllipsis <elliptic.ellipsis@gmail.com>
* format
* _B_
* review
Co-authored-by: EllipticEllipsis <elliptic.ellipsis@gmail.com>
* review
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
* format
* remove gap
* whoops
* clanups
* remove stuff from permuter_settings
* steal some OoT docs
* some other docs vscode didn't add to the last commit
* format
* data as infunction-static data
* OoT docs stealing
* Improvements on Player_PostLimbDrawGameplay
* More improvement
* Match Player_PostLimbDrawGameplay
Co-authored-by: engineer124 <engineer124engineer124@gmail.com>
* cleanups
* Convert unk_AF0 into an union and some other cleanups
* bss
* headLimbRot and upperLimbRot
* fix naming
* cleanups
* bss
* bss
* Update src/code/z_player_lib.c
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
* pr review
Co-authored-by: engineer124 <engineer124engineer124@gmail.com>
* bss
* gesture
* namefixer
* gestureInfo
* IA_MIN and BOTTLE_EMPTY
* review
Co-authored-by: engineer124 <engineer124engineer124@gmail.com>
* review
* D_801F59B0_LEN
* Remove LevelOfDetail enum
* bss
* review
* review
* gLinkDekuClosedFlowerDL gLinkDekuOpenFlowerDL
* _B_
* Player_DrawStrayFairyParticles
* fix build
---------
Co-authored-by: kyleburnette <kyle@kyleburnette.com>
Co-authored-by: Kelebek1 <eeeedddccc@hotmail.co.uk>
Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
Co-authored-by: EllipticEllipsis <elliptic.ellipsis@gmail.com>
Co-authored-by: engineer124 <engineer124engineer124@gmail.com>
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/code_8012EC80.c | 2 | ||||
| -rw-r--r-- | src/code/z_actor.c | 2 | ||||
| -rw-r--r-- | src/code/z_eff_tire_mark.c | 2 | ||||
| -rw-r--r-- | src/code/z_play.c | 2 | ||||
| -rw-r--r-- | src/code/z_player_lib.c | 2035 | ||||
| -rw-r--r-- | src/code/z_skelanime.c | 2 |
6 files changed, 1771 insertions, 274 deletions
diff --git a/src/code/code_8012EC80.c b/src/code/code_8012EC80.c index ca8a3eb1a..e10290356 100644 --- a/src/code/code_8012EC80.c +++ b/src/code/code_8012EC80.c @@ -472,7 +472,7 @@ u16 gSceneIdsPerRegion[REGION_MAX][27] = { }; s32 Inventory_GetBtnBItem(PlayState* play) { - if (gSaveContext.buttonStatus[0] == BTN_DISABLED) { + if (gSaveContext.buttonStatus[EQUIP_SLOT_B] == BTN_DISABLED) { return ITEM_NONE; } else if (gSaveContext.bButtonStatus == BTN_DISABLED) { return ITEM_NONE; diff --git a/src/code/z_actor.c b/src/code/z_actor.c index 44d9053ec..8e2f65965 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -2032,7 +2032,7 @@ s32 Actor_OfferGetItem(Actor* actor, PlayState* play, GetItemId getItemId, f32 x if (!(player->stateFlags1 & (PLAYER_STATE1_80 | PLAYER_STATE1_1000 | PLAYER_STATE1_2000 | PLAYER_STATE1_4000 | PLAYER_STATE1_40000 | PLAYER_STATE1_80000 | PLAYER_STATE1_100000 | PLAYER_STATE1_200000)) && - Player_GetExplosiveHeld(player) < 0) { + (Player_GetExplosiveHeld(player) <= PLAYER_EXPLOSIVE_NONE)) { if ((actor->xzDistToPlayer <= xzRange) && (fabsf(actor->playerHeightRel) <= fabsf(yRange))) { if ((getItemId == GI_MASK_CIRCUS_LEADER || getItemId == GI_PENDANT_OF_MEMORIES || getItemId == GI_DEED_LAND || diff --git a/src/code/z_eff_tire_mark.c b/src/code/z_eff_tire_mark.c index f19eb1289..d7754c5a7 100644 --- a/src/code/z_eff_tire_mark.c +++ b/src/code/z_eff_tire_mark.c @@ -11,7 +11,7 @@ void func_800AE930(CollisionContext* colCtx, EffectTireMark* this, Vec3f* pos, f u32 spA0; Vec3s* vtxList = colCtx->colHeader->vtxList; - if ((bgId != 50) || (this->numElements >= (ARRAY_COUNT(this->elements) - 1)) || (colPoly == NULL)) { + if ((bgId != BGCHECK_SCENE) || (this->numElements >= (ARRAY_COUNT(this->elements) - 1)) || (colPoly == NULL)) { func_800AEF44(this); return; } diff --git a/src/code/z_play.c b/src/code/z_play.c index 178802486..99073fb5c 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -1266,7 +1266,7 @@ void Play_DrawMain(PlayState* this) { goto PostWorldDraw; } - if (this->unk_18844 == 0) { + if (!this->unk_18844) { if (1) { if ((this->skyboxId != SKYBOX_NONE) && !this->envCtx.skyboxDisabled) { if ((this->skyboxId == SKYBOX_NORMAL_SKY) || (this->skyboxId == SKYBOX_3)) { diff --git a/src/code/z_player_lib.c b/src/code/z_player_lib.c index a7004ad3c..4c72496d0 100644 --- a/src/code/z_player_lib.c +++ b/src/code/z_player_lib.c @@ -1,15 +1,21 @@ -#include "prevent_bss_reordering.h" +/** + * File: z_player_lib.c + * Description: Set of library functions to interact with the Player system + */ +#include "prevent_bss_reordering.h" #include "global.h" #include "objects/gameplay_keep/gameplay_keep.h" +// Assets for each player form #include "objects/object_link_boy/object_link_boy.h" #include "objects/object_link_goron/object_link_goron.h" #include "objects/object_link_zora/object_link_zora.h" #include "objects/object_link_nuts/object_link_nuts.h" #include "objects/object_link_child/object_link_child.h" +// Assets for each mask #include "objects/object_mask_truth/object_mask_truth.h" #include "objects/object_mask_kerfay/object_mask_kerfay.h" #include "objects/object_mask_yofukasi/object_mask_yofukasi.h" @@ -35,6 +41,9 @@ #include "objects/object_mask_zora/object_mask_zora.h" #include "objects/object_mask_nuts/object_mask_nuts.h" +// Assets for other actors +#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h" + void PlayerCall_Init(Actor* thisx, PlayState* play); void PlayerCall_Destroy(Actor* thisx, PlayState* play); void PlayerCall_Update(Actor* thisx, PlayState* play); @@ -49,30 +58,29 @@ typedef struct { struct_801F58B0 D_801F58B0[3][3]; -Vec3f D_801F59B0[2]; +#define D_801F59B0_LEN 2 -s32 D_801F59C8[2]; +Vec3f D_801F59B0[D_801F59B0_LEN]; -typedef struct { - /* 0x0 */ s16 unk_0; - /* 0x2 */ s16 unk_2; - /* 0x4 */ s16 unk_4; - /* 0x6 */ s16 unk_6; - /* 0x8 */ s16 unk_8; -} struct_801F59D0; // size = 0xA +s32 D_801F59C8[D_801F59B0_LEN]; -struct_801F59D0 D_801F59D0; +typedef struct BunnyEarKinematics { + /* 0x0 */ Vec3s rot; + /* 0x6 */ Vec3s angVel; +} BunnyEarKinematics; // size = 0xC -Vec3f* D_801F59DC; +BunnyEarKinematics sBunnyEarKinematics; + +Vec3f* sPlayerCurBodyPartPos; s32 D_801F59E0; -s32 D_801F59E4; +s32 sPlayerLod; -Vec3f D_801F59E8; +Vec3f sPlayerGetItemRefPos; -s32 D_801F59F4; -s32 D_801F59F8; +PlayerModelType sPlayerLeftHandType; +PlayerModelType sPlayerRightHandType; void func_80127B64(struct_801F58B0 arg0[], s32 count, Vec3f* arg2); @@ -149,15 +157,35 @@ void func_801229A0(PlayState* play, Player* player) { CLOSE_DISPS(play->state.gfxCtx); } +// Update function void func_801229EC(Actor* thisx, PlayState* play) { } s16 sMaskObjectIds[PLAYER_MASK_MAX - 1] = { - OBJECT_MASK_TRUTH, OBJECT_MASK_KERFAY, OBJECT_MASK_YOFUKASI, OBJECT_MASK_RABIT, OBJECT_MASK_KI_TAN, - OBJECT_MASK_JSON, OBJECT_MASK_ROMERNY, OBJECT_MASK_ZACHO, OBJECT_MASK_POSTHAT, OBJECT_MASK_MEOTO, - OBJECT_MASK_BIGELF, OBJECT_MASK_GIBUDO, OBJECT_MASK_GERO, OBJECT_MASK_DANCER, OBJECT_MASK_SKJ, - OBJECT_MASK_STONE, OBJECT_MASK_BREE, OBJECT_MASK_BAKURETU, OBJECT_MASK_BU_SAN, OBJECT_MASK_KYOJIN, - OBJECT_MASK_BOY, OBJECT_MASK_GORON, OBJECT_MASK_ZORA, OBJECT_MASK_NUTS, + OBJECT_MASK_TRUTH, // PLAYER_MASK_TRUTH + OBJECT_MASK_KERFAY, // PLAYER_MASK_KAFEIS_MASK + OBJECT_MASK_YOFUKASI, // PLAYER_MASK_ALL_NIGHT + OBJECT_MASK_RABIT, // PLAYER_MASK_BUNNY + OBJECT_MASK_KI_TAN, // PLAYER_MASK_KEATON + OBJECT_MASK_JSON, // PLAYER_MASK_GARO + OBJECT_MASK_ROMERNY, // PLAYER_MASK_ROMANI + OBJECT_MASK_ZACHO, // PLAYER_MASK_CIRCUS_LEADER + OBJECT_MASK_POSTHAT, // PLAYER_MASK_POSTMAN + OBJECT_MASK_MEOTO, // PLAYER_MASK_COUPLE + OBJECT_MASK_BIGELF, // PLAYER_MASK_GREAT_FAIRY + OBJECT_MASK_GIBUDO, // PLAYER_MASK_GIBDO + OBJECT_MASK_GERO, // PLAYER_MASK_DON_GERO + OBJECT_MASK_DANCER, // PLAYER_MASK_KAMARO + OBJECT_MASK_SKJ, // PLAYER_MASK_CAPTAIN + OBJECT_MASK_STONE, // PLAYER_MASK_STONE + OBJECT_MASK_BREE, // PLAYER_MASK_BREMEN + OBJECT_MASK_BAKURETU, // PLAYER_MASK_BLAST + OBJECT_MASK_BU_SAN, // PLAYER_MASK_SCENTS + OBJECT_MASK_KYOJIN, // PLAYER_MASK_GIANT + OBJECT_MASK_BOY, // PLAYER_MASK_FIERCE_DEITY + OBJECT_MASK_GORON, // PLAYER_MASK_GORON + OBJECT_MASK_ZORA, // PLAYER_MASK_ZORA + OBJECT_MASK_NUTS, // PLAYER_MASK_DEKU }; // Load mask object? @@ -197,7 +225,7 @@ void func_801229FC(Player* player) { } else if (player->currentMask == PLAYER_MASK_CIRCUS_LEADER) { s32 i; - for (i = 0; i < ARRAY_COUNT(D_801F59C8); i++) { + for (i = 0; i < D_801F59B0_LEN; i++) { D_801F59C8[i] += Rand_S16Offset(4, 23) + (s32)(fabsf(player->linearVelocity) * 50.0f); } } @@ -356,6 +384,7 @@ void func_8012300C(PlayState* play, s32 arg1) { player->unk_B2B = arg1; } +// Update function void func_8012301C(Actor* thisx, PlayState* play2) { PlayState* play = play2; Player* this = (Player*)thisx; @@ -386,21 +415,29 @@ FlexSkeletonHeader* gPlayerSkeletons[PLAYER_FORM_MAX] = { &gLinkFierceDeitySkel, &gLinkGoronSkel, &gLinkZoraSkel, &gLinkDekuSkel, &gLinkHumanSkel, }; -s16 D_801BFE14[][18] = { +s16 D_801BFE14[PLAYER_BOOTS_MAX][18] = { + // PLAYER_BOOTS_FIERCE_DEITY { 200, 666, 200, 700, 366, 200, 600, 175, 60, 800, 1000, -100, 600, 590, 800, 125, 300, 65 }, + // PLAYER_BOOTS_HYLIAN { 200, 1000, 300, 800, 500, 400, 800, 400, 120, 800, 550, -100, 600, 540, 750, 125, 400, 200 }, + // PLAYER_BOOTS_GIANT { 100, 1000, 300, 800, 250, 200, 800, 200, 90, 800, 350, -80, 600, 540, 750, 60, 200, 200 }, + // PLAYER_BOOTS_DEKU { 200, 1000, 300, 700, 550, 270, 600, 1000, 120, 800, 600, -100, 600, 590, 750, 125, 200, 130 }, + // PLAYER_BOOTS_ZORA_LAND { 200, 1000, 300, 700, 550, 270, 700, 300, 120, 800, 600, -100, 600, 590, 750, 125, 200, 130 }, + // PLAYER_BOOTS_ZORA_UNDERWATER { 200, 1000, 300, 700, 550, 270, 700, 300, 120, 800, 600, -100, 600, 590, 750, 125, 200, 130 }, + // PLAYER_BOOTS_GORON { 200, 1000, 300, 700, 550, 270, 700, 200, 120, 800, 600, -140, 600, 590, 750, 125, 200, 130 }, + // PLAYER_BOOTS_7 { 80, 800, 150, 700, 480, 270, 600, 50, 120, 800, 300, -40, 400, 540, 270, 25, 0, 80 }, }; // OoT's Player_SetBootData void func_80123140(PlayState* play, Player* player) { s16* bootRegs; - s32 currentBoots; + PlayerBoots currentBoots; f32 scale; if ((player->actor.id == ACTOR_PLAYER) && (player->transformation == PLAYER_FORM_FIERCE_DEITY)) { @@ -637,7 +674,7 @@ u8 sActionModelGroups[PLAYER_IA_MAX] = { PLAYER_MODELGROUP_DEFAULT, // PLAYER_IA_NUT PLAYER_MODELGROUP_DEFAULT, // PLAYER_IA_PICTO_BOX PLAYER_MODELGROUP_INSTRUMENT, // PLAYER_IA_OCARINA - PLAYER_MODELGROUP_BOTTLE, // PLAYER_IA_BOTTLE + PLAYER_MODELGROUP_BOTTLE, // PLAYER_IA_BOTTLE_EMPTY PLAYER_MODELGROUP_BOTTLE, // PLAYER_IA_BOTTLE_FISH PLAYER_MODELGROUP_BOTTLE, // PLAYER_IA_BOTTLE_SPRING_WATER PLAYER_MODELGROUP_BOTTLE, // PLAYER_IA_BOTTLE_HOT_SPRING_WATER @@ -751,10 +788,10 @@ PlayerModelIndices gPlayerModelTypes[PLAYER_MODELGROUP_MAX] = { { PLAYER_ANIMTYPE_1, PLAYER_MODELTYPE_LH_ONE_HAND_SWORD, PLAYER_MODELTYPE_RH_SHIELD, PLAYER_MODELTYPE_SHEATH_13, PLAYER_MODELTYPE_WAIST }, /* PLAYER_MODELGROUP_DEFAULT */ - { PLAYER_ANIMTYPE_0, PLAYER_MODELTYPE_LH_OPEN, PLAYER_MODELTYPE_RH_OPEN, PLAYER_MODELTYPE_SHEATH_14, + { PLAYER_ANIMTYPE_DEFAULT, PLAYER_MODELTYPE_LH_OPEN, PLAYER_MODELTYPE_RH_OPEN, PLAYER_MODELTYPE_SHEATH_14, PLAYER_MODELTYPE_WAIST }, /* PLAYER_MODELGROUP_4 */ - { PLAYER_ANIMTYPE_0, PLAYER_MODELTYPE_LH_OPEN, PLAYER_MODELTYPE_RH_OPEN, PLAYER_MODELTYPE_SHEATH_14, + { PLAYER_ANIMTYPE_DEFAULT, PLAYER_MODELTYPE_LH_OPEN, PLAYER_MODELTYPE_RH_OPEN, PLAYER_MODELTYPE_SHEATH_14, PLAYER_MODELTYPE_WAIST }, /* PLAYER_MODELGROUP_TWO_HAND_SWORD */ { PLAYER_ANIMTYPE_3, PLAYER_MODELTYPE_LH_TWO_HAND_SWORD, PLAYER_MODELTYPE_RH_CLOSED, PLAYER_MODELTYPE_SHEATH_14, @@ -766,7 +803,7 @@ PlayerModelIndices gPlayerModelTypes[PLAYER_MODELGROUP_MAX] = { { PLAYER_ANIMTYPE_5, PLAYER_MODELTYPE_LH_OPEN, PLAYER_MODELTYPE_RH_OPEN, PLAYER_MODELTYPE_SHEATH_14, PLAYER_MODELTYPE_WAIST }, /* PLAYER_MODELGROUP_8 */ - { PLAYER_ANIMTYPE_0, PLAYER_MODELTYPE_LH_4, PLAYER_MODELTYPE_RH_OPEN, PLAYER_MODELTYPE_SHEATH_14, + { PLAYER_ANIMTYPE_DEFAULT, PLAYER_MODELTYPE_LH_4, PLAYER_MODELTYPE_RH_OPEN, PLAYER_MODELTYPE_SHEATH_14, PLAYER_MODELTYPE_WAIST }, /* PLAYER_MODELGROUP_HOOKSHOT */ { PLAYER_ANIMTYPE_4, PLAYER_MODELTYPE_LH_OPEN, PLAYER_MODELTYPE_RH_HOOKSHOT, PLAYER_MODELTYPE_SHEATH_14, @@ -775,16 +812,16 @@ PlayerModelIndices gPlayerModelTypes[PLAYER_MODELGROUP_MAX] = { { PLAYER_ANIMTYPE_3, PLAYER_MODELTYPE_LH_CLOSED, PLAYER_MODELTYPE_RH_CLOSED, PLAYER_MODELTYPE_SHEATH_14, PLAYER_MODELTYPE_WAIST }, /* PLAYER_MODELGROUP_INSTRUMENT */ - { PLAYER_ANIMTYPE_0, PLAYER_MODELTYPE_LH_OPEN, PLAYER_MODELTYPE_RH_INSTRUMENT, PLAYER_MODELTYPE_SHEATH_14, + { PLAYER_ANIMTYPE_DEFAULT, PLAYER_MODELTYPE_LH_OPEN, PLAYER_MODELTYPE_RH_INSTRUMENT, PLAYER_MODELTYPE_SHEATH_14, PLAYER_MODELTYPE_WAIST }, /* PLAYER_MODELGROUP_BOTTLE */ - { PLAYER_ANIMTYPE_0, PLAYER_MODELTYPE_LH_BOTTLE, PLAYER_MODELTYPE_RH_OPEN, PLAYER_MODELTYPE_SHEATH_14, + { PLAYER_ANIMTYPE_DEFAULT, PLAYER_MODELTYPE_LH_BOTTLE, PLAYER_MODELTYPE_RH_OPEN, PLAYER_MODELTYPE_SHEATH_14, PLAYER_MODELTYPE_WAIST }, /* PLAYER_MODELGROUP_13 */ - { PLAYER_ANIMTYPE_0, PLAYER_MODELTYPE_LH_ONE_HAND_SWORD, PLAYER_MODELTYPE_RH_OPEN, PLAYER_MODELTYPE_SHEATH_15, + { PLAYER_ANIMTYPE_DEFAULT, PLAYER_MODELTYPE_LH_ONE_HAND_SWORD, PLAYER_MODELTYPE_RH_OPEN, PLAYER_MODELTYPE_SHEATH_15, PLAYER_MODELTYPE_WAIST }, /* PLAYER_MODELGROUP_ZORA_FINS */ - { PLAYER_ANIMTYPE_0, PLAYER_MODELTYPE_LH_CLOSED, PLAYER_MODELTYPE_RH_CLOSED, PLAYER_MODELTYPE_SHEATH_14, + { PLAYER_ANIMTYPE_DEFAULT, PLAYER_MODELTYPE_LH_CLOSED, PLAYER_MODELTYPE_RH_CLOSED, PLAYER_MODELTYPE_SHEATH_14, PLAYER_MODELTYPE_WAIST }, }; @@ -796,9 +833,11 @@ Gfx* gPlayerWaistDLs[2 * PLAYER_FORM_MAX] = { gLinkZoraWaistDL, gLinkDekuWaistDL, gLinkDekuWaistDL, gLinkHumanWaistDL, gLinkHumanWaistDL, }; -Gfx* gPlayerHandHoldingShields[PLAYER_SHIELD_MAX - 1][2] = { - { gLinkHumanRightHandHoldingHylianShieldDL, gLinkHumanRightHandHoldingHylianShieldDL }, - { gLinkHumanRightHandHoldingMirrorShieldDL, gLinkHumanRightHandHoldingMirrorShieldDL }, +Gfx* gPlayerHandHoldingShields[2 * (PLAYER_SHIELD_MAX - 1)] = { + gLinkHumanRightHandHoldingHerosShieldDL, + gLinkHumanRightHandHoldingHerosShieldDL, + gLinkHumanRightHandHoldingMirrorShieldDL, + gLinkHumanRightHandHoldingMirrorShieldDL, }; Gfx* gPlayerSheath12DLs[2 * PLAYER_FORM_MAX] = { @@ -840,21 +879,21 @@ Gfx* gPlayerSheath14DLs[2 * PLAYER_FORM_MAX] = { gLinkHumanSheathEmptyDL, }; -Gfx* gPlayerShields[][2] = { - { gLinkHumanHylianShieldWithMtxDL, gLinkHumanHylianShieldWithMtxDL }, - { gLinkHumanMirrorShieldWithMtxDL, gLinkHumanMirrorShieldWithMtxDL }, +Gfx* gPlayerShields[] = { + gLinkHumanHerosShieldWithMtxDL, + gLinkHumanHerosShieldWithMtxDL, + gLinkHumanMirrorShieldWithMtxDL, + gLinkHumanMirrorShieldWithMtxDL, }; -Gfx* gPlayerSheathedSwords[][2] = { - { gLinkHumanSheathedKokiriSwordDL, gLinkHumanSheathedKokiriSwordDL }, - { gLinkHumanSheathedRazorSwordDL, gLinkHumanSheathedRazorSwordDL }, - { gLinkHumanSheathedGildedSwordDL, gLinkHumanSheathedGildedSwordDL }, +Gfx* gPlayerSheathedSwords[] = { + gLinkHumanSheathedKokiriSwordDL, gLinkHumanSheathedKokiriSwordDL, gLinkHumanSheathedRazorSwordDL, + gLinkHumanSheathedRazorSwordDL, gLinkHumanSheathedGildedSwordDL, gLinkHumanSheathedGildedSwordDL, }; -Gfx* gPlayerSwordSheaths[][2] = { - { gLinkHumanKokiriSwordSheathDL, gLinkHumanKokiriSwordSheathDL }, - { gLinkHumanRazorSwordSheathDL, gLinkHumanRazorSwordSheathDL }, - { gLinkHumanGildedSwordSheathDL, gLinkHumanGildedSwordSheathDL }, +Gfx* gPlayerSwordSheaths[] = { + gLinkHumanKokiriSwordSheathDL, gLinkHumanKokiriSwordSheathDL, gLinkHumanRazorSwordSheathDL, + gLinkHumanRazorSwordSheathDL, gLinkHumanGildedSwordSheathDL, gLinkHumanGildedSwordSheathDL, }; Gfx* gPlayerLeftHandTwoHandSwordDLs[2 * PLAYER_FORM_MAX] = { @@ -895,10 +934,16 @@ Gfx* gPlayerLeftHandOneHandSwordDLs[2 * PLAYER_FORM_MAX] = { gLinkHumanLeftHandHoldingKokiriSwordDL, }; -Gfx* D_801C018C[][2] = { - { gLinkHumanLeftHandHoldingKokiriSwordDL, gLinkHumanLeftHandHoldingKokiriSwordDL }, - { gLinkHumanLeftHandHoldingRazorSwordDL, gLinkHumanLeftHandHoldingRazorSwordDL }, - { gLinkHumanLeftHandHoldingGildedSwordDL, gLinkHumanLeftHandHoldingGildedSwordDL }, +Gfx* D_801C018C[] = { + // EQUIP_VALUE_SWORD_KOKIRI + gLinkHumanLeftHandHoldingKokiriSwordDL, + gLinkHumanLeftHandHoldingKokiriSwordDL, + // EQUIP_VALUE_SWORD_RAZOR + gLinkHumanLeftHandHoldingRazorSwordDL, + gLinkHumanLeftHandHoldingRazorSwordDL, + // EQUIP_VALUE_SWORD_GILDED + gLinkHumanLeftHandHoldingGildedSwordDL, + gLinkHumanLeftHandHoldingGildedSwordDL, }; Gfx* gPlayerRightHandOpenDLs[2 * PLAYER_FORM_MAX] = { @@ -967,22 +1012,22 @@ Gfx* gPlayerLeftHandBottleDLs[2 * PLAYER_FORM_MAX] = { /* DLists groups end */ -Gfx* D_801C0294[PLAYER_FORM_MAX] = { +Gfx* sPlayerFirstPersonLeftForearmDLs[PLAYER_FORM_MAX] = { gLinkFierceDeityLeftForearmDL, gLinkGoronLeftForearmDL, gLinkZoraLeftForearmDL, gLinkDekuLeftForearmDL, gLinkHumanLeftForearmDL, }; -Gfx* D_801C02A8[PLAYER_FORM_MAX] = { +Gfx* sPlayerFirstPersonLeftHandDLs[PLAYER_FORM_MAX] = { gLinkFierceDeityLeftHandDL, gLinkGoronLeftHandOpenDL, gLinkZoraLeftHandClosedDL, gLinkDekuLeftHandDL, gLinkHumanLeftHandClosedDL, }; -Gfx* D_801C02BC[PLAYER_FORM_MAX] = { +Gfx* sPlayerFirstPersonRightShoulderDLs[PLAYER_FORM_MAX] = { gLinkFierceDeityRightShoulderDL, gLinkGoronRightShoulderDL, gLinkZoraRightShoulderDL, gLinkDekuRightShoulderDL, gLinkHumanRightShoulderDL, }; -Gfx* D_801C02D0[PLAYER_FORM_MAX] = { +Gfx* sPlayerFirstPersonRightHandDLs[PLAYER_FORM_MAX] = { gLinkFierceDeityRightHandDL, //! @bug This is in the middle of a texture in the link_goron object. It has the same offset as a link_nuts dlist 0x060038C0, @@ -991,7 +1036,7 @@ Gfx* D_801C02D0[PLAYER_FORM_MAX] = { object_link_child_DL_018490, }; -Gfx* D_801C02E4[PLAYER_FORM_MAX] = { +Gfx* sPlayerFirstPersonRightHandHookshotDLs[PLAYER_FORM_MAX] = { gLinkFierceDeityRightHandDL, //! @bug This is in the middle of a texture in the link_goron object. It has the same offset as a link_nuts dlist 0x060038C0, @@ -1224,7 +1269,7 @@ void Player_SetModelGroup(Player* player, PlayerModelGroup modelGroup) { player->modelGroup = modelGroup; if (modelGroup == PLAYER_MODELGROUP_1) { - player->modelAnimType = PLAYER_ANIMTYPE_0; + player->modelAnimType = PLAYER_ANIMTYPE_DEFAULT; } else { player->modelAnimType = gPlayerModelTypes[modelGroup].modelAnimType; } @@ -1232,7 +1277,7 @@ void Player_SetModelGroup(Player* player, PlayerModelGroup modelGroup) { if (player->modelAnimType < PLAYER_ANIMTYPE_3) { if (((player->transformation != PLAYER_FORM_FIERCE_DEITY) && (player->transformation != PLAYER_FORM_HUMAN)) || (player->currentShield == PLAYER_SHIELD_NONE)) { - player->modelAnimType = PLAYER_ANIMTYPE_0; + player->modelAnimType = PLAYER_ANIMTYPE_DEFAULT; } } @@ -1367,34 +1412,35 @@ s32 func_801240DC(Player* player) { return Player_IsHoldingHookshot(player) && (player->heldActor == NULL); } -s32 func_80124110(Player* player, PlayerItemAction itemAction) { - s32 temp_v0 = itemAction - PLAYER_IA_FISHING_ROD; +PlayerBButtonSword Player_BButtonSwordFromIA(Player* player, PlayerItemAction itemAction) { + PlayerBButtonSword bButtonSword = GET_B_SWORD_FROM_IA(itemAction); if (player->transformation != PLAYER_FORM_GORON) { - if (((itemAction - PLAYER_IA_FISHING_ROD) > (PLAYER_IA_FISHING_ROD - PLAYER_IA_FISHING_ROD)) && - ((itemAction - PLAYER_IA_FISHING_ROD) < (PLAYER_IA_SWORD_GREAT_FAIRY - PLAYER_IA_FISHING_ROD))) { - return temp_v0; + if ((GET_B_SWORD_FROM_IA(itemAction) > PLAYER_B_SWORD_NONE) && + (GET_B_SWORD_FROM_IA(itemAction) < PLAYER_B_SWORD_MAX)) { + return bButtonSword; } } - return 0; + return PLAYER_B_SWORD_NONE; } -s32 func_80124148(Player* player) { - return func_80124110(player, player->heldItemAction); +PlayerBButtonSword Player_GetHeldBButtonSword(Player* player) { + return Player_BButtonSwordFromIA(player, player->heldItemAction); } -s32 Player_ActionToMeleeWeapon(PlayerItemAction itemAction) { - s32 weapon = itemAction - (PLAYER_IA_SWORD_KOKIRI - 1); +PlayerMeleeWeapon Player_MeleeWeaponFromIA(PlayerItemAction itemAction) { + PlayerMeleeWeapon weapon = GET_MELEE_WEAPON_FROM_IA(itemAction); - if ((weapon > 0) && (weapon <= (PLAYER_IA_ZORA_FINS - (PLAYER_IA_SWORD_KOKIRI - 1)))) { + if ((weapon > PLAYER_MELEEWEAPON_NONE) && (weapon < PLAYER_MELEEWEAPON_MAX)) { return weapon; } - return 0; + + return PLAYER_MELEEWEAPON_NONE; } -s32 Player_GetMeleeWeaponHeld(Player* player) { - return Player_ActionToMeleeWeapon(player->heldItemAction); +PlayerMeleeWeapon Player_GetMeleeWeaponHeld(Player* player) { + return Player_MeleeWeaponFromIA(player->heldItemAction); } s32 Player_IsHoldingTwoHandedWeapon(Player* player) { @@ -1406,47 +1452,45 @@ s32 Player_IsHoldingTwoHandedWeapon(Player* player) { return false; } -s32 Player_ActionToBottle(Player* player, PlayerItemAction itemAction) { - s32 bottle = itemAction - PLAYER_IA_BOTTLE; +PlayerBottle Player_BottleFromIA(Player* player, PlayerItemAction itemAction) { + PlayerBottle bottle = GET_BOTTLE_FROM_IA(itemAction); - // Relies on bottle-related item actions to be contiguous - if ((bottle >= (PLAYER_IA_BOTTLE - PLAYER_IA_BOTTLE)) && (bottle <= (PLAYER_IA_BOTTLE_FAIRY - PLAYER_IA_BOTTLE))) { + if ((bottle > PLAYER_BOTTLE_NONE) && (bottle < PLAYER_BOTTLE_MAX)) { return bottle; } - return -1; + return PLAYER_BOTTLE_NONE; } -s32 Player_GetBottleHeld(Player* Player) { - return Player_ActionToBottle(Player, Player->heldItemAction); +PlayerBottle Player_GetBottleHeld(Player* Player) { + return Player_BottleFromIA(Player, Player->heldItemAction); } -s32 Player_ActionToExplosive(Player* player, PlayerItemAction itemAction) { - s32 explosive = itemAction - PLAYER_IA_BOMB; +PlayerExplosive Player_ExplosiveFromIA(Player* player, PlayerItemAction itemAction) { + PlayerExplosive explosive = GET_EXPLOSIVE_FROM_IA(itemAction); - // Relies on explosive-related item actions to be contiguous - if ((explosive >= (PLAYER_IA_BOMB - PLAYER_IA_BOMB)) && (explosive <= (PLAYER_IA_BOMBCHU - PLAYER_IA_BOMB))) { + if ((explosive > PLAYER_EXPLOSIVE_NONE) && (explosive < PLAYER_EXPLOSIVE_MAX)) { return explosive; } - return -1; + return PLAYER_EXPLOSIVE_NONE; } -s32 Player_GetExplosiveHeld(Player* player) { - return Player_ActionToExplosive(player, player->heldItemAction); +PlayerExplosive Player_GetExplosiveHeld(Player* player) { + return Player_ExplosiveFromIA(player, player->heldItemAction); } -s32 Player_ActionToSword(Actor* actor, PlayerItemAction itemAction) { - s32 sword = 0; +// Note this function maps PLAYER_IA_LAST_USED to PLAYER_SWORD_KOKIRI +PlayerSword Player_SwordFromIA(Player* player, PlayerItemAction itemAction) { + PlayerSword sword = PLAYER_SWORD_KOKIRI; //! FAKE: if ((itemAction == PLAYER_IA_LAST_USED) || - ((sword = itemAction - PLAYER_IA_SWORD_KOKIRI, (sword >= PLAYER_IA_SWORD_KOKIRI - PLAYER_IA_SWORD_KOKIRI)) && - (sword <= PLAYER_IA_SWORD_GREAT_FAIRY - PLAYER_IA_SWORD_KOKIRI))) { + ((sword = GET_SWORD_FROM_IA(itemAction), (sword > PLAYER_SWORD_NONE)) && (sword < PLAYER_SWORD_MAX))) { return sword; } - return -1; + return PLAYER_SWORD_NONE; } s32 func_801242B4(Player* player) { @@ -1485,8 +1529,45 @@ s32 Player_GetEnvironmentalHazard(PlayState* play) { return envHazard + 1; } -void func_80124420(Player* player); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80124420.s") +void Player_UpdateBunnyEars(Player* player) { + Vec3s force; + s16 angle; + + sBunnyEarKinematics.angVel.x -= sBunnyEarKinematics.angVel.x >> 3; + sBunnyEarKinematics.angVel.y -= sBunnyEarKinematics.angVel.y >> 3; + sBunnyEarKinematics.angVel.x += -sBunnyEarKinematics.rot.x >> 2; + sBunnyEarKinematics.angVel.y += -sBunnyEarKinematics.rot.y >> 2; + + angle = player->actor.world.rot.y - player->actor.shape.rot.y; + force.x = + (s32)(player->actor.speed * -200.0f * Math_CosS(angle) * (randPlusMinusPoint5Scaled(2.0f) + 10.0f)) & 0xFFFF; + force.y = + (s32)(player->actor.speed * 100.0f * Math_SinS(angle) * (randPlusMinusPoint5Scaled(2.0f) + 10.0f)) & 0xFFFF; + + sBunnyEarKinematics.angVel.x += force.x >> 2; + sBunnyEarKinematics.angVel.y += force.y >> 2; + + if (sBunnyEarKinematics.angVel.x > 0x1770) { + sBunnyEarKinematics.angVel.x = 0x1770; + } else if (sBunnyEarKinematics.angVel.x < -0x1770) { + sBunnyEarKinematics.angVel.x = -0x1770; + } + + if (sBunnyEarKinematics.angVel.y > 0x1770) { + sBunnyEarKinematics.angVel.y = 0x1770; + } else if (sBunnyEarKinematics.angVel.y < -0x1770) { + sBunnyEarKinematics.angVel.y = -0x1770; + } + + sBunnyEarKinematics.rot.x += sBunnyEarKinematics.angVel.x; + sBunnyEarKinematics.rot.y += sBunnyEarKinematics.angVel.y; + + if (sBunnyEarKinematics.rot.x < 0) { + sBunnyEarKinematics.rot.z = sBunnyEarKinematics.rot.x >> 1; + } else { + sBunnyEarKinematics.rot.z = 0; + } +} void func_80124618(struct_80124618 arg0[], f32 curFrame, Vec3f* arg2) { s32 currentFrame = curFrame; @@ -1542,16 +1623,22 @@ Gfx gCullFrontDList[] = { gsSPEndDisplayList(), }; -TexturePtr sPlayerEyesTextures[] = { - gLinkHumanEyesOpenTex, gLinkHumanEyesHalfTex, gLinkHumanEyesClosedTex, gLinkHumanEyesRollRightTex, - gLinkHumanEyesRollLeftTex, gLinkHumanEyesRollUpTex, gLinkHumanEyesRollDownTex, object_link_child_Tex_003800, +TexturePtr sPlayerEyesTextures[PLAYER_EYES_MAX] = { + gLinkHumanEyesOpenTex, // PLAYER_EYES_OPEN + gLinkHumanEyesHalfTex, // PLAYER_EYES_HALF + gLinkHumanEyesClosedTex, // PLAYER_EYES_CLOSED + gLinkHumanEyesRollRightTex, // PLAYER_EYES_ROLL_RIGHT + gLinkHumanEyesRollLeftTex, // PLAYER_EYES_ROLL_LEFT + gLinkHumanEyesRollUpTex, // PLAYER_EYES_ROLL_UP + gLinkHumanEyesRollDownTex, // PLAYER_EYES_ROLL_DOWN + object_link_child_Tex_003800, // PLAYER_EYES_7 }; -TexturePtr sPlayerMouthTextures[] = { - gLinkHumanMouthClosedTex, - gLinkHumanMouthTeethTex, - gLinkHumanMouthAngryTex, - gLinkHumanMouthHappyTex, +TexturePtr sPlayerMouthTextures[PLAYER_MOUTH_MAX] = { + gLinkHumanMouthClosedTex, // PLAYER_MOUTH_CLOSED + gLinkHumanMouthTeethTex, // PLAYER_MOUTH_TEETH + gLinkHumanMouthAngryTex, // PLAYER_MOUTH_ANGRY + gLinkHumanMouthHappyTex, // PLAYER_MOUTH_HAPPY }; typedef struct PlayerFaceIndices { @@ -1583,8 +1670,8 @@ PlayerFaceIndices sPlayerFaces[] = { void Player_DrawImpl(PlayState* play, void** skeleton, Vec3s* jointTable, s32 dListCount, s32 lod, PlayerTransformation playerForm, s32 boots, s32 face, OverrideLimbDrawFlex overrideLimbDraw, PostLimbDrawFlex postLimbDraw, Actor* actor) { - s32 eyeIndex = (jointTable[22].x & 0xF) - 1; - s32 mouthIndex = ((jointTable[22].x >> 4) & 0xF) - 1; + s32 eyeIndex = GET_EYE_INDEX_FROM_JOINT_TABLE(jointTable); + s32 mouthIndex = GET_MOUTH_INDEX_FROM_JOINT_TABLE(jointTable); Gfx* gfx; OPEN_DISPS(play->state.gfxCtx); @@ -1614,68 +1701,172 @@ void Player_DrawImpl(PlayState* play, void** skeleton, Vec3s* jointTable, s32 dL POLY_OPA_DISP = &gfx[2]; D_801F59E0 = playerForm * 2; - D_801F59E4 = lod; + sPlayerLod = lod; SkelAnime_DrawFlexLod(play, skeleton, jointTable, dListCount, overrideLimbDraw, postLimbDraw, actor, lod); CLOSE_DISPS(play->state.gfxCtx); } Vec3f D_801C08C0[PLAYER_FORM_MAX] = { - { 1304.0f, 0.0f, 0.0f }, { 1156.0f, 0.0f, 0.0f }, { 1406.0f, 0.0f, 0.0f }, - { 408.0f, 0.0f, 0.0f }, { 695.0f, 0.0f, 0.0f }, + { 1304.0f, 0.0f, 0.0f }, // PLAYER_FORM_FIERCE_DEITY + { 1156.0f, 0.0f, 0.0f }, // PLAYER_FORM_GORON + { 1406.0f, 0.0f, 0.0f }, // PLAYER_FORM_ZORA + { 408.0f, 0.0f, 0.0f }, // PLAYER_FORM_DEKU + { 695.0f, 0.0f, 0.0f }, // PLAYER_FORM_HUMAN }; f32 D_801C08FC[PLAYER_FORM_MAX] = { - 1265.0f, 1056.0f, 1506.0f, 359.0f, 826.0f, + 1265.0f, // PLAYER_FORM_FIERCE_DEITY + 1056.0f, // PLAYER_FORM_GORON + 1506.0f, // PLAYER_FORM_ZORA + 359.0f, // PLAYER_FORM_DEKU + 826.0f, // PLAYER_FORM_HUMAN }; f32 D_801C0910[PLAYER_FORM_MAX] = { - 170.0416f, 133.63359f, 197.68358f, 16.646399f, 48.302498f, + 170.0416f, // PLAYER_FORM_FIERCE_DEITY + 133.63359f, // PLAYER_FORM_GORON + 197.68358f, // PLAYER_FORM_ZORA + 16.646399f, // PLAYER_FORM_DEKU + 48.302498f, // PLAYER_FORM_HUMAN }; f32 D_801C0924[PLAYER_FORM_MAX] = { - 10.019104f, 22.120003f, -29.12001f, 3.7582989f, -19.925102f, + 10.019104f, // PLAYER_FORM_FIERCE_DEITY + 22.120003f, // PLAYER_FORM_GORON + -29.12001f, // PLAYER_FORM_ZORA + 3.7582989f, // PLAYER_FORM_DEKU + -19.925102f, // PLAYER_FORM_HUMAN }; f32 D_801C0938[PLAYER_FORM_MAX] = { - 5.0f, 4.0f, 1.0f, 1.0f, 3.0f, + 5.0f, // PLAYER_FORM_FIERCE_DEITY + 4.0f, // PLAYER_FORM_GORON + 1.0f, // PLAYER_FORM_ZORA + 1.0f, // PLAYER_FORM_DEKU + 3.0f, // PLAYER_FORM_HUMAN }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80124870.s") +/** + * Adjusts player's legs to slopes and spawns flames when running on lava + */ +void Player_AdjustSingleLeg(PlayState* play, Player* player, SkelAnime* skelAnime, Vec3f* pos, Vec3s* rot, + s32 thighLimbIndex, s32 shinLimbIndex, s32 footLimbIndex) { + CollisionPoly* poly; + s32 bgId; + f32 yIntersect; + Vec3f sp90; + Vec3f sp84; + Vec3f footprintPos; + f32 sp74; + f32 sp70; + f32 sp7C; + + if ((player->stateFlags3 & PLAYER_STATE3_1) || !(player->actor.scale.y >= 0.0f) || + (player->stateFlags1 & PLAYER_STATE1_80) || play->unk_18844) { + return; + } + + sp74 = D_801C0910[player->transformation]; + sp70 = D_801C0924[player->transformation]; + sp7C = D_801C0938[player->transformation] - player->unk_AB8; + Matrix_Push(); + Matrix_TranslateRotateZYX(pos, rot); + Matrix_MultZero(&sp90); + Matrix_TranslateRotateZYX(&D_801C08C0[player->transformation], &skelAnime->jointTable[shinLimbIndex]); + Matrix_Translate(D_801C08FC[player->transformation], 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_MultZero(&sp84); + Matrix_MultVecY(-300.0f, &footprintPos); + Matrix_Pop(); + + footprintPos.y += 15.0f; + yIntersect = BgCheck_EntityRaycastFloor3(&play->colCtx, &poly, &bgId, &footprintPos) + sp7C + + (player->unk_ABC * player->actor.scale.y); + if (sp84.y < yIntersect) { + f32 diffX = sp84.x - sp90.x; + f32 diffY = sp84.y - sp90.y; + f32 diffZ = sp84.z - sp90.z; + f32 distance; + f32 sp58; + f32 sp54; + f32 temp_f20; + f32 sp4C; + f32 sp48; + s16 temp_f8; + s32 temp_v0_4; + s16 phi_t1; + + distance = sqrtf(SQ(diffX) + SQ(diffY) + SQ(diffZ)); + + sp58 = (SQ(distance) + sp70) / (2.0f * distance); + + temp_f20 = sp74 - SQ(sp58); + temp_f20 = (temp_f20 < 0.0f) ? 0.0f : sqrtf(temp_f20); + + sp4C = func_80086B30(temp_f20, sp58); + distance = sqrtf(SQ(diffX) + SQ(yIntersect - sp90.y) + SQ(diffZ)); + sp58 = (SQ(distance) + sp70) / (2.0f * distance); + sp54 = distance - sp58; + + temp_f20 = sp74 - SQ(sp58); + temp_f20 = (temp_f20 < 0.0f) ? 0.0f : sqrtf(temp_f20); + + sp48 = func_80086B30(temp_f20, sp58); + phi_t1 = (M_PI - (func_80086B30(sp54, temp_f20) + ((M_PI / 2.0f) - sp48))) * (0x8000 / M_PI); + phi_t1 = -skelAnime->jointTable[shinLimbIndex].z + phi_t1; + temp_f8 = (sp48 - sp4C) * (0x8000 / M_PI); + + if ((s16)(ABS_ALT(skelAnime->jointTable[shinLimbIndex].x) + ABS_ALT(skelAnime->jointTable[shinLimbIndex].y)) < + 0) { + phi_t1 = BINANG_ROT180(phi_t1); + } + + rot->z -= temp_f8; + + skelAnime->jointTable[thighLimbIndex].z -= temp_f8; + skelAnime->jointTable[shinLimbIndex].z += phi_t1; + skelAnime->jointTable[footLimbIndex].z = (skelAnime->jointTable[footLimbIndex].z + temp_f8) - phi_t1; + + temp_v0_4 = SurfaceType_GetFloorType(&play->colCtx, poly, bgId); + if ((temp_v0_4 >= 2) && (temp_v0_4 < 4) && !SurfaceType_IsWallDamage(&play->colCtx, poly, bgId)) { + footprintPos.y = yIntersect; + EffectSsGFire_Spawn(play, &footprintPos); + } + } +} -void func_80124CC4(PlayState* play, Player* player, f32 arg2) { +void Player_DrawHookshotReticle(PlayState* play, Player* player, f32 hookshotDistance) { static Vec3f D_801C094C = { -500.0f, -100.0f, 0.0f }; CollisionPoly* poly; s32 bgId; Vec3f sp7C; Vec3f sp70; Vec3f pos; - Vec3f sp58; - f32 sp54; - f32 scale; D_801C094C.z = 0.0f; Matrix_MultVec3f(&D_801C094C, &sp7C); - D_801C094C.z = arg2; + D_801C094C.z = hookshotDistance; Matrix_MultVec3f(&D_801C094C, &sp70); if (BgCheck_AnyLineTest3(&play->colCtx, &sp7C, &sp70, &pos, &poly, true, true, true, true, &bgId)) { if (!func_800B90AC(play, &player->actor, poly, bgId, &pos) || BgCheck_ProjectileLineTest(&play->colCtx, &sp7C, &sp70, &pos, &poly, true, true, true, true, &bgId)) { + Vec3f sp58; + f32 sp54; + f32 scale; + OPEN_DISPS(play->state.gfxCtx); OVERLAY_DISP = Gfx_CallSetupDL(OVERLAY_DISP, 7); SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, &pos, &sp58, &sp54); - if (sp54 < 200.0f) { - scale = 0.08f; - } else { - scale = (sp54 / 200.0f) * 0.08f; - } + + scale = (sp54 < 200.0f) ? 0.08f : (sp54 / 200.0f) * 0.08f; + Matrix_Translate(pos.x, pos.y, pos.z, MTXMODE_NEW); Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); gSPMatrix(OVERLAY_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPSegment(OVERLAY_DISP++, 0x06, play->objectCtx.status[player->actor.objBankIndex].segment); - gSPDisplayList(OVERLAY_DISP++, gameplay_keep_DL_04F250); + gSPDisplayList(OVERLAY_DISP++, gHookshotReticleDL); CLOSE_DISPS(play->state.gfxCtx); } @@ -1694,8 +1885,6 @@ Gfx** D_801C0964[] = { }; void func_80124F18(s16* arg0, f32* arg1, s16 arg2, f32 arg3, f32 arg4) { - f32 phi_f12; - if (*arg0 < arg2) { *arg1 += arg3; } else { @@ -1742,7 +1931,26 @@ void func_80124FF0(f32 arg0, s16 arg1, Vec3f* arg2, s16 arg3, Vec3f* arg4, Vec3f func_80124F18(arg6, arg7, temp_v0, 20.0f, 2000.0f); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_801251C4.s") +void func_801251C4(Player* player, Vec3f* arg1) { + Vec3f sp4C; + Vec3f sp40; + + sp4C.x = player->actor.world.pos.x; + sp4C.y = player->actor.world.pos.y + 60.0f; + sp4C.z = player->actor.world.pos.z; + func_80124FF0(-20.0f, player->unk_B8C, &sp4C, player->actor.shape.rot.y, + &player->bodyPartsPos[PLAYER_BODYPART_WAIST], arg1, &player->unk_B90, &player->unk_B10[0], 0.0f, + 0x1F40, &player->unk_B92, &player->unk_B10[1], 0); + + sp40.x = + (player->bodyPartsPos[PLAYER_BODYPART_LEFT_FOOT].x + player->bodyPartsPos[PLAYER_BODYPART_RIGHT_FOOT].x) / 2.0f; + sp40.y = + (player->bodyPartsPos[PLAYER_BODYPART_LEFT_FOOT].y + player->bodyPartsPos[PLAYER_BODYPART_RIGHT_FOOT].y) / 2.0f; + sp40.z = + (player->bodyPartsPos[PLAYER_BODYPART_LEFT_FOOT].z + player->bodyPartsPos[PLAYER_BODYPART_RIGHT_FOOT].z) / 2.0f; + func_80124FF0(-20.0f, player->unk_B90, arg1, (player->actor.shape.rot.y + player->unk_B92), &sp40, arg1, + &player->unk_B94, &player->unk_B10[2], -1.9f, 0x1F40, &player->unk_B96, &player->unk_B10[3], 0); +} void func_80125318(Vec3f* arg0, Vec3s* arg1) { arg0->x = 0.0f; @@ -1769,11 +1977,9 @@ void Player_DrawZoraShield(PlayState* play, Player* player) { u8* phi_a0; Vtx* vtx; Gfx* dList; - f32 scale; + f32 scale = player->unk_B62 * (10.0f / 51.0f); s32 i; - scale = player->unk_B62 * (10.0f / 51.0f); - OPEN_DISPS(play->state.gfxCtx); AnimatedMat_DrawXlu(play, Lib_SegmentedToVirtual(&object_link_zora_Matanimheader_012A80)); @@ -1801,49 +2007,399 @@ void Player_DrawZoraShield(PlayState* play, Player* player) { CLOSE_DISPS(play->state.gfxCtx); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80125500.s") +void func_80125500(PlayState* play, Player* player, s32 limbIndex, Vec3f* pos, Vec3s* rot) { + if (limbIndex == PLAYER_LIMB_LEFT_THIGH) { + Player_AdjustSingleLeg(play, player, &player->skelAnime, pos, rot, PLAYER_LIMB_LEFT_THIGH, + PLAYER_LIMB_LEFT_SHIN, PLAYER_LIMB_LEFT_FOOT); + } else if (limbIndex == PLAYER_LIMB_RIGHT_THIGH) { + Player_AdjustSingleLeg(play, player, &player->skelAnime, pos, rot, PLAYER_LIMB_RIGHT_THIGH, + PLAYER_LIMB_RIGHT_SHIN, PLAYER_LIMB_RIGHT_FOOT); + } +} + +s32 Player_OverrideLimbDrawGameplayCommon(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + s32 pad; + Player* player = (Player*)thisx; + + if (limbIndex == PLAYER_LIMB_ROOT) { + sPlayerLeftHandType = player->leftHandType; + sPlayerRightHandType = player->rightHandType; + + // `sPlayerCurBodyPartPos` is incremented before each usage, so it starts at index -1. + // What determines if a limb corresponds to a body part is whether or not it has a non-NULL `dList`. + // Note: The increment would not be done for the root limb, even if it had a non-NULL `dList`. + // So if the root limb had a non-NULL `dList` (which is not the case in vanilla), + // an out-of-bounds write to `bodyPartsPos` would occur. + sPlayerCurBodyPartPos = &player->bodyPartsPos[-1]; + + if (player->transformation != PLAYER_FORM_FIERCE_DEITY) { + if (!(player->skelAnime.moveFlags & ANIM_FLAG_4) || (player->skelAnime.moveFlags & ANIM_FLAG_1)) { + pos->x *= player->ageProperties->unk_08; + pos->z *= player->ageProperties->unk_08; + } + if (!(player->skelAnime.moveFlags & ANIM_FLAG_4) || (player->skelAnime.moveFlags & ANIM_FLAG_UPDATEY)) { + pos->y *= player->ageProperties->unk_08; + } + } + + pos->y -= player->unk_AB8; + if ((player->transformation == PLAYER_FORM_ZORA) && (player->stateFlags3 & PLAYER_STATE3_8000)) { + Matrix_Translate(pos->x, ((Math_CosS(player->unk_AAA) - 1.0f) * 200.0f) + pos->y, pos->z, MTXMODE_APPLY); + Matrix_RotateXS(player->unk_AAA, MTXMODE_APPLY); + + if (player->unk_B62 != 0) { + Matrix_Push(); + Matrix_RotateZS(player->unk_B8E, MTXMODE_APPLY); + Matrix_RotateZYX(rot->x, rot->y, rot->z, MTXMODE_APPLY); + Matrix_RotateXS(-0x8000, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, -4000.0f, MTXMODE_APPLY); + Player_DrawZoraShield(play, player); + Matrix_Pop(); + } + + Matrix_RotateZS(player->unk_B86[1], MTXMODE_APPLY); + Matrix_RotateZYX(rot->x, rot->y, rot->z, MTXMODE_APPLY); + func_80125318(pos, rot); + } else if (player->stateFlags3 & PLAYER_STATE3_2000) { + Vec3f sp54; + + func_801251C4(player, &sp54); + sp54.x -= player->actor.world.pos.x; + sp54.y -= player->actor.world.pos.y; + sp54.z -= player->actor.world.pos.z; + Matrix_Translate(pos->x + sp54.x, pos->y + sp54.y, pos->z + sp54.z, MTXMODE_APPLY); + Matrix_RotateXS(player->unk_B94, MTXMODE_APPLY); + Matrix_RotateZS(player->unk_B8E, MTXMODE_APPLY); + player->upperLimbRot.x = player->unk_B90 - player->unk_B94; + Matrix_RotateZYX(rot->x, rot->y, rot->z, MTXMODE_APPLY); + func_80125318(pos, rot); + } else if (player->unk_AAA != 0) { + Matrix_Translate(pos->x, ((Math_CosS(player->unk_AAA) - 1.0f) * 200.0f) + pos->y, pos->z, MTXMODE_APPLY); + Matrix_RotateXS(player->unk_AAA, MTXMODE_APPLY); + Matrix_RotateZYX(rot->x, rot->y, rot->z, MTXMODE_APPLY); + func_80125318(pos, rot); + } + } else { + if (*dList != NULL) { + sPlayerCurBodyPartPos++; + } + + if (limbIndex == PLAYER_LIMB_HEAD) { + rot->x += player->headLimbRot.z; + rot->y -= player->headLimbRot.y; + rot->z += player->headLimbRot.x; + + if (player->transformation == PLAYER_FORM_DEKU) { + EnArrow* bubble = NULL; + + if (((player->skelAnime.animation == &gPlayerAnim_pn_drinkend)) || + (player->unk_284.animation == &gPlayerAnim_pn_tamahaki) || + ((player->stateFlags3 & PLAYER_STATE3_40) && ((bubble = (EnArrow*)player->heldActor) != NULL))) { + Matrix_TranslateRotateZYX(pos, rot); + func_80125340(); + func_80125318(pos, rot); + + if (bubble != NULL) { + s32 requiredScopeTemp[2]; + + player->unk_AF0[0].x = 1.0f - (bubble->bubble.unk_144 * 0.03f); + player->unk_AF0[0].y = 1.0f - (bubble->bubble.unk_144 * 0.01f); + player->unk_AF0[0].z = 1.0f - (bubble->bubble.unk_144 * 0.04f); + rot->z = bubble->bubble.unk_144 * 320.0f; + } else if (player->skelAnime.animation == &gPlayerAnim_pn_drinkend) { + func_80124618(D_801C03E0, player->skelAnime.curFrame, player->unk_AF0); + } else { + func_80124618(D_801C03C0, player->unk_284.curFrame, player->unk_AF0); + } + + Matrix_Scale(player->unk_AF0[0].x, player->unk_AF0[0].y, player->unk_AF0[0].z, MTXMODE_APPLY); + } + } + } else if (limbIndex == PLAYER_LIMB_TORSO) { + if ((player->skelAnime.animation == &gPlayerAnim_pg_gakkistart) || + (player->skelAnime.animation == &gPlayerAnim_pg_wait) || + (player->skelAnime.animation == &gPlayerAnim_pg_punchC) || + (player->transformation == PLAYER_FORM_ZORA)) { + Matrix_TranslateRotateZYX(pos, rot); + if (player->transformation == PLAYER_FORM_GORON) { + func_80125340(); + } + + func_80125318(pos, rot); + if ((player->transformation != PLAYER_FORM_ZORA) || + (player->skelAnime.animation == &gPlayerAnim_pz_wait)) { + struct_80124618* phi_a0 = + (player->skelAnime.animation == &gPlayerAnim_pz_wait) + ? D_801C0608 + : ((player->skelAnime.animation == &gPlayerAnim_pg_wait) + ? D_801C0628 + : ((player->skelAnime.animation == &gPlayerAnim_pg_punchC) ? D_801C07C0 + : D_801C0460)); + + func_80124618(phi_a0, player->skelAnime.curFrame, player->unk_AF0); + } else { + player->unk_AF0[0].y = 1.0f; + } + + if (player->transformation == PLAYER_FORM_ZORA) { + player->unk_AF0[0].y *= 1.0f + (0.29999995f * player->unk_B10[0]); + player->unk_AF0[0].x = 1.0f; + player->unk_AF0[0].z = 1.0f; + } + Matrix_Scale(player->unk_AF0[0].x, player->unk_AF0[0].y, player->unk_AF0[0].z, MTXMODE_APPLY); + } + } else if (limbIndex == PLAYER_LIMB_UPPER_ROOT) { + s16 rotX; + s16 rotZ = 0x44C; + + if (player->unk_AA8 != 0) { + Matrix_RotateZS(rotZ, MTXMODE_APPLY); + Matrix_RotateYS(player->unk_AA8, MTXMODE_APPLY); + } + + if (player->upperLimbRot.y != 0) { + Matrix_RotateYS(player->upperLimbRot.y, MTXMODE_APPLY); + } + + rotX = player->upperLimbRot.x; + if ((player->transformation == PLAYER_FORM_DEKU) && (player->stateFlags3 & PLAYER_STATE3_40)) { + if (player->heldActor != NULL) { + rotX += (s16)(((EnArrow*)(player->heldActor))->bubble.unk_144 * -470.0f); + } + } + + Matrix_RotateXS(rotX, MTXMODE_APPLY); + if (player->upperLimbRot.z != 0) { + Matrix_RotateZS(player->upperLimbRot.z, MTXMODE_APPLY); + } + } else { + func_80125500(play, player, limbIndex, pos, rot); + } + } + + return false; +} + +void func_80125CE0(Player* player, struct_80124618* arg1, Vec3f* pos, Vec3s* rot) { + Matrix_TranslateRotateZYX(pos, rot); + func_80125318(pos, rot); + func_80124618(arg1, player->skelAnime.curFrame, player->unk_AF0); + Matrix_Scale(player->unk_AF0[0].x, player->unk_AF0[0].y, player->unk_AF0[0].z, MTXMODE_APPLY); +} + +s32 Player_OverrideLimbDrawGameplayDefault(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* actor) { + Player* player = (Player*)actor; + + if (!Player_OverrideLimbDrawGameplayCommon(play, limbIndex, dList, pos, rot, &player->actor)) { + if (limbIndex == PLAYER_LIMB_LEFT_HAND) { + Gfx** leftHandDLists = player->leftHandDLists; + EquipValueSword swordEquipValue; + + if (player->stateFlags3 & PLAYER_STATE3_2000) { + rot->z -= player->unk_B8C; + } else if ((sPlayerLeftHandType == PLAYER_MODELTYPE_LH_4) && + (player->stateFlags1 & PLAYER_STATE1_2000000)) { + leftHandDLists = &gPlayerLeftHandOpenDLs[D_801F59E0]; + sPlayerLeftHandType = PLAYER_MODELTYPE_LH_OPEN; + } else if ((player->leftHandType == PLAYER_MODELTYPE_LH_OPEN) && (player->actor.speed > 2.0f) && + !(player->stateFlags1 & PLAYER_STATE1_8000000)) { + leftHandDLists = &gPlayerLeftHandClosedDLs[D_801F59E0]; + sPlayerLeftHandType = PLAYER_MODELTYPE_LH_CLOSED; + } else if ((player->leftHandType == PLAYER_MODELTYPE_LH_ONE_HAND_SWORD) && + (player->transformation == PLAYER_FORM_HUMAN) && + ((swordEquipValue = GET_CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD), + swordEquipValue != EQUIP_VALUE_SWORD_NONE))) { + leftHandDLists = &D_801C018C[2 * ((swordEquipValue - 1) ^ 0)]; + } else { + s32 handIndex = GET_LEFT_HAND_INDEX_FROM_JOINT_TABLE(player->skelAnime.jointTable); + + if (handIndex != 0) { + handIndex = (handIndex >> 12) - 1; + if (handIndex >= 2) { + handIndex = 0; + } + leftHandDLists = &D_801C095C[handIndex][D_801F59E0]; + } + } + + *dList = leftHandDLists[sPlayerLod]; + + if (player->transformation == PLAYER_FORM_GORON) { + if (player->skelAnime.animation == &gPlayerAnim_pg_punchA) { + func_80125CE0(player, D_801C0750, pos, rot); + } + } else if (player->transformation == PLAYER_FORM_ZORA) { + if ((player->stateFlags1 & PLAYER_STATE1_2) || (player->stateFlags1 & PLAYER_STATE1_400) || + func_801242B4(player)) { + *dList = gLinkZoraLeftHandOpenDL; + } else { + s32 phi_a1 = (player->skelAnime.animation == &gPlayerAnim_pz_gakkistart) && + (player->skelAnime.curFrame >= 6.0f); + + if (phi_a1 || (player->skelAnime.animation == &gPlayerAnim_pz_gakkiplay)) { + *dList = object_link_zora_DL_00E2A0; + func_80125CE0(player, phi_a1 ? D_801C0538 : D_801C0560, pos, rot); + } + } + } + } else if (limbIndex == PLAYER_LIMB_RIGHT_HAND) { + if ((player->transformation == PLAYER_FORM_ZORA) && + (((player->stateFlags1 & PLAYER_STATE1_2)) || (player->stateFlags1 & PLAYER_STATE1_400) || + func_801242B4(player))) { + *dList = gLinkZoraRightHandOpenDL; + } else { + Gfx** rightHandDLists = player->rightHandDLists; + + if (player->stateFlags3 & PLAYER_STATE3_2000) { + rot->z -= player->unk_B8C; + } + + if (sPlayerRightHandType == PLAYER_MODELTYPE_RH_SHIELD) { + if (player->transformation == PLAYER_FORM_HUMAN) { + if (player->currentShield != PLAYER_SHIELD_NONE) { + //! FAKE + rightHandDLists = &gPlayerHandHoldingShields[2 * ((player->currentShield - 1) ^ 0)]; + } + } + } else if ((player->rightHandType == PLAYER_MODELTYPE_RH_OPEN) && (player->actor.speed > 2.0f) && + (!(player->stateFlags1 & PLAYER_STATE1_8000000))) { + rightHandDLists = &gPlayerRightHandClosedDLs[D_801F59E0]; + sPlayerRightHandType = PLAYER_MODELTYPE_RH_CLOSED; + } else { + s32 handIndex = GET_RIGHT_HAND_INDEX_FROM_JOINT_TABLE(player->skelAnime.jointTable); + + if (handIndex != 0) { + handIndex = (handIndex >> 8) - 1; + rightHandDLists = &D_801C0964[handIndex][D_801F59E0]; + } + } + + *dList = rightHandDLists[sPlayerLod]; + if (player->skelAnime.animation == &gPlayerAnim_pg_punchB) { + func_80125CE0(player, D_801C0784, pos, rot); + } + } + } else if (limbIndex == PLAYER_LIMB_SHEATH) { + Gfx** sheathDLists = player->sheathDLists; + + if (player->transformation == PLAYER_FORM_HUMAN) { + EquipValueSword swordEquipValue = GET_CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD); + + if (swordEquipValue != EQUIP_VALUE_SWORD_NONE) { + if ((player->sheathType == PLAYER_MODELTYPE_SHEATH_14) || + (player->sheathType == PLAYER_MODELTYPE_SHEATH_12)) { + sheathDLists = &gPlayerSheathedSwords[2 * ((swordEquipValue - 1) ^ 0)]; + } else { + sheathDLists = &gPlayerSwordSheaths[2 * ((swordEquipValue - 1) ^ 0)]; + } + } + } -s32 func_80125580(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80125580.s") + *dList = sheathDLists[sPlayerLod]; + } else if (limbIndex == PLAYER_LIMB_WAIST) { + *dList = player->waistDLists[sPlayerLod]; + } else if (limbIndex == PLAYER_LIMB_HAT) { + if (player->transformation == PLAYER_FORM_ZORA) { + Matrix_Scale((player->unk_B10[0] * 1) + 1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80125CE0.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80125D4C.s") +s32 Player_OverrideLimbDrawGameplayFirstPerson(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* actor) { + Player* player = (Player*)actor; + + if (!Player_OverrideLimbDrawGameplayCommon(play, limbIndex, dList, pos, rot, actor)) { + if (player->unk_AA5 != 3) { + *dList = NULL; + } else if (limbIndex == PLAYER_LIMB_LEFT_FOREARM) { + *dList = sPlayerFirstPersonLeftForearmDLs[player->transformation]; + } else if (limbIndex == PLAYER_LIMB_LEFT_HAND) { + *dList = sPlayerFirstPersonLeftHandDLs[player->transformation]; + } else if (limbIndex == PLAYER_LIMB_RIGHT_SHOULDER) { + *dList = sPlayerFirstPersonRightShoulderDLs[player->transformation]; + } else if (limbIndex == PLAYER_LIMB_RIGHT_HAND) { + if (Player_IsHoldingHookshot(player)) { + *dList = sPlayerFirstPersonRightHandHookshotDLs[player->transformation]; + } else { + *dList = sPlayerFirstPersonRightHandDLs[player->transformation]; + } + } else { + *dList = NULL; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_801262C8.s") + return false; +} -// unused -s32 func_801263FC(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { +// Unused remnant of OoT +s32 Player_OverrideLimbDrawGameplayCrawling(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { Player* player = (Player*)thisx; - if (!func_80125580(play, limbIndex, dList, pos, rot, thisx)) { + if (!Player_OverrideLimbDrawGameplayCommon(play, limbIndex, dList, pos, rot, thisx)) { *dList = NULL; } return false; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80126440.s") +s32 func_80126440(PlayState* play, ColliderQuad* collider, WeaponInfo* weaponInfo, Vec3f* newTip, Vec3f* newBase) { + if (!weaponInfo->active) { + if (collider != NULL) { + Collider_ResetQuadAT(play, &collider->base); + } + Math_Vec3f_Copy(&weaponInfo->tip, newTip); + Math_Vec3f_Copy(&weaponInfo->base, newBase); + weaponInfo->active = true; + + return true; + } + + if ((weaponInfo->tip.x == newTip->x) && (weaponInfo->tip.y == newTip->y) && (weaponInfo->tip.z == newTip->z)) { + if ((weaponInfo->base.x == newBase->x) && (weaponInfo->base.y == newBase->y) && + (weaponInfo->base.z == newBase->z)) { + if (collider != NULL) { + Collider_ResetQuadAT(play, &collider->base); + } + + return false; + } + } + + if (collider != NULL) { + Collider_SetQuadVertices(collider, newBase, newTip, &weaponInfo->base, &weaponInfo->tip); + CollisionCheck_SetAT(play, &play->colChkCtx, &collider->base); + } + + Math_Vec3f_Copy(&weaponInfo->base, newBase); + Math_Vec3f_Copy(&weaponInfo->tip, newTip); + weaponInfo->active = true; + + return true; +} -u8 D_801C096C[PLAYER_SHIELD_MAX] = { - COLTYPE_METAL, - COLTYPE_METAL, - COLTYPE_METAL, +u8 sPlayerShieldCollisionTypes[PLAYER_SHIELD_MAX] = { + COLTYPE_METAL, // PLAYER_SHIELD_NONE + COLTYPE_METAL, // PLAYER_SHIELD_HEROS_SHIELD + COLTYPE_METAL, // PLAYER_SHIELD_MIRROR_SHIELD }; -void func_801265C8(PlayState* play, Player* player, ColliderQuad* collider, Vec3f arg3[4]) { +void Player_UpdateShieldCollider(PlayState* play, Player* player, ColliderQuad* collider, Vec3f quadSrc[4]) { if (player->stateFlags1 & PLAYER_STATE1_400000) { - Vec3f sp4C; - Vec3f sp40; - Vec3f sp34; - Vec3f sp28; - - player->shieldQuad.base.colType = D_801C096C[player->currentShield]; - Matrix_MultVec3f(&arg3[0], &sp28); - Matrix_MultVec3f(&arg3[1], &sp34); - Matrix_MultVec3f(&arg3[2], &sp40); - Matrix_MultVec3f(&arg3[3], &sp4C); - Collider_SetQuadVertices(collider, &sp28, &sp34, &sp40, &sp4C); + Vec3f quadDest[4]; + + player->shieldQuad.base.colType = sPlayerShieldCollisionTypes[player->currentShield]; + Matrix_MultVec3f(&quadSrc[0], &quadDest[0]); + Matrix_MultVec3f(&quadSrc[1], &quadDest[1]); + Matrix_MultVec3f(&quadSrc[2], &quadDest[2]); + Matrix_MultVec3f(&quadSrc[3], &quadDest[3]); + Collider_SetQuadVertices(collider, &quadDest[0], &quadDest[1], &quadDest[2], &quadDest[3]); CollisionCheck_SetAC(play, &play->colChkCtx, &collider->base); CollisionCheck_SetAT(play, &play->colChkCtx, &collider->base); } @@ -1949,47 +2505,73 @@ Gfx* D_801C0B14[] = { }; u8 D_801C0B1C[] = { - 0x0C, - 0x0F, + PLAYER_BODYPART_LEFT_HAND, + PLAYER_BODYPART_RIGHT_HAND, }; Gfx* D_801C0B20[] = { - object_mask_truth_DL_0001A0, - object_mask_kerfay_DL_000D40, - object_mask_yofukasi_DL_000490, - object_mask_rabit_DL_000610, - object_mask_ki_tan_DL_0004A0, - object_mask_json_DL_0004C0, - object_mask_romerny_DL_0007A0, - object_mask_zacho_DL_000700, - object_mask_posthat_DL_000290, - object_mask_meoto_DL_0005A0, - object_mask_bigelf_DL_0016F0, - object_mask_gibudo_DL_000250, - gDonGeroMaskDL, - object_mask_dancer_DL_000EF0, - object_mask_skj_DL_0009F0, - object_mask_stone_DL_000820, - object_mask_bree_DL_0003C0, - object_mask_bakuretu_DL_0005C0, - object_mask_bu_san_DL_000710, - object_mask_kyojin_DL_000380, - gameplay_keep_DL_00B260, - gameplay_keep_DL_005A10, - gameplay_keep_DL_005360, - gDekuMaskDL, + object_mask_truth_DL_0001A0, // PLAYER_MASK_TRUTH + object_mask_kerfay_DL_000D40, // PLAYER_MASK_KAFEIS_MASK + object_mask_yofukasi_DL_000490, // PLAYER_MASK_ALL_NIGHT + object_mask_rabit_DL_000610, // PLAYER_MASK_BUNNY + object_mask_ki_tan_DL_0004A0, // PLAYER_MASK_KEATON + object_mask_json_DL_0004C0, // PLAYER_MASK_GARO + object_mask_romerny_DL_0007A0, // PLAYER_MASK_ROMANI + object_mask_zacho_DL_000700, // PLAYER_MASK_CIRCUS_LEADER + object_mask_posthat_DL_000290, // PLAYER_MASK_POSTMAN + object_mask_meoto_DL_0005A0, // PLAYER_MASK_COUPLE + object_mask_bigelf_DL_0016F0, // PLAYER_MASK_GREAT_FAIRY + object_mask_gibudo_DL_000250, // PLAYER_MASK_GIBDO + gDonGeroMaskDL, // PLAYER_MASK_DON_GERO + object_mask_dancer_DL_000EF0, // PLAYER_MASK_KAMARO + object_mask_skj_DL_0009F0, // PLAYER_MASK_CAPTAIN + object_mask_stone_DL_000820, // PLAYER_MASK_STONE + object_mask_bree_DL_0003C0, // PLAYER_MASK_BREMEN + object_mask_bakuretu_DL_0005C0, // PLAYER_MASK_BLAST + object_mask_bu_san_DL_000710, // PLAYER_MASK_SCENTS + object_mask_kyojin_DL_000380, // PLAYER_MASK_GIANT + gameplay_keep_DL_00B260, // PLAYER_MASK_FIERCE_DEITY + gameplay_keep_DL_005A10, // PLAYER_MASK_GORON + gameplay_keep_DL_005360, // PLAYER_MASK_ZORA + gDekuMaskDL, // PLAYER_MASK_DEKU object_mask_boy_DL_000900, object_mask_goron_DL_0014A0, object_mask_zora_DL_000DB0, object_mask_nuts_DL_001D90, }; -Vec3f D_801C0B90[] = { +Vec3f D_801C0B90[D_801F59B0_LEN] = { { 950.0f, -800.0f, 300.0f }, { 950.0f, -800.0f, -300.0f }, }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8012669C.s") +void func_8012669C(PlayState* play, Player* player, Vec3f* arg2, Vec3f* arg3) { + Vec3f sp3C; + Vec3f sp30; + + Matrix_MultVec3f(arg2, &sp3C); + Matrix_MultVec3f(arg3, &sp30); + + if (player->meleeWeaponState != 0) { + if (func_80126440(play, NULL, &player->meleeWeaponInfo[0], &sp3C, &sp30) && + (player->transformation != PLAYER_FORM_GORON) && (!(player->stateFlags1 & PLAYER_STATE1_400000))) { + EffectBlure_AddVertex(Effect_GetByIndex(player->meleeWeaponEffectIndex[0]), &player->meleeWeaponInfo[0].tip, + &player->meleeWeaponInfo[0].base); + } + if ((player->meleeWeaponState > 0) && ((player->meleeWeaponAnimation < PLAYER_MWA_SPIN_ATTACK_1H) || + (player->stateFlags2 & PLAYER_STATE2_20000))) { + Matrix_MultVec3f(&arg2[1], &sp3C); + Matrix_MultVec3f(&arg3[1], &sp30); + func_80126440(play, &player->meleeWeaponQuads[0], &player->meleeWeaponInfo[1], &sp3C, &sp30); + Matrix_MultVec3f(&arg2[2], &sp3C); + Matrix_MultVec3f(&arg3[2], &sp30); + func_80126440(play, &player->meleeWeaponQuads[1], &player->meleeWeaponInfo[2], &sp3C, &sp30); + } + } else { + Math_Vec3f_Copy(&player->meleeWeaponInfo[0].tip, &sp3C); + Math_Vec3f_Copy(&player->meleeWeaponInfo[0].base, &sp30); + } +} void Player_DrawGetItemImpl(PlayState* play, Player* player, Vec3f* refPos, s32 drawIdPlusOne) { f32 sp34; @@ -2038,21 +2620,203 @@ void Player_DrawGetItem(PlayState* play, Player* player) { refPos.y = player->actor.world.pos.y + 28.0f; } } else { - Math_Vec3f_Copy(&refPos, &D_801F59E8); + Math_Vec3f_Copy(&refPos, &sPlayerGetItemRefPos); } - drawIdPlusOne = ABS_ALT(player->getItemDrawId); + drawIdPlusOne = ABS_ALT(player->getItemDrawIdPlusOne); Player_DrawGetItemImpl(play, player, &refPos, drawIdPlusOne); } } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80126AB4.s") +void func_80126AB4(Player* player, Vec3f** arg1) { + if ((player->transformation == PLAYER_FORM_GORON) || (player->actor.id == ACTOR_EN_TEST3)) { + Math_Vec3f_Copy(&player->unk_AF0[1], &player->meleeWeaponInfo[0].base); + *arg1 = D_801C09B8; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80126B8C.s") + D_801C0994[1].x = D_801C0994[0].x; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80126BD0.s") + if (player->unk_ADD >= 3) { + player->unk_ADD++; + D_801C0994[1].x *= 1.0f + ((9 - player->unk_ADD) * 0.1f); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_801271B0.s") + D_801C0994[1].x += 1200.0f; + D_801C0994[2].x = D_801C0994[1].x; + *arg1 = D_801C0994; +} + +void func_80126B8C(PlayState* play, Player* player) { + Vec3f* sp1C; + + func_80126AB4(player, &sp1C); + func_8012669C(play, player, sp1C, D_801C0970); +} + +// Zora boomerangs (?) +void func_80126BD0(PlayState* play, Player* player, s32 arg2) { + if ((player->transformation != PLAYER_FORM_ZORA) || (player->rightHandType == PLAYER_MODELTYPE_RH_HOOKSHOT)) { + return; + } + + if ((arg2 != 0) && (player->stateFlags1 & PLAYER_STATE1_400000)) { + OPEN_DISPS(play->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_link_zora_DL_0110A8); + + CLOSE_DISPS(play->state.gfxCtx); + } else { + Actor* boomerangActor = player->boomerangActor; + Vec3f sp58; + Vec3f sp4C; + + if (player->stateFlags1 & PLAYER_STATE1_2000000) { + if (player->boomerangActor == NULL) { + return; + } + if ((player->boomerangActor->params == arg2) || + (((boomerangActor->child != NULL)) && (boomerangActor->child->params == arg2))) { + return; + } + } + + OPEN_DISPS(play->state.gfxCtx); + + if ((player->skelAnime.animation != &gPlayerAnim_pz_gakkiplay) && + (player->skelAnime.animation != &gPlayerAnim_pz_fishswim)) { + if (player->skelAnime.animation == &gPlayerAnim_pz_gakkistart) { + func_80124618(D_801C0580, player->skelAnime.curFrame, player->unk_AF0); + } else if (player->skelAnime.animation == &gPlayerAnim_pz_waterroll) { + func_80124618(D_801C05A8, player->skelAnime.curFrame, player->unk_AF0); + } else if (player->skelAnime.animation == &gPlayerAnim_pz_swimtowait) { + func_80124618(D_801C05D8, player->skelAnime.curFrame, player->unk_AF0); + } else if (player->skelAnime.animation == &gPlayerAnim_pz_bladeon) { + func_80124618(D_801C07F0, player->skelAnime.curFrame, player->unk_AF0); + } else if (player->skelAnime.animation == &gPlayerAnim_pz_jumpAT) { + func_80124618(D_801C0820, player->skelAnime.curFrame, player->unk_AF0); + } else if (player->skelAnime.animation == &gPlayerAnim_pz_jumpATend) { + func_80124618(D_801C0838, player->skelAnime.curFrame, player->unk_AF0); + } else if (player->heldItemAction == PLAYER_IA_ZORA_FINS) { + player->unk_AF0[0].x = 1.0f; + player->unk_AF0[0].y = 1.0f; + player->unk_AF0[0].z = 1.0f; + } else { + player->unk_AF0[0].x = 0.4f; + player->unk_AF0[0].y = 0.6f; + player->unk_AF0[0].z = 0.7f; + } + Matrix_Push(); + + Matrix_Scale(player->unk_AF0[0].x, player->unk_AF0[0].y, player->unk_AF0[0].z, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_OPA_DISP++, D_801C0AB4[arg2]); + + if (player->meleeWeaponState != 0) { + if ((((player->meleeWeaponAnimation == PLAYER_MWA_ZORA_PUNCH_LEFT)) && (arg2 == 0)) || + ((player->meleeWeaponAnimation == PLAYER_MWA_ZORA_PUNCH_COMBO) && (arg2 != 0))) { + func_8012669C(play, player, D_801C0A00, D_801C09DC); + } + } + + Matrix_Pop(); + } + + if (player->skelAnime.animation == &gPlayerAnim_pz_waterroll) { + func_80124618(D_801C05C8, player->skelAnime.curFrame, player->unk_AF0); + D_801C05F0[0].unk_2.x = 50; + D_801C05F0[0].unk_2.y = 50; + D_801C05F0[0].unk_2.z = 50; + D_801C05F0[1].unk_2 = D_801C05F0[0].unk_2; + } else if (player->skelAnime.animation == &gPlayerAnim_pz_swimtowait) { + func_80124618(D_801C05F0, player->skelAnime.curFrame, player->unk_AF0); + } else if (player->skelAnime.animation == &gPlayerAnim_pz_fishswim) { + player->unk_AF0[0].x = (ABS_ALT(player->unk_B8A) * 0.00003f) + 0.5f; + player->unk_AF0[0].y = player->unk_AF0[0].x; + player->unk_AF0[0].z = player->unk_AF0[0].x; + + D_801C05F0[0].unk_2.x = (player->unk_AF0[0].x * 100.0f); + + D_801C05F0[0].unk_2.y = D_801C05F0[0].unk_2.x; + D_801C05F0[0].unk_2.z = D_801C05F0[0].unk_2.x; + + D_801C05F0[1].unk_2 = D_801C05F0[0].unk_2; + } else { + //! @bug Skips CLOSE_DISPS + return; + } + + Matrix_Push(); + Matrix_Scale(player->unk_AF0[0].x, player->unk_AF0[0].y, player->unk_AF0[0].z, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_801C0ABC[arg2]); + + Matrix_MultVec3f(&D_801C0AC4[arg2], &sp58); + Matrix_MultVec3f(&D_801C0ADC[arg2], &sp4C); + + if (func_80126440(play, NULL, &player->meleeWeaponInfo[arg2], &sp58, &sp4C) && + (player->stateFlags1 & PLAYER_STATE1_8000000)) { + EffectBlure_AddVertex(Effect_GetByIndex(player->meleeWeaponEffectIndex[arg2]), + &player->meleeWeaponInfo[arg2].tip, &player->meleeWeaponInfo[arg2].base); + } + Matrix_Pop(); + + CLOSE_DISPS(play->state.gfxCtx); + } +} + +s32 func_801271B0(PlayState* play, Player* player, s32 arg2) { + if (player->transformation == PLAYER_FORM_DEKU) { + if (((player->skelAnime.animation == &gPlayerAnim_pn_kakku)) || + (player->skelAnime.animation == &gPlayerAnim_pn_kakkufinish) || + (player->skelAnime.animation == &gPlayerAnim_pn_rakkafinish) || + (player->skelAnime.animation == &gPlayerAnim_pn_batabata)) { + struct_80124618** sp3C = D_801C0AF4; + + OPEN_DISPS(play->state.gfxCtx); + + if (player->skelAnime.animation == &gPlayerAnim_pn_kakkufinish) { + sp3C = D_801C0AFC; + } else if (player->skelAnime.animation == &gPlayerAnim_pn_batabata) { + sp3C = D_801C0B0C; + } else if (player->skelAnime.animation == &gPlayerAnim_pn_rakkafinish) { + sp3C = D_801C0B04; + } + + Matrix_Push(); + Matrix_Translate(0.0f, 150.0f, 0.0f, MTXMODE_APPLY); + func_80124618(sp3C[0], player->skelAnime.curFrame, &player->unk_AF0[1]); + Matrix_Scale(player->unk_AF0[1].x, player->unk_AF0[1].y, player->unk_AF0[1].z, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_OPA_DISP++, D_801C0B14[arg2]); + + Matrix_Translate(2150.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXS(player->unk_B8A, MTXMODE_APPLY); + func_80124618(sp3C[1], player->skelAnime.curFrame, &player->unk_AF0[1]); + Matrix_Scale(player->unk_AF0[1].x, player->unk_AF0[1].y, player->unk_AF0[1].z, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + // Close flower / Open flower + gSPDisplayList(POLY_OPA_DISP++, + player->actor.velocity.y < -6.0f ? gLinkDekuClosedFlowerDL : gLinkDekuOpenFlowerDL); + + Matrix_MultZero(&player->bodyPartsPos[D_801C0B1C[arg2]]); + Matrix_Pop(); + + CLOSE_DISPS(play->state.gfxCtx); + + return true; + } + } + + return false; +} // Player_SetMaskSegment? s32 func_80127438(PlayState* play, Player* player, s32 currentMask) { @@ -2086,7 +2850,7 @@ void Player_DrawCouplesMask(PlayState* play, Player* player) { AnimatedMat_DrawOpa(play, Lib_SegmentedToVirtual(&object_mask_meoto_Matanimheader_001CD8)); } -void Player_DrawCircusLeadersMask(PlayState* play, Actor* actor) { +void Player_DrawCircusLeadersMask(PlayState* play, Player* player) { static Vec3f bubbleVelocity = { 0.0f, 0.0f, 0.0f }; static Vec3f bubbleAccel = { 0.0f, 0.0f, 0.0f }; Gfx* gfx; @@ -2096,7 +2860,7 @@ void Player_DrawCircusLeadersMask(PlayState* play, Actor* actor) { gfx = POLY_XLU_DISP; - for (i = 0; i < ARRAY_COUNT(D_801C0B90); i++) { + for (i = 0; i < D_801F59B0_LEN; i++) { f32 scaleY = (D_801F59C8[i] / 400.0f) * 0.1f; Matrix_MultVec3f(&D_801C0B90[i], &D_801F59B0[i]); @@ -2106,7 +2870,7 @@ void Player_DrawCircusLeadersMask(PlayState* play, Actor* actor) { D_801F59B0[i].y += -10.0f * scaleY; - if (D_801F59C8[i] < 0x190) { + if (D_801F59C8[i] < 400) { f32 scaleXZ = CLAMP_MAX(scaleY, 0.05f); Matrix_Push(); @@ -2124,12 +2888,11 @@ void Player_DrawCircusLeadersMask(PlayState* play, Actor* actor) { gfx = &gfx[6]; } else { - Player* player = (Player*)actor; - f32 temp_f0 = sqrtf(SQ(player->actor.velocity.x) + SQ(player->actor.velocity.z)); - s16 phi_s0 = temp_f0 * 2000.0f; + f32 speedXZ = sqrtf(SQ(player->actor.velocity.x) + SQ(player->actor.velocity.z)); + s16 phi_s0 = speedXZ * 2000.0f; f32 temp_f20; - bubbleVelocity.y = temp_f0 * 0.4f; + bubbleVelocity.y = speedXZ * 0.4f; bubbleAccel.y = -0.3f; if (phi_s0 > 0x3E80) { @@ -2137,17 +2900,14 @@ void Player_DrawCircusLeadersMask(PlayState* play, Actor* actor) { } phi_s0 = player->actor.focus.rot.y + ((i != 0) ? phi_s0 : -phi_s0); - temp_f20 = temp_f0 * 0.2f; - - if (temp_f20 > 4.0f) { - temp_f20 = 4.0f; - } + temp_f20 = speedXZ * 0.2f; + temp_f20 = CLAMP_MAX(temp_f20, 4.0f); bubbleVelocity.x = -Math_SinS(phi_s0) * temp_f20; bubbleVelocity.z = -Math_CosS(phi_s0) * temp_f20; EffectSsDtBubble_SpawnColorProfile(play, &D_801F59B0[i], &bubbleVelocity, &bubbleAccel, 20, 20, 3, 0); - D_801F59C8[i] -= 0x190; + D_801F59C8[i] -= 400; } } @@ -2214,7 +2974,7 @@ Vec3f D_801C0C30[] = { { 301.0f, -729.0f, 699.0f }, }; -typedef struct { +typedef struct struct_80128388_arg1 { /* 0x00 */ f32 unk_00; /* 0x04 */ s16 unk_04; /* 0x06 */ s16 unk_06; @@ -2230,91 +2990,237 @@ struct_80128388_arg1 D_801C0C54[] = { { 30.0f, 0x0000, 0x0000, { 0.0f, 0.0f, 0.0f }, 20.0f, 0x1F40, 0x2EE0 }, }; -Color_RGB8 D_801C0CA8[] = { - { 255, 255, 255 }, { 80, 80, 255 }, { 136, 192, 255 }, { 136, 192, 255 }, { 184, 232, 232 }, { 248, 200, 0 }, - { 255, 180, 0 }, { 0, 128, 0 }, { 252, 238, 0 }, { 131, 0, 174 }, { 64, 64, 32 }, { 0, 0, 255 }, - { 255, 0, 255 }, { 255, 0, 255 }, { 255, 0, 0 }, { 0, 0, 255 }, { 0, 200, 0 }, { 255, 255, 255 }, - { 255, 255, 255 }, { 255, 255, 255 }, { 80, 80, 255 }, +Color_RGB8 sPlayerBottleColors[PLAYER_BOTTLE_MAX] = { + { 255, 255, 255 }, // PLAYER_BOTTLE_EMPTY + { 80, 80, 255 }, // PLAYER_BOTTLE_FISH + { 136, 192, 255 }, // PLAYER_BOTTLE_SPRING_WATER + { 136, 192, 255 }, // PLAYER_BOTTLE_HOT_SPRING_WATER + { 184, 232, 232 }, // PLAYER_BOTTLE_ZORA_EGG + { 248, 200, 0 }, // PLAYER_BOTTLE_DEKU_PRINCESS + { 255, 180, 0 }, // PLAYER_BOTTLE_GOLD_DUST + { 0, 128, 0 }, // PLAYER_BOTTLE_1C + { 252, 238, 0 }, // PLAYER_BOTTLE_SEAHORSE + { 131, 0, 174 }, // PLAYER_BOTTLE_MUSHROOM + { 64, 64, 32 }, // PLAYER_BOTTLE_HYLIAN_LOACH + { 0, 0, 255 }, // PLAYER_BOTTLE_BUG + { 255, 0, 255 }, // PLAYER_BOTTLE_POE + { 255, 0, 255 }, // PLAYER_BOTTLE_BIG_POE + { 255, 0, 0 }, // PLAYER_BOTTLE_POTION_RED + { 0, 0, 255 }, // PLAYER_BOTTLE_POTION_BLUE + { 0, 200, 0 }, // PLAYER_BOTTLE_POTION_GREEN + { 255, 255, 255 }, // PLAYER_BOTTLE_MILK + { 255, 255, 255 }, // PLAYER_BOTTLE_MILK_HALF + { 255, 255, 255 }, // PLAYER_BOTTLE_CHATEAU + { 80, 80, 255 }, // PLAYER_BOTTLE_FAIRY }; Vec3f D_801C0CE8[PLAYER_FORM_MAX] = { - { 0.0f, 0.0f, 0.0f }, { 300.0f, 300.0f, -230.0f }, { 0.0f, 90.0f, -50.0f }, - { 0.0f, 20.0f, -60.0f }, { 0.0f, 0.0f, 0.0f }, -}; -Vec3f D_801C0D24[PLAYER_FORM_MAX] = { - { 200.0f, 300.0f, 0.0f }, { 200.0f, 200.0f, 0.0f }, { 200.0f, 300.0f, 0.0f }, - { 200.0f, 150.0f, 0.0f }, { 200.0f, 200.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f }, // PLAYER_FORM_FIERCE_DEITY + { 300.0f, 300.0f, -230.0f }, // PLAYER_FORM_GORON + { 0.0f, 90.0f, -50.0f }, // PLAYER_FORM_ZORA + { 0.0f, 20.0f, -60.0f }, // PLAYER_FORM_DEKU + { 0.0f, 0.0f, 0.0f }, // PLAYER_FORM_HUMAN }; -Vec3f D_801C0D60 = { 398.0f, 1419.0f, 244.0f }; -Vec3f D_801C0D6C = { 420.0f, 1210.0f, 380.0f }; -f32 D_801C0D78[] = { - 0.0f, // Player is not holding a melee weapon - 3000.0f, // PLAYER_IA_SWORD_KOKIRI - 3000.0f, // PLAYER_IA_SWORD_RAZOR - 4000.0f, // PLAYER_IA_SWORD_GILDED - 5500.0f, // PLAYER_IA_SWORD_GREAT_FAIRY - -1.0f, // PLAYER_IA_STICK - 2500.0f, // PLAYER_IA_ZORA_FINS -}; +void Player_DrawBunnyHood(PlayState* play) { + Mtx* mtx = GRAPH_ALLOC(play->state.gfxCtx, 2 * sizeof(Mtx)); + Vec3s earRot; -Gfx* D_801C0D94 = object_link_child_DL_017818; + OPEN_DISPS(play->state.gfxCtx); -f32 D_801C0D98 = -35.0f; + gSPSegment(POLY_OPA_DISP++, 0x0B, mtx); -f32 D_801C0D9C = -395.0f; -f32 D_801C0DA0 = 0.0f; + Matrix_Push(); -f32 D_801C0DA4 = 0.0f; + earRot.x = sBunnyEarKinematics.rot.y + 0x3E2; + earRot.y = sBunnyEarKinematics.rot.z + 0xDBE; + earRot.z = sBunnyEarKinematics.rot.x - 0x348A; + Matrix_SetTranslateRotateYXZ(97.0f, -1203.0f, -240.0f, &earRot); -Vec3f D_801C0DA8[4] = { - { -4500.0f, -3000.0f, -600.0f }, - { 1500.0f, -3000.0f, -600.0f }, - { -4500.0f, 3000.0f, -600.0f }, - { 1500.0f, 3000.0f, -600.0f }, -}; + Matrix_ToMtx(mtx++); -Vec3f D_801C0DD8 = { 50.0f, 800.0f, 0.0f }; -Vec3f D_801C0DE4 = { 50.0f, 850.0f, 0.0f }; -Gfx* D_801C0DF0[] = { - object_link_goron_DL_010590, object_link_goron_DL_010368, object_link_goron_DL_010140, - object_link_goron_DL_00FF18, object_link_goron_DL_00FCF0, -}; + earRot.x = sBunnyEarKinematics.rot.y - 0x3E2; + earRot.y = -sBunnyEarKinematics.rot.z - 0xDBE; + earRot.z = sBunnyEarKinematics.rot.x - 0x348A; + Matrix_SetTranslateRotateYXZ(97.0f, -1203.0f, 240.0f, &earRot); -Vec2f D_801C0E04[PLAYER_FORM_MAX] = { - { 140.0f, -130.0f }, { 0.0f, -200.0f }, { -160.0f, 0.0f }, { 220.0f, -200.0f }, { 0.0f, 0.0f }, -}; + Matrix_ToMtx(mtx); -Gfx* D_801C0E2C[] = { - object_link_nuts_DL_007A28, object_link_nuts_DL_0077D0, object_link_nuts_DL_007548, - object_link_nuts_DL_007900, object_link_nuts_DL_0076A0, -}; -Vec3f D_801C0E40[PLAYER_FORM_MAX] = { - { 0.0f, 0.0f, 0.0f }, { -578.3f, -1100.9f, 0.0f }, { -189.5f, -594.87f, 0.0f }, - { -570.0f, -812.0f, 0.0f }, { -230.0f, -520.0f, 0.0f }, -}; -Vec3f D_801C0E7C = { 1100.0f, -700.0f, 0.0f }; + Matrix_Pop(); -// unused -Vec3f D_801C0E88 = { 1600.0f, -1700.0f, -70.0f }; + CLOSE_DISPS(play->state.gfxCtx); +} -Vec3f D_801C0E94 = { 1800.0f, -300.0f, 0.0f }; -Vec3f D_801C0EA0 = { 1300.0f, -400.0f, 0.0f }; -Vec3f D_801C0EAC = { 630.0f, 100.0f, -30.0f }; -Vec3s D_801C0EB8 = { 0, 0, 0x7FFF }; +void func_80127B64(struct_801F58B0 arg0[], s32 count, Vec3f* arg2) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/Player_DrawBunnyHood.s") + for (i = 0; i < count; i++, arg0++) { + Math_Vec3f_Copy(&arg0->unk_00, arg2); + Math_Vec3f_Copy(&arg0->unk_0C, &gZeroVec3f); + arg0->unk_18 = 0; + arg0->unk_1A = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80127B64.s") +// Draws the Great Fairy's Mask particles when a stray fairy is in the room +void Player_DrawStrayFairyParticles(PlayState* play, Vec3f* arg1) { + Vec3f sp2C; + f32 sp28; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80127BE8.s") + D_801C0BE0.y = Rand_ZeroFloat(0.07f) + -0.1f; + D_801C0BEC.y = Rand_ZeroFloat(0.1f) + 0.04f; + if (Rand_ZeroOne() < 0.5f) { + sp28 = -1.0f; + } else { + sp28 = 1.0f; + } + + D_801C0BE0.x = (Rand_ZeroFloat(0.2f) + 0.1f) * sp28; + D_801C0BEC.x = 0.1f * sp28; + if (Rand_ZeroOne() < 0.5f) { + sp28 = -1.0f; + } else { + sp28 = 1.0f; + } + + D_801C0BE0.z = (Rand_ZeroFloat(0.2f) + 0.1f) * sp28; + D_801C0BEC.z = 0.1f * sp28; + sp2C.x = arg1->x; + sp2C.y = Rand_ZeroFloat(15.0f) + arg1->y; + sp2C.z = arg1->z; + EffectSsKirakira_SpawnDispersed(play, &sp2C, &D_801C0BE0, &D_801C0BEC, &D_801C0BF8, &D_801C0BFC, -50, 11); +} void func_80127DA4(PlayState* play, struct_801F58B0 arg1[], struct_80128388_arg1 arg2[], s32 arg3, Vec3f* arg4, - Vec3f* arg5, u32* arg6); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80127DA4.s") + Vec3f* arg5, u32* arg6) { + struct_801F58B0* phi_s1 = &arg1[1]; + Vec3f spB0; + Vec3f spA4; + f32 f22; + f32 f28; + f32 f24; + f32 f20; + f32 f0; + f32 sp8C = -1.0f; + s32 i; + s16 s0; + s16 s2; + + Math_Vec3f_Copy(&arg1->unk_00, arg4); + Math_Vec3f_Diff(arg5, arg4, &spB0); + arg1->unk_18 = Math_Atan2S_XY(spB0.z, spB0.x); + arg1->unk_1A = Math_Atan2S_XY(sqrtf(SQXZ(spB0)), spB0.y); + i = 1; + arg2++; + + while (i < arg3) { + if (play->actorCtx.flags & ACTORCTX_FLAG_3) { + if (*arg6 & 0x20) { + sp8C = -0.2f; + } else { + sp8C = 0.2f; + } + + *arg6 += 0x16; + if (!(*arg6 & 1)) { + Player_DrawStrayFairyParticles(play, &phi_s1->unk_00); + } + } + Math_Vec3f_Sum(&phi_s1->unk_00, &phi_s1->unk_0C, &phi_s1->unk_00); + + f0 = Math_Vec3f_DistXYZAndStoreDiff(&arg1->unk_00, &phi_s1->unk_00, &spB0); + f28 = f0 - arg2->unk_00; + if (f0 == 0.0f) { + spB0.x = 0.0f; + spB0.y = arg2->unk_00; + spB0.z = 0.0f; + } + f20 = sqrtf(SQXZ(spB0)); + + if (f20 > 4.0f) { + phi_s1->unk_18 = Math_Atan2S_XY(spB0.z, spB0.x); + s2 = phi_s1->unk_18 - arg1->unk_18; -void func_80128388(struct_801F58B0 arg0[], struct_80128388_arg1 arg1[], s32 arg2, Mtx** arg3); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80128388.s") + if (ABS_ALT(s2) > 0x4000) { + phi_s1->unk_18 = (s16)(phi_s1->unk_18 + 0x8000); + f20 = -f20; + } + } + + phi_s1->unk_1A = Math_Atan2S_XY(f20, spB0.y); + + s2 = phi_s1->unk_18 - arg1->unk_18; + s2 = CLAMP(s2, -arg2->unk_18, arg2->unk_18); + phi_s1->unk_18 = arg1->unk_18 + s2; + + s0 = phi_s1->unk_1A - arg1->unk_1A; + s0 = CLAMP(s0, -arg2->unk_1A, arg2->unk_1A); + phi_s1->unk_1A = arg1->unk_1A + s0; + + f20 = Math_CosS(phi_s1->unk_1A) * arg2->unk_00; + spA4.x = Math_SinS(phi_s1->unk_18) * f20; + spA4.z = Math_CosS(phi_s1->unk_18) * f20; + spA4.y = Math_SinS(phi_s1->unk_1A) * arg2->unk_00; + Math_Vec3f_Sum(&arg1->unk_00, &spA4, &phi_s1->unk_00); + phi_s1->unk_0C.x *= 0.9f; + phi_s1->unk_0C.z *= 0.9f; + + f22 = Math_CosS(s0) * f28; + f24 = Math_SinS(s0) * f28; + phi_s1->unk_0C.y += sp8C; + + if (play->actorCtx.flags & ACTORCTX_FLAG_3) { + phi_s1->unk_0C.y = CLAMP(phi_s1->unk_0C.y, -0.8f, 0.8f); + } else { + phi_s1->unk_0C.y = phi_s1->unk_0C.y; + f20 = Math_SinS(arg1->unk_1A); + phi_s1->unk_0C.y += (((f22 * Math_CosS(arg1->unk_1A)) + (f24 * f20)) * 0.2f); + phi_s1->unk_0C.y = CLAMP(phi_s1->unk_0C.y, -2.0f, 4.0f); + } + + f20 = (f24 * Math_CosS(arg1->unk_1A)) - (Math_SinS(arg1->unk_1A) * f22); + f22 = Math_CosS(s2) * f20; + f24 = Math_SinS(s2) * f20; + + f20 = Math_SinS(arg1->unk_18); + + phi_s1->unk_0C.x += (((f24 * Math_CosS(arg1->unk_18)) - (f22 * f20)) * 0.1f); + phi_s1->unk_0C.x = CLAMP(phi_s1->unk_0C.x, -4.0f, 4.0f); + + f20 = Math_SinS(arg1->unk_18); + + phi_s1->unk_0C.z += (((f22 * Math_CosS(arg1->unk_18)) + (f24 * f20)) * -0.1f); + phi_s1->unk_0C.z = CLAMP(phi_s1->unk_0C.z, -4.0f, 4.0f); + + arg1++; + phi_s1++; + i++; + arg2++; + } +} + +void func_80128388(struct_801F58B0 arg0[], struct_80128388_arg1 arg1[], s32 arg2, Mtx** arg3) { + struct_801F58B0* phi_s1 = &arg0[1]; + Vec3f sp58; + Vec3s sp50; + s32 i; + + sp58.y = 0.0f; + sp58.z = 0.0f; + sp50.x = 0; + + for (i = 1; i < arg2; i++) { + sp58.x = arg1->unk_00 * 100.0f; + sp50.z = arg1->unk_06 + (s16)(phi_s1->unk_1A - arg0->unk_1A); + sp50.y = arg1->unk_04 + (s16)(phi_s1->unk_18 - arg0->unk_18); + Matrix_TranslateRotateZYX(&sp58, &sp50); + Matrix_ToMtx(*arg3); + (*arg3)++; + arg0++; + phi_s1++; + arg1++; + } +} void Player_DrawGreatFairysMask(PlayState* play, Player* player) { s32 pad; @@ -2331,7 +3237,8 @@ void Player_DrawGreatFairysMask(PlayState* play, Player* player) { gSPSegment(POLY_OPA_DISP++, 0x0B, mtx); Matrix_MultVec3f(&D_801C0C00, &D_801C0C54[1].unk_08); - Math_Vec3f_Lerp(&player->bodyPartsPos[7], &player->bodyPartsPos[0], 0.2f, &D_801C0C54[2].unk_08); + Math_Vec3f_Lerp(&player->bodyPartsPos[PLAYER_BODYPART_HEAD], &player->bodyPartsPos[PLAYER_BODYPART_WAIST], 0.2f, + &D_801C0C54[2].unk_08); for (i = 0; i < ARRAY_COUNT(D_801C0C0C); i++) { Matrix_MultVec3f(iter, &sp84); @@ -2351,8 +3258,598 @@ void Player_DrawGreatFairysMask(PlayState* play, Player* player) { CLOSE_DISPS(play->state.gfxCtx); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80128640.s") +s32 func_80128640(PlayState* play, Player* player, Gfx* dlist) { + s32 temp_v1 = player->skelAnime.animation == &gPlayerAnim_cl_maskoff; + f32 temp_f0; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80128B74.s") + if (temp_v1 || + ((player->currentMask != PLAYER_MASK_NONE) && (player->skelAnime.animation == &gPlayerAnim_cl_setmask) && + (temp_f0 = player->skelAnime.curFrame - 8.0f, (temp_f0 >= 0.0f)) && (temp_f0 < 4.0f)) || + (player->stateFlags2 & PLAYER_STATE2_1000000)) { + s32 mask; + + if (temp_v1) { + mask = player->prevMask; + } else { + mask = player->currentMask; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80128BD0.s") + if (func_80127438(play, player, mask)) { + OPEN_DISPS(play->state.gfxCtx); + + Matrix_Push(); + Matrix_Translate(-323.67f, 412.15f, -969.96f, MTXMODE_APPLY); + Matrix_RotateZYX(-0x32BE, -0x50DE, -0x7717, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_OPA_DISP++, D_801C0B20[mask - 1]); + + Matrix_Pop(); + + CLOSE_DISPS(play->state.gfxCtx); + } + + } else if (player->itemAction == PLAYER_IA_STICK) { + OPEN_DISPS(play->state.gfxCtx); + + Matrix_Push(); + Matrix_Translate(-428.26f, 267.2f, -33.82f, MTXMODE_APPLY); + Matrix_RotateZYX(-0x8000, 0, 0x4000, MTXMODE_APPLY); + Matrix_Scale(1.0f, player->unk_B08[1], 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gDekuStickDL); + + Matrix_Pop(); + + CLOSE_DISPS(play->state.gfxCtx); + } else if (player->leftHandType == PLAYER_MODELTYPE_LH_BOTTLE) { + PlayerBottle bottle = Player_BottleFromIA(player, player->itemAction); + Vec3f* temp_v1_2 = &D_801C0CE8[player->transformation]; + + OPEN_DISPS(play->state.gfxCtx); + + Matrix_Push(); + Matrix_Translate(temp_v1_2->x, temp_v1_2->y, temp_v1_2->z, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + // Note this does not check for PLAYER_BOTTLE_NONE, which would produce an OoB access on sPlayerBottleColors. + // Under normal circunstances it should not be a problem because of the previous + // `player->leftHandType == PLAYER_MODELTYPE_LH_BOTTLE` check + if (bottle != PLAYER_BOTTLE_EMPTY) { + Color_RGB8* bottleColor = &sPlayerBottleColors[bottle]; + + gDPSetEnvColor(POLY_XLU_DISP++, bottleColor->r, bottleColor->g, bottleColor->b, 0); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_000320); + } + + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_0003E0); + + Matrix_Pop(); + + CLOSE_DISPS(play->state.gfxCtx); + } else if (dlist == object_link_zora_DL_00E2A0) { // zora guitar + s16 sp26 = Math_SinS(player->unk_B86[0]) * (ABS_ALT(player->upperLimbRot.x) * ((f32)(IREG(52) + 20)) / 100.0f); + s16 sp24 = Math_SinS(player->unk_B86[1]) * (ABS_ALT(player->upperLimbRot.y) * ((f32)(IREG(53) + 15)) / 100.0f); + + OPEN_DISPS(play->state.gfxCtx); + + Matrix_Push(); + Matrix_RotateXS(sp26, MTXMODE_APPLY); + Matrix_RotateYS(sp24, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_link_zora_DL_00E088); // hand + + Matrix_Pop(); + + CLOSE_DISPS(play->state.gfxCtx); + } else { + return false; + } + + return true; +} + +Vec3f sPlayerFootPos[PLAYER_FORM_MAX] = { + { 200.0f, 300.0f, 0.0f }, // PLAYER_FORM_FIERCE_DEITY + { 200.0f, 200.0f, 0.0f }, // PLAYER_FORM_GORON + { 200.0f, 300.0f, 0.0f }, // PLAYER_FORM_ZORA + { 200.0f, 150.0f, 0.0f }, // PLAYER_FORM_DEKU + { 200.0f, 200.0f, 0.0f }, // PLAYER_FORM_HUMAN +}; + +void Player_SetFeetPos(PlayState* play, Player* player, s32 limbIndex) { + Vec3f* footPos = &sPlayerFootPos[player->transformation]; + + Actor_SetFeetPos(&player->actor, limbIndex, PLAYER_LIMB_LEFT_FOOT, footPos, PLAYER_LIMB_RIGHT_FOOT, footPos); +} + +void Player_PostLimbDrawGameplay(PlayState* play, s32 limbIndex, Gfx** dList1, Gfx** dList2, Vec3s* rot, Actor* actor) { + Player* player = (Player*)actor; + + if (*dList2 != NULL) { + Matrix_MultZero(sPlayerCurBodyPartPos); + } + + if (limbIndex == PLAYER_LIMB_LEFT_HAND) { + Math_Vec3f_Copy(&player->leftHandWorld.pos, sPlayerCurBodyPartPos); + + if ((*dList1 != NULL) && !func_801271B0(play, player, 0) && !func_80128640(play, player, *dList1) && + (player->skelAnime.animation == &gPlayerAnim_pg_punchA)) { + func_80127488(play, player, D_801C0778[(s32)player->skelAnime.curFrame]); + } + + if (player->actor.scale.y >= 0.0f) { + Actor* heldActor; + MtxF sp230; + + if (!Player_IsHoldingHookshot(player) && ((heldActor = player->heldActor) != NULL)) { + if ((player->stateFlags3 & PLAYER_STATE3_40) && (player->transformation != PLAYER_FORM_DEKU)) { + static Vec3f D_801C0D60 = { 398.0f, 1419.0f, 244.0f }; + static Vec3f D_801C0D6C = { 420.0f, 1210.0f, 380.0f }; + Vec3s* temp_s1; + Vec3f* var_a0 = &D_801C0D60; + + if (player->transformation == PLAYER_FORM_HUMAN) { + var_a0 = &D_801C0D6C; + } + + Matrix_MultVec3f(var_a0, &heldActor->world.pos); + Matrix_RotateZYX(0x69E8, -0x5708, 0x458E, MTXMODE_APPLY); + + Matrix_Get(&sp230); + temp_s1 = &heldActor->world.rot; + Matrix_MtxFToYXZRot(&sp230, temp_s1, false); + heldActor->shape.rot = *temp_s1; + } else if (player->stateFlags1 & PLAYER_STATE1_800) { + heldActor->world.rot.y = heldActor->shape.rot.y = + player->actor.shape.rot.y + player->leftHandWorld.rot.y; + } + } else { + static f32 sMeleeWeaponLengths[PLAYER_MELEEWEAPON_MAX] = { + 0.0f, // PLAYER_MELEEWEAPON_NONE + 3000.0f, // PLAYER_MELEEWEAPON_SWORD_KOKIRI + 3000.0f, // PLAYER_MELEEWEAPON_SWORD_RAZOR + 4000.0f, // PLAYER_MELEEWEAPON_SWORD_GILDED + 5500.0f, // PLAYER_MELEEWEAPON_SWORD_GREAT_FAIRY + -1.0f, // PLAYER_MELEEWEAPON_STICK + 2500.0f, // PLAYER_MELEEWEAPON_ZORA_FINS + }; + + if ((player->transformation == PLAYER_FORM_FIERCE_DEITY) || + ((player->transformation != PLAYER_FORM_ZORA) && + ((player->itemAction == PLAYER_IA_STICK) || + ((player->meleeWeaponState != 0) && + (player->meleeWeaponAnimation != PLAYER_MWA_GORON_PUNCH_RIGHT) && + (player->meleeWeaponAnimation != PLAYER_MWA_GORON_PUNCH_BUTT))))) { + if (player->itemAction == PLAYER_IA_STICK) { + D_801C0994->x = player->unk_B08[1] * 5000.0f; + } else { + D_801C0994->x = sMeleeWeaponLengths[Player_GetMeleeWeaponHeld(player)]; + } + func_80126B8C(play, player); + } + + Matrix_Get(&player->mf_CC4); + Matrix_MtxFToYXZRot(&player->mf_CC4, &player->leftHandWorld.rot, false); + } + } + } else if (limbIndex == PLAYER_LIMB_RIGHT_HAND) { + Actor* heldActor = player->heldActor; + s32 pad; + + if (*dList1 != NULL) { + if (player->rightHandType == PLAYER_MODELTYPE_RH_BOW) { + static Gfx* D_801C0D94 = object_link_child_DL_017818; + static Vec3f D_801C0D98 = { -35.0f, -395.0f, 0.0f }; + // Unused + static s32 D_801C0DA4 = 0; + + OPEN_DISPS(play->state.gfxCtx); + + Matrix_Push(); + Matrix_Translate(D_801C0D98.x, D_801C0D98.y, D_801C0D98.z, MTXMODE_APPLY); + if ((player->stateFlags3 & PLAYER_STATE3_40) && (player->unk_B28 >= 0) && (player->unk_ACC < 0xB)) { + Vec3f sp20C; + f32 temp_fv0; + s32 pad2; + + Matrix_MultZero(&sp20C); + temp_fv0 = Math_Vec3f_DistXYZ(sPlayerCurBodyPartPos, &sp20C); + player->unk_B08[0] = temp_fv0 - 3.0f; + if (temp_fv0 < 3.0f) { + player->unk_B08[0] = 0.0f; + } else { + player->unk_B08[0] *= 1.6f; + if (player->unk_B08[0] > 1.0f) { + player->unk_B08[0] = 1.0f; + } + } + player->unk_B08[1] = -0.5f; + } + Matrix_Scale(1.0f, player->unk_B08[0], 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_801C0D94); + + Matrix_Pop(); + + CLOSE_DISPS(play->state.gfxCtx); + } else if (player->skelAnime.animation == &gPlayerAnim_pg_punchB) { + func_80127488(play, player, D_801C07AC[(s32)player->skelAnime.curFrame]); + } else { + func_801271B0(play, player, 1); + } + } + + if (player->actor.scale.y >= 0.0f) { + if (player->rightHandType == PLAYER_MODELTYPE_RH_FF) { + Matrix_Get(&player->shieldMf); + } else if (player->rightHandType == PLAYER_MODELTYPE_RH_SHIELD) { + // Coordinates of the shield quad collider vertices, in the right hand limb's own model space. + static Vec3f sRightHandLimbModelShieldQuadVertices[4] = { + { -4500.0f, -3000.0f, -600.0f }, + { 1500.0f, -3000.0f, -600.0f }, + { -4500.0f, 3000.0f, -600.0f }, + { 1500.0f, 3000.0f, -600.0f }, + }; + + Matrix_Get(&player->shieldMf); + Player_UpdateShieldCollider(play, player, &player->shieldQuad, sRightHandLimbModelShieldQuadVertices); + } else if (player->rightHandType == PLAYER_MODELTYPE_RH_HOOKSHOT) { + static Vec3f D_801C0DD8 = { 50.0f, 800.0f, 0.0f }; + + Matrix_MultVec3f(&D_801C0DD8, &player->rightHandWorld.pos); + + if (heldActor != NULL) { + static Vec3f D_801C0DE4 = { 50.0f, 850.0f, 0.0f }; + MtxF sp1BC; + + Matrix_MultVec3f(&D_801C0DE4, &heldActor->world.pos); + Matrix_RotateZYX(0, -0x4000, -0x4000, MTXMODE_APPLY); + Matrix_Get(&sp1BC); + Matrix_MtxFToYXZRot(&sp1BC, &heldActor->world.rot, false); + heldActor->shape.rot = heldActor->world.rot; + if (func_800B7128(player)) { + Matrix_Translate(500.0f, 300.0f, 0.0f, MTXMODE_APPLY); + Player_DrawHookshotReticle(play, player, 77600.0f); + } + } + } else if (player->meleeWeaponState != 0) { + if (player->meleeWeaponAnimation == PLAYER_MWA_GORON_PUNCH_RIGHT) { + func_80126B8C(play, player); + } + } + if ((player->getItemDrawIdPlusOne != (GID_NONE + 1)) || + ((func_800B7118(player) == 0) && (heldActor != NULL))) { + if (!(player->stateFlags1 & PLAYER_STATE1_400) && (player->getItemDrawIdPlusOne != (GID_NONE + 1)) && + (player->exchangeItemId != PLAYER_IA_NONE)) { + Math_Vec3f_Copy(&sPlayerGetItemRefPos, &player->leftHandWorld.pos); + } else { + sPlayerGetItemRefPos.x = + (player->bodyPartsPos[PLAYER_BODYPART_RIGHT_HAND].x + player->leftHandWorld.pos.x) * 0.5f; + sPlayerGetItemRefPos.y = + (player->bodyPartsPos[PLAYER_BODYPART_RIGHT_HAND].y + player->leftHandWorld.pos.y) * 0.5f; + sPlayerGetItemRefPos.z = + (player->bodyPartsPos[PLAYER_BODYPART_RIGHT_HAND].z + player->leftHandWorld.pos.z) * 0.5f; + } + + if (player->getItemDrawIdPlusOne == (GID_NONE + 1)) { + Math_Vec3f_Copy(&heldActor->world.pos, &sPlayerGetItemRefPos); + } + } + } + } else if (limbIndex == PLAYER_LIMB_LEFT_FOREARM) { + func_80126BD0(play, player, 0); + } else if (limbIndex == PLAYER_LIMB_RIGHT_FOREARM) { + func_80126BD0(play, player, 1); + } else if (limbIndex == PLAYER_LIMB_TORSO) { + if (player->transformation == PLAYER_FORM_GORON) { + s32 temp_a0 = player->skelAnime.animation == &gPlayerAnim_pg_gakkistart; + s32 temp_v1_3 = player->skelAnime.animation == &gPlayerAnim_pg_gakkiwait; + + if ((temp_a0 || temp_v1_3 || (player->skelAnime.animation == &gPlayerAnim_pg_gakkiplay))) { + static Gfx* D_801C0DF0[] = { + object_link_goron_DL_010590, object_link_goron_DL_010368, object_link_goron_DL_010140, + object_link_goron_DL_00FF18, object_link_goron_DL_00FCF0, + }; + Vec3f sp178[ARRAY_COUNT(D_801C0DF0)]; + s32 i; + + OPEN_DISPS(play->state.gfxCtx); + + if (temp_v1_3) { + f32* var_v0 = player->unk_B10; + + for (i = 0; i < ARRAY_COUNT(sp178); i++, var_v0++) { + func_80124618(D_801C0510, *var_v0, &sp178[i]); + } + } else { + if (temp_a0 != 0) { + func_8012536C(); + func_80124618(D_801C0428, player->skelAnime.curFrame, &player->unk_AF0[1]); + } + + for (i = 0; i < ARRAY_COUNT(sp178); i++) { + Math_Vec3f_Copy(&sp178[i], &player->unk_AF0[1]); + } + } + Matrix_Push(); + Matrix_Scale(player->unk_AF0[1].x, player->unk_AF0[1].y, player->unk_AF0[1].z, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_OPA_DISP++, object_link_goron_DL_00FC18); + + Matrix_Pop(); + + for (i = 0; i < ARRAY_COUNT(sp178); i++) { + Matrix_Push(); + Matrix_Scale(sp178[i].x, sp178[i].y, sp178[i].z, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_OPA_DISP++, D_801C0DF0[i]); + Matrix_Pop(); + } + + CLOSE_DISPS(play->state.gfxCtx); + } + } + } else if (limbIndex == PLAYER_LIMB_HEAD) { + //! FAKE + if (((*dList1 != NULL) && ((((void)0, player->currentMask)) != (((void)0, PLAYER_MASK_NONE)))) && + (((player->transformation == PLAYER_FORM_HUMAN) && + ((player->skelAnime.animation != &gPlayerAnim_cl_setmask) || (player->skelAnime.curFrame >= 12.0f))) || + ((((player->transformation != PLAYER_FORM_HUMAN) && (player->currentMask >= PLAYER_MASK_FIERCE_DEITY)) && + ((player->transformation + PLAYER_MASK_FIERCE_DEITY) != player->currentMask)) && + (player->skelAnime.curFrame >= 10.0f)))) { + if (func_80127438(play, player, player->currentMask)) { + s32 maskMinusOne = ((void)0, player->currentMask) - 1; + + OPEN_DISPS(play->state.gfxCtx); + + if (((void)0, player->currentMask) == PLAYER_MASK_COUPLE) { + Player_DrawCouplesMask(play, player); + } else if (((void)0, player->currentMask) == PLAYER_MASK_CIRCUS_LEADER) { + Player_DrawCircusLeadersMask(play, player); + } else if (((void)0, player->currentMask) == PLAYER_MASK_BLAST) { + Player_DrawBlastMask(play, player); + } else if (((void)0, player->currentMask) == PLAYER_MASK_BUNNY) { + Player_DrawBunnyHood(play); + } else if (((void)0, player->currentMask) == PLAYER_MASK_GREAT_FAIRY) { + Player_DrawGreatFairysMask(play, player); + } else if (((void)0, player->currentMask) >= PLAYER_MASK_FIERCE_DEITY) { + static Vec2f D_801C0E04[PLAYER_FORM_MAX] = { + { 140.0f, -130.0f }, // PLAYER_FORM_FIERCE_DEITY + { 0.0f, -200.0f }, // PLAYER_FORM_GORON + { -160.0f, 0.0f }, // PLAYER_FORM_ZORA + { 220.0f, -200.0f }, // PLAYER_FORM_DEKU + { 0.0f, 0.0f }, // PLAYER_FORM_HUMAN + }; + Vec2f* temp_s0_4 = &D_801C0E04[player->transformation]; + + Matrix_Push(); + Matrix_Translate(temp_s0_4->x, temp_s0_4->z, 0.0f, MTXMODE_APPLY); + Matrix_Scale(1.0f, 1.0f - player->unk_B10[3], 1.0f - player->unk_B10[2], MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + Matrix_Pop(); + + if (((player->skelAnime.animation == &gPlayerAnim_cl_setmask) && + (player->skelAnime.curFrame >= 51.0f)) || + (player->skelAnime.animation == &gPlayerAnim_cl_setmaskend)) { + maskMinusOne += 4; + } + } + + gSPDisplayList(POLY_OPA_DISP++, D_801C0B20[maskMinusOne]); + + CLOSE_DISPS(play->state.gfxCtx); + } + } else if (player->transformation == PLAYER_FORM_DEKU) { + if (player->skelAnime.animation == &gPlayerAnim_pn_gurd) { + OPEN_DISPS(play->state.gfxCtx); + + func_80124618(D_801C0410, player->skelAnime.curFrame, player->unk_AF0); + Matrix_Push(); + + Matrix_Scale(player->unk_AF0[0].x, player->unk_AF0[0].y, player->unk_AF0[0].z, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_link_nuts_DL_00A348); + + Matrix_Pop(); + + CLOSE_DISPS(play->state.gfxCtx); + } else { + s32 temp_v1_5 = player->skelAnime.animation == &gPlayerAnim_pn_gakkistart; + + if (temp_v1_5 || (player->skelAnime.animation == &gPlayerAnim_pn_gakkiplay) || + (player->skelAnime.animation == &gPlayerAnim_dl_kokeru)) { + static Gfx* D_801C0E2C[] = { + object_link_nuts_DL_007A28, object_link_nuts_DL_0077D0, object_link_nuts_DL_007548, + object_link_nuts_DL_007900, object_link_nuts_DL_0076A0, + }; + Vec3f spF0[ARRAY_COUNT(D_801C0E2C)]; + s32 i; + f32* temp; + + OPEN_DISPS(play->state.gfxCtx); + + if (temp_v1_5) { + Vec3f spD4; + + func_80124618(D_801C0340, player->skelAnime.curFrame, &spD4); + player->arr_AF0[0] = spD4.x; + func_80124618(D_801C0368, player->skelAnime.curFrame, spF0); + + for (i = 0; i < ARRAY_COUNT(spF0) - 1; i++) { + Math_Vec3f_Copy(&spF0[i + 1], spF0); + } + + temp = &player->arr_AF0[1]; + for (i = 0; i < ARRAY_COUNT(spF0); i++) { + *temp = spF0[0].x; + temp++; + } + } else { + temp = &player->arr_AF0[1]; + for (i = 0; i < ARRAY_COUNT(spF0); i++) { + spF0[i].x = *temp; + spF0[i].y = *temp; + spF0[i].z = *temp; + temp++; + } + } + + Matrix_Push(); + Matrix_Scale(player->arr_AF0[0], player->arr_AF0[0], player->arr_AF0[0], MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_link_nuts_DL_007390); + + Matrix_Pop(); + + for (i = 0; i < ARRAY_COUNT(spF0); i++) { + Matrix_Push(); + + Matrix_Scale(spF0[i].x, spF0[i].y, spF0[i].z, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + //! FAKE (yes, all of them are required) + // https://decomp.me/scratch/AdU3G + if (1) {} + if (1) {} + if (1) {} + if (1) {} + if (1) {} + if (1) {} + gSPDisplayList(POLY_OPA_DISP++, D_801C0E2C[i]); + + Matrix_Pop(); + } + + CLOSE_DISPS(play->state.gfxCtx); + } + } + } + + if ((player->stateFlags1 & (PLAYER_STATE1_2 | PLAYER_STATE1_100)) && (player->unk_AE8 != 0)) { + static Vec3f D_801C0E40[PLAYER_FORM_MAX] = { + { 0.0f, 0.0f, 0.0f }, // PLAYER_FORM_FIERCE_DEITY + { -578.3f, -1100.9f, 0.0f }, // PLAYER_FORM_GORON + { -189.5f, -594.87f, 0.0f }, // PLAYER_FORM_ZORA + { -570.0f, -812.0f, 0.0f }, // PLAYER_FORM_DEKU + { -230.0f, -520.0f, 0.0f }, // PLAYER_FORM_HUMAN + }; + Vec3f* temp_s0_7 = &D_801C0E40[player->transformation]; + + OPEN_DISPS(play->state.gfxCtx); + + Matrix_Push(); + AnimatedMat_DrawXlu(play, Lib_SegmentedToVirtual(gameplay_keep_Matanimheader_054F18)); + Matrix_Translate(temp_s0_7->x, temp_s0_7->y, 0.0f, MTXMODE_APPLY); + if (player->transformation == PLAYER_FORM_ZORA) { + Matrix_Scale(0.7f, 0.7f, 0.7f, MTXMODE_APPLY); + } + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 255, (u8)player->unk_AE8); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_054C90); + + Matrix_Pop(); + + CLOSE_DISPS(play->state.gfxCtx); + } + if (player->actor.scale.y >= 0.0f) { + static Vec3f sPlayerFocusHeadLimbModelPos = { 1100.0f, -700.0f, 0.0f }; + static Vec3f D_801C0E88 = { 1600.0f, -1700.0f, -70.0f }; // unused + Actor* spA8 = NULL; + + if (player->transformation != PLAYER_FORM_DEKU) { + Matrix_MultVec3f(&sPlayerFocusHeadLimbModelPos, &player->actor.focus.pos); + } else { + static Vec3f D_801C0E94 = { 1800.0f, -300.0f, 0.0f }; + + Matrix_MultVec3f(&sPlayerFocusHeadLimbModelPos, &player->actor.focus.pos); + Matrix_MultVec3f(&D_801C0E94, sPlayerCurBodyPartPos); + if ((player->skelAnime.animation == &gPlayerAnim_pn_drinkend) || + (player->unk_284.animation == &gPlayerAnim_pn_tamahaki) || + ((player->stateFlags3 & PLAYER_STATE3_40) && ((spA8 = player->heldActor) != NULL))) { + if (spA8 != NULL) { + static Vec3f D_801C0EA0 = { 1300.0f, -400.0f, 0.0f }; + MtxF sp68; + + Matrix_Push(); + Matrix_MultVec3f(&D_801C0EA0, &spA8->world.pos); + Matrix_RotateZYX(0, 0x4000, 0, MTXMODE_APPLY); + Matrix_Get(&sp68); + Matrix_MtxFToYXZRot(&sp68, &spA8->world.rot, false); + spA8->shape.rot = spA8->world.rot; + Matrix_Pop(); + } + } + } + } + } else if ((limbIndex == PLAYER_LIMB_HAT) && (player->stateFlags3 & PLAYER_STATE3_100000)) { + Vec3f sp5C; + Vec3f sp50; + + Matrix_MultVecX(3000.0f, &sp5C); + Matrix_MultVecX(2300.0f, &sp50); + if (func_80126440(play, NULL, player->meleeWeaponInfo, &sp5C, &sp50)) { + EffectBlure_AddVertex(Effect_GetByIndex(player->meleeWeaponEffectIndex[0]), &player->meleeWeaponInfo[0].tip, + &player->meleeWeaponInfo[0].base); + } + } else if (limbIndex == PLAYER_LIMB_RIGHT_SHIN) { + if (player->meleeWeaponState != 0) { + if ((player->meleeWeaponAnimation == PLAYER_MWA_ZORA_PUNCH_KICK) || + (player->meleeWeaponAnimation == PLAYER_MWA_ZORA_JUMPKICK_START) || + (player->meleeWeaponAnimation == PLAYER_MWA_ZORA_JUMPKICK_FINISH)) { + func_8012669C(play, player, D_801C0A48, D_801C0A24); + } + } + } else if (limbIndex == PLAYER_LIMB_WAIST) { + if (player->meleeWeaponState != 0) { + if (player->meleeWeaponAnimation == PLAYER_MWA_GORON_PUNCH_BUTT) { + Math_Vec3f_Copy(&player->unk_AF0[1], &player->meleeWeaponInfo[0].base); + func_8012669C(play, player, D_801C0A90, D_801C0A6C); + } + } + } else if (limbIndex == PLAYER_LIMB_SHEATH) { + if ((*dList1 != NULL) && (player->transformation == PLAYER_FORM_HUMAN) && + (player->currentShield != PLAYER_SHIELD_NONE) && + ((player->sheathType == PLAYER_MODELTYPE_SHEATH_14) || + (player->sheathType == PLAYER_MODELTYPE_SHEATH_15))) { + OPEN_DISPS(play->state.gfxCtx); + + gSPDisplayList(POLY_OPA_DISP++, gPlayerShields[2 * ((player->currentShield - 1) ^ 0)]); + + CLOSE_DISPS(play->state.gfxCtx); + } + + if (player->actor.scale.y >= 0.0f) { + if ((player->rightHandType != PLAYER_MODELTYPE_RH_SHIELD) && + (player->rightHandType != PLAYER_MODELTYPE_RH_FF)) { + static Vec3f sSheathLimbModelShieldOnBackPos = { 630.0f, 100.0f, -30.0f }; + static Vec3s sSheathLimbModelShieldOnBackZyxRot = { 0, 0, 0x7FFF }; + + Matrix_TranslateRotateZYX(&sSheathLimbModelShieldOnBackPos, &sSheathLimbModelShieldOnBackZyxRot); + Matrix_Get(&player->shieldMf); + } + } + } else if (player->actor.scale.y >= 0.0f) { + Player_SetFeetPos(play, player, limbIndex); + } + + func_8012536C(); +} diff --git a/src/code/z_skelanime.c b/src/code/z_skelanime.c index cf7f95078..085cb4de2 100644 --- a/src/code/z_skelanime.c +++ b/src/code/z_skelanime.c @@ -1226,7 +1226,7 @@ void SkelAnime_InitPlayer(PlayState* play, SkelAnime* skelAnime, FlexSkeletonHea allocSize = sizeof(Vec3s) * limbCount; if (flags & 8) { - allocSize += 2; + allocSize += sizeof(u16); } if (jointTableBuffer == NULL) { |
