16053 lines
591 KiB
C
16053 lines
591 KiB
C
/*
|
|
* File: z_player.c
|
|
* Overlay: ovl_player_actor
|
|
* Description: Link
|
|
*/
|
|
|
|
#include <libultraship/libultra.h>
|
|
#include "global.h"
|
|
|
|
#include "overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.h"
|
|
#include "overlays/actors/ovl_Door_Shutter/z_door_shutter.h"
|
|
#include "overlays/actors/ovl_En_Boom/z_en_boom.h"
|
|
#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h"
|
|
#include "overlays/actors/ovl_En_Box/z_en_box.h"
|
|
#include "overlays/actors/ovl_En_Door/z_en_door.h"
|
|
#include "overlays/actors/ovl_En_Elf/z_en_elf.h"
|
|
#include "overlays/actors/ovl_En_Fish/z_en_fish.h"
|
|
#include "overlays/actors/ovl_En_Horse/z_en_horse.h"
|
|
#include "overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.h"
|
|
#include "overlays/misc/ovl_kaleido_scope/z_kaleido_scope.h"
|
|
#include "objects/gameplay_keep/gameplay_keep.h"
|
|
#include "objects/object_link_child/object_link_child.h"
|
|
#include "textures/icon_item_24_static/icon_item_24_static.h"
|
|
#include <soh/Enhancements/custom-message/CustomMessageTypes.h>
|
|
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
|
|
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
|
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
|
#include <overlays/actors/ovl_En_Partner/z_en_partner.h>
|
|
#include "soh/Enhancements/enhancementTypes.h"
|
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
|
#include "soh/Enhancements/randomizer/randomizer_grotto.h"
|
|
#include "soh/frame_interpolation.h"
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
// Some player animations are played at this reduced speed, for reasons yet unclear.
|
|
// This is called "adjusted" for now.
|
|
#define PLAYER_ANIM_ADJUSTED_SPEED (2.0f / 3.0f)
|
|
|
|
typedef enum {
|
|
/* 0x00 */ KNOB_ANIM_ADULT_L,
|
|
/* 0x01 */ KNOB_ANIM_CHILD_L,
|
|
/* 0x02 */ KNOB_ANIM_ADULT_R,
|
|
/* 0x03 */ KNOB_ANIM_CHILD_R
|
|
} KnobDoorAnim;
|
|
|
|
typedef struct {
|
|
/* 0x00 */ u8 itemId;
|
|
/* 0x02 */ s16 actorId;
|
|
} ExplosiveInfo; // size = 0x04
|
|
|
|
typedef struct {
|
|
/* 0x00 */ s16 actorId;
|
|
/* 0x02 */ u8 itemId;
|
|
/* 0x03 */ u8 itemAction;
|
|
/* 0x04 */ u8 textId;
|
|
} BottleCatchInfo; // size = 0x06
|
|
|
|
typedef struct {
|
|
/* 0x00 */ s16 actorId;
|
|
/* 0x02 */ s16 actorParams;
|
|
} BottleDropInfo; // size = 0x04
|
|
|
|
typedef struct {
|
|
/* 0x00 */ s8 damage;
|
|
/* 0x01 */ u8 rumbleStrength;
|
|
/* 0x02 */ u8 rumbleDuration;
|
|
/* 0x03 */ u8 rumbleDecreaseRate;
|
|
/* 0x04 */ u16 sfxId;
|
|
} FallImpactInfo; // size = 0x06
|
|
|
|
typedef struct {
|
|
/* 0x00 */ Vec3f pos;
|
|
/* 0x0C */ s16 yaw;
|
|
} SpecialRespawnInfo; // size = 0x10
|
|
|
|
typedef enum {
|
|
/* 1 */ ANIMSFX_TYPE_1 = 1,
|
|
/* 2 */ ANIMSFX_TYPE_2,
|
|
/* 3 */ ANIMSFX_TYPE_3,
|
|
/* 4 */ ANIMSFX_TYPE_4,
|
|
/* 5 */ ANIMSFX_TYPE_5,
|
|
/* 6 */ ANIMSFX_TYPE_6,
|
|
/* 7 */ ANIMSFX_TYPE_7,
|
|
/* 8 */ ANIMSFX_TYPE_8,
|
|
/* 9 */ ANIMSFX_TYPE_9
|
|
} AnimSfxType;
|
|
|
|
#define ANIMSFX_SHIFT_TYPE(type) ((type) << 11)
|
|
|
|
#define ANIMSFX_DATA(type, frame) ((ANIMSFX_SHIFT_TYPE(type) | ((frame)&0x7FF)))
|
|
|
|
#define ANIMSFX_GET_TYPE(data) ((data)&0x7800)
|
|
#define ANIMSFX_GET_FRAME(data) ((data)&0x7FF)
|
|
|
|
typedef struct {
|
|
/* 0x00 */ u16 sfxId;
|
|
/* 0x02 */ s16 data;
|
|
} AnimSfxEntry; // size = 0x04
|
|
|
|
typedef struct {
|
|
/* 0x00 */ u16 unk_00;
|
|
/* 0x02 */ s16 unk_02;
|
|
} struct_808551A4; // size = 0x04
|
|
|
|
typedef struct {
|
|
/* 0x00 */ LinkAnimationHeader* anim;
|
|
/* 0x04 */ u8 changeFrame;
|
|
} ItemChangeInfo; // size = 0x08
|
|
|
|
typedef struct {
|
|
/* 0x00 */ LinkAnimationHeader* unk_00;
|
|
/* 0x04 */ LinkAnimationHeader* unk_04;
|
|
/* 0x08 */ u8 unk_08;
|
|
/* 0x09 */ u8 unk_09;
|
|
} struct_80854554; // size = 0x0C
|
|
|
|
typedef struct {
|
|
/* 0x00 */ LinkAnimationHeader* unk_00;
|
|
/* 0x04 */ LinkAnimationHeader* unk_04;
|
|
/* 0x08 */ LinkAnimationHeader* unk_08;
|
|
/* 0x0C */ u8 unk_0C;
|
|
/* 0x0D */ u8 unk_0D;
|
|
} struct_80854190; // size = 0x10
|
|
|
|
typedef struct {
|
|
/* 0x00 */ LinkAnimationHeader* anim;
|
|
/* 0x04 */ f32 unk_04;
|
|
/* 0x04 */ f32 unk_08;
|
|
} struct_80854578; // size = 0x0C
|
|
|
|
typedef struct {
|
|
/* 0x00 */ s8 type;
|
|
/* 0x04 */ union {
|
|
void* ptr;
|
|
void (*func)(PlayState*, Player*, CsCmdActorAction*);
|
|
};
|
|
} struct_80854B18; // size = 0x08
|
|
|
|
void Player_InitItemAction(PlayState* play, Player* this, s8 itemAction);
|
|
|
|
void Player_InitDefaultIA(PlayState* play, Player* this);
|
|
void Player_InitHammerIA(PlayState* play, Player* this);
|
|
void Player_InitBowOrSlingshotIA(PlayState* play, Player* this);
|
|
void Player_InitDekuStickIA(PlayState* play, Player* this);
|
|
void Player_InitExplosiveIA(PlayState* play, Player* this);
|
|
void Player_InitHookshotIA(PlayState* play, Player* this);
|
|
void Player_InitBoomerangIA(PlayState* play, Player* this);
|
|
|
|
s32 Player_UpperAction_ChangeHeldItem(Player* this, PlayState* play);
|
|
s32 func_8083485C(Player* this, PlayState* play);
|
|
s32 Player_UpperAction_Sword(Player* this, PlayState* play);
|
|
s32 func_80834B5C(Player* this, PlayState* play);
|
|
s32 func_80834C74(Player* this, PlayState* play);
|
|
s32 func_8083501C(Player* this, PlayState* play);
|
|
s32 func_808351D4(Player* this, PlayState* play); // Arrow nocked
|
|
s32 func_808353D8(Player* this, PlayState* play); // Aiming in first person
|
|
s32 func_80835588(Player* this, PlayState* play);
|
|
s32 Player_UpperAction_CarryActor(Player* this, PlayState* play);
|
|
s32 func_80835800(Player* this, PlayState* play);
|
|
s32 func_80835884(Player* this, PlayState* play); // Start aiming boomerang
|
|
s32 func_808358F0(Player* this, PlayState* play); // Aim boomerang
|
|
s32 func_808359FC(Player* this, PlayState* play); // Throw boomerang
|
|
s32 spawn_boomerang_ivan(EnPartner* this, PlayState* play); // Throw boomerang Ivan
|
|
s32 func_80835B60(Player* this, PlayState* play); // Boomerang active
|
|
s32 func_80835C08(Player* this, PlayState* play);
|
|
|
|
void Player_UseItem(PlayState* play, Player* this, s32 item);
|
|
void func_80839F90(Player* this, PlayState* play);
|
|
s32 func_8083C61C(PlayState* play, Player* this);
|
|
void func_8083CA20(PlayState* play, Player* this);
|
|
void func_8083CA54(PlayState* play, Player* this);
|
|
void func_8083CA9C(PlayState* play, Player* this);
|
|
void Player_SetPendingFlag(Player* this, PlayState* play);
|
|
void func_80846648(PlayState* play, Player* this);
|
|
void func_80846660(PlayState* play, Player* this);
|
|
void func_808467D4(PlayState* play, Player* this);
|
|
void func_808468A8(PlayState* play, Player* this);
|
|
void func_808468E8(PlayState* play, Player* this);
|
|
void func_80846978(PlayState* play, Player* this);
|
|
void func_808469BC(PlayState* play, Player* this);
|
|
void func_80846A68(PlayState* play, Player* this);
|
|
void Player_UpdateCommon(Player* this, PlayState* play, Input* input);
|
|
s32 func_8084FCAC(Player* this, PlayState* play);
|
|
void func_8084FF7C(Player* this);
|
|
void Player_UpdateBunnyEars(Player* this);
|
|
void func_80851008(PlayState* play, Player* this, void* anim);
|
|
void func_80851030(PlayState* play, Player* this, void* anim);
|
|
void func_80851050(PlayState* play, Player* this, void* anim);
|
|
void func_80851094(PlayState* play, Player* this, void* anim);
|
|
void func_808510B4(PlayState* play, Player* this, void* anim);
|
|
void func_808510D4(PlayState* play, Player* this, void* anim);
|
|
void func_808510F4(PlayState* play, Player* this, void* anim);
|
|
void func_80851114(PlayState* play, Player* this, void* anim);
|
|
void func_80851134(PlayState* play, Player* this, void* anim);
|
|
void func_80851154(PlayState* play, Player* this, void* anim);
|
|
void func_80851174(PlayState* play, Player* this, void* anim);
|
|
void func_80851194(PlayState* play, Player* this, void* anim);
|
|
void func_808511B4(PlayState* play, Player* this, void* anim);
|
|
void func_808511D4(PlayState* play, Player* this, void* anim);
|
|
void func_808511FC(PlayState* play, Player* this, void* anim);
|
|
void func_80851248(PlayState* play, Player* this, void* anim);
|
|
void func_80851294(PlayState* play, Player* this, void* anim);
|
|
void func_808512E0(PlayState* play, Player* this, void* arg2);
|
|
void func_80851368(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_808513BC(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_808514C0(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_8085157C(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_808515A4(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851688(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851750(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851788(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851828(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_808518DC(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_8085190C(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851998(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_808519C0(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_808519EC(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851A50(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851B90(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851BE8(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851CA4(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851D2C(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851D80(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851DEC(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851E28(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851E64(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851E90(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851ECC(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851F84(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80851FB0(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852048(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852080(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852174(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_808521B8(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_808521F4(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852234(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_8085225C(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852280(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852358(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852388(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852298(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852328(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852480(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852450(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_808524B0(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_808524D0(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852514(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852544(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852554(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852564(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_808525C0(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852608(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852648(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_808526EC(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_8085283C(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_808528C8(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852944(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_808529D0(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
void func_80852C50(PlayState* play, Player* this, CsCmdActorAction* arg2);
|
|
int Player_IsDroppingFish(PlayState* play);
|
|
s32 Player_StartFishing(PlayState* play);
|
|
s32 func_80852F38(PlayState* play, Player* this);
|
|
s32 Player_TryCsAction(PlayState* play, Actor* actor, s32 csAction);
|
|
void func_80853080(Player* this, PlayState* play);
|
|
s32 Player_InflictDamage(PlayState* play, s32 damage);
|
|
s32 Player_InflictDamageModified(PlayState* play, s32 damage, u8 modified);
|
|
void Player_StartTalking(PlayState* play, Actor* actor);
|
|
|
|
void Player_Action_80840450(Player* this, PlayState* play);
|
|
void Player_Action_808407CC(Player* this, PlayState* play);
|
|
void Player_Action_80840BC8(Player* this, PlayState* play);
|
|
void Player_Action_80840DE4(Player* this, PlayState* play);
|
|
void Player_Action_808414F8(Player* this, PlayState* play);
|
|
void Player_Action_8084170C(Player* this, PlayState* play);
|
|
void Player_Action_808417FC(Player* this, PlayState* play);
|
|
void Player_Action_8084193C(Player* this, PlayState* play);
|
|
void Player_Action_80841BA8(Player* this, PlayState* play);
|
|
void Player_Action_80842180(Player* this, PlayState* play);
|
|
void Player_Action_8084227C(Player* this, PlayState* play);
|
|
void Player_Action_8084279C(Player* this, PlayState* play);
|
|
void Player_Action_808423EC(Player* this, PlayState* play);
|
|
void Player_Action_8084251C(Player* this, PlayState* play);
|
|
void Player_Action_80843188(Player* this, PlayState* play);
|
|
void Player_Action_808435C4(Player* this, PlayState* play);
|
|
void Player_Action_8084370C(Player* this, PlayState* play);
|
|
void Player_Action_8084377C(Player* this, PlayState* play);
|
|
void Player_Action_80843954(Player* this, PlayState* play);
|
|
void Player_Action_80843A38(Player* this, PlayState* play);
|
|
void Player_Action_80843CEC(Player* this, PlayState* play);
|
|
void Player_Action_8084411C(Player* this, PlayState* play);
|
|
void Player_Action_80844708(Player* this, PlayState* play);
|
|
void Player_Action_80844A44(Player* this, PlayState* play);
|
|
void Player_Action_80844AF4(Player* this, PlayState* play);
|
|
void Player_Action_80844E68(Player* this, PlayState* play);
|
|
void Player_Action_80845000(Player* this, PlayState* play);
|
|
void Player_Action_80845308(Player* this, PlayState* play);
|
|
void Player_Action_80845668(Player* this, PlayState* play);
|
|
void Player_Action_808458D0(Player* this, PlayState* play);
|
|
void Player_Action_80845CA4(Player* this, PlayState* play);
|
|
void Player_Action_80845EF8(Player* this, PlayState* play);
|
|
void Player_Action_80846050(Player* this, PlayState* play);
|
|
void Player_Action_80846120(Player* this, PlayState* play);
|
|
void Player_Action_80846260(Player* this, PlayState* play);
|
|
void Player_Action_80846358(Player* this, PlayState* play);
|
|
void Player_Action_80846408(Player* this, PlayState* play);
|
|
void Player_Action_808464B0(Player* this, PlayState* play);
|
|
void Player_Action_80846578(Player* this, PlayState* play);
|
|
void Player_Action_8084B1D8(Player* this, PlayState* play);
|
|
void Player_Action_8084B530(Player* this, PlayState* play);
|
|
void Player_Action_8084B78C(Player* this, PlayState* play);
|
|
void Player_Action_8084B898(Player* this, PlayState* play);
|
|
void Player_Action_8084B9E4(Player* this, PlayState* play);
|
|
void Player_Action_8084BBE4(Player* this, PlayState* play);
|
|
void Player_Action_8084BDFC(Player* this, PlayState* play);
|
|
void Player_Action_8084BF1C(Player* this, PlayState* play);
|
|
void Player_Action_8084C5F8(Player* this, PlayState* play);
|
|
void Player_Action_8084C760(Player* this, PlayState* play);
|
|
void Player_Action_8084C81C(Player* this, PlayState* play);
|
|
void Player_Action_8084CC98(Player* this, PlayState* play);
|
|
void Player_Action_8084D3E4(Player* this, PlayState* play);
|
|
void Player_Action_8084D610(Player* this, PlayState* play);
|
|
void Player_Action_8084D7C4(Player* this, PlayState* play);
|
|
void Player_Action_8084D84C(Player* this, PlayState* play);
|
|
void Player_Action_8084DAB4(Player* this, PlayState* play);
|
|
void Player_Action_8084DC48(Player* this, PlayState* play);
|
|
void Player_Action_8084E1EC(Player* this, PlayState* play);
|
|
void Player_Action_8084E30C(Player* this, PlayState* play);
|
|
void Player_Action_8084E368(Player* this, PlayState* play);
|
|
void Player_Action_8084E3C4(Player* this, PlayState* play);
|
|
void Player_Action_8084E604(Player* this, PlayState* play);
|
|
void Player_Action_8084E6D4(Player* this, PlayState* play);
|
|
void Player_Action_8084E9AC(Player* this, PlayState* play);
|
|
void Player_Action_8084EAC0(Player* this, PlayState* play);
|
|
void Player_Action_8084ECA4(Player* this, PlayState* play);
|
|
void Player_Action_8084EED8(Player* this, PlayState* play);
|
|
void Player_Action_8084EFC0(Player* this, PlayState* play);
|
|
void Player_Action_8084F104(Player* this, PlayState* play);
|
|
void Player_Action_8084F390(Player* this, PlayState* play);
|
|
void Player_Action_8084F608(Player* this, PlayState* play);
|
|
void Player_Action_8084F698(Player* this, PlayState* play);
|
|
void Player_Action_8084F710(Player* this, PlayState* play);
|
|
void Player_Action_8084F88C(Player* this, PlayState* play);
|
|
void Player_Action_8084F9A0(Player* this, PlayState* play);
|
|
void Player_Action_8084F9C0(Player* this, PlayState* play);
|
|
void Player_Action_8084FA54(Player* this, PlayState* play);
|
|
void Player_Action_8084FB10(Player* this, PlayState* play);
|
|
void Player_Action_8084FBF4(Player* this, PlayState* play);
|
|
void Player_Action_808502D0(Player* this, PlayState* play);
|
|
void Player_Action_808505DC(Player* this, PlayState* play);
|
|
void Player_Action_8085063C(Player* this, PlayState* play);
|
|
void Player_Action_8085076C(Player* this, PlayState* play);
|
|
void Player_Action_808507F4(Player* this, PlayState* play);
|
|
void Player_Action_80850AEC(Player* this, PlayState* play);
|
|
void Player_Action_80850C68(Player* this, PlayState* play);
|
|
void Player_Action_80850E84(Player* this, PlayState* play);
|
|
void Player_Action_CsAction(Player* this, PlayState* play);
|
|
|
|
// .bss part 1
|
|
static s32 D_80858AA0;
|
|
static s32 D_80858AA4;
|
|
static Vec3f sInteractWallCheckResult;
|
|
static Input* sControlInput;
|
|
|
|
// .data
|
|
|
|
static u8 sUpperBodyLimbCopyMap[PLAYER_LIMB_MAX] = {
|
|
false, // PLAYER_LIMB_NONE
|
|
false, // PLAYER_LIMB_ROOT
|
|
false, // PLAYER_LIMB_WAIST
|
|
false, // PLAYER_LIMB_LOWER
|
|
false, // PLAYER_LIMB_R_THIGH
|
|
false, // PLAYER_LIMB_R_SHIN
|
|
false, // PLAYER_LIMB_R_FOOT
|
|
false, // PLAYER_LIMB_L_THIGH
|
|
false, // PLAYER_LIMB_L_SHIN
|
|
false, // PLAYER_LIMB_L_FOOT
|
|
true, // PLAYER_LIMB_UPPER
|
|
true, // PLAYER_LIMB_HEAD
|
|
true, // PLAYER_LIMB_HAT
|
|
true, // PLAYER_LIMB_COLLAR
|
|
true, // PLAYER_LIMB_L_SHOULDER
|
|
true, // PLAYER_LIMB_L_FOREARM
|
|
true, // PLAYER_LIMB_L_HAND
|
|
true, // PLAYER_LIMB_R_SHOULDER
|
|
true, // PLAYER_LIMB_R_FOREARM
|
|
true, // PLAYER_LIMB_R_HAND
|
|
true, // PLAYER_LIMB_SHEATH
|
|
true // PLAYER_LIMB_TORSO
|
|
};
|
|
|
|
static PlayerAgeProperties sAgeProperties[] = {
|
|
{
|
|
56.0f, // ceilingCheckHeight
|
|
90.0f, // unk_04
|
|
1.0f, // unk_08
|
|
111.0f, // unk_0C
|
|
70.0f, // unk_10
|
|
79.4f, // unk_14
|
|
59.0f, // unk_18
|
|
41.0f, // unk_1C
|
|
19.0f, // unk_20
|
|
36.0f, // unk_24
|
|
44.8f, // unk_28
|
|
56.0f, // unk_2C
|
|
68.0f, // unk_30
|
|
70.0f, // unk_34
|
|
18.0f, // wallCheckRadius
|
|
15.0f, // unk_3C
|
|
70.0f, // unk_40
|
|
{ 9, 4671, 359 }, // unk_44
|
|
{
|
|
{ 8, 4694, 380 },
|
|
{ 9, 6122, 359 },
|
|
{ 8, 4694, 380 },
|
|
{ 9, 6122, 359 },
|
|
}, // unk_4A
|
|
{
|
|
{ 9, 6122, 359 },
|
|
{ 9, 7693, 380 },
|
|
{ 9, 6122, 359 },
|
|
{ 9, 7693, 380 },
|
|
}, // unk_62
|
|
{
|
|
{ 8, 4694, 380 },
|
|
{ 9, 6122, 359 },
|
|
}, // unk_7A
|
|
{
|
|
{ -1592, 4694, 380 },
|
|
{ -1591, 6122, 359 },
|
|
}, // unk_86
|
|
0, // unk_92
|
|
0x80, // unk_94
|
|
&gPlayerAnim_link_demo_Tbox_open, // unk_98
|
|
&gPlayerAnim_link_demo_back_to_past, // unk_9C
|
|
&gPlayerAnim_link_demo_return_to_past, // unk_A0
|
|
&gPlayerAnim_link_normal_climb_startA, // unk_A4
|
|
&gPlayerAnim_link_normal_climb_startB, // unk_A8
|
|
{ &gPlayerAnim_link_normal_climb_upL, &gPlayerAnim_link_normal_climb_upR, &gPlayerAnim_link_normal_Fclimb_upL,
|
|
&gPlayerAnim_link_normal_Fclimb_upR }, // unk_AC
|
|
{ &gPlayerAnim_link_normal_Fclimb_sideL, &gPlayerAnim_link_normal_Fclimb_sideR }, // unk_BC
|
|
{ &gPlayerAnim_link_normal_climb_endAL, &gPlayerAnim_link_normal_climb_endAR }, // unk_C4
|
|
{ &gPlayerAnim_link_normal_climb_endBR, &gPlayerAnim_link_normal_climb_endBL }, // unk_CC
|
|
},
|
|
{
|
|
40.0f, // ceilingCheckHeight
|
|
60.0f, // unk_04
|
|
11.0f / 17.0f, // unk_08
|
|
71.0f, // unk_0C
|
|
50.0f, // unk_10
|
|
47.0f, // unk_14
|
|
39.0f, // unk_18
|
|
27.0f, // unk_1C
|
|
19.0f, // unk_20
|
|
22.0f, // unk_24
|
|
29.6f, // unk_28
|
|
32.0f, // unk_2C
|
|
48.0f, // unk_30
|
|
70.0f * (11.0f / 17.0f), // unk_34
|
|
14.0f, // wallCheckRadius
|
|
12.0f, // unk_3C
|
|
55.0f, // unk_40
|
|
{ -24, 3565, 876 }, // unk_44
|
|
{
|
|
{ -24, 3474, 862 },
|
|
{ -24, 4977, 937 },
|
|
{ 8, 4694, 380 },
|
|
{ 9, 6122, 359 },
|
|
}, // unk_4A
|
|
{
|
|
{ -24, 4977, 937 },
|
|
{ -24, 6495, 937 },
|
|
{ 9, 6122, 359 },
|
|
{ 9, 7693, 380 },
|
|
}, // unk_62
|
|
{
|
|
{ 8, 4694, 380 },
|
|
{ 9, 6122, 359 },
|
|
}, // unk_7A
|
|
{
|
|
{ -1592, 4694, 380 },
|
|
{ -1591, 6122, 359 },
|
|
}, // unk_86
|
|
0x20, // unk_92
|
|
0, // unk_94
|
|
&gPlayerAnim_clink_demo_Tbox_open, // unk_98
|
|
&gPlayerAnim_clink_demo_goto_future, // unk_9C
|
|
&gPlayerAnim_clink_demo_return_to_future, // unk_A0
|
|
&gPlayerAnim_clink_normal_climb_startA, // unk_A4
|
|
&gPlayerAnim_clink_normal_climb_startB, // unk_A8
|
|
{ &gPlayerAnim_clink_normal_climb_upL, &gPlayerAnim_clink_normal_climb_upR, &gPlayerAnim_link_normal_Fclimb_upL,
|
|
&gPlayerAnim_link_normal_Fclimb_upR }, // unk_AC
|
|
{ &gPlayerAnim_link_normal_Fclimb_sideL, &gPlayerAnim_link_normal_Fclimb_sideR }, // unk_BC
|
|
{ &gPlayerAnim_clink_normal_climb_endAL, &gPlayerAnim_clink_normal_climb_endAR }, // unk_C4
|
|
{ &gPlayerAnim_clink_normal_climb_endBR, &gPlayerAnim_clink_normal_climb_endBL }, // unk_CC
|
|
},
|
|
};
|
|
|
|
static u32 D_808535D0 = false;
|
|
static f32 sControlStickMagnitude = 0.0f;
|
|
static s16 sControlStickAngle = 0;
|
|
static s16 D_808535DC = 0;
|
|
static s32 D_808535E0 = 0;
|
|
static s32 sFloorType = 0;
|
|
static f32 D_808535E8 = 1.0f;
|
|
static f32 D_808535EC = 1.0f;
|
|
static u32 sTouchedWallFlags = 0;
|
|
static u32 sConveyorSpeed = 0;
|
|
static s16 sIsFloorConveyor = false;
|
|
static s16 sConveyorYaw = 0;
|
|
static f32 sYDistToFloor = 0.0f;
|
|
static s32 sPrevFloorProperty = 0;
|
|
static s32 sShapeYawToTouchedWall = 0;
|
|
static s32 sWorldYawToTouchedWall = 0;
|
|
static s16 sFloorShapePitch = 0;
|
|
static s32 sUseHeldItem = false; // When true, the current held item is used. Is reset to false every frame.
|
|
static s32 sHeldItemButtonIsHeldDown = false; // Indicates if the button for the current held item is held down.
|
|
|
|
static u16 D_8085361C[] = {
|
|
NA_SE_VO_LI_SWEAT,
|
|
NA_SE_VO_LI_SNEEZE,
|
|
NA_SE_VO_LI_RELAX,
|
|
NA_SE_VO_LI_FALL_L,
|
|
};
|
|
|
|
#define GET_PLAYER_ANIM(group, type) D_80853914[group][type]
|
|
|
|
static LinkAnimationHeader* D_80853914[PLAYER_ANIMGROUP_MAX][PLAYER_ANIMTYPE_MAX] = {
|
|
/* PLAYER_ANIMGROUP_wait */
|
|
{
|
|
&gPlayerAnim_link_normal_wait_free,
|
|
&gPlayerAnim_link_normal_wait,
|
|
&gPlayerAnim_link_normal_wait,
|
|
&gPlayerAnim_link_fighter_wait_long,
|
|
&gPlayerAnim_link_normal_wait_free,
|
|
&gPlayerAnim_link_normal_wait_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_walk */
|
|
{
|
|
&gPlayerAnim_link_normal_walk_free,
|
|
&gPlayerAnim_link_normal_walk,
|
|
&gPlayerAnim_link_normal_walk,
|
|
&gPlayerAnim_link_fighter_walk_long,
|
|
&gPlayerAnim_link_normal_walk_free,
|
|
&gPlayerAnim_link_normal_walk_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_run */
|
|
{
|
|
&gPlayerAnim_link_normal_run_free,
|
|
&gPlayerAnim_link_fighter_run,
|
|
&gPlayerAnim_link_normal_run,
|
|
&gPlayerAnim_link_fighter_run_long,
|
|
&gPlayerAnim_link_normal_run_free,
|
|
&gPlayerAnim_link_normal_run_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_damage_run */
|
|
{
|
|
&gPlayerAnim_link_normal_damage_run_free,
|
|
&gPlayerAnim_link_fighter_damage_run,
|
|
&gPlayerAnim_link_normal_damage_run_free,
|
|
&gPlayerAnim_link_fighter_damage_run_long,
|
|
&gPlayerAnim_link_normal_damage_run_free,
|
|
&gPlayerAnim_link_normal_damage_run_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_heavy_run */
|
|
{
|
|
&gPlayerAnim_link_normal_heavy_run_free,
|
|
&gPlayerAnim_link_normal_heavy_run,
|
|
&gPlayerAnim_link_normal_heavy_run_free,
|
|
&gPlayerAnim_link_fighter_heavy_run_long,
|
|
&gPlayerAnim_link_normal_heavy_run_free,
|
|
&gPlayerAnim_link_normal_heavy_run_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_waitL */
|
|
{
|
|
&gPlayerAnim_link_normal_waitL_free,
|
|
&gPlayerAnim_link_anchor_waitL,
|
|
&gPlayerAnim_link_anchor_waitL,
|
|
&gPlayerAnim_link_fighter_waitL_long,
|
|
&gPlayerAnim_link_normal_waitL_free,
|
|
&gPlayerAnim_link_normal_waitL_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_waitR */
|
|
{
|
|
&gPlayerAnim_link_normal_waitR_free,
|
|
&gPlayerAnim_link_anchor_waitR,
|
|
&gPlayerAnim_link_anchor_waitR,
|
|
&gPlayerAnim_link_fighter_waitR_long,
|
|
&gPlayerAnim_link_normal_waitR_free,
|
|
&gPlayerAnim_link_normal_waitR_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_wait2waitR */
|
|
{
|
|
&gPlayerAnim_link_fighter_wait2waitR_long,
|
|
&gPlayerAnim_link_normal_wait2waitR,
|
|
&gPlayerAnim_link_normal_wait2waitR,
|
|
&gPlayerAnim_link_fighter_wait2waitR_long,
|
|
&gPlayerAnim_link_fighter_wait2waitR_long,
|
|
&gPlayerAnim_link_fighter_wait2waitR_long,
|
|
},
|
|
/* PLAYER_ANIMGROUP_normal2fighter */
|
|
{
|
|
&gPlayerAnim_link_normal_normal2fighter_free,
|
|
&gPlayerAnim_link_fighter_normal2fighter,
|
|
&gPlayerAnim_link_fighter_normal2fighter,
|
|
&gPlayerAnim_link_normal_normal2fighter_free,
|
|
&gPlayerAnim_link_normal_normal2fighter_free,
|
|
&gPlayerAnim_link_normal_normal2fighter_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_doorA_free */
|
|
{
|
|
&gPlayerAnim_link_demo_doorA_link_free,
|
|
&gPlayerAnim_link_demo_doorA_link,
|
|
&gPlayerAnim_link_demo_doorA_link,
|
|
&gPlayerAnim_link_demo_doorA_link_free,
|
|
&gPlayerAnim_link_demo_doorA_link_free,
|
|
&gPlayerAnim_link_demo_doorA_link_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_doorA */
|
|
{
|
|
&gPlayerAnim_clink_demo_doorA_link,
|
|
&gPlayerAnim_clink_demo_doorA_link,
|
|
&gPlayerAnim_clink_demo_doorA_link,
|
|
&gPlayerAnim_clink_demo_doorA_link,
|
|
&gPlayerAnim_clink_demo_doorA_link,
|
|
&gPlayerAnim_clink_demo_doorA_link,
|
|
},
|
|
/* PLAYER_ANIMGROUP_doorB_free */
|
|
{
|
|
&gPlayerAnim_link_demo_doorB_link_free,
|
|
&gPlayerAnim_link_demo_doorB_link,
|
|
&gPlayerAnim_link_demo_doorB_link,
|
|
&gPlayerAnim_link_demo_doorB_link_free,
|
|
&gPlayerAnim_link_demo_doorB_link_free,
|
|
&gPlayerAnim_link_demo_doorB_link_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_doorB */
|
|
{
|
|
&gPlayerAnim_clink_demo_doorB_link,
|
|
&gPlayerAnim_clink_demo_doorB_link,
|
|
&gPlayerAnim_clink_demo_doorB_link,
|
|
&gPlayerAnim_clink_demo_doorB_link,
|
|
&gPlayerAnim_clink_demo_doorB_link,
|
|
&gPlayerAnim_clink_demo_doorB_link,
|
|
},
|
|
/* PLAYER_ANIMGROUP_carryB */
|
|
{
|
|
&gPlayerAnim_link_normal_carryB_free,
|
|
&gPlayerAnim_link_normal_carryB,
|
|
&gPlayerAnim_link_normal_carryB,
|
|
&gPlayerAnim_link_normal_carryB_free,
|
|
&gPlayerAnim_link_normal_carryB_free,
|
|
&gPlayerAnim_link_normal_carryB_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_landing */
|
|
{
|
|
&gPlayerAnim_link_normal_landing_free,
|
|
&gPlayerAnim_link_normal_landing,
|
|
&gPlayerAnim_link_normal_landing,
|
|
&gPlayerAnim_link_normal_landing_free,
|
|
&gPlayerAnim_link_normal_landing_free,
|
|
&gPlayerAnim_link_normal_landing_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_short_landing */
|
|
{
|
|
&gPlayerAnim_link_normal_short_landing_free,
|
|
&gPlayerAnim_link_normal_short_landing,
|
|
&gPlayerAnim_link_normal_short_landing,
|
|
&gPlayerAnim_link_normal_short_landing_free,
|
|
&gPlayerAnim_link_normal_short_landing_free,
|
|
&gPlayerAnim_link_normal_short_landing_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_landing_roll */
|
|
{
|
|
&gPlayerAnim_link_normal_landing_roll_free,
|
|
&gPlayerAnim_link_normal_landing_roll,
|
|
&gPlayerAnim_link_normal_landing_roll,
|
|
&gPlayerAnim_link_fighter_landing_roll_long,
|
|
&gPlayerAnim_link_normal_landing_roll_free,
|
|
&gPlayerAnim_link_normal_landing_roll_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_hip_down */
|
|
{
|
|
&gPlayerAnim_link_normal_hip_down_free,
|
|
&gPlayerAnim_link_normal_hip_down,
|
|
&gPlayerAnim_link_normal_hip_down,
|
|
&gPlayerAnim_link_normal_hip_down_long,
|
|
&gPlayerAnim_link_normal_hip_down_free,
|
|
&gPlayerAnim_link_normal_hip_down_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_walk_endL */
|
|
{
|
|
&gPlayerAnim_link_normal_walk_endL_free,
|
|
&gPlayerAnim_link_normal_walk_endL,
|
|
&gPlayerAnim_link_normal_walk_endL,
|
|
&gPlayerAnim_link_fighter_walk_endL_long,
|
|
&gPlayerAnim_link_normal_walk_endL_free,
|
|
&gPlayerAnim_link_normal_walk_endL_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_walk_endR */
|
|
{
|
|
&gPlayerAnim_link_normal_walk_endR_free,
|
|
&gPlayerAnim_link_normal_walk_endR,
|
|
&gPlayerAnim_link_normal_walk_endR,
|
|
&gPlayerAnim_link_fighter_walk_endR_long,
|
|
&gPlayerAnim_link_normal_walk_endR_free,
|
|
&gPlayerAnim_link_normal_walk_endR_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_defense */
|
|
{
|
|
&gPlayerAnim_link_normal_defense_free,
|
|
&gPlayerAnim_link_normal_defense,
|
|
&gPlayerAnim_link_normal_defense,
|
|
&gPlayerAnim_link_normal_defense_free,
|
|
&gPlayerAnim_link_bow_defense,
|
|
&gPlayerAnim_link_normal_defense_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_defense_wait */
|
|
{
|
|
&gPlayerAnim_link_normal_defense_wait_free,
|
|
&gPlayerAnim_link_normal_defense_wait,
|
|
&gPlayerAnim_link_normal_defense_wait,
|
|
&gPlayerAnim_link_normal_defense_wait_free,
|
|
&gPlayerAnim_link_bow_defense_wait,
|
|
&gPlayerAnim_link_normal_defense_wait_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_defense_end */
|
|
{
|
|
&gPlayerAnim_link_normal_defense_end_free,
|
|
&gPlayerAnim_link_normal_defense_end,
|
|
&gPlayerAnim_link_normal_defense_end,
|
|
&gPlayerAnim_link_normal_defense_end_free,
|
|
&gPlayerAnim_link_normal_defense_end_free,
|
|
&gPlayerAnim_link_normal_defense_end_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_side_walk */
|
|
{
|
|
&gPlayerAnim_link_normal_side_walk_free,
|
|
&gPlayerAnim_link_normal_side_walk,
|
|
&gPlayerAnim_link_normal_side_walk,
|
|
&gPlayerAnim_link_fighter_side_walk_long,
|
|
&gPlayerAnim_link_normal_side_walk_free,
|
|
&gPlayerAnim_link_normal_side_walk_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_side_walkL */
|
|
{
|
|
&gPlayerAnim_link_normal_side_walkL_free,
|
|
&gPlayerAnim_link_anchor_side_walkL,
|
|
&gPlayerAnim_link_anchor_side_walkL,
|
|
&gPlayerAnim_link_fighter_side_walkL_long,
|
|
&gPlayerAnim_link_normal_side_walkL_free,
|
|
&gPlayerAnim_link_normal_side_walkL_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_side_walkR */
|
|
{
|
|
&gPlayerAnim_link_normal_side_walkR_free,
|
|
&gPlayerAnim_link_anchor_side_walkR,
|
|
&gPlayerAnim_link_anchor_side_walkR,
|
|
&gPlayerAnim_link_fighter_side_walkR_long,
|
|
&gPlayerAnim_link_normal_side_walkR_free,
|
|
&gPlayerAnim_link_normal_side_walkR_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_45_turn */
|
|
{
|
|
&gPlayerAnim_link_normal_45_turn_free,
|
|
&gPlayerAnim_link_normal_45_turn,
|
|
&gPlayerAnim_link_normal_45_turn,
|
|
&gPlayerAnim_link_normal_45_turn_free,
|
|
&gPlayerAnim_link_normal_45_turn_free,
|
|
&gPlayerAnim_link_normal_45_turn_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_waitL2wait */
|
|
{
|
|
&gPlayerAnim_link_fighter_waitL2wait_long,
|
|
&gPlayerAnim_link_normal_waitL2wait,
|
|
&gPlayerAnim_link_normal_waitL2wait,
|
|
&gPlayerAnim_link_fighter_waitL2wait_long,
|
|
&gPlayerAnim_link_fighter_waitL2wait_long,
|
|
&gPlayerAnim_link_fighter_waitL2wait_long,
|
|
},
|
|
/* PLAYER_ANIMGROUP_waitR2wait */
|
|
{
|
|
&gPlayerAnim_link_fighter_waitR2wait_long,
|
|
&gPlayerAnim_link_normal_waitR2wait,
|
|
&gPlayerAnim_link_normal_waitR2wait,
|
|
&gPlayerAnim_link_fighter_waitR2wait_long,
|
|
&gPlayerAnim_link_fighter_waitR2wait_long,
|
|
&gPlayerAnim_link_fighter_waitR2wait_long,
|
|
},
|
|
/* PLAYER_ANIMGROUP_throw */
|
|
{
|
|
&gPlayerAnim_link_normal_throw_free,
|
|
&gPlayerAnim_link_normal_throw,
|
|
&gPlayerAnim_link_normal_throw,
|
|
&gPlayerAnim_link_normal_throw_free,
|
|
&gPlayerAnim_link_normal_throw_free,
|
|
&gPlayerAnim_link_normal_throw_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_put */
|
|
{
|
|
&gPlayerAnim_link_normal_put_free,
|
|
&gPlayerAnim_link_normal_put,
|
|
&gPlayerAnim_link_normal_put,
|
|
&gPlayerAnim_link_normal_put_free,
|
|
&gPlayerAnim_link_normal_put_free,
|
|
&gPlayerAnim_link_normal_put_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_back_walk */
|
|
{
|
|
&gPlayerAnim_link_normal_back_walk,
|
|
&gPlayerAnim_link_normal_back_walk,
|
|
&gPlayerAnim_link_normal_back_walk,
|
|
&gPlayerAnim_link_normal_back_walk,
|
|
&gPlayerAnim_link_normal_back_walk,
|
|
&gPlayerAnim_link_normal_back_walk,
|
|
},
|
|
/* PLAYER_ANIMGROUP_check */
|
|
{
|
|
&gPlayerAnim_link_normal_check_free,
|
|
&gPlayerAnim_link_normal_check,
|
|
&gPlayerAnim_link_normal_check,
|
|
&gPlayerAnim_link_normal_check_free,
|
|
&gPlayerAnim_link_normal_check_free,
|
|
&gPlayerAnim_link_normal_check_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_check_wait */
|
|
{
|
|
&gPlayerAnim_link_normal_check_wait_free,
|
|
&gPlayerAnim_link_normal_check_wait,
|
|
&gPlayerAnim_link_normal_check_wait,
|
|
&gPlayerAnim_link_normal_check_wait_free,
|
|
&gPlayerAnim_link_normal_check_wait_free,
|
|
&gPlayerAnim_link_normal_check_wait_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_check_end */
|
|
{
|
|
&gPlayerAnim_link_normal_check_end_free,
|
|
&gPlayerAnim_link_normal_check_end,
|
|
&gPlayerAnim_link_normal_check_end,
|
|
&gPlayerAnim_link_normal_check_end_free,
|
|
&gPlayerAnim_link_normal_check_end_free,
|
|
&gPlayerAnim_link_normal_check_end_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_pull_start */
|
|
{
|
|
&gPlayerAnim_link_normal_pull_start_free,
|
|
&gPlayerAnim_link_normal_pull_start,
|
|
&gPlayerAnim_link_normal_pull_start,
|
|
&gPlayerAnim_link_normal_pull_start_free,
|
|
&gPlayerAnim_link_normal_pull_start_free,
|
|
&gPlayerAnim_link_normal_pull_start_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_pulling */
|
|
{
|
|
&gPlayerAnim_link_normal_pulling_free,
|
|
&gPlayerAnim_link_normal_pulling,
|
|
&gPlayerAnim_link_normal_pulling,
|
|
&gPlayerAnim_link_normal_pulling_free,
|
|
&gPlayerAnim_link_normal_pulling_free,
|
|
&gPlayerAnim_link_normal_pulling_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_pull_end */
|
|
{
|
|
&gPlayerAnim_link_normal_pull_end_free,
|
|
&gPlayerAnim_link_normal_pull_end,
|
|
&gPlayerAnim_link_normal_pull_end,
|
|
&gPlayerAnim_link_normal_pull_end_free,
|
|
&gPlayerAnim_link_normal_pull_end_free,
|
|
&gPlayerAnim_link_normal_pull_end_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_fall_up */
|
|
{
|
|
&gPlayerAnim_link_normal_fall_up_free,
|
|
&gPlayerAnim_link_normal_fall_up,
|
|
&gPlayerAnim_link_normal_fall_up,
|
|
&gPlayerAnim_link_normal_fall_up_free,
|
|
&gPlayerAnim_link_normal_fall_up_free,
|
|
&gPlayerAnim_link_normal_fall_up_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_jump_climb_hold */
|
|
{
|
|
&gPlayerAnim_link_normal_jump_climb_hold_free,
|
|
&gPlayerAnim_link_normal_jump_climb_hold,
|
|
&gPlayerAnim_link_normal_jump_climb_hold,
|
|
&gPlayerAnim_link_normal_jump_climb_hold_free,
|
|
&gPlayerAnim_link_normal_jump_climb_hold_free,
|
|
&gPlayerAnim_link_normal_jump_climb_hold_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_jump_climb_wait */
|
|
{
|
|
&gPlayerAnim_link_normal_jump_climb_wait_free,
|
|
&gPlayerAnim_link_normal_jump_climb_wait,
|
|
&gPlayerAnim_link_normal_jump_climb_wait,
|
|
&gPlayerAnim_link_normal_jump_climb_wait_free,
|
|
&gPlayerAnim_link_normal_jump_climb_wait_free,
|
|
&gPlayerAnim_link_normal_jump_climb_wait_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_jump_climb_up */
|
|
{
|
|
&gPlayerAnim_link_normal_jump_climb_up_free,
|
|
&gPlayerAnim_link_normal_jump_climb_up,
|
|
&gPlayerAnim_link_normal_jump_climb_up,
|
|
&gPlayerAnim_link_normal_jump_climb_up_free,
|
|
&gPlayerAnim_link_normal_jump_climb_up_free,
|
|
&gPlayerAnim_link_normal_jump_climb_up_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_down_slope_slip_end */
|
|
{
|
|
&gPlayerAnim_link_normal_down_slope_slip_end_free,
|
|
&gPlayerAnim_link_normal_down_slope_slip_end,
|
|
&gPlayerAnim_link_normal_down_slope_slip_end,
|
|
&gPlayerAnim_link_normal_down_slope_slip_end_long,
|
|
&gPlayerAnim_link_normal_down_slope_slip_end_free,
|
|
&gPlayerAnim_link_normal_down_slope_slip_end_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_up_slope_slip_end */
|
|
{
|
|
&gPlayerAnim_link_normal_up_slope_slip_end_free,
|
|
&gPlayerAnim_link_normal_up_slope_slip_end,
|
|
&gPlayerAnim_link_normal_up_slope_slip_end,
|
|
&gPlayerAnim_link_normal_up_slope_slip_end_long,
|
|
&gPlayerAnim_link_normal_up_slope_slip_end_free,
|
|
&gPlayerAnim_link_normal_up_slope_slip_end_free,
|
|
},
|
|
/* PLAYER_ANIMGROUP_nwait */
|
|
{
|
|
&gPlayerAnim_sude_nwait,
|
|
&gPlayerAnim_lkt_nwait,
|
|
&gPlayerAnim_lkt_nwait,
|
|
&gPlayerAnim_sude_nwait,
|
|
&gPlayerAnim_sude_nwait,
|
|
&gPlayerAnim_sude_nwait,
|
|
}
|
|
};
|
|
|
|
static LinkAnimationHeader* D_80853D4C[][3] = {
|
|
{ &gPlayerAnim_link_fighter_front_jump, &gPlayerAnim_link_fighter_front_jump_end,
|
|
&gPlayerAnim_link_fighter_front_jump_endR },
|
|
{ &gPlayerAnim_link_fighter_Lside_jump, &gPlayerAnim_link_fighter_Lside_jump_end,
|
|
&gPlayerAnim_link_fighter_Lside_jump_endL },
|
|
{ &gPlayerAnim_link_fighter_backturn_jump, &gPlayerAnim_link_fighter_backturn_jump_end,
|
|
&gPlayerAnim_link_fighter_backturn_jump_endR },
|
|
{ &gPlayerAnim_link_fighter_Rside_jump, &gPlayerAnim_link_fighter_Rside_jump_end,
|
|
&gPlayerAnim_link_fighter_Rside_jump_endR },
|
|
};
|
|
|
|
static LinkAnimationHeader* D_80853D7C[][2] = {
|
|
{ &gPlayerAnim_link_normal_wait_typeA_20f, &gPlayerAnim_link_normal_waitF_typeA_20f },
|
|
{ &gPlayerAnim_link_normal_wait_typeC_20f, &gPlayerAnim_link_normal_waitF_typeC_20f },
|
|
{ &gPlayerAnim_link_normal_wait_typeB_20f, &gPlayerAnim_link_normal_waitF_typeB_20f },
|
|
{ &gPlayerAnim_link_normal_wait_typeB_20f, &gPlayerAnim_link_normal_waitF_typeB_20f },
|
|
{ &gPlayerAnim_link_wait_typeD_20f, &gPlayerAnim_link_waitF_typeD_20f },
|
|
{ &gPlayerAnim_link_wait_typeD_20f, &gPlayerAnim_link_waitF_typeD_20f },
|
|
{ &gPlayerAnim_link_wait_typeD_20f, &gPlayerAnim_link_waitF_typeD_20f },
|
|
{ &gPlayerAnim_link_wait_heat1_20f, &gPlayerAnim_link_waitF_heat1_20f },
|
|
{ &gPlayerAnim_link_wait_heat2_20f, &gPlayerAnim_link_waitF_heat2_20f },
|
|
{ &gPlayerAnim_link_wait_itemD1_20f, &gPlayerAnim_link_wait_itemD1_20f },
|
|
{ &gPlayerAnim_link_wait_itemA_20f, &gPlayerAnim_link_waitF_itemA_20f },
|
|
{ &gPlayerAnim_link_wait_itemB_20f, &gPlayerAnim_link_waitF_itemB_20f },
|
|
{ &gPlayerAnim_link_wait_itemC_20f, &gPlayerAnim_link_wait_itemC_20f },
|
|
{ &gPlayerAnim_link_wait_itemD2_20f, &gPlayerAnim_link_wait_itemD2_20f }
|
|
};
|
|
|
|
static AnimSfxEntry D_80853DEC[] = {
|
|
{ NA_SE_VO_LI_SNEEZE, -ANIMSFX_DATA(ANIMSFX_TYPE_4, 8) },
|
|
};
|
|
|
|
static AnimSfxEntry D_80853DF0[] = {
|
|
{ NA_SE_VO_LI_SWEAT, -ANIMSFX_DATA(ANIMSFX_TYPE_4, 18) },
|
|
};
|
|
|
|
static AnimSfxEntry D_80853DF4[] = {
|
|
{ NA_SE_VO_LI_BREATH_REST, -ANIMSFX_DATA(ANIMSFX_TYPE_4, 13) },
|
|
};
|
|
|
|
static AnimSfxEntry D_80853DF8[] = {
|
|
{ NA_SE_VO_LI_BREATH_REST, -ANIMSFX_DATA(ANIMSFX_TYPE_4, 10) },
|
|
};
|
|
|
|
static AnimSfxEntry D_80853DFC[] = {
|
|
{ NA_SE_PL_CALM_HIT, ANIMSFX_DATA(ANIMSFX_TYPE_1, 44) }, { NA_SE_PL_CALM_HIT, ANIMSFX_DATA(ANIMSFX_TYPE_1, 48) },
|
|
{ NA_SE_PL_CALM_HIT, ANIMSFX_DATA(ANIMSFX_TYPE_1, 52) }, { NA_SE_PL_CALM_HIT, ANIMSFX_DATA(ANIMSFX_TYPE_1, 56) },
|
|
{ NA_SE_PL_CALM_HIT, -ANIMSFX_DATA(ANIMSFX_TYPE_1, 60) },
|
|
};
|
|
|
|
static AnimSfxEntry D_80853E10[] = {
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_8, 25) }, { 0, ANIMSFX_DATA(ANIMSFX_TYPE_8, 30) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_8, 44) }, { 0, ANIMSFX_DATA(ANIMSFX_TYPE_8, 48) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_8, 52) }, { 0, -ANIMSFX_DATA(ANIMSFX_TYPE_8, 56) },
|
|
};
|
|
|
|
static AnimSfxEntry D_80853E28[] = {
|
|
{ NA_SE_IT_SHIELD_POSTURE, ANIMSFX_DATA(ANIMSFX_TYPE_1, 16) },
|
|
{ NA_SE_IT_SHIELD_POSTURE, ANIMSFX_DATA(ANIMSFX_TYPE_1, 20) },
|
|
{ NA_SE_IT_SHIELD_POSTURE, -ANIMSFX_DATA(ANIMSFX_TYPE_1, 70) },
|
|
};
|
|
|
|
static AnimSfxEntry D_80853E34[] = {
|
|
{ NA_SE_IT_HAMMER_SWING, ANIMSFX_DATA(ANIMSFX_TYPE_1, 10) },
|
|
{ NA_SE_VO_LI_AUTO_JUMP, ANIMSFX_DATA(ANIMSFX_TYPE_4, 10) },
|
|
{ NA_SE_IT_SWORD_SWING, ANIMSFX_DATA(ANIMSFX_TYPE_1, 22) },
|
|
{ NA_SE_VO_LI_SWORD_N, -ANIMSFX_DATA(ANIMSFX_TYPE_4, 22) },
|
|
};
|
|
|
|
static AnimSfxEntry D_80853E44[] = {
|
|
{ NA_SE_IT_SWORD_SWING, ANIMSFX_DATA(ANIMSFX_TYPE_1, 39) },
|
|
{ NA_SE_VO_LI_SWORD_N, -ANIMSFX_DATA(ANIMSFX_TYPE_4, 39) },
|
|
};
|
|
|
|
static AnimSfxEntry D_80853E4C[] = {
|
|
{ NA_SE_VO_LI_RELAX, -ANIMSFX_DATA(ANIMSFX_TYPE_4, 20) },
|
|
};
|
|
|
|
static AnimSfxEntry* D_80853E50[] = {
|
|
D_80853DEC, D_80853DF0, D_80853DF4, D_80853DF8, D_80853DFC, D_80853E10,
|
|
D_80853E28, D_80853E34, D_80853E44, D_80853E4C, NULL,
|
|
};
|
|
|
|
static u8 D_80853E7C[] = {
|
|
0, 0, 1, 1, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 3, 3, 4, 4, 8, 8, 5, 5, 6, 6, 7, 7, 9, 9, 0,
|
|
};
|
|
|
|
// Used to map item IDs to item actions
|
|
static s8 sItemActions[] = {
|
|
PLAYER_IA_DEKU_STICK, // ITEM_DEKU_STICK
|
|
PLAYER_IA_DEKU_NUT, // ITEM_DEKU_NUT
|
|
PLAYER_IA_BOMB, // ITEM_BOMB
|
|
PLAYER_IA_BOW, // ITEM_BOW
|
|
PLAYER_IA_BOW_FIRE, // ITEM_ARROW_FIRE
|
|
PLAYER_IA_DINS_FIRE, // ITEM_DINS_FIRE
|
|
PLAYER_IA_SLINGSHOT, // ITEM_SLINGSHOT
|
|
PLAYER_IA_OCARINA_FAIRY, // ITEM_OCARINA_FAIRY
|
|
PLAYER_IA_OCARINA_OF_TIME, // ITEM_OCARINA_OF_TIME
|
|
PLAYER_IA_BOMBCHU, // ITEM_BOMBCHU
|
|
PLAYER_IA_HOOKSHOT, // ITEM_HOOKSHOT
|
|
PLAYER_IA_LONGSHOT, // ITEM_LONGSHOT
|
|
PLAYER_IA_BOW_ICE, // ITEM_ARROW_ICE
|
|
PLAYER_IA_FARORES_WIND, // ITEM_FARORES_WIND
|
|
PLAYER_IA_BOOMERANG, // ITEM_BOOMERANG
|
|
PLAYER_IA_LENS_OF_TRUTH, // ITEM_LENS_OF_TRUTH
|
|
PLAYER_IA_MAGIC_BEAN, // ITEM_MAGIC_BEAN
|
|
PLAYER_IA_HAMMER, // ITEM_HAMMER
|
|
PLAYER_IA_BOW_LIGHT, // ITEM_ARROW_LIGHT
|
|
PLAYER_IA_NAYRUS_LOVE, // ITEM_NAYRUS_LOVE
|
|
PLAYER_IA_BOTTLE, // ITEM_BOTTLE_EMPTY
|
|
PLAYER_IA_BOTTLE_POTION_RED, // ITEM_BOTTLE_POTION_RED
|
|
PLAYER_IA_BOTTLE_POTION_GREEN, // ITEM_BOTTLE_POTION_GREEN
|
|
PLAYER_IA_BOTTLE_POTION_BLUE, // ITEM_BOTTLE_POTION_BLUE
|
|
PLAYER_IA_BOTTLE_FAIRY, // ITEM_BOTTLE_FAIRY
|
|
PLAYER_IA_BOTTLE_FISH, // ITEM_BOTTLE_FISH
|
|
PLAYER_IA_BOTTLE_MILK_FULL, // ITEM_BOTTLE_MILK_FULL
|
|
PLAYER_IA_BOTTLE_RUTOS_LETTER, // ITEM_BOTTLE_RUTOS_LETTER
|
|
PLAYER_IA_BOTTLE_FIRE, // ITEM_BOTTLE_BLUE_FIRE
|
|
PLAYER_IA_BOTTLE_BUG, // ITEM_BOTTLE_BUG
|
|
PLAYER_IA_BOTTLE_BIG_POE, // ITEM_BOTTLE_BIG_POE
|
|
PLAYER_IA_BOTTLE_MILK_HALF, // ITEM_BOTTLE_MILK_HALF
|
|
PLAYER_IA_BOTTLE_POE, // ITEM_BOTTLE_POE
|
|
PLAYER_IA_WEIRD_EGG, // ITEM_WEIRD_EGG
|
|
PLAYER_IA_CHICKEN, // ITEM_CHICKEN
|
|
PLAYER_IA_ZELDAS_LETTER, // ITEM_ZELDAS_LETTER
|
|
PLAYER_IA_MASK_KEATON, // ITEM_MASK_KEATON
|
|
PLAYER_IA_MASK_SKULL, // ITEM_MASK_SKULL
|
|
PLAYER_IA_MASK_SPOOKY, // ITEM_MASK_SPOOKY
|
|
PLAYER_IA_MASK_BUNNY_HOOD, // ITEM_MASK_BUNNY_HOOD
|
|
PLAYER_IA_MASK_GORON, // ITEM_MASK_GORON
|
|
PLAYER_IA_MASK_ZORA, // ITEM_MASK_ZORA
|
|
PLAYER_IA_MASK_GERUDO, // ITEM_MASK_GERUDO
|
|
PLAYER_IA_MASK_TRUTH, // ITEM_MASK_TRUTH
|
|
PLAYER_IA_SWORD_MASTER, // ITEM_SOLD_OUT
|
|
PLAYER_IA_POCKET_EGG, // ITEM_POCKET_EGG
|
|
PLAYER_IA_POCKET_CUCCO, // ITEM_POCKET_CUCCO
|
|
PLAYER_IA_COJIRO, // ITEM_COJIRO
|
|
PLAYER_IA_ODD_MUSHROOM, // ITEM_ODD_MUSHROOM
|
|
PLAYER_IA_ODD_POTION, // ITEM_ODD_POTION
|
|
PLAYER_IA_POACHERS_SAW, // ITEM_POACHERS_SAW
|
|
PLAYER_IA_BROKEN_GORONS_SWORD, // ITEM_BROKEN_GORONS_SWORD
|
|
PLAYER_IA_PRESCRIPTION, // ITEM_PRESCRIPTION
|
|
PLAYER_IA_FROG, // ITEM_EYEBALL_FROG
|
|
PLAYER_IA_EYEDROPS, // ITEM_EYE_DROPS
|
|
PLAYER_IA_CLAIM_CHECK, // ITEM_CLAIM_CHECK
|
|
PLAYER_IA_BOW_FIRE, // ITEM_BOW_FIRE
|
|
PLAYER_IA_BOW_ICE, // ITEM_BOW_ICE
|
|
PLAYER_IA_BOW_LIGHT, // ITEM_BOW_LIGHT
|
|
PLAYER_IA_SWORD_KOKIRI, // ITEM_SWORD_KOKIRI
|
|
PLAYER_IA_SWORD_MASTER, // ITEM_SWORD_MASTER
|
|
PLAYER_IA_SWORD_BIGGORON, // ITEM_SWORD_BIGGORON
|
|
};
|
|
|
|
static u8 sMaskMemory;
|
|
u8 gWalkSpeedToggle1;
|
|
u8 gWalkSpeedToggle2;
|
|
|
|
static s32 (*sItemActionUpdateFuncs[])(Player* this, PlayState* play) = {
|
|
func_8083485C, // PLAYER_IA_NONE
|
|
func_8083485C, // PLAYER_IA_SWORD_CS
|
|
func_8083485C, // PLAYER_IA_FISHING_POLE
|
|
Player_UpperAction_Sword, // PLAYER_IA_SWORD_MASTER
|
|
Player_UpperAction_Sword, // PLAYER_IA_SWORD_KOKIRI
|
|
Player_UpperAction_Sword, // PLAYER_IA_SWORD_BIGGORON
|
|
func_8083485C, // PLAYER_IA_DEKU_STICK
|
|
func_8083485C, // PLAYER_IA_HAMMER
|
|
func_8083501C, // PLAYER_IA_BOW
|
|
func_8083501C, // PLAYER_IA_BOW_FIRE
|
|
func_8083501C, // PLAYER_IA_BOW_ICE
|
|
func_8083501C, // PLAYER_IA_BOW_LIGHT
|
|
func_8083501C, // PLAYER_IA_BOW_0C
|
|
func_8083501C, // PLAYER_IA_BOW_0D
|
|
func_8083501C, // PLAYER_IA_BOW_0E
|
|
func_8083501C, // PLAYER_IA_SLINGSHOT
|
|
func_8083501C, // PLAYER_IA_HOOKSHOT
|
|
func_8083501C, // PLAYER_IA_LONGSHOT
|
|
Player_UpperAction_CarryActor, // PLAYER_IA_BOMB
|
|
Player_UpperAction_CarryActor, // PLAYER_IA_BOMBCHU
|
|
func_80835800, // PLAYER_IA_BOOMERANG
|
|
func_8083485C, // PLAYER_IA_MAGIC_SPELL_15
|
|
func_8083485C, // PLAYER_IA_MAGIC_SPELL_16
|
|
func_8083485C, // PLAYER_IA_MAGIC_SPELL_17
|
|
func_8083485C, // PLAYER_IA_FARORES_WIND
|
|
func_8083485C, // PLAYER_IA_NAYRUS_LOVE
|
|
func_8083485C, // PLAYER_IA_DINS_FIRE
|
|
func_8083485C, // PLAYER_IA_DEKU_NUT
|
|
func_8083485C, // PLAYER_IA_OCARINA_FAIRY
|
|
func_8083485C, // PLAYER_IA_OCARINA_OF_TIME
|
|
func_8083485C, // PLAYER_IA_BOTTLE
|
|
func_8083485C, // PLAYER_IA_BOTTLE_FISH
|
|
func_8083485C, // PLAYER_IA_BOTTLE_FIRE
|
|
func_8083485C, // PLAYER_IA_BOTTLE_BUG
|
|
func_8083485C, // PLAYER_IA_BOTTLE_POE
|
|
func_8083485C, // PLAYER_IA_BOTTLE_BIG_POE
|
|
func_8083485C, // PLAYER_IA_BOTTLE_RUTOS_LETTER
|
|
func_8083485C, // PLAYER_IA_BOTTLE_POTION_RED
|
|
func_8083485C, // PLAYER_IA_BOTTLE_POTION_BLUE
|
|
func_8083485C, // PLAYER_IA_BOTTLE_POTION_GREEN
|
|
func_8083485C, // PLAYER_IA_BOTTLE_MILK_FULL
|
|
func_8083485C, // PLAYER_IA_BOTTLE_MILK_HALF
|
|
func_8083485C, // PLAYER_IA_BOTTLE_FAIRY
|
|
func_8083485C, // PLAYER_IA_ZELDAS_LETTER
|
|
func_8083485C, // PLAYER_IA_WEIRD_EGG
|
|
func_8083485C, // PLAYER_IA_CHICKEN
|
|
func_8083485C, // PLAYER_IA_MAGIC_BEAN
|
|
func_8083485C, // PLAYER_IA_POCKET_EGG
|
|
func_8083485C, // PLAYER_IA_POCKET_CUCCO
|
|
func_8083485C, // PLAYER_IA_COJIRO
|
|
func_8083485C, // PLAYER_IA_ODD_MUSHROOM
|
|
func_8083485C, // PLAYER_IA_ODD_POTION
|
|
func_8083485C, // PLAYER_IA_POACHERS_SAW
|
|
func_8083485C, // PLAYER_IA_BROKEN_GORONS_SWORD
|
|
func_8083485C, // PLAYER_IA_PRESCRIPTION
|
|
func_8083485C, // PLAYER_IA_FROG
|
|
func_8083485C, // PLAYER_IA_EYEDROPS
|
|
func_8083485C, // PLAYER_IA_CLAIM_CHECK
|
|
func_8083485C, // PLAYER_IA_MASK_KEATON
|
|
func_8083485C, // PLAYER_IA_MASK_SKULL
|
|
func_8083485C, // PLAYER_IA_MASK_SPOOKY
|
|
func_8083485C, // PLAYER_IA_MASK_BUNNY_HOOD
|
|
func_8083485C, // PLAYER_IA_MASK_GORON
|
|
func_8083485C, // PLAYER_IA_MASK_ZORA
|
|
func_8083485C, // PLAYER_IA_MASK_GERUDO
|
|
func_8083485C, // PLAYER_IA_MASK_TRUTH
|
|
func_8083485C, // PLAYER_IA_LENS_OF_TRUTH
|
|
};
|
|
|
|
static void (*sItemActionInitFuncs[])(PlayState* play, Player* this) = {
|
|
Player_InitDefaultIA, // PLAYER_IA_NONE
|
|
Player_InitDefaultIA, // PLAYER_IA_SWORD_CS
|
|
Player_InitDefaultIA, // PLAYER_IA_FISHING_POLE
|
|
Player_InitDefaultIA, // PLAYER_IA_SWORD_MASTER
|
|
Player_InitDefaultIA, // PLAYER_IA_SWORD_KOKIRI
|
|
Player_InitDefaultIA, // PLAYER_IA_SWORD_BIGGORON
|
|
Player_InitDekuStickIA, // PLAYER_IA_DEKU_STICK
|
|
Player_InitHammerIA, // PLAYER_IA_HAMMER
|
|
Player_InitBowOrSlingshotIA, // PLAYER_IA_BOW
|
|
Player_InitBowOrSlingshotIA, // PLAYER_IA_BOW_FIRE
|
|
Player_InitBowOrSlingshotIA, // PLAYER_IA_BOW_ICE
|
|
Player_InitBowOrSlingshotIA, // PLAYER_IA_BOW_LIGHT
|
|
Player_InitBowOrSlingshotIA, // PLAYER_IA_BOW_0C
|
|
Player_InitBowOrSlingshotIA, // PLAYER_IA_BOW_0D
|
|
Player_InitBowOrSlingshotIA, // PLAYER_IA_BOW_0E
|
|
Player_InitBowOrSlingshotIA, // PLAYER_IA_SLINGSHOT
|
|
Player_InitHookshotIA, // PLAYER_IA_HOOKSHOT
|
|
Player_InitHookshotIA, // PLAYER_IA_LONGSHOT
|
|
Player_InitExplosiveIA, // PLAYER_IA_BOMB
|
|
Player_InitExplosiveIA, // PLAYER_IA_BOMBCHU
|
|
Player_InitBoomerangIA, // PLAYER_IA_BOOMERANG
|
|
Player_InitDefaultIA, // PLAYER_IA_MAGIC_SPELL_15
|
|
Player_InitDefaultIA, // PLAYER_IA_MAGIC_SPELL_16
|
|
Player_InitDefaultIA, // PLAYER_IA_MAGIC_SPELL_17
|
|
Player_InitDefaultIA, // PLAYER_IA_FARORES_WIND
|
|
Player_InitDefaultIA, // PLAYER_IA_NAYRUS_LOVE
|
|
Player_InitDefaultIA, // PLAYER_IA_DINS_FIRE
|
|
Player_InitDefaultIA, // PLAYER_IA_DEKU_NUT
|
|
Player_InitDefaultIA, // PLAYER_IA_OCARINA_FAIRY
|
|
Player_InitDefaultIA, // PLAYER_IA_OCARINA_OF_TIME
|
|
Player_InitDefaultIA, // PLAYER_IA_BOTTLE
|
|
Player_InitDefaultIA, // PLAYER_IA_BOTTLE_FISH
|
|
Player_InitDefaultIA, // PLAYER_IA_BOTTLE_FIRE
|
|
Player_InitDefaultIA, // PLAYER_IA_BOTTLE_BUG
|
|
Player_InitDefaultIA, // PLAYER_IA_BOTTLE_POE
|
|
Player_InitDefaultIA, // PLAYER_IA_BOTTLE_BIG_POE
|
|
Player_InitDefaultIA, // PLAYER_IA_BOTTLE_RUTOS_LETTER
|
|
Player_InitDefaultIA, // PLAYER_IA_BOTTLE_POTION_RED
|
|
Player_InitDefaultIA, // PLAYER_IA_BOTTLE_POTION_BLUE
|
|
Player_InitDefaultIA, // PLAYER_IA_BOTTLE_POTION_GREEN
|
|
Player_InitDefaultIA, // PLAYER_IA_BOTTLE_MILK_FULL
|
|
Player_InitDefaultIA, // PLAYER_IA_BOTTLE_MILK_HALF
|
|
Player_InitDefaultIA, // PLAYER_IA_BOTTLE_FAIRY
|
|
Player_InitDefaultIA, // PLAYER_IA_ZELDAS_LETTER
|
|
Player_InitDefaultIA, // PLAYER_IA_WEIRD_EGG
|
|
Player_InitDefaultIA, // PLAYER_IA_CHICKEN
|
|
Player_InitDefaultIA, // PLAYER_IA_MAGIC_BEAN
|
|
Player_InitDefaultIA, // PLAYER_IA_POCKET_EGG
|
|
Player_InitDefaultIA, // PLAYER_IA_POCKET_CUCCO
|
|
Player_InitDefaultIA, // PLAYER_IA_COJIRO
|
|
Player_InitDefaultIA, // PLAYER_IA_ODD_MUSHROOM
|
|
Player_InitDefaultIA, // PLAYER_IA_ODD_POTION
|
|
Player_InitDefaultIA, // PLAYER_IA_POACHERS_SAW
|
|
Player_InitDefaultIA, // PLAYER_IA_BROKEN_GORONS_SWORD
|
|
Player_InitDefaultIA, // PLAYER_IA_PRESCRIPTION
|
|
Player_InitDefaultIA, // PLAYER_IA_FROG
|
|
Player_InitDefaultIA, // PLAYER_IA_EYEDROPS
|
|
Player_InitDefaultIA, // PLAYER_IA_CLAIM_CHECK
|
|
Player_InitDefaultIA, // PLAYER_IA_MASK_KEATON
|
|
Player_InitDefaultIA, // PLAYER_IA_MASK_SKULL
|
|
Player_InitDefaultIA, // PLAYER_IA_MASK_SPOOKY
|
|
Player_InitDefaultIA, // PLAYER_IA_MASK_BUNNY_HOOD
|
|
Player_InitDefaultIA, // PLAYER_IA_MASK_GORON
|
|
Player_InitDefaultIA, // PLAYER_IA_MASK_ZORA
|
|
Player_InitDefaultIA, // PLAYER_IA_MASK_GERUDO
|
|
Player_InitDefaultIA, // PLAYER_IA_MASK_TRUTH
|
|
Player_InitDefaultIA, // PLAYER_IA_LENS_OF_TRUTH
|
|
};
|
|
|
|
typedef enum {
|
|
/* 0 */ PLAYER_ITEM_CHG_0,
|
|
/* 1 */ PLAYER_ITEM_CHG_1,
|
|
/* 2 */ PLAYER_ITEM_CHG_2,
|
|
/* 3 */ PLAYER_ITEM_CHG_3,
|
|
/* 4 */ PLAYER_ITEM_CHG_4,
|
|
/* 5 */ PLAYER_ITEM_CHG_5,
|
|
/* 6 */ PLAYER_ITEM_CHG_6,
|
|
/* 7 */ PLAYER_ITEM_CHG_7,
|
|
/* 8 */ PLAYER_ITEM_CHG_8,
|
|
/* 9 */ PLAYER_ITEM_CHG_9,
|
|
/* 10 */ PLAYER_ITEM_CHG_10,
|
|
/* 11 */ PLAYER_ITEM_CHG_11,
|
|
/* 12 */ PLAYER_ITEM_CHG_12,
|
|
/* 13 */ PLAYER_ITEM_CHG_13,
|
|
/* 14 */ PLAYER_ITEM_CHG_MAX
|
|
} ItemChangeType;
|
|
|
|
static ItemChangeInfo sItemChangeInfo[PLAYER_ITEM_CHG_MAX] = {
|
|
/* PLAYER_ITEM_CHG_0 */ { &gPlayerAnim_link_normal_free2free, 12 },
|
|
/* PLAYER_ITEM_CHG_1 */ { &gPlayerAnim_link_normal_normal2fighter, 6 },
|
|
/* PLAYER_ITEM_CHG_2 */ { &gPlayerAnim_link_hammer_normal2long, 8 },
|
|
/* PLAYER_ITEM_CHG_3 */ { &gPlayerAnim_link_normal_normal2free, 8 },
|
|
/* PLAYER_ITEM_CHG_4 */ { &gPlayerAnim_link_fighter_fighter2long, 8 },
|
|
/* PLAYER_ITEM_CHG_5 */ { &gPlayerAnim_link_normal_fighter2free, 10 },
|
|
/* PLAYER_ITEM_CHG_6 */ { &gPlayerAnim_link_hammer_long2free, 7 },
|
|
/* PLAYER_ITEM_CHG_7 */ { &gPlayerAnim_link_hammer_long2long, 11 },
|
|
/* PLAYER_ITEM_CHG_8 */ { &gPlayerAnim_link_normal_free2free, 12 },
|
|
/* PLAYER_ITEM_CHG_9 */ { &gPlayerAnim_link_normal_normal2bom, 4 },
|
|
/* PLAYER_ITEM_CHG_10 */ { &gPlayerAnim_link_normal_long2bom, 4 },
|
|
/* PLAYER_ITEM_CHG_11 */ { &gPlayerAnim_link_normal_free2bom, 4 },
|
|
/* PLAYER_ITEM_CHG_12 */ { &gPlayerAnim_link_anchor_anchor2fighter, 5 },
|
|
/* PLAYER_ITEM_CHG_13 */ { &gPlayerAnim_link_normal_free2freeB, 13 },
|
|
};
|
|
|
|
// Maps the appropriate ItemChangeType based on current and next animtype.
|
|
// A negative type value means the corresponding animation should be played in reverse.
|
|
static s8 sItemChangeTypes[PLAYER_ANIMTYPE_MAX][PLAYER_ANIMTYPE_MAX] = {
|
|
{ PLAYER_ITEM_CHG_8, -PLAYER_ITEM_CHG_5, -PLAYER_ITEM_CHG_3, -PLAYER_ITEM_CHG_6, PLAYER_ITEM_CHG_8,
|
|
PLAYER_ITEM_CHG_11 },
|
|
{ PLAYER_ITEM_CHG_5, PLAYER_ITEM_CHG_0, -PLAYER_ITEM_CHG_1, PLAYER_ITEM_CHG_4, PLAYER_ITEM_CHG_5,
|
|
PLAYER_ITEM_CHG_9 },
|
|
{ PLAYER_ITEM_CHG_3, PLAYER_ITEM_CHG_1, PLAYER_ITEM_CHG_0, PLAYER_ITEM_CHG_2, PLAYER_ITEM_CHG_3,
|
|
PLAYER_ITEM_CHG_9 },
|
|
{ PLAYER_ITEM_CHG_6, -PLAYER_ITEM_CHG_4, -PLAYER_ITEM_CHG_2, PLAYER_ITEM_CHG_7, PLAYER_ITEM_CHG_6,
|
|
PLAYER_ITEM_CHG_10 },
|
|
{ PLAYER_ITEM_CHG_8, -PLAYER_ITEM_CHG_5, -PLAYER_ITEM_CHG_3, -PLAYER_ITEM_CHG_6, PLAYER_ITEM_CHG_8,
|
|
PLAYER_ITEM_CHG_11 },
|
|
{ PLAYER_ITEM_CHG_8, -PLAYER_ITEM_CHG_5, -PLAYER_ITEM_CHG_3, -PLAYER_ITEM_CHG_6, PLAYER_ITEM_CHG_8,
|
|
PLAYER_ITEM_CHG_11 },
|
|
};
|
|
|
|
static ExplosiveInfo sExplosiveInfos[] = {
|
|
{ ITEM_BOMB, ACTOR_EN_BOM },
|
|
{ ITEM_BOMBCHU, ACTOR_EN_BOM_CHU },
|
|
};
|
|
|
|
static struct_80854190 D_80854190[PLAYER_MWA_MAX] = {
|
|
/* PLAYER_MWA_FORWARD_SLASH_1H */
|
|
{ &gPlayerAnim_link_fighter_normal_kiru, &gPlayerAnim_link_fighter_normal_kiru_end,
|
|
&gPlayerAnim_link_fighter_normal_kiru_endR, 1, 4 },
|
|
/* PLAYER_MWA_FORWARD_SLASH_2H */
|
|
{ &gPlayerAnim_link_fighter_Lnormal_kiru, &gPlayerAnim_link_fighter_Lnormal_kiru_end,
|
|
&gPlayerAnim_link_anchor_Lnormal_kiru_endR, 1, 4 },
|
|
/* PLAYER_MWA_FORWARD_COMBO_1H */
|
|
{ &gPlayerAnim_link_fighter_normal_kiru_finsh, &gPlayerAnim_link_fighter_normal_kiru_finsh_end,
|
|
&gPlayerAnim_link_anchor_normal_kiru_finsh_endR, 0, 5 },
|
|
/* PLAYER_MWA_FORWARD_COMBO_2H */
|
|
{ &gPlayerAnim_link_fighter_Lnormal_kiru_finsh, &gPlayerAnim_link_fighter_Lnormal_kiru_finsh_end,
|
|
&gPlayerAnim_link_anchor_Lnormal_kiru_finsh_endR, 1, 7 },
|
|
/* PLAYER_MWA_RIGHT_SLASH_1H */
|
|
{ &gPlayerAnim_link_fighter_Lside_kiru, &gPlayerAnim_link_fighter_Lside_kiru_end,
|
|
&gPlayerAnim_link_anchor_Lside_kiru_endR, 1, 4 },
|
|
/* PLAYER_MWA_RIGHT_SLASH_2H */
|
|
{ &gPlayerAnim_link_fighter_LLside_kiru, &gPlayerAnim_link_fighter_LLside_kiru_end,
|
|
&gPlayerAnim_link_anchor_LLside_kiru_endL, 0, 5 },
|
|
/* PLAYER_MWA_RIGHT_COMBO_1H */
|
|
{ &gPlayerAnim_link_fighter_Lside_kiru_finsh, &gPlayerAnim_link_fighter_Lside_kiru_finsh_end,
|
|
&gPlayerAnim_link_anchor_Lside_kiru_finsh_endR, 2, 8 },
|
|
/* PLAYER_MWA_RIGHT_COMBO_2H */
|
|
{ &gPlayerAnim_link_fighter_LLside_kiru_finsh, &gPlayerAnim_link_fighter_LLside_kiru_finsh_end,
|
|
&gPlayerAnim_link_anchor_LLside_kiru_finsh_endR, 3, 8 },
|
|
/* PLAYER_MWA_LEFT_SLASH_1H */
|
|
{ &gPlayerAnim_link_fighter_Rside_kiru, &gPlayerAnim_link_fighter_Rside_kiru_end,
|
|
&gPlayerAnim_link_anchor_Rside_kiru_endR, 0, 4 },
|
|
/* PLAYER_MWA_LEFT_SLASH_2H */
|
|
{ &gPlayerAnim_link_fighter_LRside_kiru, &gPlayerAnim_link_fighter_LRside_kiru_end,
|
|
&gPlayerAnim_link_anchor_LRside_kiru_endR, 0, 5 },
|
|
/* PLAYER_MWA_LEFT_COMBO_1H */
|
|
{ &gPlayerAnim_link_fighter_Rside_kiru_finsh, &gPlayerAnim_link_fighter_Rside_kiru_finsh_end,
|
|
&gPlayerAnim_link_anchor_Rside_kiru_finsh_endR, 0, 6 },
|
|
/* PLAYER_MWA_LEFT_COMBO_2H */
|
|
{ &gPlayerAnim_link_fighter_LRside_kiru_finsh, &gPlayerAnim_link_fighter_LRside_kiru_finsh_end,
|
|
&gPlayerAnim_link_anchor_LRside_kiru_finsh_endL, 1, 5 },
|
|
/* PLAYER_MWA_STAB_1H */
|
|
{ &gPlayerAnim_link_fighter_pierce_kiru, &gPlayerAnim_link_fighter_pierce_kiru_end,
|
|
&gPlayerAnim_link_anchor_pierce_kiru_endR, 0, 3 },
|
|
/* PLAYER_MWA_STAB_2H */
|
|
{ &gPlayerAnim_link_fighter_Lpierce_kiru, &gPlayerAnim_link_fighter_Lpierce_kiru_end,
|
|
&gPlayerAnim_link_anchor_Lpierce_kiru_endL, 0, 3 },
|
|
/* PLAYER_MWA_STAB_COMBO_1H */
|
|
{ &gPlayerAnim_link_fighter_pierce_kiru_finsh, &gPlayerAnim_link_fighter_pierce_kiru_finsh_end,
|
|
&gPlayerAnim_link_anchor_pierce_kiru_finsh_endR, 1, 9 },
|
|
/* PLAYER_MWA_STAB_COMBO_2H */
|
|
{ &gPlayerAnim_link_fighter_Lpierce_kiru_finsh, &gPlayerAnim_link_fighter_Lpierce_kiru_finsh_end,
|
|
&gPlayerAnim_link_anchor_Lpierce_kiru_finsh_endR, 1, 8 },
|
|
/* PLAYER_MWA_FLIPSLASH_START */
|
|
{ &gPlayerAnim_link_fighter_jump_rollkiru, &gPlayerAnim_link_fighter_jump_kiru_finsh,
|
|
&gPlayerAnim_link_fighter_jump_kiru_finsh, 1, 10 },
|
|
/* PLAYER_MWA_JUMPSLASH_START */
|
|
{ &gPlayerAnim_link_fighter_Lpower_jump_kiru, &gPlayerAnim_link_fighter_Lpower_jump_kiru_hit,
|
|
&gPlayerAnim_link_fighter_Lpower_jump_kiru_hit, 1, 11 },
|
|
/* PLAYER_MWA_FLIPSLASH_FINISH */
|
|
{ &gPlayerAnim_link_fighter_jump_kiru_finsh, &gPlayerAnim_link_fighter_jump_kiru_finsh_end,
|
|
&gPlayerAnim_link_fighter_jump_kiru_finsh_end, 1, 2 },
|
|
/* PLAYER_MWA_JUMPSLASH_FINISH */
|
|
{ &gPlayerAnim_link_fighter_Lpower_jump_kiru_hit, &gPlayerAnim_link_fighter_Lpower_jump_kiru_end,
|
|
&gPlayerAnim_link_fighter_Lpower_jump_kiru_end, 1, 2 },
|
|
/* PLAYER_MWA_BACKSLASH_RIGHT */
|
|
{ &gPlayerAnim_link_fighter_turn_kiruR, &gPlayerAnim_link_fighter_turn_kiruR_end,
|
|
&gPlayerAnim_link_fighter_turn_kiruR_end, 1, 5 },
|
|
/* PLAYER_MWA_BACKSLASH_LEFT */
|
|
{ &gPlayerAnim_link_fighter_turn_kiruL, &gPlayerAnim_link_fighter_turn_kiruL_end,
|
|
&gPlayerAnim_link_fighter_turn_kiruL_end, 1, 4 },
|
|
/* PLAYER_MWA_HAMMER_FORWARD */
|
|
{ &gPlayerAnim_link_hammer_hit, &gPlayerAnim_link_hammer_hit_end, &gPlayerAnim_link_hammer_hit_endR, 3, 10 },
|
|
/* PLAYER_MWA_HAMMER_SIDE */
|
|
{ &gPlayerAnim_link_hammer_side_hit, &gPlayerAnim_link_hammer_side_hit_end, &gPlayerAnim_link_hammer_side_hit_endR,
|
|
2, 11 },
|
|
/* PLAYER_MWA_SPIN_ATTACK_1H */
|
|
{ &gPlayerAnim_link_fighter_rolling_kiru, &gPlayerAnim_link_fighter_rolling_kiru_end,
|
|
&gPlayerAnim_link_anchor_rolling_kiru_endR, 0, 12 },
|
|
/* PLAYER_MWA_SPIN_ATTACK_2H */
|
|
{ &gPlayerAnim_link_fighter_Lrolling_kiru, &gPlayerAnim_link_fighter_Lrolling_kiru_end,
|
|
&gPlayerAnim_link_anchor_Lrolling_kiru_endR, 0, 15 },
|
|
/* PLAYER_MWA_BIG_SPIN_1H */
|
|
{ &gPlayerAnim_link_fighter_Wrolling_kiru, &gPlayerAnim_link_fighter_Wrolling_kiru_end,
|
|
&gPlayerAnim_link_anchor_rolling_kiru_endR, 0, 16 },
|
|
/* PLAYER_MWA_BIG_SPIN_2H */
|
|
{ &gPlayerAnim_link_fighter_Wrolling_kiru, &gPlayerAnim_link_fighter_Wrolling_kiru_end,
|
|
&gPlayerAnim_link_anchor_Lrolling_kiru_endR, 0, 16 },
|
|
};
|
|
|
|
static LinkAnimationHeader* D_80854350[] = {
|
|
&gPlayerAnim_link_fighter_power_kiru_start,
|
|
&gPlayerAnim_link_fighter_Lpower_kiru_start,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_80854358[] = {
|
|
&gPlayerAnim_link_fighter_power_kiru_startL,
|
|
&gPlayerAnim_link_fighter_Lpower_kiru_start,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_80854360[] = {
|
|
&gPlayerAnim_link_fighter_power_kiru_wait,
|
|
&gPlayerAnim_link_fighter_Lpower_kiru_wait,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_80854368[] = {
|
|
&gPlayerAnim_link_fighter_power_kiru_wait_end,
|
|
&gPlayerAnim_link_fighter_Lpower_kiru_wait_end,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_80854370[] = {
|
|
&gPlayerAnim_link_fighter_power_kiru_walk,
|
|
&gPlayerAnim_link_fighter_Lpower_kiru_walk,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_80854378[] = {
|
|
&gPlayerAnim_link_fighter_power_kiru_side_walk,
|
|
&gPlayerAnim_link_fighter_Lpower_kiru_side_walk,
|
|
};
|
|
|
|
static u8 D_80854380[2] = { PLAYER_MWA_SPIN_ATTACK_1H, PLAYER_MWA_SPIN_ATTACK_2H };
|
|
static u8 D_80854384[2] = { PLAYER_MWA_BIG_SPIN_1H, PLAYER_MWA_BIG_SPIN_2H };
|
|
|
|
static u16 sItemButtons[] = { BTN_B, BTN_CLEFT, BTN_CDOWN, BTN_CRIGHT, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT };
|
|
|
|
static u8 sMagicSpellCosts[] = { 12, 24, 24, 12, 24, 12 };
|
|
|
|
static u16 D_80854398[] = { NA_SE_IT_BOW_DRAW, NA_SE_IT_SLING_DRAW, NA_SE_IT_HOOKSHOT_READY };
|
|
|
|
static u8 sMagicArrowCosts[] = { 4, 4, 8 };
|
|
|
|
static LinkAnimationHeader* D_808543A4[] = {
|
|
&gPlayerAnim_link_anchor_waitR2defense,
|
|
&gPlayerAnim_link_anchor_waitR2defense_long,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_808543AC[] = {
|
|
&gPlayerAnim_link_anchor_waitL2defense,
|
|
&gPlayerAnim_link_anchor_waitL2defense_long,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_808543B4[] = {
|
|
&gPlayerAnim_link_anchor_defense_hit,
|
|
&gPlayerAnim_link_anchor_defense_long_hitL,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_808543BC[] = {
|
|
&gPlayerAnim_link_anchor_defense_hit,
|
|
&gPlayerAnim_link_anchor_defense_long_hitR,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_808543C4[] = {
|
|
&gPlayerAnim_link_normal_defense_hit,
|
|
&gPlayerAnim_link_fighter_defense_long_hit,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_808543CC[] = {
|
|
&gPlayerAnim_link_bow_walk2ready,
|
|
&gPlayerAnim_link_hook_walk2ready,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_808543D4[] = {
|
|
&gPlayerAnim_link_bow_bow_wait,
|
|
&gPlayerAnim_link_hook_wait,
|
|
};
|
|
|
|
void Player_ZeroSpeedXZ(Player* this) {
|
|
this->actor.speedXZ = 0.0f;
|
|
this->linearVelocity = 0.0f;
|
|
}
|
|
|
|
void func_80832224(Player* this) {
|
|
Player_ZeroSpeedXZ(this);
|
|
this->unk_6AD = 0;
|
|
}
|
|
|
|
s32 func_8083224C(PlayState* play) {
|
|
Player* this = GET_PLAYER(play);
|
|
|
|
return CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_PLAYER_TALKED_TO);
|
|
}
|
|
|
|
void Player_AnimPlayOnce(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
LinkAnimation_PlayOnce(play, &this->skelAnime, anim);
|
|
}
|
|
|
|
void Player_AnimPlayLoop(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
LinkAnimation_PlayLoop(play, &this->skelAnime, anim);
|
|
}
|
|
|
|
void Player_AnimPlayLoopAdjusted(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
LinkAnimation_PlayLoopSetSpeed(play, &this->skelAnime, anim, PLAYER_ANIM_ADJUSTED_SPEED);
|
|
}
|
|
|
|
void Player_AnimPlayOnceAdjusted(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, anim, PLAYER_ANIM_ADJUSTED_SPEED);
|
|
}
|
|
|
|
void func_808322FC(Player* this) {
|
|
this->actor.shape.rot.y += this->skelAnime.jointTable[1].y;
|
|
this->skelAnime.jointTable[1].y = 0;
|
|
}
|
|
|
|
void func_80832318(Player* this) {
|
|
this->stateFlags2 &= ~PLAYER_STATE2_SPIN_ATTACKING;
|
|
this->meleeWeaponState = 0;
|
|
this->meleeWeaponInfo[0].active = this->meleeWeaponInfo[1].active = this->meleeWeaponInfo[2].active = 0;
|
|
}
|
|
|
|
void func_80832340(PlayState* play, Player* this) {
|
|
Camera* subCam;
|
|
|
|
if (this->subCamId != SUBCAM_NONE) {
|
|
subCam = play->cameraPtrs[this->subCamId];
|
|
if ((subCam != NULL) && (subCam->csId == 1100)) {
|
|
OnePointCutscene_EndCutscene(play, this->subCamId);
|
|
this->subCamId = SUBCAM_NONE;
|
|
}
|
|
}
|
|
|
|
this->stateFlags2 &= ~(PLAYER_STATE2_UNDERWATER | PLAYER_STATE2_DIVING);
|
|
}
|
|
|
|
void Player_DetachHeldActor(PlayState* play, Player* this) {
|
|
Actor* heldActor = this->heldActor;
|
|
|
|
if ((heldActor != NULL) && !Player_HoldsHookshot(this)) {
|
|
this->actor.child = NULL;
|
|
this->heldActor = NULL;
|
|
this->interactRangeActor = NULL;
|
|
heldActor->parent = NULL;
|
|
this->stateFlags1 &= ~PLAYER_STATE1_ITEM_OVER_HEAD;
|
|
}
|
|
|
|
if (Player_GetExplosiveHeld(this) >= 0) {
|
|
Player_InitItemAction(play, this, PLAYER_IA_NONE);
|
|
this->heldItemId = ITEM_NONE_FE;
|
|
}
|
|
}
|
|
|
|
void func_80832440(PlayState* play, Player* this) {
|
|
if ((this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) && (this->heldActor == NULL)) {
|
|
if (this->interactRangeActor != NULL) {
|
|
if (this->getItemId == GI_NONE) {
|
|
this->stateFlags1 &= ~PLAYER_STATE1_ITEM_OVER_HEAD;
|
|
this->interactRangeActor = NULL;
|
|
}
|
|
} else {
|
|
this->stateFlags1 &= ~PLAYER_STATE1_ITEM_OVER_HEAD;
|
|
}
|
|
}
|
|
|
|
func_80832318(this);
|
|
this->unk_6AD = 0;
|
|
|
|
func_80832340(play, this);
|
|
func_8005B1A4(Play_GetCamera(play, 0));
|
|
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_FIRST_PERSON | PLAYER_STATE1_CLIMBING_LADDER);
|
|
this->stateFlags2 &= ~(PLAYER_STATE2_MOVING_DYNAPOLY | PLAYER_STATE2_GRABBED_BY_ENEMY | PLAYER_STATE2_CRAWLING);
|
|
|
|
this->actor.shape.rot.x = 0;
|
|
this->actor.shape.yOffset = 0.0f;
|
|
|
|
this->unk_845 = this->unk_844 = 0;
|
|
}
|
|
|
|
s32 func_80832528(PlayState* play, Player* this) {
|
|
if (this->heldItemAction >= PLAYER_IA_FISHING_POLE) {
|
|
Player_UseItem(play, this, ITEM_NONE);
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void func_80832564(PlayState* play, Player* this) {
|
|
func_80832440(play, this);
|
|
Player_DetachHeldActor(play, this);
|
|
}
|
|
|
|
s32 func_80832594(Player* this, s32 arg1, s32 arg2) {
|
|
s16 controlStickAngleDiff = this->prevControlStickAngle - sControlStickAngle;
|
|
|
|
this->av2.actionVar2 += arg1 + (s16)(ABS(controlStickAngleDiff) * fabsf(sControlStickMagnitude) * 2.5415802156203426e-06f);
|
|
|
|
if (CHECK_BTN_ANY(sControlInput->press.button, BTN_A | BTN_B)) {
|
|
this->av2.actionVar2 += 5;
|
|
}
|
|
|
|
return this->av2.actionVar2 > arg2;
|
|
}
|
|
|
|
void func_80832630(PlayState* play) {
|
|
if (play->actorCtx.freezeFlashTimer == 0) {
|
|
play->actorCtx.freezeFlashTimer = 1;
|
|
}
|
|
}
|
|
|
|
void Player_RequestRumble(Player* this, s32 sourceStrength, s32 duration, s32 decreaseRate, s32 distSq) {
|
|
if (this->actor.category == ACTORCAT_PLAYER) {
|
|
func_800AA000(distSq, sourceStrength, duration, decreaseRate);
|
|
}
|
|
}
|
|
|
|
void func_80832698(Player* this, u16 sfxId) {
|
|
if (this->actor.category == ACTORCAT_PLAYER) {
|
|
Player_PlaySfx(this, sfxId + this->ageProperties->unk_92);
|
|
} else {
|
|
func_800F4190(&this->actor.projectedPos, sfxId);
|
|
}
|
|
}
|
|
|
|
void func_808326F0(Player* this) {
|
|
u16* entry = &D_8085361C[0];
|
|
s32 i;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
Audio_StopSfxById((u16)(*entry + this->ageProperties->unk_92));
|
|
entry++;
|
|
}
|
|
}
|
|
|
|
u16 func_8083275C(Player* this, u16 sfxId) {
|
|
return sfxId + this->floorSfxOffset;
|
|
}
|
|
|
|
void func_80832770(Player* this, u16 sfxId) {
|
|
Player_PlaySfx(this, func_8083275C(this, sfxId));
|
|
}
|
|
|
|
u16 func_808327A4(Player* this, u16 sfxId) {
|
|
return sfxId + this->floorSfxOffset + this->ageProperties->unk_94;
|
|
}
|
|
|
|
void func_808327C4(Player* this, u16 sfxId) {
|
|
Player_PlaySfx(this, func_808327A4(this, sfxId));
|
|
}
|
|
|
|
void func_808327F8(Player* this, f32 arg1) {
|
|
s32 sfxId;
|
|
|
|
if (this->currentBoots == PLAYER_BOOTS_IRON) {
|
|
sfxId = NA_SE_PL_WALK_HEAVYBOOTS;
|
|
} else {
|
|
sfxId = func_808327A4(this, NA_SE_PL_WALK_GROUND);
|
|
}
|
|
|
|
func_800F4010(&this->actor.projectedPos, sfxId, arg1);
|
|
// Gameplay stats: Count footsteps
|
|
// Only count while game isn't complete and don't count Link's idle animations or crawling in crawlspaces
|
|
if (!gSaveContext.sohStats.gameComplete && !(this->stateFlags2 & PLAYER_STATE2_IDLING) &&
|
|
!(this->stateFlags2 & PLAYER_STATE2_CRAWLING)) {
|
|
gSaveContext.sohStats.count[COUNT_STEPS]++;
|
|
}
|
|
}
|
|
|
|
void func_80832854(Player* this) {
|
|
s32 sfxId;
|
|
|
|
if (this->currentBoots == PLAYER_BOOTS_IRON) {
|
|
sfxId = NA_SE_PL_JUMP_HEAVYBOOTS;
|
|
} else {
|
|
sfxId = func_808327A4(this, NA_SE_PL_JUMP);
|
|
}
|
|
|
|
Player_PlaySfx(this, sfxId);
|
|
}
|
|
|
|
void func_808328A0(Player* this) {
|
|
s32 sfxId;
|
|
|
|
if (this->currentBoots == PLAYER_BOOTS_IRON) {
|
|
sfxId = NA_SE_PL_LAND_HEAVYBOOTS;
|
|
} else {
|
|
sfxId = func_808327A4(this, NA_SE_PL_LAND);
|
|
}
|
|
|
|
Player_PlaySfx(this, sfxId);
|
|
}
|
|
|
|
void func_808328EC(Player* this, u16 sfxId) {
|
|
Player_PlaySfx(this, sfxId);
|
|
this->stateFlags2 |= PLAYER_STATE2_FOOTSTEP;
|
|
}
|
|
|
|
/**
|
|
* Process a list of `AnimSfx` entries.
|
|
* An `AnimSfx` entry contains a sound effect to play, a frame number that indicates
|
|
* when during an animation it should play, and a type value that indicates how it should be played back.
|
|
*
|
|
* The list will stop being processed after an entry that has a negative value for the `data` field.
|
|
*
|
|
* Some types do not make use of `sfxId`, the SFX function called will pick a sound on its own.
|
|
* The `sfxId` field is not used in this case and can be any value, but 0 is typically used.
|
|
*
|
|
* @param entry A pointer to the first entry of an `AnimSfx` list.
|
|
*/
|
|
void Player_ProcessAnimSfxList(Player* this, AnimSfxEntry* entry) {
|
|
s32 cont;
|
|
s32 pad;
|
|
|
|
do {
|
|
s32 absData = ABS(entry->data);
|
|
s32 type = ANIMSFX_GET_TYPE(absData);
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, fabsf(ANIMSFX_GET_FRAME(absData)))) {
|
|
if (type == ANIMSFX_SHIFT_TYPE(ANIMSFX_TYPE_1)) {
|
|
Player_PlaySfx(this, entry->sfxId);
|
|
} else if (type == ANIMSFX_SHIFT_TYPE(ANIMSFX_TYPE_2)) {
|
|
func_80832770(this, entry->sfxId);
|
|
} else if (type == ANIMSFX_SHIFT_TYPE(ANIMSFX_TYPE_3)) {
|
|
func_808327C4(this, entry->sfxId);
|
|
} else if (type == ANIMSFX_SHIFT_TYPE(ANIMSFX_TYPE_4)) {
|
|
func_80832698(this, entry->sfxId);
|
|
} else if (type == ANIMSFX_SHIFT_TYPE(ANIMSFX_TYPE_5)) {
|
|
func_808328A0(this);
|
|
} else if (type == ANIMSFX_SHIFT_TYPE(ANIMSFX_TYPE_6)) {
|
|
func_808327F8(this, 6.0f);
|
|
} else if (type == ANIMSFX_SHIFT_TYPE(ANIMSFX_TYPE_7)) {
|
|
func_80832854(this);
|
|
} else if (type == ANIMSFX_SHIFT_TYPE(ANIMSFX_TYPE_8)) {
|
|
func_808327F8(this, 0.0f);
|
|
} else if (type == ANIMSFX_SHIFT_TYPE(ANIMSFX_TYPE_9)) {
|
|
func_800F4010(&this->actor.projectedPos,
|
|
NA_SE_PL_WALK_LADDER + this->ageProperties->unk_94, 0.0f);
|
|
}
|
|
}
|
|
|
|
cont = (entry->data >= 0); // stop processing if `data` is negative
|
|
entry++;
|
|
} while (cont);
|
|
}
|
|
|
|
void Player_AnimChangeOnceMorph(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
LinkAnimation_Change(play, &this->skelAnime, anim, 1.0f, 0.0f, Animation_GetLastFrame(anim), ANIMMODE_ONCE, -6.0f);
|
|
}
|
|
|
|
void Player_AnimChangeOnceMorphAdjusted(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
LinkAnimation_Change(play, &this->skelAnime, anim, PLAYER_ANIM_ADJUSTED_SPEED, 0.0f, Animation_GetLastFrame(anim),
|
|
ANIMMODE_ONCE, -6.0f);
|
|
}
|
|
|
|
void Player_AnimChangeLoopMorph(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
LinkAnimation_Change(play, &this->skelAnime, anim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -6.0f);
|
|
}
|
|
|
|
void Player_AnimChangeFreeze(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
LinkAnimation_Change(play, &this->skelAnime, anim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 0.0f);
|
|
}
|
|
|
|
void Player_AnimChangeLoopSlowMorph(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
LinkAnimation_Change(play, &this->skelAnime, anim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -16.0f);
|
|
}
|
|
|
|
s32 func_80832CB0(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimPlayLoop(play, this, anim);
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void Player_SkelAnimeResetPrevTranslRot(Player* this) {
|
|
this->skelAnime.prevTransl = this->skelAnime.baseTransl;
|
|
this->skelAnime.prevRot = this->actor.shape.rot.y;
|
|
}
|
|
|
|
void Player_SkelAnimeResetPrevTranslRotAgeScale(Player* this) {
|
|
Player_SkelAnimeResetPrevTranslRot(this);
|
|
this->skelAnime.prevTransl.x *= this->ageProperties->unk_08;
|
|
this->skelAnime.prevTransl.y *= this->ageProperties->unk_08;
|
|
this->skelAnime.prevTransl.z *= this->ageProperties->unk_08;
|
|
}
|
|
|
|
void Player_ZeroRootLimbYaw(Player* this) {
|
|
this->skelAnime.jointTable[1].y = 0;
|
|
}
|
|
|
|
void func_80832DBC(Player* this) {
|
|
if (this->skelAnime.moveFlags != 0) {
|
|
func_808322FC(this);
|
|
this->skelAnime.jointTable[0].x = this->skelAnime.baseTransl.x;
|
|
this->skelAnime.jointTable[0].z = this->skelAnime.baseTransl.z;
|
|
if (this->skelAnime.moveFlags & 8) {
|
|
if (this->skelAnime.moveFlags & 2) {
|
|
this->skelAnime.jointTable[0].y = this->skelAnime.prevTransl.y;
|
|
}
|
|
} else {
|
|
this->skelAnime.jointTable[0].y = this->skelAnime.baseTransl.y;
|
|
}
|
|
Player_SkelAnimeResetPrevTranslRot(this);
|
|
this->skelAnime.moveFlags = 0;
|
|
}
|
|
}
|
|
|
|
void func_80832E48(Player* this, s32 flags) {
|
|
Vec3f pos;
|
|
|
|
this->skelAnime.moveFlags = flags;
|
|
this->skelAnime.prevTransl = this->skelAnime.baseTransl;
|
|
SkelAnime_UpdateTranslation(&this->skelAnime, &pos, this->actor.shape.rot.y);
|
|
|
|
if (flags & 1) {
|
|
if (!LINK_IS_ADULT) {
|
|
pos.x *= 0.64f;
|
|
pos.z *= 0.64f;
|
|
}
|
|
this->actor.world.pos.x += pos.x * this->actor.scale.x;
|
|
this->actor.world.pos.z += pos.z * this->actor.scale.z;
|
|
}
|
|
|
|
if (flags & 2) {
|
|
if (!(flags & 4)) {
|
|
pos.y *= this->ageProperties->unk_08;
|
|
}
|
|
this->actor.world.pos.y += pos.y * this->actor.scale.y;
|
|
}
|
|
|
|
func_808322FC(this);
|
|
}
|
|
|
|
#define ANIM_REPLACE_APPLY_FLAG_8 (1 << 8)
|
|
#define ANIM_REPLACE_APPLY_FLAG_9 (1 << 9)
|
|
|
|
void Player_AnimReplaceApplyFlags(PlayState* play, Player* this, s32 flags) {
|
|
if (flags & ANIM_REPLACE_APPLY_FLAG_9) {
|
|
Player_SkelAnimeResetPrevTranslRotAgeScale(this);
|
|
} else if ((flags & ANIM_REPLACE_APPLY_FLAG_8) || (this->skelAnime.moveFlags != 0)) {
|
|
Player_SkelAnimeResetPrevTranslRot(this);
|
|
} else {
|
|
this->skelAnime.prevTransl = this->skelAnime.jointTable[0];
|
|
this->skelAnime.prevRot = this->actor.shape.rot.y;
|
|
}
|
|
|
|
this->skelAnime.moveFlags = flags;
|
|
Player_ZeroSpeedXZ(this);
|
|
AnimationContext_DisableQueue(play);
|
|
}
|
|
|
|
void Player_AnimReplacePlayOnceSetSpeed(PlayState* play, Player* this, LinkAnimationHeader* anim, s32 flags,
|
|
f32 playbackSpeed) {
|
|
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, anim, playbackSpeed);
|
|
Player_AnimReplaceApplyFlags(play, this, flags);
|
|
}
|
|
|
|
void Player_AnimReplacePlayOnce(PlayState* play, Player* this, LinkAnimationHeader* anim, s32 flags) {
|
|
Player_AnimReplacePlayOnceSetSpeed(play, this, anim, flags, 1.0f);
|
|
}
|
|
|
|
void Player_AnimReplacePlayOnceAdjusted(PlayState* play, Player* this, LinkAnimationHeader* anim, s32 flags) {
|
|
Player_AnimReplacePlayOnceSetSpeed(play, this, anim, flags, PLAYER_ANIM_ADJUSTED_SPEED);
|
|
}
|
|
|
|
void Player_AnimReplaceNormalPlayOnceAdjusted(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
Player_AnimReplacePlayOnceAdjusted(play, this, anim, 0x1C);
|
|
}
|
|
|
|
void Player_AnimReplacePlayLoopSetSpeed(PlayState* play, Player* this, LinkAnimationHeader* anim, s32 flags,
|
|
f32 playbackSpeed) {
|
|
LinkAnimation_PlayLoopSetSpeed(play, &this->skelAnime, anim, playbackSpeed);
|
|
Player_AnimReplaceApplyFlags(play, this, flags);
|
|
}
|
|
|
|
void Player_AnimReplacePlayLoop(PlayState* play, Player* this, LinkAnimationHeader* anim, s32 flags) {
|
|
Player_AnimReplacePlayLoopSetSpeed(play, this, anim, flags, 1.0f);
|
|
}
|
|
|
|
void Player_AnimReplacePlayLoopAdjusted(PlayState* play, Player* this, LinkAnimationHeader* anim, s32 flags) {
|
|
Player_AnimReplacePlayLoopSetSpeed(play, this, anim, flags, PLAYER_ANIM_ADJUSTED_SPEED);
|
|
}
|
|
|
|
void Player_AnimReplaceNormalPlayLoopAdjusted(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
Player_AnimReplacePlayLoopAdjusted(play, this, anim, 0x1C);
|
|
}
|
|
|
|
void Player_ProcessControlStick(PlayState* play, Player* this) {
|
|
s8 phi_v1;
|
|
s8 phi_v0;
|
|
|
|
this->prevControlStickMagnitude = sControlStickMagnitude;
|
|
this->prevControlStickAngle = sControlStickAngle;
|
|
|
|
func_80077D10(&sControlStickMagnitude, &sControlStickAngle, sControlInput);
|
|
|
|
D_808535DC = Camera_GetInputDirYaw(GET_ACTIVE_CAM(play)) + sControlStickAngle;
|
|
|
|
this->unk_846 = (this->unk_846 + 1) % 4;
|
|
|
|
if (sControlStickMagnitude < 55.0f) {
|
|
phi_v0 = -1;
|
|
phi_v1 = -1;
|
|
} else {
|
|
phi_v1 = (u16)(sControlStickAngle + 0x2000) >> 9;
|
|
phi_v0 = (u16)((s16)(D_808535DC - this->actor.shape.rot.y) + 0x2000) >> 14;
|
|
}
|
|
|
|
this->unk_847[this->unk_846] = phi_v1;
|
|
this->unk_84B[this->unk_846] = phi_v0;
|
|
}
|
|
|
|
void func_8083328C(PlayState* play, Player* this, LinkAnimationHeader* linkAnim) {
|
|
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, linkAnim, D_808535E8);
|
|
}
|
|
|
|
int func_808332B8(Player* this) {
|
|
return (this->stateFlags1 & PLAYER_STATE1_IN_WATER) && (this->currentBoots != PLAYER_BOOTS_IRON);
|
|
}
|
|
|
|
s32 func_808332E4(Player* this) {
|
|
return (this->stateFlags1 & PLAYER_STATE1_BOOMERANG_IN_HAND);
|
|
}
|
|
|
|
void func_808332F4(Player* this, PlayState* play) {
|
|
GetItemEntry giEntry;
|
|
if (this->getItemEntry.objectId == OBJECT_INVALID || (this->getItemId != this->getItemEntry.getItemId)) {
|
|
giEntry = ItemTable_Retrieve(this->getItemId);
|
|
} else {
|
|
giEntry = this->getItemEntry;
|
|
}
|
|
|
|
this->unk_862 = ABS(giEntry.gi);
|
|
}
|
|
|
|
static LinkAnimationHeader* func_80833338(Player* this) {
|
|
return GET_PLAYER_ANIM(PLAYER_ANIMGROUP_wait, this->modelAnimType);
|
|
}
|
|
|
|
s32 func_80833350(Player* this) {
|
|
LinkAnimationHeader** entry;
|
|
s32 i;
|
|
|
|
if (func_80833338(this) != this->skelAnime.animation) {
|
|
for (i = 0, entry = &D_80853D7C[0][0]; i < 28; i++, entry++) {
|
|
if (this->skelAnime.animation == *entry) {
|
|
return i + 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void func_808333FC(Player* this, s32 arg1) {
|
|
if (D_80853E7C[arg1] != 0) {
|
|
Player_ProcessAnimSfxList(this, D_80853E50[D_80853E7C[arg1] - 1]);
|
|
}
|
|
}
|
|
|
|
LinkAnimationHeader* func_80833438(Player* this) {
|
|
if (this->unk_890 != 0) {
|
|
return GET_PLAYER_ANIM(PLAYER_ANIMGROUP_damage_run, this->modelAnimType);
|
|
} else if (!(this->stateFlags1 & (PLAYER_STATE1_IN_WATER | PLAYER_STATE1_IN_CUTSCENE)) &&
|
|
(this->currentBoots == PLAYER_BOOTS_IRON)) {
|
|
return GET_PLAYER_ANIM(PLAYER_ANIMGROUP_heavy_run, this->modelAnimType);
|
|
} else {
|
|
return GET_PLAYER_ANIM(PLAYER_ANIMGROUP_run, this->modelAnimType);
|
|
}
|
|
}
|
|
|
|
int func_808334B4(Player* this) {
|
|
return func_808332E4(this) && (this->unk_834 != 0);
|
|
}
|
|
|
|
LinkAnimationHeader* func_808334E4(Player* this) {
|
|
if (func_808334B4(this)) {
|
|
return &gPlayerAnim_link_boom_throw_waitR;
|
|
} else {
|
|
return GET_PLAYER_ANIM(PLAYER_ANIMGROUP_waitR, this->modelAnimType);
|
|
}
|
|
}
|
|
|
|
LinkAnimationHeader* func_80833528(Player* this) {
|
|
if (func_808334B4(this)) {
|
|
return &gPlayerAnim_link_boom_throw_waitL;
|
|
} else {
|
|
return GET_PLAYER_ANIM(PLAYER_ANIMGROUP_waitL, this->modelAnimType);
|
|
}
|
|
}
|
|
|
|
LinkAnimationHeader* func_8083356C(Player* this) {
|
|
if (func_8002DD78(this)) {
|
|
return &gPlayerAnim_link_bow_side_walk;
|
|
} else {
|
|
return GET_PLAYER_ANIM(PLAYER_ANIMGROUP_side_walk, this->modelAnimType);
|
|
}
|
|
}
|
|
|
|
LinkAnimationHeader* func_808335B0(Player* this) {
|
|
if (func_808334B4(this)) {
|
|
return &gPlayerAnim_link_boom_throw_side_walkR;
|
|
} else {
|
|
return GET_PLAYER_ANIM(PLAYER_ANIMGROUP_side_walkR, this->modelAnimType);
|
|
}
|
|
}
|
|
|
|
LinkAnimationHeader* func_808335F4(Player* this) {
|
|
if (func_808334B4(this)) {
|
|
return &gPlayerAnim_link_boom_throw_side_walkL;
|
|
} else {
|
|
return GET_PLAYER_ANIM(PLAYER_ANIMGROUP_side_walkL, this->modelAnimType);
|
|
}
|
|
}
|
|
|
|
void Player_SetUpperActionFunc(Player* this, UpperActionFunc upperActionFunc) {
|
|
this->upperActionFunc = upperActionFunc;
|
|
this->unk_836 = 0;
|
|
this->upperAnimBlendWeight = 0.0f;
|
|
func_808326F0(this);
|
|
}
|
|
|
|
void Player_InitItemActionWithAnim(PlayState* play, Player* this, s8 itemAction) {
|
|
LinkAnimationHeader* current = this->skelAnime.animation;
|
|
LinkAnimationHeader** iter = &D_80853914[0][this->modelAnimType];
|
|
u32 animGroup;
|
|
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_ITEM_IN_HAND | PLAYER_STATE1_BOOMERANG_IN_HAND);
|
|
|
|
for (animGroup = 0; animGroup < PLAYER_ANIMGROUP_MAX; animGroup++) {
|
|
if (current == *iter) {
|
|
break;
|
|
}
|
|
iter += PLAYER_ANIMTYPE_MAX;
|
|
}
|
|
|
|
Player_InitItemAction(play, this, itemAction);
|
|
|
|
if (animGroup < PLAYER_ANIMGROUP_MAX) {
|
|
this->skelAnime.animation = GET_PLAYER_ANIM(animGroup, this->modelAnimType);
|
|
}
|
|
}
|
|
|
|
s8 Player_ItemToItemAction(s32 item) {
|
|
if (item >= ITEM_NONE_FE) {
|
|
return PLAYER_IA_NONE;
|
|
} else if (item == ITEM_LAST_USED) {
|
|
return PLAYER_IA_LAST_USED;
|
|
} else if (item == ITEM_FISHING_POLE) {
|
|
return PLAYER_IA_FISHING_POLE;
|
|
// #region SOH [Enhancement] Added to prevent crashes with assignable equipment
|
|
} else if (item >= ITEM_TUNIC_KOKIRI && item <= ITEM_BOOTS_HOVER) {
|
|
return PLAYER_IA_NONE;
|
|
// #endregion
|
|
} else {
|
|
return sItemActions[item];
|
|
}
|
|
}
|
|
|
|
void Player_InitDefaultIA(PlayState* play, Player* this) {
|
|
}
|
|
|
|
void Player_InitDekuStickIA(PlayState* play, Player* this) {
|
|
this->unk_85C = 1.0f;
|
|
}
|
|
|
|
void Player_InitHammerIA(PlayState* play, Player* this) {
|
|
}
|
|
|
|
void Player_InitBowOrSlingshotIA(PlayState* play, Player* this) {
|
|
this->stateFlags1 |= PLAYER_STATE1_ITEM_IN_HAND;
|
|
|
|
if (this->heldItemAction != PLAYER_IA_SLINGSHOT) {
|
|
this->unk_860 = -1;
|
|
} else {
|
|
this->unk_860 = -2;
|
|
}
|
|
}
|
|
|
|
void Player_InitExplosiveIA(PlayState* play, Player* this) {
|
|
s32 explosiveType;
|
|
ExplosiveInfo* explosiveInfo;
|
|
Actor* spawnedActor;
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) {
|
|
func_80832528(play, this);
|
|
return;
|
|
}
|
|
|
|
explosiveType = Player_GetExplosiveHeld(this);
|
|
explosiveInfo = &sExplosiveInfos[explosiveType];
|
|
|
|
spawnedActor =
|
|
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, explosiveInfo->actorId, this->actor.world.pos.x,
|
|
this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, 0);
|
|
if (spawnedActor != NULL) {
|
|
if ((explosiveType != 0) && (play->bombchuBowlingStatus != 0)) {
|
|
if (!CVarGetInteger("gInfiniteAmmo", 0)) {
|
|
play->bombchuBowlingStatus--;
|
|
}
|
|
if (play->bombchuBowlingStatus == 0) {
|
|
play->bombchuBowlingStatus = -1;
|
|
}
|
|
} else {
|
|
Inventory_ChangeAmmo(explosiveInfo->itemId, -1);
|
|
}
|
|
|
|
this->interactRangeActor = spawnedActor;
|
|
this->heldActor = spawnedActor;
|
|
this->getItemId = GI_NONE;
|
|
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
|
|
this->unk_3BC.y = spawnedActor->shape.rot.y - this->actor.shape.rot.y;
|
|
this->stateFlags1 |= PLAYER_STATE1_ITEM_OVER_HEAD;
|
|
}
|
|
}
|
|
|
|
void Player_InitHookshotIA(PlayState* play, Player* this) {
|
|
this->stateFlags1 |= PLAYER_STATE1_ITEM_IN_HAND;
|
|
this->unk_860 = -3;
|
|
|
|
this->heldActor =
|
|
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_ARMS_HOOK, this->actor.world.pos.x,
|
|
this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, 0);
|
|
}
|
|
|
|
void Player_InitBoomerangIA(PlayState* play, Player* this) {
|
|
this->stateFlags1 |= PLAYER_STATE1_BOOMERANG_IN_HAND;
|
|
}
|
|
|
|
void Player_InitItemAction(PlayState* play, Player* this, s8 itemAction) {
|
|
this->unk_860 = 0;
|
|
this->unk_85C = 0.0f;
|
|
this->unk_858 = 0.0f;
|
|
|
|
this->heldItemAction = this->itemAction = itemAction;
|
|
this->modelGroup = this->nextModelGroup;
|
|
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_ITEM_IN_HAND | PLAYER_STATE1_BOOMERANG_IN_HAND);
|
|
|
|
sItemActionInitFuncs[itemAction](play, this);
|
|
|
|
Player_SetModelGroup(this, this->modelGroup);
|
|
}
|
|
|
|
void func_80833A20(Player* this, s32 newMeleeWeaponState) {
|
|
u16 itemSfx;
|
|
u16 voiceSfx;
|
|
|
|
if (this->meleeWeaponState == 0) {
|
|
if ((this->heldItemAction == PLAYER_IA_SWORD_BIGGORON) &&
|
|
(gSaveContext.swordHealth > 0.0f)) {
|
|
itemSfx = NA_SE_IT_HAMMER_SWING;
|
|
} else {
|
|
itemSfx = NA_SE_IT_SWORD_SWING;
|
|
}
|
|
|
|
voiceSfx = NA_SE_VO_LI_SWORD_N;
|
|
if (this->heldItemAction == PLAYER_IA_HAMMER) {
|
|
itemSfx = NA_SE_IT_HAMMER_SWING;
|
|
} else if (this->meleeWeaponAnimation >= PLAYER_MWA_SPIN_ATTACK_1H) {
|
|
itemSfx = 0;
|
|
voiceSfx = NA_SE_VO_LI_SWORD_L;
|
|
} else if (this->unk_845 >= 3) {
|
|
itemSfx = NA_SE_IT_SWORD_SWING_HARD;
|
|
voiceSfx = NA_SE_VO_LI_SWORD_L;
|
|
}
|
|
|
|
if (itemSfx != 0) {
|
|
func_808328EC(this, itemSfx);
|
|
}
|
|
|
|
if (!((this->meleeWeaponAnimation >= PLAYER_MWA_FLIPSLASH_START) &&
|
|
(this->meleeWeaponAnimation <= PLAYER_MWA_JUMPSLASH_FINISH))) {
|
|
func_80832698(this, voiceSfx);
|
|
}
|
|
|
|
if (this->heldItemAction >= PLAYER_IA_SWORD_MASTER && this->heldItemAction <= PLAYER_IA_SWORD_BIGGORON) {
|
|
gSaveContext.sohStats.count[COUNT_SWORD_SWINGS]++;
|
|
}
|
|
}
|
|
|
|
this->meleeWeaponState = newMeleeWeaponState;
|
|
}
|
|
|
|
s32 func_80833B2C(Player* this) {
|
|
if (this->stateFlags1 & (PLAYER_STATE1_TARGET_LOCKED | PLAYER_STATE1_TARGET_NOTHING | PLAYER_STATE1_30)) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
s32 func_80833B54(Player* this) {
|
|
if ((this->unk_664 != NULL) && CHECK_FLAG_ALL(this->unk_664->flags, ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE)) {
|
|
this->stateFlags1 |= PLAYER_STATE1_ENEMY_TARGET;
|
|
return 1;
|
|
}
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_ENEMY_TARGET) {
|
|
this->stateFlags1 &= ~PLAYER_STATE1_ENEMY_TARGET;
|
|
if (this->linearVelocity == 0.0f) {
|
|
this->yaw = this->actor.shape.rot.y;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int func_80833BCC(Player* this) {
|
|
return func_8008E9C4(this) || func_80833B2C(this);
|
|
}
|
|
|
|
int func_80833C04(Player* this) {
|
|
return func_80833B54(this) || func_80833B2C(this);
|
|
}
|
|
|
|
void func_80833C3C(Player* this) {
|
|
this->unk_870 = this->unk_874 = 0.0f;
|
|
}
|
|
|
|
s32 Player_ItemIsInUse(Player* this, s32 item) {
|
|
if ((item < ITEM_NONE_FE) && (Player_ItemToItemAction(item) == this->itemAction)) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
s32 Player_ItemIsItemAction(s32 item1, s32 itemAction) {
|
|
if ((item1 < ITEM_NONE_FE) && (Player_ItemToItemAction(item1) == itemAction)) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
s32 Player_GetItemOnButton(PlayState* play, s32 index) {
|
|
if (index >= ((CVarGetInteger("gDpadEquips", 0) != 0) ? 8 : 4)) {
|
|
return ITEM_NONE;
|
|
} else if (play->bombchuBowlingStatus != 0) {
|
|
return (play->bombchuBowlingStatus > 0) ? ITEM_BOMBCHU : ITEM_NONE;
|
|
} else if (index == 0) {
|
|
return B_BTN_ITEM;
|
|
} else if (index == 1) {
|
|
return C_BTN_ITEM(0);
|
|
} else if (index == 2) {
|
|
return C_BTN_ITEM(1);
|
|
} else if (index == 3) {
|
|
return C_BTN_ITEM(2);
|
|
} else if (index == 4) {
|
|
return DPAD_ITEM(0);
|
|
} else if (index == 5) {
|
|
return DPAD_ITEM(1);
|
|
} else if (index == 6) {
|
|
return DPAD_ITEM(2);
|
|
} else if (index == 7) {
|
|
return DPAD_ITEM(3);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handles the high level item usage and changing process based on the B and C buttons.
|
|
*
|
|
* Tasks include:
|
|
* - Put away a mask if it is not present on any C button
|
|
* - Put away an item if it is not present on the B button or any C button
|
|
* - Use an item on the B button or any C button if the corresponding button is pressed
|
|
* - Keep track of the current item button being held down
|
|
*/
|
|
void Player_ProcessItemButtons(Player* this, PlayState* play) {
|
|
s32 maskItemAction;
|
|
s32 item;
|
|
s32 i;
|
|
|
|
if (this->currentMask != PLAYER_MASK_NONE) {
|
|
if (CVarGetInteger("gMMBunnyHood", BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA) {
|
|
s32 maskItem = this->currentMask - PLAYER_MASK_KEATON + ITEM_MASK_KEATON;
|
|
bool hasOnDpad = false;
|
|
if (CVarGetInteger("gDpadEquips", 0) != 0) {
|
|
for (int buttonIndex = 4; buttonIndex < 8; buttonIndex++) {
|
|
hasOnDpad |= gSaveContext.equips.buttonItems[buttonIndex] == maskItem;
|
|
}
|
|
}
|
|
|
|
if (gSaveContext.equips.buttonItems[0] != maskItem && gSaveContext.equips.buttonItems[1] != maskItem &&
|
|
gSaveContext.equips.buttonItems[2] != maskItem && gSaveContext.equips.buttonItems[3] != maskItem &&
|
|
!hasOnDpad) {
|
|
this->currentMask = sMaskMemory = PLAYER_MASK_NONE;
|
|
func_808328EC(this, NA_SE_PL_CHANGE_ARMS);
|
|
}
|
|
} else {
|
|
maskItemAction = this->currentMask - 1 + PLAYER_IA_MASK_KEATON;
|
|
|
|
bool hasOnDpad = false;
|
|
if (CVarGetInteger("gDpadEquips", 0) != 0) {
|
|
for (int buttonIndex = 0; buttonIndex < 4; buttonIndex++) {
|
|
hasOnDpad |= Player_ItemIsItemAction(DPAD_ITEM(buttonIndex), maskItemAction);
|
|
}
|
|
}
|
|
if (!Player_ItemIsItemAction(C_BTN_ITEM(0), maskItemAction) &&
|
|
!Player_ItemIsItemAction(C_BTN_ITEM(1), maskItemAction) &&
|
|
!Player_ItemIsItemAction(C_BTN_ITEM(2), maskItemAction) && !hasOnDpad) {
|
|
this->currentMask = PLAYER_MASK_NONE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!(this->stateFlags1 & (PLAYER_STATE1_ITEM_OVER_HEAD | PLAYER_STATE1_IN_CUTSCENE)) && !func_8008F128(this)) {
|
|
if (this->itemAction >= PLAYER_IA_FISHING_POLE) {
|
|
bool hasOnDpad = false;
|
|
if (CVarGetInteger("gDpadEquips", 0) != 0) {
|
|
for (int buttonIndex = 0; buttonIndex < 4; buttonIndex++) {
|
|
hasOnDpad |= Player_ItemIsInUse(this, DPAD_ITEM(buttonIndex));
|
|
}
|
|
}
|
|
if (!Player_ItemIsInUse(this, B_BTN_ITEM) && !Player_ItemIsInUse(this, C_BTN_ITEM(0)) &&
|
|
!Player_ItemIsInUse(this, C_BTN_ITEM(1)) && !Player_ItemIsInUse(this, C_BTN_ITEM(2)) && !hasOnDpad) {
|
|
Player_UseItem(play, this, ITEM_NONE);
|
|
return;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < ARRAY_COUNT(sItemButtons); i++) {
|
|
if (CHECK_BTN_ALL(sControlInput->press.button, sItemButtons[i])) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
item = Player_GetItemOnButton(play, i);
|
|
|
|
if (item >= ITEM_NONE_FE) {
|
|
for (i = 0; i < ARRAY_COUNT(sItemButtons); i++) {
|
|
if (CHECK_BTN_ALL(sControlInput->cur.button, sItemButtons[i])) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
item = Player_GetItemOnButton(play, i);
|
|
|
|
if ((item < ITEM_NONE_FE) && (Player_ItemToItemAction(item) == this->heldItemAction)) {
|
|
sHeldItemButtonIsHeldDown = true;
|
|
}
|
|
} else {
|
|
this->heldItemButton = i;
|
|
Player_UseItem(play, this, item);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_StartChangingHeldItem(Player* this, PlayState* play) {
|
|
LinkAnimationHeader* anim;
|
|
f32 endFrameTemp;
|
|
f32 startFrame;
|
|
f32 endFrame;
|
|
f32 playSpeed;
|
|
s32 itemChangeType;
|
|
s8 heldItemAction;
|
|
s32 nextAnimType;
|
|
|
|
heldItemAction = Player_ItemToItemAction(this->heldItemId);
|
|
|
|
Player_SetUpperActionFunc(this, Player_UpperAction_ChangeHeldItem);
|
|
|
|
nextAnimType = gPlayerModelTypes[this->nextModelGroup][PLAYER_MODELGROUPENTRY_ANIM];
|
|
itemChangeType = sItemChangeTypes[gPlayerModelTypes[this->modelGroup][PLAYER_MODELGROUPENTRY_ANIM]][nextAnimType];
|
|
|
|
if ((heldItemAction == PLAYER_IA_BOTTLE) || (heldItemAction == PLAYER_IA_BOOMERANG) ||
|
|
((heldItemAction == PLAYER_IA_NONE) &&
|
|
((this->heldItemAction == PLAYER_IA_BOTTLE) || (this->heldItemAction == PLAYER_IA_BOOMERANG)))) {
|
|
itemChangeType = (heldItemAction == PLAYER_IA_NONE) ? -PLAYER_ITEM_CHG_13 : PLAYER_ITEM_CHG_13;
|
|
}
|
|
|
|
this->itemChangeType = ABS(itemChangeType);
|
|
anim = sItemChangeInfo[this->itemChangeType].anim;
|
|
|
|
if ((anim == &gPlayerAnim_link_normal_fighter2free) && (this->currentShield == PLAYER_SHIELD_NONE)) {
|
|
anim = &gPlayerAnim_link_normal_free2fighter_free;
|
|
}
|
|
|
|
endFrameTemp = Animation_GetLastFrame(anim);
|
|
endFrame = endFrameTemp;
|
|
|
|
if (itemChangeType >= 0) {
|
|
playSpeed = 1.2f;
|
|
startFrame = 0.0f;
|
|
} else {
|
|
endFrame = 0.0f;
|
|
playSpeed = -1.2f;
|
|
startFrame = endFrameTemp;
|
|
}
|
|
|
|
if (heldItemAction != PLAYER_IA_NONE) {
|
|
playSpeed *= 2.0f;
|
|
}
|
|
|
|
LinkAnimation_Change(play, &this->upperSkelAnime, anim, playSpeed, startFrame, endFrame, ANIMMODE_ONCE, 0.0f);
|
|
|
|
this->stateFlags1 &= ~PLAYER_STATE1_START_PUTAWAY;
|
|
}
|
|
|
|
void Player_UpdateItems(Player* this, PlayState* play) {
|
|
if ((this->actor.category == ACTORCAT_PLAYER) && (CVarGetInteger("gQuickPutaway", 0) || !(this->stateFlags1 & PLAYER_STATE1_START_PUTAWAY)) &&
|
|
((this->heldItemAction == this->itemAction) || (this->stateFlags1 & PLAYER_STATE1_SHIELDING)) &&
|
|
(gSaveContext.health != 0) && (play->csCtx.state == CS_STATE_IDLE) && (this->csAction == 0) &&
|
|
(play->shootingGalleryStatus == 0) && (play->activeCamera == MAIN_CAM) &&
|
|
(play->transitionTrigger != TRANS_TRIGGER_START) && (gSaveContext.timer1State != 10)) {
|
|
Player_ProcessItemButtons(this, play);
|
|
}
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_START_PUTAWAY) {
|
|
Player_StartChangingHeldItem(this, play);
|
|
}
|
|
}
|
|
|
|
// Determine projectile type for bow or slingshot
|
|
s32 func_80834380(PlayState* play, Player* this, s32* itemPtr, s32* typePtr) {
|
|
bool useBow = LINK_IS_ADULT;
|
|
if(CVarGetInteger("gBowSlingShotAmmoFix", 0)){
|
|
useBow = this->heldItemAction != PLAYER_IA_SLINGSHOT;
|
|
}
|
|
if (useBow) {
|
|
*itemPtr = ITEM_BOW;
|
|
if (this->stateFlags1 & PLAYER_STATE1_ON_HORSE) {
|
|
*typePtr = ARROW_NORMAL_HORSE;
|
|
} else {
|
|
*typePtr = this->heldItemAction - 6;
|
|
}
|
|
} else {
|
|
*itemPtr = ITEM_SLINGSHOT;
|
|
*typePtr = ARROW_SEED;
|
|
}
|
|
|
|
if (gSaveContext.minigameState == 1) {
|
|
return play->interfaceCtx.hbaAmmo;
|
|
} else if (play->shootingGalleryStatus != 0) {
|
|
return play->shootingGalleryStatus;
|
|
} else {
|
|
return AMMO(*itemPtr);
|
|
}
|
|
}
|
|
|
|
// The player has pressed the bow or hookshot button
|
|
s32 func_8083442C(Player* this, PlayState* play) {
|
|
s32 item;
|
|
s32 arrowType;
|
|
s32 magicArrowType;
|
|
|
|
if ((this->heldItemAction >= PLAYER_IA_BOW_FIRE) && (this->heldItemAction <= PLAYER_IA_BOW_0E) &&
|
|
(gSaveContext.magicState != MAGIC_STATE_IDLE)) {
|
|
func_80078884(NA_SE_SY_ERROR);
|
|
} else {
|
|
Player_SetUpperActionFunc(this, func_808351D4);
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_READY_TO_FIRE;
|
|
this->unk_834 = 14;
|
|
|
|
if (this->unk_860 >= 0) {
|
|
Player_PlaySfx(this, D_80854398[ABS(this->unk_860) - 1]);
|
|
|
|
if (!Player_HoldsHookshot(this) && (func_80834380(play, this, &item, &arrowType) > 0)) {
|
|
magicArrowType = arrowType - ARROW_FIRE;
|
|
|
|
if (this->unk_860 >= 0) {
|
|
if ((magicArrowType >= 0) && (magicArrowType <= 2) &&
|
|
!Magic_RequestChange(play, sMagicArrowCosts[magicArrowType], MAGIC_CONSUME_NOW)) {
|
|
arrowType = ARROW_NORMAL;
|
|
}
|
|
|
|
this->heldActor = Actor_SpawnAsChild(
|
|
&play->actorCtx, &this->actor, play, ACTOR_EN_ARROW, this->actor.world.pos.x,
|
|
this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, arrowType);
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Player_FinishItemChange(PlayState* play, Player* this) {
|
|
if (this->heldItemAction != PLAYER_IA_NONE) {
|
|
if (func_8008F2BC(this, this->heldItemAction) >= 0) {
|
|
func_808328EC(this, NA_SE_IT_SWORD_PUTAWAY);
|
|
} else {
|
|
func_808328EC(this, NA_SE_PL_CHANGE_ARMS);
|
|
}
|
|
}
|
|
|
|
Player_UseItem(play, this, this->heldItemId);
|
|
|
|
if (func_8008F2BC(this, this->heldItemAction) >= 0) {
|
|
func_808328EC(this, NA_SE_IT_SWORD_PICKOUT);
|
|
} else if (this->heldItemAction != PLAYER_IA_NONE) {
|
|
func_808328EC(this, NA_SE_PL_CHANGE_ARMS);
|
|
}
|
|
}
|
|
|
|
void func_80834644(PlayState* play, Player* this) {
|
|
if (Player_UpperAction_ChangeHeldItem == this->upperActionFunc) {
|
|
Player_FinishItemChange(play, this);
|
|
}
|
|
|
|
Player_SetUpperActionFunc(this, sItemActionUpdateFuncs[this->heldItemAction]);
|
|
this->unk_834 = 0;
|
|
this->unk_6AC = 0;
|
|
Player_DetachHeldActor(play, this);
|
|
this->stateFlags1 &= ~PLAYER_STATE1_START_PUTAWAY;
|
|
}
|
|
|
|
LinkAnimationHeader* func_808346C4(PlayState* play, Player* this) {
|
|
Player_SetUpperActionFunc(this, func_80834B5C);
|
|
Player_DetachHeldActor(play, this);
|
|
|
|
if (this->unk_870 < 0.5f) {
|
|
return D_808543A4[Player_HoldsTwoHandedWeapon(this) &&
|
|
!(CVarGetInteger("gShieldTwoHanded", 0) && (this->heldItemAction != PLAYER_IA_DEKU_STICK))];
|
|
} else {
|
|
return D_808543AC[Player_HoldsTwoHandedWeapon(this) &&
|
|
!(CVarGetInteger("gShieldTwoHanded", 0) && (this->heldItemAction != PLAYER_IA_DEKU_STICK))];
|
|
}
|
|
}
|
|
|
|
s32 func_80834758(PlayState* play, Player* this) {
|
|
LinkAnimationHeader* anim;
|
|
f32 frame;
|
|
|
|
if (!(this->stateFlags1 & (PLAYER_STATE1_SHIELDING | PLAYER_STATE1_ON_HORSE | PLAYER_STATE1_IN_CUTSCENE)) &&
|
|
(play->shootingGalleryStatus == 0) && (this->heldItemAction == this->itemAction) &&
|
|
(this->currentShield != PLAYER_SHIELD_NONE) && !Player_IsChildWithHylianShield(this) && func_80833BCC(this) &&
|
|
CHECK_BTN_ALL(sControlInput->cur.button, BTN_R)) {
|
|
|
|
anim = func_808346C4(play, this);
|
|
frame = Animation_GetLastFrame(anim);
|
|
LinkAnimation_Change(play, &this->upperSkelAnime, anim, 1.0f, frame, frame, ANIMMODE_ONCE, 0.0f);
|
|
Player_PlaySfx(this, NA_SE_IT_SHIELD_POSTURE);
|
|
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
s32 func_8083485C(Player* this, PlayState* play) {
|
|
if (func_80834758(play, this)) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void func_80834894(Player* this) {
|
|
Player_SetUpperActionFunc(this, func_80834C74);
|
|
|
|
if (this->itemAction < 0) {
|
|
func_8008EC70(this);
|
|
}
|
|
|
|
Animation_Reverse(&this->upperSkelAnime);
|
|
Player_PlaySfx(this, NA_SE_IT_SHIELD_REMOVE);
|
|
}
|
|
|
|
void Player_WaitToFinishItemChange(PlayState* play, Player* this) {
|
|
ItemChangeInfo* itemChangeEntry = &sItemChangeInfo[this->itemChangeType];
|
|
f32 changeFrame;
|
|
|
|
changeFrame = itemChangeEntry->changeFrame;
|
|
changeFrame = (this->upperSkelAnime.playSpeed < 0.0f) ? changeFrame - 1.0f : changeFrame;
|
|
|
|
if (LinkAnimation_OnFrame(&this->upperSkelAnime, changeFrame)) {
|
|
Player_FinishItemChange(play, this);
|
|
}
|
|
|
|
func_80833B54(this);
|
|
}
|
|
|
|
s32 func_8083499C(Player* this, PlayState* play) {
|
|
if (this->stateFlags1 & PLAYER_STATE1_START_PUTAWAY) {
|
|
Player_StartChangingHeldItem(this, play);
|
|
} else {
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* The actual sword weapon is not handled here. See `Player_ActionChange_7` for melee weapon usage.
|
|
* This upper body action allows for shielding or changing held items while a sword is in hand.
|
|
*/
|
|
s32 Player_UpperAction_Sword(Player* this, PlayState* play) {
|
|
if (func_80834758(play, this) || func_8083499C(this, play)) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
s32 Player_UpperAction_ChangeHeldItem(Player* this, PlayState* play) {
|
|
if (LinkAnimation_Update(play, &this->upperSkelAnime) ||
|
|
((Player_ItemToItemAction(this->heldItemId) == this->heldItemAction) &&
|
|
(sUseHeldItem =
|
|
(sUseHeldItem || ((this->modelAnimType != PLAYER_ANIMTYPE_3) && (play->shootingGalleryStatus == 0)))))) {
|
|
Player_SetUpperActionFunc(this, sItemActionUpdateFuncs[this->heldItemAction]);
|
|
this->unk_834 = 0;
|
|
this->unk_6AC = 0;
|
|
sHeldItemButtonIsHeldDown = sUseHeldItem;
|
|
return this->upperActionFunc(this, play);
|
|
}
|
|
|
|
if (func_80833350(this) != 0) {
|
|
Player_WaitToFinishItemChange(play, this);
|
|
Player_AnimPlayOnce(play, this, func_80833338(this));
|
|
this->unk_6AC = 0;
|
|
} else {
|
|
Player_WaitToFinishItemChange(play, this);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 func_80834B5C(Player* this, PlayState* play) {
|
|
LinkAnimation_Update(play, &this->upperSkelAnime);
|
|
|
|
if (!CHECK_BTN_ALL(sControlInput->cur.button, BTN_R)) {
|
|
func_80834894(this);
|
|
return 1;
|
|
} else {
|
|
this->stateFlags1 |= PLAYER_STATE1_SHIELDING;
|
|
Player_SetModelsForHoldingShield(this);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
s32 func_80834BD4(Player* this, PlayState* play) {
|
|
LinkAnimationHeader* anim;
|
|
f32 frame;
|
|
|
|
if (LinkAnimation_Update(play, &this->upperSkelAnime)) {
|
|
anim = func_808346C4(play, this);
|
|
frame = Animation_GetLastFrame(anim);
|
|
LinkAnimation_Change(play, &this->upperSkelAnime, anim, 1.0f, frame, frame, ANIMMODE_ONCE, 0.0f);
|
|
}
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_SHIELDING;
|
|
Player_SetModelsForHoldingShield(this);
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 func_80834C74(Player* this, PlayState* play) {
|
|
sUseHeldItem = sHeldItemButtonIsHeldDown;
|
|
|
|
if (sUseHeldItem || LinkAnimation_Update(play, &this->upperSkelAnime)) {
|
|
Player_SetUpperActionFunc(this, sItemActionUpdateFuncs[this->heldItemAction]);
|
|
LinkAnimation_PlayLoop(play, &this->upperSkelAnime,
|
|
GET_PLAYER_ANIM(PLAYER_ANIMGROUP_wait, this->modelAnimType));
|
|
this->unk_6AC = 0;
|
|
this->upperActionFunc(this, play);
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 func_80834D2C(Player* this, PlayState* play) {
|
|
LinkAnimationHeader* anim;
|
|
|
|
if (this->heldItemAction != PLAYER_IA_BOOMERANG) {
|
|
if (!func_8083442C(this, play)) {
|
|
return 0;
|
|
}
|
|
|
|
if (!Player_HoldsHookshot(this)) {
|
|
anim = &gPlayerAnim_link_bow_bow_ready;
|
|
} else {
|
|
anim = &gPlayerAnim_link_hook_shot_ready;
|
|
}
|
|
LinkAnimation_PlayOnce(play, &this->upperSkelAnime, anim);
|
|
} else {
|
|
Player_SetUpperActionFunc(this, func_80835884);
|
|
this->unk_834 = 10;
|
|
LinkAnimation_PlayOnce(play, &this->upperSkelAnime, &gPlayerAnim_link_boom_throw_wait2waitR);
|
|
}
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_ON_HORSE) {
|
|
Player_AnimPlayLoop(play, this, &gPlayerAnim_link_uma_anim_walk);
|
|
} else if ((this->actor.bgCheckFlags & 1) && !func_80833B54(this)) {
|
|
Player_AnimPlayLoop(play, this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_wait, this->modelAnimType));
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int func_80834E44(PlayState* play) {
|
|
return (play->shootingGalleryStatus > 0) && CHECK_BTN_ALL(sControlInput->press.button, BTN_B);
|
|
}
|
|
|
|
int func_80834E7C(PlayState* play) {
|
|
u16 buttonsToCheck = BTN_A | BTN_B | BTN_CUP | BTN_CLEFT | BTN_CRIGHT | BTN_CDOWN;
|
|
if (CVarGetInteger("gDpadEquips", 0) != 0) {
|
|
buttonsToCheck |= BTN_DUP | BTN_DDOWN | BTN_DLEFT | BTN_DRIGHT;
|
|
}
|
|
return (play->shootingGalleryStatus != 0) &&
|
|
((play->shootingGalleryStatus < 0) ||
|
|
CHECK_BTN_ANY(sControlInput->cur.button, buttonsToCheck));
|
|
}
|
|
|
|
s32 func_80834EB8(Player* this, PlayState* play) {
|
|
if ((this->unk_6AD == 0) || (this->unk_6AD == 2)) {
|
|
if (func_80833BCC(this) ||
|
|
(Camera_CheckValidMode(Play_GetCamera(play, 0), 7) == 0)) {
|
|
return 1;
|
|
}
|
|
this->unk_6AD = 2;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_80834F2C(Player* this, PlayState* play) {
|
|
if ((this->doorType == PLAYER_DOORTYPE_NONE) && !(this->stateFlags1 & PLAYER_STATE1_THREW_BOOMERANG)) {
|
|
if (sUseHeldItem || func_80834E44(play)) {
|
|
if (func_80834D2C(this, play)) {
|
|
return func_80834EB8(this, play);
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_80834FBC(Player* this) {
|
|
if (this->actor.child != NULL) {
|
|
if (this->heldActor == NULL) {
|
|
this->heldActor = this->actor.child;
|
|
Player_RequestRumble(this, 255, 10, 250, 0);
|
|
Player_PlaySfx(this, NA_SE_IT_HOOKSHOT_RECEIVE);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_8083501C(Player* this, PlayState* play) {
|
|
if (this->unk_860 >= 0) {
|
|
this->unk_860 = -this->unk_860;
|
|
}
|
|
|
|
if ((!Player_HoldsHookshot(this) || func_80834FBC(this)) && !func_80834758(play, this) &&
|
|
!func_80834F2C(this, play)) {
|
|
return 0;
|
|
} else if (this->rideActor != NULL) {
|
|
this->unk_6AD = 2; // OTRTODO: THIS IS A BAD IDEA BUT IT FIXES THE HORSE FIRST PERSON?
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
// Fire the projectile
|
|
s32 func_808350A4(PlayState* play, Player* this) {
|
|
s32 item;
|
|
s32 arrowType;
|
|
|
|
if (this->heldActor != NULL) {
|
|
if (!Player_HoldsHookshot(this)) {
|
|
func_80834380(play, this, &item, &arrowType);
|
|
|
|
if (gSaveContext.minigameState == 1) {
|
|
if (!CVarGetInteger("gInfiniteAmmo", 0)) {
|
|
play->interfaceCtx.hbaAmmo--;
|
|
}
|
|
} else if (play->shootingGalleryStatus != 0) {
|
|
if (!CVarGetInteger("gInfiniteAmmo", 0)) {
|
|
play->shootingGalleryStatus--;
|
|
}
|
|
} else {
|
|
Inventory_ChangeAmmo(item, -1);
|
|
}
|
|
|
|
if (play->shootingGalleryStatus == 1) {
|
|
play->shootingGalleryStatus = -10;
|
|
}
|
|
|
|
Player_RequestRumble(this, 150, 10, 150, 0);
|
|
} else {
|
|
Player_RequestRumble(this, 255, 20, 150, 0);
|
|
}
|
|
|
|
this->unk_A73 = 4;
|
|
this->heldActor->parent = NULL;
|
|
this->actor.child = NULL;
|
|
this->heldActor = NULL;
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static u16 D_808543DC[] = { NA_SE_IT_BOW_FLICK, NA_SE_IT_SLING_FLICK };
|
|
|
|
s32 func_808351D4(Player* this, PlayState* play) {
|
|
s32 sp2C;
|
|
|
|
if (!Player_HoldsHookshot(this)) {
|
|
sp2C = 0;
|
|
} else {
|
|
sp2C = 1;
|
|
}
|
|
|
|
Math_ScaledStepToS(&this->unk_6C0, 1200, 400);
|
|
this->unk_6AE |= 0x100;
|
|
|
|
if ((this->unk_836 == 0) && (func_80833350(this) == 0) &&
|
|
(this->skelAnime.animation == &gPlayerAnim_link_bow_side_walk)) {
|
|
LinkAnimation_PlayOnce(play, &this->upperSkelAnime, D_808543CC[sp2C]);
|
|
this->unk_836 = -1;
|
|
} else if (LinkAnimation_Update(play, &this->upperSkelAnime)) {
|
|
LinkAnimation_PlayLoop(play, &this->upperSkelAnime, D_808543D4[sp2C]);
|
|
this->unk_836 = 1;
|
|
} else if (this->unk_836 == 1) {
|
|
this->unk_836 = 2;
|
|
}
|
|
|
|
if (this->unk_834 > 10) {
|
|
this->unk_834--;
|
|
}
|
|
|
|
func_80834EB8(this, play);
|
|
|
|
if ((this->unk_836 > 0) && ((this->unk_860 < 0) || (!sHeldItemButtonIsHeldDown && !func_80834E7C(play)))) {
|
|
Player_SetUpperActionFunc(this, func_808353D8);
|
|
if (this->unk_860 >= 0) {
|
|
if (sp2C == 0) {
|
|
if (!func_808350A4(play, this)) {
|
|
Player_PlaySfx(this, D_808543DC[ABS(this->unk_860) - 1]);
|
|
}
|
|
} else if (this->actor.bgCheckFlags & 1) {
|
|
func_808350A4(play, this);
|
|
}
|
|
}
|
|
this->unk_834 = 10;
|
|
Player_ZeroSpeedXZ(this);
|
|
} else {
|
|
this->stateFlags1 |= PLAYER_STATE1_READY_TO_FIRE;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 func_808353D8(Player* this, PlayState* play) {
|
|
LinkAnimation_Update(play, &this->upperSkelAnime);
|
|
|
|
if (Player_HoldsHookshot(this) && !func_80834FBC(this)) {
|
|
return 1;
|
|
}
|
|
|
|
if (!func_80834758(play, this) &&
|
|
(sUseHeldItem || ((this->unk_860 < 0) && sHeldItemButtonIsHeldDown) || func_80834E44(play))) {
|
|
this->unk_860 = ABS(this->unk_860);
|
|
|
|
if (func_8083442C(this, play)) {
|
|
if (Player_HoldsHookshot(this)) {
|
|
this->unk_836 = 1;
|
|
} else {
|
|
LinkAnimation_PlayOnce(play, &this->upperSkelAnime, &gPlayerAnim_link_bow_bow_shoot_next);
|
|
}
|
|
}
|
|
} else {
|
|
if (this->unk_834 != 0) {
|
|
this->unk_834--;
|
|
}
|
|
|
|
if (func_80833BCC(this) || (this->unk_6AD != 0) || (this->stateFlags1 & PLAYER_STATE1_FIRST_PERSON)) {
|
|
if (this->unk_834 == 0) {
|
|
this->unk_834++;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
if (Player_HoldsHookshot(this)) {
|
|
Player_SetUpperActionFunc(this, func_8083501C);
|
|
} else {
|
|
Player_SetUpperActionFunc(this, func_80835588);
|
|
LinkAnimation_PlayOnce(play, &this->upperSkelAnime, &gPlayerAnim_link_bow_bow_shoot_end);
|
|
}
|
|
|
|
this->unk_834 = 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 func_80835588(Player* this, PlayState* play) {
|
|
if (!(this->actor.bgCheckFlags & 1) || LinkAnimation_Update(play, &this->upperSkelAnime)) {
|
|
Player_SetUpperActionFunc(this, func_8083501C);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void func_808355DC(Player* this) {
|
|
this->stateFlags1 |= PLAYER_STATE1_TARGET_NOTHING;
|
|
|
|
if (!(this->skelAnime.moveFlags & 0x80) && (this->actor.bgCheckFlags & 0x200) && (sShapeYawToTouchedWall < 0x2000)) {
|
|
this->yaw = this->actor.shape.rot.y = this->actor.wallYaw + 0x8000;
|
|
}
|
|
|
|
this->zTargetYaw = this->actor.shape.rot.y;
|
|
}
|
|
|
|
s32 func_80835644(PlayState* play, Player* this, Actor* arg2) {
|
|
if (arg2 == NULL) {
|
|
func_80832564(play, this);
|
|
func_80839F90(this, play);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_80835688(Player* this, PlayState* play) {
|
|
if (!func_80835644(play, this, this->heldActor)) {
|
|
Player_SetUpperActionFunc(this, Player_UpperAction_CarryActor);
|
|
LinkAnimation_PlayLoop(play, &this->upperSkelAnime, &gPlayerAnim_link_normal_carryB_wait);
|
|
}
|
|
}
|
|
|
|
s32 Player_UpperAction_CarryActor(Player* this, PlayState* play) {
|
|
Actor* heldActor = this->heldActor;
|
|
|
|
if (heldActor == NULL) {
|
|
func_80834644(play, this);
|
|
}
|
|
|
|
if (func_80834758(play, this)) {
|
|
return 1;
|
|
}
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) {
|
|
if (LinkAnimation_Update(play, &this->upperSkelAnime)) {
|
|
LinkAnimation_PlayLoop(play, &this->upperSkelAnime, &gPlayerAnim_link_normal_carryB_wait);
|
|
}
|
|
|
|
if ((heldActor->id == ACTOR_EN_NIW) && (this->actor.velocity.y <= 0.0f)) {
|
|
this->actor.minVelocityY = -2.0f;
|
|
this->actor.gravity = -0.5f;
|
|
this->fallStartHeight = this->actor.world.pos.y;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
return func_8083485C(this, play);
|
|
}
|
|
|
|
void func_808357E8(Player* this, Gfx** dLists) {
|
|
if (LINK_IS_ADULT && (CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0))) {
|
|
this->leftHandDLists = &dLists[1];
|
|
} else {
|
|
this->leftHandDLists = &dLists[gSaveContext.linkAge];
|
|
}
|
|
}
|
|
|
|
s32 func_80835800(Player* this, PlayState* play) {
|
|
if (func_80834758(play, this)) {
|
|
return 1;
|
|
}
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_THREW_BOOMERANG) {
|
|
Player_SetUpperActionFunc(this, func_80835B60);
|
|
} else if (func_80834F2C(this, play)) {
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_80835884(Player* this, PlayState* play) {
|
|
if (LinkAnimation_Update(play, &this->upperSkelAnime)) {
|
|
Player_SetUpperActionFunc(this, func_808358F0);
|
|
LinkAnimation_PlayLoop(play, &this->upperSkelAnime, &gPlayerAnim_link_boom_throw_waitR);
|
|
}
|
|
|
|
func_80834EB8(this, play);
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 func_808358F0(Player* this, PlayState* play) {
|
|
LinkAnimationHeader* animSeg = this->skelAnime.animation;
|
|
|
|
if ((func_808334E4(this) == animSeg) || (func_80833528(this) == animSeg) || (func_808335B0(this) == animSeg) ||
|
|
(func_808335F4(this) == animSeg)) {
|
|
AnimationContext_SetCopyAll(play, this->skelAnime.limbCount, this->upperSkelAnime.jointTable,
|
|
this->skelAnime.jointTable);
|
|
} else {
|
|
LinkAnimation_Update(play, &this->upperSkelAnime);
|
|
}
|
|
|
|
func_80834EB8(this, play);
|
|
|
|
if (!sHeldItemButtonIsHeldDown) {
|
|
Player_SetUpperActionFunc(this, func_808359FC);
|
|
LinkAnimation_PlayOnce(play, &this->upperSkelAnime,
|
|
(this->unk_870 < 0.5f) ? &gPlayerAnim_link_boom_throwR : &gPlayerAnim_link_boom_throwL);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 func_808359FC(Player* this, PlayState* play) {
|
|
if (LinkAnimation_Update(play, &this->upperSkelAnime)) {
|
|
Player_SetUpperActionFunc(this, func_80835B60);
|
|
this->unk_834 = 0;
|
|
} else if (LinkAnimation_OnFrame(&this->upperSkelAnime, 6.0f)) {
|
|
f32 posX = (Math_SinS(this->actor.shape.rot.y) * 10.0f) + this->actor.world.pos.x;
|
|
f32 posZ = (Math_CosS(this->actor.shape.rot.y) * 10.0f) + this->actor.world.pos.z;
|
|
s32 yaw = (this->unk_664 != NULL) ? this->actor.shape.rot.y + 14000 : this->actor.shape.rot.y;
|
|
EnBoom* boomerang =
|
|
(EnBoom*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_BOOM, posX, this->actor.world.pos.y + 30.0f, posZ,
|
|
this->actor.focus.rot.x, yaw, 0, 0, true);
|
|
|
|
this->boomerangActor = &boomerang->actor;
|
|
if (boomerang != NULL) {
|
|
boomerang->moveTo = this->unk_664;
|
|
boomerang->returnTimer = 20;
|
|
this->stateFlags1 |= PLAYER_STATE1_THREW_BOOMERANG;
|
|
if (!func_8008E9C4(this)) {
|
|
func_808355DC(this);
|
|
}
|
|
this->unk_A73 = 4;
|
|
Player_PlaySfx(this, NA_SE_IT_BOOMERANG_THROW);
|
|
func_80832698(this, NA_SE_VO_LI_SWORD_N);
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 spawn_boomerang_ivan(EnPartner* this, PlayState* play) {
|
|
if (!CVarGetInteger("gIvanCoopModeEnabled", 0)) {
|
|
return 0;
|
|
}
|
|
|
|
f32 posX = (Math_SinS(this->actor.shape.rot.y) * 1.0f) + this->actor.world.pos.x;
|
|
f32 posZ = (Math_CosS(this->actor.shape.rot.y) * 1.0f) + this->actor.world.pos.z;
|
|
s32 yaw = this->actor.shape.rot.y;
|
|
EnBoom* boomerang =
|
|
(EnBoom*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_BOOM, posX, this->actor.world.pos.y + 7.0f, posZ,
|
|
this->actor.focus.rot.x, yaw, 0, 0, true);
|
|
|
|
this->boomerangActor = &boomerang->actor;
|
|
if (boomerang != NULL) {
|
|
boomerang->returnTimer = 20;
|
|
Audio_PlayActorSound2(&this->actor, NA_SE_IT_BOOMERANG_THROW);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 func_80835B60(Player* this, PlayState* play) {
|
|
if (func_80834758(play, this)) {
|
|
return 1;
|
|
}
|
|
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_THREW_BOOMERANG)) {
|
|
Player_SetUpperActionFunc(this, func_80835C08);
|
|
LinkAnimation_PlayOnce(play, &this->upperSkelAnime, &gPlayerAnim_link_boom_catch);
|
|
func_808357E8(this, gPlayerLeftHandBoomerangDLs);
|
|
Player_PlaySfx(this, NA_SE_PL_CATCH_BOOMERANG);
|
|
func_80832698(this, NA_SE_VO_LI_SWORD_N);
|
|
return 1;
|
|
}
|
|
|
|
if (sUseHeldItem && CVarGetInteger("gFastBoomerang", 0)) {
|
|
this->boomerangQuickRecall = true;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_80835C08(Player* this, PlayState* play) {
|
|
if (!func_80835800(this, play) && LinkAnimation_Update(play, &this->upperSkelAnime)) {
|
|
Player_SetUpperActionFunc(this, func_80835800);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 Player_SetupAction(PlayState* play, Player* this, PlayerActionFunc actionFunc, s32 flags) {
|
|
if (actionFunc == this->actionFunc) {
|
|
return 0;
|
|
}
|
|
|
|
if (Player_Action_8084E3C4 == this->actionFunc) {
|
|
Audio_OcaSetInstrument(0);
|
|
this->stateFlags2 &= ~(PLAYER_STATE2_ATTEMPT_PLAY_FOR_ACTOR | PLAYER_STATE2_PLAY_FOR_ACTOR);
|
|
} else if (Player_Action_808507F4 == this->actionFunc) {
|
|
func_80832340(play, this);
|
|
}
|
|
|
|
this->actionFunc = actionFunc;
|
|
|
|
if ((this->itemAction != this->heldItemAction) && (!(flags & 1) || !(this->stateFlags1 & PLAYER_STATE1_SHIELDING))) {
|
|
func_8008EC70(this);
|
|
}
|
|
|
|
if (!(flags & 1) && !(this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD)) {
|
|
func_80834644(play, this);
|
|
this->stateFlags1 &= ~PLAYER_STATE1_SHIELDING;
|
|
}
|
|
|
|
func_80832DBC(this);
|
|
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_HOOKSHOT_FALLING | PLAYER_STATE1_TEXT_ON_SCREEN | PLAYER_STATE1_DAMAGED | PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE |
|
|
PLAYER_STATE1_FLOOR_DISABLED);
|
|
this->stateFlags2 &= ~(PLAYER_STATE2_HOPPING | PLAYER_STATE2_OCARINA_PLAYING | PLAYER_STATE2_IDLING);
|
|
this->stateFlags3 &= ~(PLAYER_STATE3_MIDAIR | PLAYER_STATE3_FINISHED_ATTACKING | PLAYER_STATE3_HOOKSHOT_TRAVELLING);
|
|
|
|
this->av1.actionVar1 = 0;
|
|
this->av2.actionVar2 = 0;
|
|
|
|
this->unk_6AC = 0;
|
|
|
|
func_808326F0(this);
|
|
|
|
return 1;
|
|
}
|
|
|
|
void func_80835DAC(PlayState* play, Player* this, PlayerActionFunc actionFunc, s32 flags) {
|
|
s32 temp;
|
|
|
|
temp = this->skelAnime.moveFlags;
|
|
this->skelAnime.moveFlags = 0;
|
|
Player_SetupAction(play, this, actionFunc, flags);
|
|
this->skelAnime.moveFlags = temp;
|
|
}
|
|
|
|
void func_80835DE4(PlayState* play, Player* this, PlayerActionFunc actionFunc, s32 flags) {
|
|
s32 temp;
|
|
|
|
if (this->itemAction >= 0) {
|
|
temp = this->itemAction;
|
|
this->itemAction = this->heldItemAction;
|
|
Player_SetupAction(play, this, actionFunc, flags);
|
|
this->itemAction = temp;
|
|
Player_SetModels(this, Player_ActionToModelGroup(this, this->itemAction));
|
|
}
|
|
}
|
|
|
|
void func_80835E44(PlayState* play, s16 camSetting) {
|
|
if (!func_800C0CB8(play)) {
|
|
if (camSetting == CAM_SET_SCENE_TRANSITION) {
|
|
Interface_ChangeAlpha(2);
|
|
}
|
|
} else {
|
|
Camera_ChangeSetting(Play_GetCamera(play, 0), camSetting);
|
|
}
|
|
}
|
|
|
|
void func_80835EA4(PlayState* play, s32 arg1) {
|
|
func_80835E44(play, CAM_SET_TURN_AROUND);
|
|
Camera_SetCameraData(Play_GetCamera(play, 0), 4, NULL, NULL, arg1, 0, 0);
|
|
}
|
|
|
|
void Player_DestroyHookshot(Player* this) {
|
|
if (Player_HoldsHookshot(this)) {
|
|
Actor* heldActor = this->heldActor;
|
|
|
|
if (heldActor != NULL) {
|
|
Actor_Kill(heldActor);
|
|
this->actor.child = NULL;
|
|
this->heldActor = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_UseItem(PlayState* play, Player* this, s32 item) {
|
|
s8 itemAction;
|
|
s32 temp;
|
|
s32 nextAnimType;
|
|
|
|
itemAction = Player_ItemToItemAction(item);
|
|
|
|
if (((this->heldItemAction == this->itemAction) &&
|
|
(!(this->stateFlags1 & PLAYER_STATE1_SHIELDING) || (Player_ActionToMeleeWeapon(itemAction) != 0) ||
|
|
(itemAction == PLAYER_IA_NONE))) ||
|
|
((this->itemAction < 0) && ((Player_ActionToMeleeWeapon(itemAction) != 0) || (itemAction == PLAYER_IA_NONE)))) {
|
|
|
|
if ((itemAction == PLAYER_IA_NONE) || !(this->stateFlags1 & PLAYER_STATE1_IN_WATER) ||
|
|
((this->actor.bgCheckFlags & 1) &&
|
|
((itemAction == PLAYER_IA_HOOKSHOT) || (itemAction == PLAYER_IA_LONGSHOT)))) {
|
|
|
|
if ((play->bombchuBowlingStatus == 0) &&
|
|
(((itemAction == PLAYER_IA_DEKU_STICK) && (AMMO(ITEM_STICK) == 0)) ||
|
|
((itemAction == PLAYER_IA_MAGIC_BEAN) && (AMMO(ITEM_BEAN) == 0)) ||
|
|
(temp = Player_ActionToExplosive(this, itemAction),
|
|
((temp >= 0) && ((AMMO(sExplosiveInfos[temp].itemId) == 0) ||
|
|
(play->actorCtx.actorLists[ACTORCAT_EXPLOSIVE].length >= 3 && !CVarGetInteger("gRemoveExplosiveLimit", 0))))))) {
|
|
// Prevent some items from being used if player is out of ammo.
|
|
// Also prevent explosives from being used if there are 3 or more active (outside of bombchu bowling)
|
|
func_80078884(NA_SE_SY_ERROR);
|
|
} else if (itemAction == PLAYER_IA_LENS_OF_TRUTH) {
|
|
// Handle Lens of Truth
|
|
if (Magic_RequestChange(play, 0, MAGIC_CONSUME_LENS)) {
|
|
if (play->actorCtx.lensActive) {
|
|
Actor_DisableLens(play);
|
|
} else {
|
|
play->actorCtx.lensActive = true;
|
|
}
|
|
func_80078884((play->actorCtx.lensActive) ? NA_SE_SY_GLASSMODE_ON : NA_SE_SY_GLASSMODE_OFF);
|
|
} else {
|
|
func_80078884(NA_SE_SY_ERROR);
|
|
}
|
|
} else if (itemAction == PLAYER_IA_DEKU_NUT) {
|
|
// Handle Deku Nuts
|
|
if (AMMO(ITEM_NUT) != 0) {
|
|
func_8083C61C(play, this);
|
|
} else {
|
|
func_80078884(NA_SE_SY_ERROR);
|
|
}
|
|
} else if ((temp = Player_ActionToMagicSpell(this, itemAction)) >= 0) {
|
|
// Handle magic spells
|
|
if (((itemAction == PLAYER_IA_FARORES_WIND) && (gSaveContext.respawn[RESPAWN_MODE_TOP].data > 0)) ||
|
|
((gSaveContext.magicCapacity != 0) && (gSaveContext.magicState == MAGIC_STATE_IDLE) &&
|
|
(gSaveContext.magic >= sMagicSpellCosts[temp]))) {
|
|
this->itemAction = itemAction;
|
|
this->unk_6AD = 4;
|
|
} else {
|
|
func_80078884(NA_SE_SY_ERROR);
|
|
}
|
|
} else if (itemAction >= PLAYER_IA_MASK_KEATON) {
|
|
// Handle wearable masks
|
|
if (this->currentMask != PLAYER_MASK_NONE) {
|
|
this->currentMask = PLAYER_MASK_NONE;
|
|
} else {
|
|
this->currentMask = itemAction - PLAYER_IA_MASK_KEATON + 1;
|
|
}
|
|
|
|
sMaskMemory = this->currentMask;
|
|
func_808328EC(this, NA_SE_PL_CHANGE_ARMS);
|
|
} else if (((itemAction >= PLAYER_IA_OCARINA_FAIRY) && (itemAction <= PLAYER_IA_OCARINA_OF_TIME)) ||
|
|
(itemAction >= PLAYER_IA_BOTTLE_FISH)) {
|
|
// Handle "cutscene items"
|
|
if (!func_8008E9C4(this) ||
|
|
((itemAction >= PLAYER_IA_BOTTLE_POTION_RED) && (itemAction <= PLAYER_IA_BOTTLE_FAIRY))) {
|
|
func_8002D53C(play, &play->actorCtx.titleCtx);
|
|
this->unk_6AD = 4;
|
|
this->itemAction = itemAction;
|
|
}
|
|
} else if ((itemAction != this->heldItemAction) ||
|
|
((this->heldActor == NULL) && (Player_ActionToExplosive(this, itemAction) >= 0))) {
|
|
// Handle using a new held item
|
|
this->nextModelGroup = Player_ActionToModelGroup(this, itemAction);
|
|
nextAnimType = gPlayerModelTypes[this->nextModelGroup][PLAYER_MODELGROUPENTRY_ANIM];
|
|
|
|
if ((this->heldItemAction >= 0) && (Player_ActionToMagicSpell(this, itemAction) < 0) &&
|
|
(item != this->heldItemId) &&
|
|
(sItemChangeTypes[gPlayerModelTypes[this->modelGroup][PLAYER_MODELGROUPENTRY_ANIM]][nextAnimType] !=
|
|
PLAYER_ITEM_CHG_0) &&
|
|
(!CVarGetInteger("gSeparateArrows", 0) ||
|
|
itemAction < PLAYER_IA_BOW || itemAction > PLAYER_IA_BOW_0E ||
|
|
this->heldItemAction < PLAYER_IA_BOW || this->heldItemAction > PLAYER_IA_BOW_0E)) {
|
|
// Start the held item change process
|
|
this->heldItemId = item;
|
|
this->stateFlags1 |= PLAYER_STATE1_START_PUTAWAY;
|
|
} else {
|
|
// Init new held item for use
|
|
Player_DestroyHookshot(this);
|
|
Player_DetachHeldActor(play, this);
|
|
Player_InitItemActionWithAnim(play, this, itemAction);
|
|
}
|
|
} else {
|
|
// Handle using the held item already in hand
|
|
sUseHeldItem = sHeldItemButtonIsHeldDown = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void func_80836448(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
s32 cond = func_808332B8(this);
|
|
|
|
func_80832564(play, this);
|
|
|
|
Player_SetupAction(play, this, cond ? Player_Action_8084E368 : Player_Action_80843CEC, 0);
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_DEAD;
|
|
|
|
Player_AnimPlayOnce(play, this, anim);
|
|
if (anim == &gPlayerAnim_link_derth_rebirth) {
|
|
this->skelAnime.endFrame = 84.0f;
|
|
}
|
|
|
|
func_80832224(this);
|
|
func_80832698(this, NA_SE_VO_LI_DOWN);
|
|
|
|
if (this->actor.category == ACTORCAT_PLAYER) {
|
|
func_800F47BC();
|
|
|
|
if (Inventory_ConsumeFairy(play)) {
|
|
play->gameOverCtx.state = GAMEOVER_REVIVE_START;
|
|
this->av1.actionVar1 = 1;
|
|
} else {
|
|
play->gameOverCtx.state = GAMEOVER_DEATH_START;
|
|
func_800F6AB0(0);
|
|
Audio_PlayFanfare(NA_BGM_GAME_OVER);
|
|
gSaveContext.seqId = (u8)NA_BGM_DISABLED;
|
|
gSaveContext.natureAmbienceId = NATURE_ID_DISABLED;
|
|
}
|
|
|
|
OnePointCutscene_Init(play, 9806, cond ? 120 : 60, &this->actor, MAIN_CAM);
|
|
ShrinkWindow_SetVal(0x20);
|
|
}
|
|
}
|
|
|
|
s32 Player_CanUpdateItems(Player* this) {
|
|
return (!(Player_Action_808458D0 == this->actionFunc) ||
|
|
((this->stateFlags1 & PLAYER_STATE1_START_PUTAWAY) &&
|
|
((this->heldItemId == ITEM_LAST_USED) || (this->heldItemId == ITEM_NONE)))) &&
|
|
(!(Player_UpperAction_ChangeHeldItem == this->upperActionFunc) ||
|
|
(Player_ItemToItemAction(this->heldItemId) == this->heldItemAction));
|
|
}
|
|
|
|
s32 Player_UpdateUpperBody(Player* this, PlayState* play) {
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_ON_HORSE) && (this->actor.parent != NULL) && Player_HoldsHookshot(this)) {
|
|
Player_SetupAction(play, this, Player_Action_80850AEC, 1);
|
|
this->stateFlags3 |= PLAYER_STATE3_HOOKSHOT_TRAVELLING;
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_hook_fly_start);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x9B);
|
|
func_80832224(this);
|
|
this->yaw = this->actor.shape.rot.y;
|
|
this->actor.bgCheckFlags &= ~1;
|
|
this->hoverBootsTimer = 0;
|
|
this->unk_6AE |= 0x43;
|
|
func_80832698(this, NA_SE_VO_LI_LASH);
|
|
return 1;
|
|
}
|
|
|
|
if (Player_CanUpdateItems(this)) {
|
|
Player_UpdateItems(this, play);
|
|
if (Player_Action_8084E604 == this->actionFunc) {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (!this->upperActionFunc(this, play)) {
|
|
return 0;
|
|
}
|
|
|
|
if (this->upperAnimBlendWeight != 0.0f) {
|
|
if ((func_80833350(this) == 0) || (this->linearVelocity != 0.0f)) {
|
|
AnimationContext_SetCopyFalse(play, this->skelAnime.limbCount, this->upperSkelAnime.jointTable,
|
|
this->skelAnime.jointTable, sUpperBodyLimbCopyMap);
|
|
}
|
|
Math_StepToF(&this->upperAnimBlendWeight, 0.0f, 0.25f);
|
|
AnimationContext_SetInterp(play, this->skelAnime.limbCount, this->skelAnime.jointTable,
|
|
this->upperSkelAnime.jointTable, 1.0f - this->upperAnimBlendWeight);
|
|
} else if ((func_80833350(this) == 0) || (this->linearVelocity != 0.0f)) {
|
|
AnimationContext_SetCopyTrue(play, this->skelAnime.limbCount, this->skelAnime.jointTable,
|
|
this->upperSkelAnime.jointTable, sUpperBodyLimbCopyMap);
|
|
} else {
|
|
AnimationContext_SetCopyAll(play, this->skelAnime.limbCount, this->skelAnime.jointTable,
|
|
this->upperSkelAnime.jointTable);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 func_80836898(PlayState* play, Player* this, PlayerFuncA74 func) {
|
|
this->func_A74 = func;
|
|
Player_SetupAction(play, this, Player_Action_808458D0, 0);
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
return func_80832528(play, this);
|
|
}
|
|
|
|
void func_808368EC(Player* this, PlayState* play) {
|
|
s16 previousYaw = this->actor.shape.rot.y;
|
|
|
|
if (!(this->stateFlags2 & (PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET | PLAYER_STATE2_DISABLE_ROTATION_ALWAYS))) {
|
|
if ((this->unk_664 != NULL) &&
|
|
((play->actorCtx.targetCtx.unk_4B != 0) || (this->actor.category != ACTORCAT_PLAYER))) {
|
|
Math_ScaledStepToS(&this->actor.shape.rot.y,
|
|
Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_664->focus.pos), 4000);
|
|
} else if ((this->stateFlags1 & PLAYER_STATE1_TARGET_NOTHING) &&
|
|
!(this->stateFlags2 & (PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET | PLAYER_STATE2_DISABLE_ROTATION_ALWAYS))) {
|
|
Math_ScaledStepToS(&this->actor.shape.rot.y, this->zTargetYaw, 4000);
|
|
}
|
|
} else if (!(this->stateFlags2 & PLAYER_STATE2_DISABLE_ROTATION_ALWAYS)) {
|
|
Math_ScaledStepToS(&this->actor.shape.rot.y, this->yaw, 2000);
|
|
}
|
|
|
|
this->unk_87C = this->actor.shape.rot.y - previousYaw;
|
|
}
|
|
|
|
s32 func_808369C8(s16* pValue, s16 arg1, s16 arg2, s16 arg3, s16 arg4, s16 arg5) {
|
|
s16 temp1;
|
|
s16 temp2;
|
|
s16 temp3;
|
|
|
|
temp1 = temp2 = arg4 - *pValue;
|
|
temp2 = CLAMP(temp2, -arg5, arg5);
|
|
*pValue += (s16)(temp1 - temp2);
|
|
|
|
Math_ScaledStepToS(pValue, arg1, arg2);
|
|
|
|
temp3 = *pValue;
|
|
if (*pValue < -arg3) {
|
|
*pValue = -arg3;
|
|
} else if (*pValue > arg3) {
|
|
*pValue = arg3;
|
|
}
|
|
return temp3 - *pValue;
|
|
}
|
|
|
|
s32 func_80836AB8(Player* this, s32 arg1) {
|
|
s16 sp36;
|
|
s16 var;
|
|
|
|
var = this->actor.shape.rot.y;
|
|
if (arg1 != 0) {
|
|
var = this->actor.focus.rot.y;
|
|
this->unk_6BC = this->actor.focus.rot.x;
|
|
this->unk_6AE |= 0x41;
|
|
} else {
|
|
func_808369C8(&this->unk_6BC,
|
|
func_808369C8(&this->unk_6B6, this->actor.focus.rot.x, 600, 10000, this->actor.focus.rot.x, 0),
|
|
200, 4000, this->unk_6B6, 10000);
|
|
sp36 = this->actor.focus.rot.y - var;
|
|
func_808369C8(&sp36, 0, 200, 24000, this->unk_6BE, 8000);
|
|
var = this->actor.focus.rot.y - sp36;
|
|
func_808369C8(&this->unk_6B8, sp36 - this->unk_6BE, 200, 8000, sp36, 8000);
|
|
func_808369C8(&this->unk_6BE, sp36, 200, 8000, this->unk_6B8, 8000);
|
|
this->unk_6AE |= 0xD9;
|
|
}
|
|
|
|
return var;
|
|
}
|
|
|
|
void func_80836BEC(Player* this, PlayState* play) {
|
|
s32 sp1C = 0;
|
|
s32 zTrigPressed = CHECK_BTN_ALL(sControlInput->cur.button, BTN_Z);
|
|
Actor* actorToTarget;
|
|
s32 pad;
|
|
s32 holdTarget;
|
|
s32 cond;
|
|
|
|
if (!zTrigPressed) {
|
|
this->stateFlags1 &= ~PLAYER_STATE1_30;
|
|
}
|
|
|
|
if ((play->csCtx.state != CS_STATE_IDLE) || (this->csAction != 0) ||
|
|
(this->stateFlags1 & (PLAYER_STATE1_DEAD | PLAYER_STATE1_IN_CUTSCENE)) || (this->stateFlags3 & PLAYER_STATE3_HOOKSHOT_TRAVELLING)) {
|
|
this->unk_66C = 0;
|
|
} else if (zTrigPressed || (this->stateFlags2 & PLAYER_STATE2_SWITCH_TARGETING) || (this->unk_684 != NULL)) {
|
|
if (this->unk_66C <= 5) {
|
|
this->unk_66C = 5;
|
|
} else {
|
|
this->unk_66C--;
|
|
}
|
|
} else if (this->stateFlags1 & PLAYER_STATE1_TARGET_NOTHING) {
|
|
this->unk_66C = 0;
|
|
} else if (this->unk_66C != 0) {
|
|
this->unk_66C--;
|
|
}
|
|
|
|
if (this->unk_66C >= 6) {
|
|
sp1C = 1;
|
|
}
|
|
|
|
cond = func_8083224C(play);
|
|
if (cond || (this->unk_66C != 0) || (this->stateFlags1 & (PLAYER_STATE1_CHARGING_SPIN_ATTACK | PLAYER_STATE1_THREW_BOOMERANG))) {
|
|
if (!cond) {
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_THREW_BOOMERANG) &&
|
|
((this->heldItemAction != PLAYER_IA_FISHING_POLE) || (this->unk_860 == 0)) &&
|
|
CHECK_BTN_ALL(sControlInput->press.button, BTN_Z)) {
|
|
|
|
if (this->actor.category == ACTORCAT_PLAYER) {
|
|
actorToTarget = play->actorCtx.targetCtx.arrowPointedActor;
|
|
} else {
|
|
actorToTarget = &GET_PLAYER(play)->actor;
|
|
}
|
|
|
|
holdTarget = (gSaveContext.zTargetSetting != 0) || (this->actor.category != ACTORCAT_PLAYER);
|
|
this->stateFlags1 |= PLAYER_STATE1_TARGETING;
|
|
|
|
if ((actorToTarget != NULL) && !(actorToTarget->flags & ACTOR_FLAG_NO_LOCKON)) {
|
|
if ((actorToTarget == this->unk_664) && (this->actor.category == ACTORCAT_PLAYER)) {
|
|
actorToTarget = play->actorCtx.targetCtx.unk_94;
|
|
}
|
|
|
|
if (actorToTarget != this->unk_664) {
|
|
if (!holdTarget) {
|
|
this->stateFlags2 |= PLAYER_STATE2_SWITCH_TARGETING;
|
|
}
|
|
this->unk_664 = actorToTarget;
|
|
this->unk_66C = 15;
|
|
this->stateFlags2 &= ~(PLAYER_STATE2_SPEAK_OR_CHECK | PLAYER_STATE2_NAVI_ALERT);
|
|
} else {
|
|
if (!holdTarget) {
|
|
func_8008EDF0(this);
|
|
}
|
|
}
|
|
|
|
this->stateFlags1 &= ~PLAYER_STATE1_30;
|
|
} else {
|
|
if (!(this->stateFlags1 & (PLAYER_STATE1_TARGET_NOTHING | PLAYER_STATE1_30))) {
|
|
func_808355DC(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this->unk_664 != NULL) {
|
|
if ((this->actor.category == ACTORCAT_PLAYER) && (this->unk_664 != this->unk_684) &&
|
|
func_8002F0C8(this->unk_664, this, sp1C)) {
|
|
func_8008EDF0(this);
|
|
this->stateFlags1 |= PLAYER_STATE1_30;
|
|
} else if (this->unk_664 != NULL) {
|
|
this->unk_664->targetPriority = 40;
|
|
}
|
|
} else if (this->unk_684 != NULL) {
|
|
this->unk_664 = this->unk_684;
|
|
}
|
|
}
|
|
|
|
if (this->unk_664 != NULL) {
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_TARGET_LOCKED | PLAYER_STATE1_TARGET_NOTHING);
|
|
if ((this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) ||
|
|
!CHECK_FLAG_ALL(this->unk_664->flags, ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE)) {
|
|
this->stateFlags1 |= PLAYER_STATE1_TARGET_LOCKED;
|
|
}
|
|
} else {
|
|
if (this->stateFlags1 & PLAYER_STATE1_TARGET_NOTHING) {
|
|
this->stateFlags2 &= ~PLAYER_STATE2_SWITCH_TARGETING;
|
|
} else {
|
|
func_8008EE08(this);
|
|
}
|
|
}
|
|
} else {
|
|
func_8008EE08(this);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* These defines exist to simplify the variable used to toggle the different speed modes.
|
|
* While the `speedMode` variable is a float and can contain a non-boolean value,
|
|
* `Player_CalcSpeedAndYawFromControlStick` never actually uses the value for anything.
|
|
* It simply checks if the value is non-zero to toggle the "curved" mode.
|
|
* In practice, 0.0f or 0.018f are the only values passed to this function.
|
|
*
|
|
* It's clear that this value was intended to mean something in the curved mode calculation at
|
|
* some point in development, but was either never implemented or removed.
|
|
*
|
|
* To see the difference between linear and curved mode, with interactive toggles for
|
|
* speed cap and floor pitch, see the following desmos graph: https://www.desmos.com/calculator/hri7dcws4c
|
|
*/
|
|
|
|
// Linear mode is a straight line, increasing target speed at a steady rate relative to the control stick magnitude
|
|
#define SPEED_MODE_LINEAR 0.0f
|
|
|
|
// Curved mode drops any input below 20 units of magnitude, resulting in zero for target speed.
|
|
// Beyond 20 units, a gradual curve slowly moves up until around the 40 unit mark
|
|
// when target speed ramps up very quickly.
|
|
#define SPEED_MODE_CURVED 0.018f
|
|
|
|
/**
|
|
* Calculates target speed and yaw based on input from the control stick.
|
|
* See `Player_GetMovementSpeedAndYaw` for detailed argument descriptions.
|
|
*
|
|
* @return true if the control stick has any magnitude, false otherwise.
|
|
*/
|
|
s32 Player_CalcSpeedAndYawFromControlStick(PlayState* play, Player* this, f32* outSpeedTarget, s16* outYawTarget,
|
|
f32 speedMode) {
|
|
f32 temp;
|
|
f32 sinFloorPitch;
|
|
f32 floorPitchInfluence;
|
|
f32 speedCap;
|
|
|
|
if ((this->unk_6AD != 0) || (play->transitionTrigger == TRANS_TRIGGER_START) ||
|
|
(this->stateFlags1 & PLAYER_STATE1_LOADING)) {
|
|
*outSpeedTarget = 0.0f;
|
|
*outYawTarget = this->actor.shape.rot.y;
|
|
} else {
|
|
*outSpeedTarget = sControlStickMagnitude;
|
|
*outYawTarget = sControlStickAngle;
|
|
|
|
// The value of `speedMode` is never actually used. It only toggles this condition.
|
|
// See the definition of `SPEED_MODE_LINEAR` and `SPEED_MODE_CURVED` for more information.
|
|
if (speedMode != SPEED_MODE_LINEAR) {
|
|
*outSpeedTarget -= 20.0f;
|
|
if (*outSpeedTarget < 0.0f) {
|
|
// If control stick magnitude is below 20, return zero speed.
|
|
*outSpeedTarget = 0.0f;
|
|
} else {
|
|
// Cosine of the control stick magnitude isn't exactly meaningful, but
|
|
// it happens to give a desirable curve for grounded movement speed relative
|
|
// to control stick magnitude.
|
|
temp = 1.0f - Math_CosS(*outSpeedTarget * 450.0f);
|
|
*outSpeedTarget = (SQ(temp) * 30.0f) + 7.0f;
|
|
}
|
|
} else {
|
|
// Speed increases linearly relative to control stick magnitude
|
|
*outSpeedTarget *= 0.8f;
|
|
}
|
|
|
|
if (sControlStickMagnitude != 0.0f) {
|
|
sinFloorPitch = Math_SinS(this->floorPitch);
|
|
speedCap = this->unk_880;
|
|
floorPitchInfluence = CLAMP(sinFloorPitch, 0.0f, 0.6f);
|
|
|
|
if (this->unk_6C4 != 0.0f) {
|
|
speedCap -= (this->unk_6C4 * 0.008f);
|
|
speedCap = CLAMP_MIN(speedCap, 2.0f);
|
|
}
|
|
|
|
*outSpeedTarget = (*outSpeedTarget * 0.14f) - (8.0f * floorPitchInfluence * floorPitchInfluence);
|
|
*outSpeedTarget = CLAMP(*outSpeedTarget, 0.0f, speedCap);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
s32 func_8083721C(Player* this) {
|
|
return Math_StepToF(&this->linearVelocity, 0.0f, REG(43) / 100.0f);
|
|
}
|
|
|
|
/**
|
|
* Gets target speed and yaw values for movement based on control stick input.
|
|
* Control stick magnitude and angle are processed in `Player_CalcSpeedAndYawFromControlStick` to get target values.
|
|
* Additionally, this function does extra processing on the target yaw value if the control stick is neutral.
|
|
*
|
|
* @param outSpeedTarget a pointer to the variable that will hold the resulting target speed value
|
|
* @param outYawTarget a pointer to the variable that will hold the resulting target yaw value
|
|
* @param speedMode toggles between a linear and curved mode for the speed value
|
|
*
|
|
* @see Player_CalcSpeedAndYawFromControlStick for more information on the linear vs curved speed mode.
|
|
*
|
|
* @return true if the control stick has any magnitude, false otherwise.
|
|
*/
|
|
s32 Player_GetMovementSpeedAndYaw(Player* this, f32* outSpeedTarget, s16* outYawTarget, f32 speedMode,
|
|
PlayState* play) {
|
|
if (!Player_CalcSpeedAndYawFromControlStick(play, this, outSpeedTarget, outYawTarget, speedMode)) {
|
|
*outYawTarget = this->actor.shape.rot.y;
|
|
|
|
if (this->unk_664 != NULL) {
|
|
if ((play->actorCtx.targetCtx.unk_4B != 0) && !(this->stateFlags2 & PLAYER_STATE2_DISABLE_ROTATION_ALWAYS)) {
|
|
*outYawTarget = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_664->focus.pos);
|
|
return false;
|
|
}
|
|
} else if (func_80833B2C(this)) {
|
|
*outYawTarget = this->zTargetYaw;
|
|
}
|
|
|
|
return false;
|
|
} else {
|
|
*outYawTarget += Camera_GetInputDirYaw(GET_ACTIVE_CAM(play));
|
|
return true;
|
|
}
|
|
}
|
|
|
|
typedef enum {
|
|
/* 0 */ PLAYER_ACTION_CHG_0,
|
|
/* 1 */ PLAYER_ACTION_CHG_1,
|
|
/* 2 */ PLAYER_ACTION_CHG_2,
|
|
/* 3 */ PLAYER_ACTION_CHG_3,
|
|
/* 4 */ PLAYER_ACTION_CHG_4,
|
|
/* 5 */ PLAYER_ACTION_CHG_5,
|
|
/* 6 */ PLAYER_ACTION_CHG_6,
|
|
/* 7 */ PLAYER_ACTION_CHG_7,
|
|
/* 8 */ PLAYER_ACTION_CHG_8,
|
|
/* 9 */ PLAYER_ACTION_CHG_9,
|
|
/* 10 */ PLAYER_ACTION_CHG_10,
|
|
/* 11 */ PLAYER_ACTION_CHG_11,
|
|
/* 12 */ PLAYER_ACTION_CHG_12,
|
|
/* 13 */ PLAYER_ACTION_CHG_13
|
|
} ActionChangeIndex;
|
|
|
|
static s8 sActionChangeList1[] = {
|
|
PLAYER_ACTION_CHG_13, PLAYER_ACTION_CHG_2, PLAYER_ACTION_CHG_4, PLAYER_ACTION_CHG_9,
|
|
PLAYER_ACTION_CHG_10, PLAYER_ACTION_CHG_11, PLAYER_ACTION_CHG_8, -PLAYER_ACTION_CHG_7,
|
|
};
|
|
|
|
static s8 sActionChangeList2[] = {
|
|
PLAYER_ACTION_CHG_13, PLAYER_ACTION_CHG_1, PLAYER_ACTION_CHG_2, PLAYER_ACTION_CHG_5,
|
|
PLAYER_ACTION_CHG_3, PLAYER_ACTION_CHG_4, PLAYER_ACTION_CHG_9, PLAYER_ACTION_CHG_10,
|
|
PLAYER_ACTION_CHG_11, PLAYER_ACTION_CHG_7, PLAYER_ACTION_CHG_8, -PLAYER_ACTION_CHG_6,
|
|
};
|
|
|
|
static s8 sActionChangeList3[] = {
|
|
PLAYER_ACTION_CHG_13, PLAYER_ACTION_CHG_1, PLAYER_ACTION_CHG_2, PLAYER_ACTION_CHG_3,
|
|
PLAYER_ACTION_CHG_4, PLAYER_ACTION_CHG_9, PLAYER_ACTION_CHG_10, PLAYER_ACTION_CHG_11,
|
|
PLAYER_ACTION_CHG_8, PLAYER_ACTION_CHG_7, -PLAYER_ACTION_CHG_6,
|
|
};
|
|
|
|
static s8 sActionChangeList4[] = {
|
|
PLAYER_ACTION_CHG_13, PLAYER_ACTION_CHG_2, PLAYER_ACTION_CHG_4, PLAYER_ACTION_CHG_9,
|
|
PLAYER_ACTION_CHG_10, PLAYER_ACTION_CHG_11, PLAYER_ACTION_CHG_8, -PLAYER_ACTION_CHG_7,
|
|
};
|
|
|
|
static s8 sActionChangeList5[] = {
|
|
PLAYER_ACTION_CHG_13, PLAYER_ACTION_CHG_2, PLAYER_ACTION_CHG_4, PLAYER_ACTION_CHG_9, PLAYER_ACTION_CHG_10,
|
|
PLAYER_ACTION_CHG_11, PLAYER_ACTION_CHG_12, PLAYER_ACTION_CHG_8, -PLAYER_ACTION_CHG_7,
|
|
};
|
|
|
|
static s8 sActionChangeList6[] = {
|
|
-PLAYER_ACTION_CHG_7,
|
|
};
|
|
|
|
static s8 sActionChangeList7[] = {
|
|
PLAYER_ACTION_CHG_0, PLAYER_ACTION_CHG_11, PLAYER_ACTION_CHG_1, PLAYER_ACTION_CHG_2,
|
|
PLAYER_ACTION_CHG_3, PLAYER_ACTION_CHG_5, PLAYER_ACTION_CHG_4, PLAYER_ACTION_CHG_9,
|
|
PLAYER_ACTION_CHG_8, PLAYER_ACTION_CHG_7, -PLAYER_ACTION_CHG_6,
|
|
};
|
|
|
|
static s8 sActionChangeList8[] = {
|
|
PLAYER_ACTION_CHG_0, PLAYER_ACTION_CHG_11, PLAYER_ACTION_CHG_1, PLAYER_ACTION_CHG_2,
|
|
PLAYER_ACTION_CHG_3, PLAYER_ACTION_CHG_12, PLAYER_ACTION_CHG_5, PLAYER_ACTION_CHG_4,
|
|
PLAYER_ACTION_CHG_9, PLAYER_ACTION_CHG_8, PLAYER_ACTION_CHG_7, -PLAYER_ACTION_CHG_6,
|
|
};
|
|
|
|
static s8 sActionChangeList9[] = {
|
|
PLAYER_ACTION_CHG_13, PLAYER_ACTION_CHG_1, PLAYER_ACTION_CHG_2, PLAYER_ACTION_CHG_3, PLAYER_ACTION_CHG_12,
|
|
PLAYER_ACTION_CHG_5, PLAYER_ACTION_CHG_4, PLAYER_ACTION_CHG_9, PLAYER_ACTION_CHG_10, PLAYER_ACTION_CHG_11,
|
|
PLAYER_ACTION_CHG_8, PLAYER_ACTION_CHG_7, -PLAYER_ACTION_CHG_6,
|
|
};
|
|
|
|
static s8 sActionChangeList10[] = {
|
|
PLAYER_ACTION_CHG_10,
|
|
PLAYER_ACTION_CHG_8,
|
|
-PLAYER_ACTION_CHG_7,
|
|
};
|
|
|
|
static s8 sActionChangeList11[] = {
|
|
PLAYER_ACTION_CHG_0,
|
|
PLAYER_ACTION_CHG_12,
|
|
PLAYER_ACTION_CHG_5,
|
|
-PLAYER_ACTION_CHG_4,
|
|
};
|
|
|
|
s32 Player_ActionChange_0(Player* this, PlayState* play);
|
|
s32 Player_ActionChange_1(Player* this, PlayState* play);
|
|
s32 Player_ActionChange_2(Player* this, PlayState* play);
|
|
s32 Player_ActionChange_3(Player* this, PlayState* play);
|
|
s32 Player_ActionChange_4(Player* this, PlayState* play);
|
|
s32 Player_ActionChange_5(Player* this, PlayState* play);
|
|
s32 Player_ActionChange_6(Player* this, PlayState* play);
|
|
s32 Player_ActionChange_7(Player* this, PlayState* play);
|
|
s32 Player_ActionChange_8(Player* this, PlayState* play);
|
|
s32 Player_ActionChange_9(Player* this, PlayState* play);
|
|
s32 Player_ActionChange_10(Player* this, PlayState* play);
|
|
s32 Player_ActionChange_11(Player* this, PlayState* play);
|
|
s32 Player_ActionChange_12(Player* this, PlayState* play);
|
|
s32 Player_ActionChange_13(Player* this, PlayState* play);
|
|
|
|
static s32 (*sActionChangeFuncs[])(Player* this, PlayState* play) = {
|
|
/* PLAYER_ACTION_CHG_0 */ Player_ActionChange_0,
|
|
/* PLAYER_ACTION_CHG_1 */ Player_ActionChange_1,
|
|
/* PLAYER_ACTION_CHG_2 */ Player_ActionChange_2,
|
|
/* PLAYER_ACTION_CHG_3 */ Player_ActionChange_3,
|
|
/* PLAYER_ACTION_CHG_4 */ Player_ActionChange_4,
|
|
/* PLAYER_ACTION_CHG_5 */ Player_ActionChange_5,
|
|
/* PLAYER_ACTION_CHG_6 */ Player_ActionChange_6,
|
|
/* PLAYER_ACTION_CHG_7 */ Player_ActionChange_7,
|
|
/* PLAYER_ACTION_CHG_8 */ Player_ActionChange_8,
|
|
/* PLAYER_ACTION_CHG_9 */ Player_ActionChange_9,
|
|
/* PLAYER_ACTION_CHG_10 */ Player_ActionChange_10,
|
|
/* PLAYER_ACTION_CHG_11 */ Player_ActionChange_11,
|
|
/* PLAYER_ACTION_CHG_12 */ Player_ActionChange_12,
|
|
/* PLAYER_ACTION_CHG_13 */ Player_ActionChange_13,
|
|
};
|
|
|
|
/**
|
|
* This function processes "Action Change Lists", which run various functions that
|
|
* check if it is appropriate to change to a new action.
|
|
*
|
|
* Action Change Lists are a list of indices for the `sActionChangeFuncs` array.
|
|
* The functions are ran in order until one of them returns true, or the end of the list is reached.
|
|
* An Action Change index having a negative value indicates that it is the last member in the list.
|
|
*
|
|
* Because these lists are processed sequentially, the order of the indices in the list determines its priority.
|
|
*
|
|
* If the `updateUpperBody` argument is true, Player's upper body will update before the Action Change List
|
|
* is processed. This allows for Item Action functions to run.
|
|
*
|
|
* @return true if a new action has been chosen
|
|
*
|
|
*/
|
|
s32 Player_TryActionChangeList(PlayState* play, Player* this, s8* actionChangeList, s32 updateUpperBody) {
|
|
s32 i;
|
|
|
|
if (!(this->stateFlags1 & (PLAYER_STATE1_LOADING | PLAYER_STATE1_DEAD | PLAYER_STATE1_IN_CUTSCENE))) {
|
|
if (updateUpperBody) {
|
|
D_808535E0 = Player_UpdateUpperBody(this, play);
|
|
|
|
if (Player_Action_8084E604 == this->actionFunc) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (func_8008F128(this)) {
|
|
this->unk_6AE |= 0x41;
|
|
return true;
|
|
}
|
|
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_START_PUTAWAY) &&
|
|
(Player_UpperAction_ChangeHeldItem != this->upperActionFunc)) {
|
|
// Process all entries in the Action Change List with a positive index
|
|
while (*actionChangeList >= 0) {
|
|
if (sActionChangeFuncs[*actionChangeList](this, play)) {
|
|
return true;
|
|
}
|
|
actionChangeList++;
|
|
}
|
|
|
|
// Try the last entry in the list. Negate the index to make it positive again.
|
|
if (sActionChangeFuncs[-(*actionChangeList)](this, play)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
s32 func_808374A0(PlayState* play, Player* this, SkelAnime* skelAnime, f32 arg3) {
|
|
f32 speedTarget;
|
|
s16 yawTarget;
|
|
|
|
if ((skelAnime->endFrame - arg3) <= skelAnime->curFrame) {
|
|
if (Player_TryActionChangeList(play, this, sActionChangeList7, true)) {
|
|
return 0;
|
|
}
|
|
|
|
if (Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_CURVED, play)) {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void func_80837530(PlayState* play, Player* this, s32 arg2) {
|
|
if (arg2 != 0) {
|
|
this->unk_858 = 0.0f;
|
|
} else {
|
|
this->unk_858 = 0.5f;
|
|
}
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_CHARGING_SPIN_ATTACK;
|
|
|
|
if (this->actor.category == ACTORCAT_PLAYER) {
|
|
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_M_THUNDER, this->bodyPartsPos[PLAYER_BODYPART_WAIST].x,
|
|
this->bodyPartsPos[PLAYER_BODYPART_WAIST].y, this->bodyPartsPos[PLAYER_BODYPART_WAIST].z, 0, 0, 0,
|
|
Player_GetMeleeWeaponHeld(this) | arg2, true);
|
|
}
|
|
}
|
|
|
|
s32 func_808375D8(Player* this) {
|
|
s8 sp3C[4];
|
|
s8* iter;
|
|
s8* iter2;
|
|
s8 temp1;
|
|
s8 temp2;
|
|
s32 i;
|
|
|
|
if ((this->heldItemAction == PLAYER_IA_DEKU_STICK) || Player_HoldsBrokenKnife(this)) {
|
|
return 0;
|
|
}
|
|
|
|
iter = &this->unk_847[0];
|
|
iter2 = &sp3C[0];
|
|
for (i = 0; i < 4; i++, iter++, iter2++) {
|
|
if ((*iter2 = *iter) < 0) {
|
|
return 0;
|
|
}
|
|
*iter2 *= 2;
|
|
}
|
|
|
|
temp1 = sp3C[0] - sp3C[1];
|
|
if (ABS(temp1) < 10) {
|
|
return 0;
|
|
}
|
|
|
|
iter2 = &sp3C[1];
|
|
for (i = 1; i < 3; i++, iter2++) {
|
|
temp2 = *iter2 - *(iter2 + 1);
|
|
if ((ABS(temp2) < 10) || (temp2 * temp1 < 0)) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void func_80837704(PlayState* play, Player* this) {
|
|
LinkAnimationHeader* anim;
|
|
|
|
if ((this->meleeWeaponAnimation >= PLAYER_MWA_RIGHT_SLASH_1H) &&
|
|
(this->meleeWeaponAnimation <= PLAYER_MWA_RIGHT_COMBO_2H)) {
|
|
anim = D_80854358[Player_HoldsTwoHandedWeapon(this)];
|
|
} else {
|
|
anim = D_80854350[Player_HoldsTwoHandedWeapon(this)];
|
|
}
|
|
|
|
func_80832318(this);
|
|
LinkAnimation_Change(play, &this->skelAnime, anim, 1.0f, 8.0f, Animation_GetLastFrame(anim), ANIMMODE_ONCE, -9.0f);
|
|
func_80837530(play, this, 0x200);
|
|
}
|
|
|
|
void func_808377DC(PlayState* play, Player* this) {
|
|
Player_SetupAction(play, this, Player_Action_80844E68, 1);
|
|
func_80837704(play, this);
|
|
}
|
|
|
|
static s8 D_80854480[] = {
|
|
PLAYER_MWA_STAB_1H,
|
|
PLAYER_MWA_RIGHT_SLASH_1H,
|
|
PLAYER_MWA_RIGHT_SLASH_1H,
|
|
PLAYER_MWA_LEFT_SLASH_1H,
|
|
};
|
|
static s8 D_80854484[] = {
|
|
PLAYER_MWA_HAMMER_FORWARD,
|
|
PLAYER_MWA_HAMMER_SIDE,
|
|
PLAYER_MWA_HAMMER_FORWARD,
|
|
PLAYER_MWA_HAMMER_SIDE,
|
|
};
|
|
|
|
s32 func_80837818(Player* this) {
|
|
s32 sp1C = this->unk_84B[this->unk_846];
|
|
s32 sp18;
|
|
|
|
if (this->heldItemAction == PLAYER_IA_HAMMER) {
|
|
if (sp1C < 0) {
|
|
sp1C = 0;
|
|
}
|
|
sp18 = D_80854484[sp1C];
|
|
this->unk_845 = 0;
|
|
} else {
|
|
if (func_808375D8(this)) {
|
|
sp18 = PLAYER_MWA_SPIN_ATTACK_1H;
|
|
} else {
|
|
if (sp1C < 0) {
|
|
if (func_80833BCC(this)) {
|
|
sp18 = PLAYER_MWA_FORWARD_SLASH_1H;
|
|
} else {
|
|
sp18 = PLAYER_MWA_RIGHT_SLASH_1H;
|
|
}
|
|
} else {
|
|
sp18 = D_80854480[sp1C];
|
|
if (sp18 == PLAYER_MWA_STAB_1H) {
|
|
this->stateFlags2 |= PLAYER_STATE2_SWORD_LUNGE;
|
|
if (!func_80833BCC(this)) {
|
|
sp18 = PLAYER_MWA_FORWARD_SLASH_1H;
|
|
}
|
|
}
|
|
}
|
|
if (this->heldItemAction == PLAYER_IA_DEKU_STICK) {
|
|
sp18 = PLAYER_MWA_FORWARD_SLASH_1H;
|
|
}
|
|
}
|
|
if (Player_HoldsTwoHandedWeapon(this)) {
|
|
sp18++;
|
|
}
|
|
}
|
|
|
|
return sp18;
|
|
}
|
|
|
|
void func_80837918(Player* this, s32 quadIndex, u32 dmgFlags) {
|
|
this->meleeWeaponQuads[quadIndex].info.toucher.dmgFlags = dmgFlags;
|
|
|
|
if (dmgFlags == 2) {
|
|
this->meleeWeaponQuads[quadIndex].info.toucherFlags = TOUCH_ON | TOUCH_NEAREST | TOUCH_SFX_WOOD;
|
|
} else {
|
|
this->meleeWeaponQuads[quadIndex].info.toucherFlags = TOUCH_ON | TOUCH_NEAREST;
|
|
}
|
|
}
|
|
|
|
static u32 D_80854488[][2] = {
|
|
{ 0x00000200, 0x08000000 }, { 0x00000100, 0x02000000 }, { 0x00000400, 0x04000000 },
|
|
{ 0x00000002, 0x08000000 }, { 0x00000040, 0x40000000 },
|
|
};
|
|
|
|
void func_80837948(PlayState* play, Player* this, s32 arg2) {
|
|
s32 pad;
|
|
u32 dmgFlags;
|
|
s32 temp;
|
|
|
|
Player_SetupAction(play, this, Player_Action_808502D0, 0);
|
|
this->unk_844 = 8;
|
|
if (!((arg2 >= PLAYER_MWA_FLIPSLASH_FINISH) && (arg2 <= PLAYER_MWA_JUMPSLASH_FINISH))) {
|
|
func_80832318(this);
|
|
}
|
|
|
|
if ((arg2 != this->meleeWeaponAnimation) || !(this->unk_845 < 3)) {
|
|
this->unk_845 = 0;
|
|
}
|
|
|
|
this->unk_845++;
|
|
if (this->unk_845 >= 3) {
|
|
arg2 += 2;
|
|
}
|
|
|
|
this->meleeWeaponAnimation = arg2;
|
|
|
|
Player_AnimPlayOnceAdjusted(play, this, D_80854190[arg2].unk_00);
|
|
if ((arg2 != PLAYER_MWA_FLIPSLASH_START) && (arg2 != PLAYER_MWA_JUMPSLASH_START)) {
|
|
Player_AnimReplaceApplyFlags(play, this, 0x209);
|
|
}
|
|
|
|
this->yaw = this->actor.shape.rot.y;
|
|
|
|
if (Player_HoldsBrokenKnife(this)) {
|
|
temp = 1;
|
|
} else {
|
|
temp = Player_GetMeleeWeaponHeld(this) - 1;
|
|
}
|
|
|
|
if ((arg2 >= PLAYER_MWA_FLIPSLASH_START) && (arg2 <= PLAYER_MWA_JUMPSLASH_FINISH)) {
|
|
if (CVarGetInteger("gRestoreQPA", 1) && temp == -1) {
|
|
dmgFlags = 0x16171617;
|
|
}
|
|
else {
|
|
dmgFlags = D_80854488[temp][1];
|
|
}
|
|
} else {
|
|
dmgFlags = D_80854488[temp][0];
|
|
}
|
|
|
|
func_80837918(this, 0, dmgFlags);
|
|
func_80837918(this, 1, dmgFlags);
|
|
}
|
|
|
|
void func_80837AE0(Player* this, s32 timer) {
|
|
if (this->invincibilityTimer >= 0) {
|
|
this->invincibilityTimer = timer;
|
|
this->unk_88F = 0;
|
|
}
|
|
}
|
|
|
|
void func_80837AFC(Player* this, s32 timer) {
|
|
if (this->invincibilityTimer > timer) {
|
|
this->invincibilityTimer = timer;
|
|
}
|
|
this->unk_88F = 0;
|
|
}
|
|
|
|
s32 func_80837B18_modified(PlayState* play, Player* this, s32 damage, u8 modified) {
|
|
if ((this->invincibilityTimer != 0) || (this->actor.category != ACTORCAT_PLAYER)) {
|
|
return 1;
|
|
}
|
|
|
|
s32 modifiedDamage = damage;
|
|
if (modified) {
|
|
modifiedDamage *= (1 << CVarGetInteger("gDamageMul", 0));
|
|
}
|
|
|
|
return Health_ChangeBy(play, modifiedDamage);
|
|
}
|
|
|
|
s32 func_80837B18(PlayState* play, Player* this, s32 damage) {
|
|
return func_80837B18_modified(play, this, damage, true);
|
|
}
|
|
|
|
void func_80837B60(Player* this) {
|
|
this->skelAnime.prevTransl = this->skelAnime.jointTable[0];
|
|
func_80832E48(this, 3);
|
|
}
|
|
|
|
void func_80837B9C(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_8084411C, 0);
|
|
Player_AnimPlayLoop(play, this, &gPlayerAnim_link_normal_landing_wait);
|
|
this->av2.actionVar2 = 1;
|
|
if (this->unk_6AD != 3) {
|
|
this->unk_6AD = 0;
|
|
}
|
|
}
|
|
|
|
static LinkAnimationHeader* D_808544B0[] = {
|
|
&gPlayerAnim_link_normal_front_shit, &gPlayerAnim_link_normal_front_shitR, &gPlayerAnim_link_normal_back_shit,
|
|
&gPlayerAnim_link_normal_back_shitR, &gPlayerAnim_link_normal_front_hit, &gPlayerAnim_link_anchor_front_hitR,
|
|
&gPlayerAnim_link_normal_back_hit, &gPlayerAnim_link_anchor_back_hitR,
|
|
};
|
|
|
|
void func_80837C0C(PlayState* play, Player* this, s32 arg2, f32 arg3, f32 arg4, s16 arg5, s32 arg6) {
|
|
LinkAnimationHeader* anim = NULL;
|
|
LinkAnimationHeader** sp28;
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_HANGING_OFF_LEDGE) {
|
|
func_80837B60(this);
|
|
}
|
|
|
|
this->unk_890 = 0;
|
|
|
|
Player_PlaySfx(this, NA_SE_PL_DAMAGE);
|
|
|
|
if (!func_80837B18(play, this, 0 - this->actor.colChkInfo.damage)) {
|
|
this->stateFlags2 &= ~PLAYER_STATE2_GRABBED_BY_ENEMY;
|
|
if (!(this->actor.bgCheckFlags & 1) && !(this->stateFlags1 & PLAYER_STATE1_IN_WATER)) {
|
|
func_80837B9C(this, play);
|
|
}
|
|
return;
|
|
}
|
|
|
|
func_80837AE0(this, arg6);
|
|
|
|
if (arg2 == 3) {
|
|
Player_SetupAction(play, this, Player_Action_8084FB10, 0);
|
|
|
|
anim = &gPlayerAnim_link_normal_ice_down;
|
|
|
|
func_80832224(this);
|
|
Player_RequestRumble(this, 255, 10, 40, 0);
|
|
|
|
Player_PlaySfx(this, NA_SE_PL_FREEZE_S);
|
|
func_80832698(this, NA_SE_VO_LI_FREEZE);
|
|
} else if (arg2 == 4) {
|
|
Player_SetupAction(play, this, Player_Action_8084FBF4, 0);
|
|
|
|
Player_RequestRumble(this, 255, 80, 150, 0);
|
|
|
|
Player_AnimPlayLoopAdjusted(play, this, &gPlayerAnim_link_normal_electric_shock);
|
|
func_80832224(this);
|
|
|
|
this->av2.actionVar2 = 20;
|
|
} else {
|
|
arg5 -= this->actor.shape.rot.y;
|
|
if (this->stateFlags1 & PLAYER_STATE1_IN_WATER) {
|
|
Player_SetupAction(play, this, Player_Action_8084E30C, 0);
|
|
Player_RequestRumble(this, 180, 20, 50, 0);
|
|
|
|
this->linearVelocity = 4.0f;
|
|
this->actor.velocity.y = 0.0f;
|
|
|
|
anim = &gPlayerAnim_link_swimer_swim_hit;
|
|
|
|
func_80832698(this, NA_SE_VO_LI_DAMAGE_S);
|
|
} else if ((arg2 == 1) || (arg2 == 2) || !(this->actor.bgCheckFlags & 1) ||
|
|
(this->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_CLIMBING_LADDER))) {
|
|
Player_SetupAction(play, this, Player_Action_8084377C, 0);
|
|
|
|
this->stateFlags3 |= PLAYER_STATE3_MIDAIR;
|
|
|
|
Player_RequestRumble(this, 255, 20, 150, 0);
|
|
func_80832224(this);
|
|
|
|
if (arg2 == 2) {
|
|
this->av2.actionVar2 = 4;
|
|
|
|
this->actor.speedXZ = 3.0f;
|
|
this->linearVelocity = 3.0f;
|
|
this->actor.velocity.y = 6.0f;
|
|
|
|
Player_AnimChangeFreeze(play, this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_damage_run, this->modelAnimType));
|
|
func_80832698(this, NA_SE_VO_LI_DAMAGE_S);
|
|
} else {
|
|
this->actor.speedXZ = arg3;
|
|
this->linearVelocity = arg3;
|
|
this->actor.velocity.y = arg4;
|
|
|
|
if (ABS(arg5) > 0x4000) {
|
|
anim = &gPlayerAnim_link_normal_front_downA;
|
|
} else {
|
|
anim = &gPlayerAnim_link_normal_back_downA;
|
|
}
|
|
|
|
if ((this->actor.category != ACTORCAT_PLAYER) && (this->actor.colChkInfo.health == 0)) {
|
|
func_80832698(this, NA_SE_VO_BL_DOWN);
|
|
} else {
|
|
func_80832698(this, NA_SE_VO_LI_FALL_L);
|
|
}
|
|
}
|
|
|
|
this->hoverBootsTimer = 0;
|
|
this->actor.bgCheckFlags &= ~1;
|
|
} else {
|
|
if ((this->linearVelocity > 4.0f) && !func_8008E9C4(this)) {
|
|
this->unk_890 = 20;
|
|
Player_RequestRumble(this, 120, 20, 10, 0);
|
|
func_80832698(this, NA_SE_VO_LI_DAMAGE_S);
|
|
return;
|
|
}
|
|
|
|
sp28 = D_808544B0;
|
|
|
|
Player_SetupAction(play, this, Player_Action_8084370C, 0);
|
|
func_80833C3C(this);
|
|
|
|
if (this->actor.colChkInfo.damage < 5) {
|
|
Player_RequestRumble(this, 120, 20, 10, 0);
|
|
} else {
|
|
Player_RequestRumble(this, 180, 20, 100, 0);
|
|
this->linearVelocity = 23.0f;
|
|
sp28 += 4;
|
|
}
|
|
|
|
if (ABS(arg5) <= 0x4000) {
|
|
sp28 += 2;
|
|
}
|
|
|
|
if (func_8008E9C4(this)) {
|
|
sp28 += 1;
|
|
}
|
|
|
|
anim = *sp28;
|
|
|
|
func_80832698(this, NA_SE_VO_LI_DAMAGE_S);
|
|
}
|
|
|
|
this->actor.shape.rot.y += arg5;
|
|
this->yaw = this->actor.shape.rot.y;
|
|
this->actor.world.rot.y = this->actor.shape.rot.y;
|
|
if (ABS(arg5) > 0x4000) {
|
|
this->actor.shape.rot.y += 0x8000;
|
|
}
|
|
}
|
|
|
|
func_80832564(play, this);
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_DAMAGED;
|
|
|
|
if (anim != NULL) {
|
|
Player_AnimPlayOnceAdjusted(play, this, anim);
|
|
}
|
|
}
|
|
|
|
s32 func_80838144(s32 arg0) {
|
|
s32 temp = arg0 - 2;
|
|
|
|
if ((temp >= 0) && (temp < 2)) {
|
|
return temp;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
s32 func_8083816C(s32 arg0) {
|
|
return (arg0 == 4) || (arg0 == 7) || (arg0 == 12);
|
|
}
|
|
|
|
void func_8083819C(Player* this, PlayState* play) {
|
|
if (this->currentShield == PLAYER_SHIELD_DEKU && (CVarGetInteger("gFireproofDekuShield", 0) == 0)) {
|
|
Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_SHIELD, this->actor.world.pos.x, this->actor.world.pos.y,
|
|
this->actor.world.pos.z, 0, 0, 0, 1, true);
|
|
Inventory_DeleteEquipment(play, EQUIP_TYPE_SHIELD);
|
|
Message_StartTextbox(play, 0x305F, NULL);
|
|
}
|
|
}
|
|
|
|
void func_8083821C(Player* this) {
|
|
s32 i;
|
|
|
|
// clang-format off
|
|
for (i = 0; i < PLAYER_BODYPART_MAX; i++) { this->bodyFlameTimers[i] = Rand_S16Offset(0, 200); }
|
|
// clang-format on
|
|
|
|
this->bodyIsBurning = true;
|
|
}
|
|
|
|
void func_80838280(Player* this) {
|
|
if (this->actor.colChkInfo.acHitEffect == 1) {
|
|
func_8083821C(this);
|
|
}
|
|
func_80832698(this, NA_SE_VO_LI_FALL_L);
|
|
}
|
|
|
|
void func_808382BC(Player* this) {
|
|
if ((this->invincibilityTimer >= 0) && (this->invincibilityTimer < 20)) {
|
|
this->invincibilityTimer = 20;
|
|
}
|
|
}
|
|
|
|
s32 func_808382DC(Player* this, PlayState* play) {
|
|
s32 pad;
|
|
s32 sp68 = false;
|
|
s32 sp64;
|
|
|
|
if (this->unk_A86 != 0) {
|
|
if (!Player_InBlockingCsMode(play, this)) {
|
|
Player_InflictDamageModified(play, -16 * (1 << CVarGetInteger("gVoidDamageMul", 0)), false);
|
|
this->unk_A86 = 0;
|
|
}
|
|
} else {
|
|
sp68 = ((Player_GetHeight(this) - 8.0f) < (this->unk_6C4 * this->actor.scale.y));
|
|
|
|
if (sp68 || (this->actor.bgCheckFlags & 0x100) || (sFloorType == 9) || (this->stateFlags2 & PLAYER_STATE2_FORCED_VOID_OUT)) {
|
|
func_80832698(this, NA_SE_VO_LI_DAMAGE_S);
|
|
|
|
if (sp68) {
|
|
Play_TriggerRespawn(play);
|
|
Scene_SetTransitionForNextEntrance(play);
|
|
} else {
|
|
// Special case for getting crushed in Forest Temple's Checkboard Ceiling Hall or Shadow Temple's
|
|
// Falling Spike Trap Room, to respawn the player in a specific place
|
|
if (((play->sceneNum == SCENE_FOREST_TEMPLE) && (play->roomCtx.curRoom.num == 15)) ||
|
|
((play->sceneNum == SCENE_SHADOW_TEMPLE) && (play->roomCtx.curRoom.num == 10))) {
|
|
static SpecialRespawnInfo checkboardCeilingRespawn = { { 1992.0f, 403.0f, -3432.0f }, 0 };
|
|
static SpecialRespawnInfo fallingSpikeTrapRespawn = { { 1200.0f, -1343.0f, 3850.0f }, 0 };
|
|
SpecialRespawnInfo* respawnInfo;
|
|
|
|
if (play->sceneNum == SCENE_FOREST_TEMPLE) {
|
|
respawnInfo = &checkboardCeilingRespawn;
|
|
} else {
|
|
respawnInfo = &fallingSpikeTrapRespawn;
|
|
}
|
|
|
|
Play_SetupRespawnPoint(play, RESPAWN_MODE_DOWN, 0xDFF);
|
|
gSaveContext.respawn[RESPAWN_MODE_DOWN].pos = respawnInfo->pos;
|
|
gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw = respawnInfo->yaw;
|
|
}
|
|
|
|
Play_TriggerVoidOut(play);
|
|
}
|
|
|
|
func_80832698(this, NA_SE_VO_LI_TAKEN_AWAY);
|
|
play->unk_11DE9 = 1;
|
|
func_80078884(NA_SE_OC_ABYSS);
|
|
} else if ((this->unk_8A1 != 0) && ((this->unk_8A1 >= 2) || (this->invincibilityTimer == 0))) {
|
|
u8 sp5C[] = { 2, 1, 1 };
|
|
|
|
func_80838280(this);
|
|
|
|
if (this->unk_8A1 == 3) {
|
|
this->bodyShockTimer = 40;
|
|
}
|
|
|
|
this->actor.colChkInfo.damage += this->unk_8A0;
|
|
func_80837C0C(play, this, sp5C[this->unk_8A1 - 1], this->unk_8A4, this->unk_8A8, this->unk_8A2, 20);
|
|
} else {
|
|
sp64 = (this->shieldQuad.base.acFlags & AC_BOUNCED) != 0;
|
|
|
|
//! @bug The second set of conditions here seems intended as a way for Link to "block" hits by rolling.
|
|
// However, `Collider.atFlags` is a byte so the flag check at the end is incorrect and cannot work.
|
|
// Additionally, `Collider.atHit` can never be set while already colliding as AC, so it's also bugged.
|
|
// This behavior was later fixed in MM, most likely by removing both the `atHit` and `atFlags` checks.
|
|
if (sp64 || ((this->invincibilityTimer < 0) && (this->cylinder.base.acFlags & AC_HIT) &&
|
|
(this->cylinder.info.atHit != NULL) && (this->cylinder.info.atHit->atFlags & 0x20000000))) {
|
|
|
|
Player_RequestRumble(this, 180, 20, 100, 0);
|
|
|
|
if (!Player_IsChildWithHylianShield(this)) {
|
|
if (this->invincibilityTimer >= 0) {
|
|
LinkAnimationHeader* anim;
|
|
s32 sp54 = Player_Action_80843188 == this->actionFunc;
|
|
|
|
if (!func_808332B8(this)) {
|
|
Player_SetupAction(play, this, Player_Action_808435C4, 0);
|
|
}
|
|
|
|
if (!(this->av1.actionVar1 = sp54)) {
|
|
Player_SetUpperActionFunc(this, func_80834BD4);
|
|
|
|
if (this->unk_870 < 0.5f) {
|
|
anim = D_808543BC[Player_HoldsTwoHandedWeapon(this) &&
|
|
!(CVarGetInteger("gShieldTwoHanded", 0) &&
|
|
(this->heldItemAction != PLAYER_IA_DEKU_STICK))];
|
|
} else {
|
|
anim = D_808543B4[Player_HoldsTwoHandedWeapon(this) &&
|
|
!(CVarGetInteger("gShieldTwoHanded", 0) &&
|
|
(this->heldItemAction != PLAYER_IA_DEKU_STICK))];
|
|
}
|
|
LinkAnimation_PlayOnce(play, &this->upperSkelAnime, anim);
|
|
} else {
|
|
Player_AnimPlayOnce(play, this,
|
|
D_808543C4[Player_HoldsTwoHandedWeapon(this) &&
|
|
!(CVarGetInteger("gShieldTwoHanded", 0) &&
|
|
(this->heldItemAction != PLAYER_IA_DEKU_STICK))]);
|
|
}
|
|
}
|
|
|
|
if (!(this->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_CLIMBING_LADDER))) {
|
|
this->linearVelocity = -18.0f;
|
|
this->yaw = this->actor.shape.rot.y;
|
|
}
|
|
}
|
|
|
|
if (sp64 && (this->shieldQuad.info.acHitInfo->toucher.effect == 1)) {
|
|
func_8083819C(this, play);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
if ((this->unk_A87 != 0) || (this->invincibilityTimer > 0) || (this->stateFlags1 & PLAYER_STATE1_DAMAGED) ||
|
|
(this->csAction != 0) || (this->meleeWeaponQuads[0].base.atFlags & AT_HIT) ||
|
|
(this->meleeWeaponQuads[1].base.atFlags & AT_HIT)) {
|
|
return 0;
|
|
}
|
|
|
|
if (this->cylinder.base.acFlags & AC_HIT) {
|
|
Actor* ac = this->cylinder.base.ac;
|
|
s32 sp4C;
|
|
|
|
if (ac->flags & ACTOR_FLAG_PLAY_HIT_SFX) {
|
|
Player_PlaySfx(this, NA_SE_PL_BODY_HIT);
|
|
}
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_IN_WATER) {
|
|
sp4C = 0;
|
|
} else if (this->actor.colChkInfo.acHitEffect == 2) {
|
|
sp4C = 3;
|
|
} else if (this->actor.colChkInfo.acHitEffect == 3) {
|
|
sp4C = 4;
|
|
} else if (this->actor.colChkInfo.acHitEffect == 4) {
|
|
sp4C = 1;
|
|
} else {
|
|
func_80838280(this);
|
|
sp4C = 0;
|
|
}
|
|
|
|
func_80837C0C(play, this, sp4C, 4.0f, 5.0f, Actor_WorldYawTowardActor(ac, &this->actor), 20);
|
|
} else if (this->invincibilityTimer != 0) {
|
|
return 0;
|
|
} else {
|
|
static u8 D_808544F4[] = { 120, 60 };
|
|
s32 sp48 = func_80838144(sFloorType);
|
|
|
|
if (((this->actor.wallPoly != NULL) &&
|
|
SurfaceType_IsWallDamage(&play->colCtx, this->actor.wallPoly, this->actor.wallBgId)) ||
|
|
((sp48 >= 0) &&
|
|
SurfaceType_IsWallDamage(&play->colCtx, this->actor.floorPoly, this->actor.floorBgId) &&
|
|
(this->floorTypeTimer >= D_808544F4[sp48])) ||
|
|
((sp48 >= 0) && ((this->currentTunic != PLAYER_TUNIC_GORON && CVarGetInteger("gSuperTunic", 0) == 0) ||
|
|
(this->floorTypeTimer >= D_808544F4[sp48])))) {
|
|
this->floorTypeTimer = 0;
|
|
this->actor.colChkInfo.damage = 4;
|
|
func_80837C0C(play, this, 0, 4.0f, 5.0f, this->actor.shape.rot.y, 20);
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void func_80838940(Player* this, LinkAnimationHeader* anim, f32 arg2, PlayState* play, u16 sfxId) {
|
|
Player_SetupAction(play, this, Player_Action_8084411C, 1);
|
|
|
|
if (anim != NULL) {
|
|
Player_AnimPlayOnceAdjusted(play, this, anim);
|
|
}
|
|
|
|
this->actor.velocity.y = arg2 * D_808535E8;
|
|
this->hoverBootsTimer = 0;
|
|
this->actor.bgCheckFlags &= ~1;
|
|
|
|
func_80832854(this);
|
|
func_80832698(this, sfxId);
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_JUMPING;
|
|
}
|
|
|
|
void func_808389E8(Player* this, LinkAnimationHeader* anim, f32 arg2, PlayState* play) {
|
|
func_80838940(this, anim, arg2, play, NA_SE_VO_LI_SWORD_N);
|
|
}
|
|
|
|
s32 Player_ActionChange_12(Player* this, PlayState* play) {
|
|
s32 sp3C;
|
|
LinkAnimationHeader* anim;
|
|
f32 sp34;
|
|
f32 temp;
|
|
f32 wallPolyNormalX;
|
|
f32 wallPolyNormalZ;
|
|
f32 sp24;
|
|
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) && (this->ledgeClimbType >= 2) &&
|
|
(!(this->stateFlags1 & PLAYER_STATE1_IN_WATER) || (this->ageProperties->unk_14 > this->yDistToLedge))) {
|
|
sp3C = 0;
|
|
|
|
if (func_808332B8(this)) {
|
|
if (this->actor.yDistToWater < 50.0f) {
|
|
if ((this->ledgeClimbType < 2) || (this->yDistToLedge > this->ageProperties->unk_10)) {
|
|
return 0;
|
|
}
|
|
} else if ((this->currentBoots != PLAYER_BOOTS_IRON) || (this->ledgeClimbType > 2)) {
|
|
return 0;
|
|
}
|
|
} else if (!(this->actor.bgCheckFlags & 1) ||
|
|
((this->ageProperties->unk_14 <= this->yDistToLedge) && (this->stateFlags1 & PLAYER_STATE1_IN_WATER))) {
|
|
return 0;
|
|
}
|
|
|
|
if ((this->actor.wallBgId != BGCHECK_SCENE) && (sTouchedWallFlags & 0x40)) {
|
|
if (this->ledgeClimbDelayTimer >= 6) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DO_ACTION_CLIMB;
|
|
if (CHECK_BTN_ALL(sControlInput->press.button, BTN_A)) {
|
|
sp3C = 1;
|
|
}
|
|
}
|
|
} else if ((this->ledgeClimbDelayTimer >= 6) || CHECK_BTN_ALL(sControlInput->press.button, BTN_A)) {
|
|
sp3C = 1;
|
|
}
|
|
|
|
if (sp3C != 0) {
|
|
Player_SetupAction(play, this, Player_Action_80845668, 0);
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_JUMPING;
|
|
|
|
sp34 = this->yDistToLedge;
|
|
|
|
if (this->ageProperties->unk_14 <= sp34) {
|
|
anim = &gPlayerAnim_link_normal_250jump_start;
|
|
this->linearVelocity = 1.0f;
|
|
} else {
|
|
wallPolyNormalX = COLPOLY_GET_NORMAL(this->actor.wallPoly->normal.x);
|
|
wallPolyNormalZ = COLPOLY_GET_NORMAL(this->actor.wallPoly->normal.z);
|
|
sp24 = this->distToInteractWall + 0.5f;
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_CLIMBING_LEDGE;
|
|
|
|
if (func_808332B8(this)) {
|
|
anim = &gPlayerAnim_link_swimer_swim_15step_up;
|
|
sp34 -= (60.0f * this->ageProperties->unk_08);
|
|
this->stateFlags1 &= ~PLAYER_STATE1_IN_WATER;
|
|
} else if (this->ageProperties->unk_18 <= sp34) {
|
|
anim = &gPlayerAnim_link_normal_150step_up;
|
|
sp34 -= (59.0f * this->ageProperties->unk_08);
|
|
} else {
|
|
anim = &gPlayerAnim_link_normal_100step_up;
|
|
sp34 -= (41.0f * this->ageProperties->unk_08);
|
|
}
|
|
|
|
this->actor.shape.yOffset -= sp34 * 100.0f;
|
|
|
|
this->actor.world.pos.x -= sp24 * wallPolyNormalX;
|
|
this->actor.world.pos.y += this->yDistToLedge;
|
|
this->actor.world.pos.z -= sp24 * wallPolyNormalZ;
|
|
|
|
func_80832224(this);
|
|
}
|
|
|
|
this->actor.bgCheckFlags |= 1;
|
|
|
|
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, anim, 1.3f);
|
|
AnimationContext_DisableQueue(play);
|
|
|
|
this->actor.shape.rot.y = this->yaw = this->actor.wallYaw + 0x8000;
|
|
|
|
return 1;
|
|
}
|
|
} else if ((this->actor.bgCheckFlags & 1) && (this->ledgeClimbType == 1) && (this->ledgeClimbDelayTimer >= 3)) {
|
|
temp = (this->yDistToLedge * 0.08f) + 5.5f;
|
|
func_808389E8(this, &gPlayerAnim_link_normal_jump, temp, play);
|
|
this->linearVelocity = 2.5f;
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_80838E70(PlayState* play, Player* this, f32 arg2, s16 arg3) {
|
|
Player_SetupAction(play, this, Player_Action_80845CA4, 0);
|
|
func_80832440(play, this);
|
|
|
|
this->av1.actionVar1 = 1;
|
|
this->av2.actionVar2 = 1;
|
|
|
|
this->unk_450.x = (Math_SinS(arg3) * arg2) + this->actor.world.pos.x;
|
|
this->unk_450.z = (Math_CosS(arg3) * arg2) + this->actor.world.pos.z;
|
|
|
|
Player_AnimPlayOnce(play, this, func_80833338(this));
|
|
}
|
|
|
|
void func_80838F18(PlayState* play, Player* this) {
|
|
Player_SetupAction(play, this, Player_Action_8084D610, 0);
|
|
Player_AnimChangeLoopSlowMorph(play, this, &gPlayerAnim_link_swimer_swim_wait);
|
|
}
|
|
|
|
void func_80838F5C(PlayState* play, Player* this) {
|
|
Player_SetupAction(play, this, Player_Action_8084F88C, 0);
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE | PLAYER_STATE1_FLOOR_DISABLED;
|
|
|
|
Camera_ChangeSetting(Play_GetCamera(play, 0), CAM_SET_FREE0);
|
|
}
|
|
|
|
s32 func_80838FB8(PlayState* play, Player* this) {
|
|
if ((play->transitionTrigger == TRANS_TRIGGER_OFF) && (this->stateFlags1 & PLAYER_STATE1_FLOOR_DISABLED)) {
|
|
func_80838F5C(play, this);
|
|
Player_AnimPlayLoop(play, this, &gPlayerAnim_link_normal_landing_wait);
|
|
func_80832698(this, NA_SE_VO_LI_FALL_S);
|
|
func_800788CC(NA_SE_OC_SECRET_WARP_IN);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* The actual entrances each "return entrance" value can map to.
|
|
* This is used by scenes that are shared between locations, like child/adult Shooting Gallery or Great Fairy Fountains.
|
|
*
|
|
* This 1D array is split into groups of entrances.
|
|
* The start of each group is indexed by `sReturnEntranceGroupIndices` values.
|
|
* The resulting groups are then indexed by the spawn value.
|
|
*
|
|
* The spawn value (`PlayState.spawn`) is set to a different value depending on the entrance used to enter the
|
|
* scene, which allows these dynamic "return entrances" to link back to the previous scene.
|
|
*
|
|
* Note: grottos and normal fairy fountains use `ENTR_RETURN_GROTTO`
|
|
*/
|
|
s16 sReturnEntranceGroupData[] = {
|
|
// ENTR_RETURN_GREAT_FAIRYS_FOUNTAIN_MAGIC
|
|
/* 0 */ ENTR_DEATH_MOUNTAIN_TRAIL_4, // from Magic Fairy Fountain
|
|
/* 1 */ ENTR_DEATH_MOUNTAIN_CRATER_3, // from Double Magic Fairy Fountain
|
|
/* 2 */ ENTR_HYRULE_CASTLE_2, // from Double Defense Fairy Fountain (as adult)
|
|
|
|
// ENTR_RETURN_2
|
|
/* 3 */ ENTR_KAKARIKO_VILLAGE_9, // from Potion Shop in Kakariko
|
|
/* 4 */ ENTR_MARKET_DAY_5, // from Potion Shop in Market
|
|
|
|
// ENTR_RETURN_BAZAAR
|
|
/* 5 */ ENTR_KAKARIKO_VILLAGE_3,
|
|
/* 6 */ ENTR_MARKET_DAY_6,
|
|
|
|
// ENTR_RETURN_4
|
|
/* 7 */ ENTR_KAKARIKO_VILLAGE_11, // from House of Skulltulas
|
|
/* 8 */ ENTR_BACK_ALLEY_DAY_2, // from Bombchu Shop
|
|
|
|
// ENTR_RETURN_SHOOTING_GALLERY
|
|
/* 9 */ ENTR_KAKARIKO_VILLAGE_10,
|
|
/* 10 */ ENTR_MARKET_DAY_8,
|
|
|
|
// ENTR_RETURN_GREAT_FAIRYS_FOUNTAIN_SPELLS
|
|
/* 11 */ ENTR_ZORAS_FOUNTAIN_5, // from Farores Wind Fairy Fountain
|
|
/* 12 */ ENTR_HYRULE_CASTLE_2, // from Dins Fire Fairy Fountain (as child)
|
|
/* 13 */ ENTR_DESERT_COLOSSUS_7, // from Nayrus Love Fairy Fountain
|
|
};
|
|
|
|
/**
|
|
* The values are indices into `sReturnEntranceGroupData` marking the start of each group
|
|
*/
|
|
u8 sReturnEntranceGroupIndices[] = {
|
|
11, // ENTR_RETURN_GREAT_FAIRYS_FOUNTAIN_SPELLS
|
|
9, // ENTR_RETURN_SHOOTING_GALLERY
|
|
3, // ENTR_RETURN_2
|
|
5, // ENTR_RETURN_BAZAAR
|
|
7, // ENTR_RETURN_4
|
|
0, // ENTR_RETURN_GREAT_FAIRYS_FOUNTAIN_MAGIC
|
|
};
|
|
|
|
s32 Player_HandleExitsAndVoids(PlayState* play, Player* this, CollisionPoly* poly, u32 bgId) {
|
|
s32 exitIndex;
|
|
s32 temp;
|
|
s32 sp34;
|
|
f32 speedXZ;
|
|
s32 yaw;
|
|
|
|
if (this->actor.category == ACTORCAT_PLAYER) {
|
|
exitIndex = 0;
|
|
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_DEAD) && (play->transitionTrigger == TRANS_TRIGGER_OFF) && (this->csAction == 0) &&
|
|
!(this->stateFlags1 & PLAYER_STATE1_LOADING) &&
|
|
(((poly != NULL) && (exitIndex = SurfaceType_GetSceneExitIndex(&play->colCtx, poly, bgId), exitIndex != 0)) ||
|
|
(func_8083816C(sFloorType) && (this->floorProperty == 12)))) {
|
|
|
|
sp34 = this->unk_A84 - (s32)this->actor.world.pos.y;
|
|
|
|
if (!(this->stateFlags1 & (PLAYER_STATE1_ON_HORSE | PLAYER_STATE1_IN_WATER | PLAYER_STATE1_IN_CUTSCENE)) &&
|
|
!(this->actor.bgCheckFlags & 1) && (sp34 < 100) && (sYDistToFloor > 100.0f)) {
|
|
return 0;
|
|
}
|
|
|
|
if (exitIndex == 0) {
|
|
Play_TriggerVoidOut(play);
|
|
Scene_SetTransitionForNextEntrance(play);
|
|
} else {
|
|
play->nextEntranceIndex = play->setupExitList[exitIndex - 1];
|
|
|
|
// Main override for entrance rando and entrance skips
|
|
if (IS_RANDO) {
|
|
play->nextEntranceIndex = Entrance_OverrideNextIndex(play->nextEntranceIndex);
|
|
}
|
|
|
|
if (play->nextEntranceIndex == ENTR_RETURN_GROTTO) {
|
|
gSaveContext.respawnFlag = 2;
|
|
play->nextEntranceIndex = gSaveContext.respawn[RESPAWN_MODE_RETURN].entranceIndex;
|
|
play->transitionType = TRANS_TYPE_FADE_WHITE;
|
|
gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE;
|
|
} else if (play->nextEntranceIndex >= ENTR_RETURN_YOUSEI_IZUMI_YOKO) {
|
|
// handle dynamic exits
|
|
if (IS_RANDO) {
|
|
play->nextEntranceIndex = Entrance_OverrideDynamicExit(sReturnEntranceGroupIndices[play->nextEntranceIndex - ENTR_RETURN_YOUSEI_IZUMI_YOKO] + play->curSpawn);
|
|
} else {
|
|
play->nextEntranceIndex =
|
|
sReturnEntranceGroupData[sReturnEntranceGroupIndices[play->nextEntranceIndex - ENTR_RETURN_YOUSEI_IZUMI_YOKO] + play->curSpawn];
|
|
}
|
|
|
|
Scene_SetTransitionForNextEntrance(play);
|
|
} else {
|
|
// In Entrance rando, if our respawnFlag is set for a grotto return, we don't want the void out to happen
|
|
if (SurfaceType_GetSlope(&play->colCtx, poly, bgId) == 2 &&
|
|
(!IS_RANDO || (Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES) && gSaveContext.respawnFlag != 2))) {
|
|
gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex = play->nextEntranceIndex;
|
|
Play_TriggerVoidOut(play);
|
|
gSaveContext.respawnFlag = -2;
|
|
}
|
|
gSaveContext.retainWeatherMode = 1;
|
|
Scene_SetTransitionForNextEntrance(play);
|
|
}
|
|
play->transitionTrigger = TRANS_TRIGGER_START;
|
|
}
|
|
|
|
if (!(this->stateFlags1 & (PLAYER_STATE1_ON_HORSE | PLAYER_STATE1_IN_CUTSCENE)) &&
|
|
!(this->stateFlags2 & PLAYER_STATE2_CRAWLING) && !func_808332B8(this) &&
|
|
(temp = func_80041D4C(&play->colCtx, poly, bgId), (temp != 10)) &&
|
|
((sp34 < 100) || (this->actor.bgCheckFlags & 1))) {
|
|
|
|
if (temp == 11) {
|
|
func_800788CC(NA_SE_OC_SECRET_HOLE_OUT);
|
|
func_800F6964(5);
|
|
gSaveContext.seqId = (u8)NA_BGM_DISABLED;
|
|
gSaveContext.natureAmbienceId = NATURE_ID_DISABLED;
|
|
} else {
|
|
speedXZ = this->linearVelocity;
|
|
|
|
if (speedXZ < 0.0f) {
|
|
this->actor.world.rot.y += 0x8000;
|
|
speedXZ = -speedXZ;
|
|
}
|
|
|
|
if (speedXZ > R_RUN_SPEED_LIMIT / 100.0f) {
|
|
gSaveContext.entranceSpeed = R_RUN_SPEED_LIMIT / 100.0f;
|
|
} else {
|
|
gSaveContext.entranceSpeed = speedXZ;
|
|
}
|
|
|
|
if (sConveyorSpeed != 0) {
|
|
yaw = sConveyorYaw;
|
|
} else {
|
|
yaw = this->actor.world.rot.y;
|
|
}
|
|
func_80838E70(play, this, 400.0f, yaw);
|
|
}
|
|
} else {
|
|
if (!(this->actor.bgCheckFlags & 1)) {
|
|
Player_ZeroSpeedXZ(this);
|
|
}
|
|
}
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_LOADING | PLAYER_STATE1_IN_CUTSCENE;
|
|
|
|
func_80835E44(play, 0x2F);
|
|
|
|
return 1;
|
|
} else {
|
|
if (play->transitionTrigger == TRANS_TRIGGER_OFF) {
|
|
|
|
if ((this->actor.world.pos.y < -4000.0f) ||
|
|
(((this->floorProperty == 5) || (this->floorProperty == 12)) &&
|
|
((sYDistToFloor < 100.0f) || (this->fallDistance > 400.0f) ||
|
|
((play->sceneNum != SCENE_SHADOW_TEMPLE) && (this->fallDistance > 200.0f)))) ||
|
|
((play->sceneNum == SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR) && (this->fallDistance > 320.0f))) {
|
|
|
|
if (this->actor.bgCheckFlags & 1) {
|
|
if (this->floorProperty == 5) {
|
|
Play_TriggerRespawn(play);
|
|
} else {
|
|
Play_TriggerVoidOut(play);
|
|
}
|
|
play->transitionType = TRANS_TYPE_FADE_BLACK_FAST;
|
|
func_80078884(NA_SE_OC_ABYSS);
|
|
} else {
|
|
func_80838F5C(play, this);
|
|
this->av2.actionVar2 = 9999;
|
|
if (this->floorProperty == 5) {
|
|
this->av1.actionVar1 = -1;
|
|
} else {
|
|
this->av1.actionVar1 = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
this->unk_A84 = this->actor.world.pos.y;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Gets a position relative to player's yaw.
|
|
* An offset is applied to the provided base position in the direction of shape y rotation.
|
|
* The resulting position is stored in `dest`
|
|
*/
|
|
void Player_GetRelativePosition(Player* this, Vec3f* base, Vec3f* offset, Vec3f* dest) {
|
|
f32 cos = Math_CosS(this->actor.shape.rot.y);
|
|
f32 sin = Math_SinS(this->actor.shape.rot.y);
|
|
|
|
dest->x = base->x + ((offset->x * cos) + (offset->z * sin));
|
|
dest->y = base->y + offset->y;
|
|
dest->z = base->z + ((offset->z * cos) - (offset->x * sin));
|
|
}
|
|
|
|
Actor* Player_SpawnFairy(PlayState* play, Player* this, Vec3f* arg2, Vec3f* arg3, s32 type) {
|
|
Vec3f pos;
|
|
|
|
Player_GetRelativePosition(this, arg2, arg3, &pos);
|
|
|
|
return Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELF, pos.x, pos.y, pos.z, 0, 0, 0, type, true);
|
|
}
|
|
|
|
f32 func_808396F4(PlayState* play, Player* this, Vec3f* arg2, Vec3f* arg3, CollisionPoly** arg4, s32* arg5) {
|
|
Player_GetRelativePosition(this, &this->actor.world.pos, arg2, arg3);
|
|
|
|
return BgCheck_EntityRaycastFloor3(&play->colCtx, arg4, arg5, arg3);
|
|
}
|
|
|
|
f32 func_8083973C(PlayState* play, Player* this, Vec3f* arg2, Vec3f* arg3) {
|
|
CollisionPoly* sp24;
|
|
s32 sp20;
|
|
|
|
return func_808396F4(play, this, arg2, arg3, &sp24, &sp20);
|
|
}
|
|
|
|
/**
|
|
* Checks if a line between the player's position and the provided `offset` intersect a wall.
|
|
*
|
|
* Point A of the line is at player's world position offset by the height provided in `offset`.
|
|
* Point B of the line is at player's world position offset by the entire `offset` vector.
|
|
* Point A and B are always at the same height, meaning this is a horizontal line test.
|
|
*/
|
|
s32 Player_PosVsWallLineTest(PlayState* play, Player* this, Vec3f* offset, CollisionPoly** wallPoly, s32* bgId,
|
|
Vec3f* posResult) {
|
|
Vec3f posA;
|
|
Vec3f posB;
|
|
|
|
posA.x = this->actor.world.pos.x;
|
|
posA.y = this->actor.world.pos.y + offset->y;
|
|
posA.z = this->actor.world.pos.z;
|
|
|
|
Player_GetRelativePosition(this, &this->actor.world.pos, offset, &posB);
|
|
|
|
return BgCheck_EntityLineTest1(&play->colCtx, &posA, &posB, posResult, wallPoly, true, false, false, true, bgId);
|
|
}
|
|
|
|
s32 Player_ActionChange_1(Player* this, PlayState* play) {
|
|
DoorShutter* doorShutter;
|
|
EnDoor* door; // Can also be DoorKiller*
|
|
s32 doorDirection;
|
|
f32 sp78;
|
|
f32 sp74;
|
|
Actor* doorActor;
|
|
f32 sp6C;
|
|
s32 pad3;
|
|
s32 frontRoom;
|
|
Actor* attachedActor;
|
|
LinkAnimationHeader* sp5C;
|
|
CollisionPoly* groundPoly;
|
|
Vec3f checkPos;
|
|
|
|
if ((this->doorType != PLAYER_DOORTYPE_NONE) &&
|
|
(!(this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) ||
|
|
((this->heldActor != NULL) && (this->heldActor->id == ACTOR_EN_RU1)))) {
|
|
// Disable doors in Boss Rush so the player can't leave the boss rooms backwards.
|
|
if ((CHECK_BTN_ALL(sControlInput->press.button, BTN_A) || (Player_Action_8084F9A0 == this->actionFunc)) && !IS_BOSS_RUSH) {
|
|
doorActor = this->doorActor;
|
|
|
|
if (this->doorType <= PLAYER_DOORTYPE_AJAR) {
|
|
doorActor->textId = 0xD0;
|
|
Player_StartTalking(play, doorActor);
|
|
return 0;
|
|
}
|
|
|
|
doorDirection = this->doorDirection;
|
|
sp78 = Math_CosS(doorActor->shape.rot.y);
|
|
sp74 = Math_SinS(doorActor->shape.rot.y);
|
|
|
|
if (this->doorType == PLAYER_DOORTYPE_SLIDING) {
|
|
doorShutter = (DoorShutter*)doorActor;
|
|
|
|
this->yaw = doorShutter->dyna.actor.home.rot.y;
|
|
if (doorDirection > 0) {
|
|
this->yaw -= 0x8000;
|
|
}
|
|
this->actor.shape.rot.y = this->yaw;
|
|
|
|
if (this->linearVelocity <= 0.0f) {
|
|
this->linearVelocity = 0.1f;
|
|
}
|
|
|
|
func_80838E70(play, this, 50.0f, this->actor.shape.rot.y);
|
|
|
|
this->av1.actionVar1 = 0;
|
|
this->unk_447 = this->doorType;
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
|
|
|
this->unk_450.x = this->actor.world.pos.x + ((doorDirection * 20.0f) * sp74);
|
|
this->unk_450.z = this->actor.world.pos.z + ((doorDirection * 20.0f) * sp78);
|
|
this->unk_45C.x = this->actor.world.pos.x + ((doorDirection * -120.0f) * sp74);
|
|
this->unk_45C.z = this->actor.world.pos.z + ((doorDirection * -120.0f) * sp78);
|
|
|
|
doorShutter->unk_164 = 1;
|
|
func_80832224(this);
|
|
|
|
if (this->doorTimer != 0) {
|
|
this->av2.actionVar2 = 0;
|
|
Player_AnimChangeOnceMorph(play, this, func_80833338(this));
|
|
this->skelAnime.endFrame = 0.0f;
|
|
} else {
|
|
this->linearVelocity = 0.1f;
|
|
}
|
|
|
|
if (doorShutter->dyna.actor.category == ACTORCAT_DOOR) {
|
|
this->doorBgCamIndex = play->transiActorCtx.list[(u16)doorShutter->dyna.actor.params >> 10]
|
|
.sides[(doorDirection > 0) ? 0 : 1]
|
|
.effects;
|
|
|
|
Actor_DisableLens(play);
|
|
}
|
|
} else {
|
|
// This actor can be either EnDoor or DoorKiller.
|
|
// Don't try to access any struct vars other than `animStyle` and `playerIsOpening`! These two variables
|
|
// are common across the two actors' structs however most other variables are not!
|
|
door = (EnDoor*)doorActor;
|
|
|
|
door->animStyle = (doorDirection < 0.0f) ? (LINK_IS_ADULT ? KNOB_ANIM_ADULT_L : KNOB_ANIM_CHILD_L)
|
|
: (LINK_IS_ADULT ? KNOB_ANIM_ADULT_R : KNOB_ANIM_CHILD_R);
|
|
|
|
if (door->animStyle == KNOB_ANIM_ADULT_L) {
|
|
sp5C = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_doorA_free, this->modelAnimType);
|
|
} else if (door->animStyle == KNOB_ANIM_CHILD_L) {
|
|
sp5C = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_doorA, this->modelAnimType);
|
|
} else if (door->animStyle == KNOB_ANIM_ADULT_R) {
|
|
sp5C = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_doorB_free, this->modelAnimType);
|
|
} else {
|
|
sp5C = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_doorB, this->modelAnimType);
|
|
}
|
|
|
|
Player_SetupAction(play, this, Player_Action_80845EF8, 0);
|
|
func_80832528(play, this);
|
|
|
|
if (doorDirection < 0) {
|
|
this->actor.shape.rot.y = doorActor->shape.rot.y;
|
|
} else {
|
|
this->actor.shape.rot.y = doorActor->shape.rot.y - 0x8000;
|
|
}
|
|
|
|
this->yaw = this->actor.shape.rot.y;
|
|
|
|
sp6C = (doorDirection * 22.0f);
|
|
this->actor.world.pos.x = doorActor->world.pos.x + sp6C * sp74;
|
|
this->actor.world.pos.z = doorActor->world.pos.z + sp6C * sp78;
|
|
|
|
func_8083328C(play, this, sp5C);
|
|
|
|
if (this->doorTimer != 0) {
|
|
this->skelAnime.endFrame = 0.0f;
|
|
}
|
|
|
|
func_80832224(this);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x28F);
|
|
|
|
if (doorActor->parent != NULL) {
|
|
doorDirection = -doorDirection;
|
|
}
|
|
|
|
door->playerIsOpening = 1;
|
|
|
|
if (this->doorType != PLAYER_DOORTYPE_FAKE) {
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
|
Actor_DisableLens(play);
|
|
|
|
if (((doorActor->params >> 7) & 7) == 3) {
|
|
checkPos.x = doorActor->world.pos.x - (sp6C * sp74);
|
|
checkPos.y = doorActor->world.pos.y + 10.0f;
|
|
checkPos.z = doorActor->world.pos.z - (sp6C * sp78);
|
|
|
|
BgCheck_EntityRaycastFloor1(&play->colCtx, &groundPoly, &checkPos);
|
|
|
|
//! @bug groundPoly's bgId is not guaranteed to be BGCHECK_SCENE
|
|
if (Player_HandleExitsAndVoids(play, this, groundPoly, BGCHECK_SCENE)) {
|
|
gSaveContext.entranceSpeed = 2.0f;
|
|
gSaveContext.entranceSound = NA_SE_OC_DOOR_OPEN;
|
|
}
|
|
} else {
|
|
Camera_ChangeDoorCam(Play_GetCamera(play, 0), doorActor,
|
|
play->transiActorCtx.list[(u16)doorActor->params >> 10]
|
|
.sides[(doorDirection > 0) ? 0 : 1]
|
|
.effects,
|
|
0, 38.0f * D_808535EC, 26.0f * D_808535EC, 10.0f * D_808535EC);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((this->doorType != PLAYER_DOORTYPE_FAKE) && (doorActor->category == ACTORCAT_DOOR)) {
|
|
frontRoom = play->transiActorCtx.list[(u16)doorActor->params >> 10]
|
|
.sides[(doorDirection > 0) ? 0 : 1]
|
|
.room;
|
|
|
|
if ((frontRoom >= 0) && (frontRoom != play->roomCtx.curRoom.num)) {
|
|
func_8009728C(play, &play->roomCtx, frontRoom);
|
|
}
|
|
}
|
|
|
|
doorActor->room = play->roomCtx.curRoom.num;
|
|
|
|
if (((attachedActor = doorActor->child) != NULL) || ((attachedActor = doorActor->parent) != NULL)) {
|
|
attachedActor->room = play->roomCtx.curRoom.num;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_80839E88(Player* this, PlayState* play) {
|
|
LinkAnimationHeader* anim;
|
|
|
|
Player_SetupAction(play, this, Player_Action_80840450, 1);
|
|
|
|
if (this->unk_870 < 0.5f) {
|
|
anim = func_808334E4(this);
|
|
this->unk_870 = 0.0f;
|
|
} else {
|
|
anim = func_80833528(this);
|
|
this->unk_870 = 1.0f;
|
|
}
|
|
|
|
this->unk_874 = this->unk_870;
|
|
Player_AnimPlayLoop(play, this, anim);
|
|
this->yaw = this->actor.shape.rot.y;
|
|
}
|
|
|
|
void func_80839F30(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_808407CC, 1);
|
|
Player_AnimChangeOnceMorph(play, this, func_80833338(this));
|
|
this->yaw = this->actor.shape.rot.y;
|
|
}
|
|
|
|
void func_80839F90(Player* this, PlayState* play) {
|
|
if (func_8008E9C4(this)) {
|
|
func_80839E88(this, play);
|
|
} else if (func_80833B2C(this)) {
|
|
func_80839F30(this, play);
|
|
} else {
|
|
func_80853080(this, play);
|
|
}
|
|
}
|
|
|
|
void func_80839FFC(Player* this, PlayState* play) {
|
|
PlayerActionFunc actionFunc;
|
|
|
|
if (func_8008E9C4(this)) {
|
|
actionFunc = Player_Action_80840450;
|
|
} else if (func_80833B2C(this)) {
|
|
actionFunc = Player_Action_808407CC;
|
|
} else {
|
|
actionFunc = Player_Action_80840BC8;
|
|
}
|
|
|
|
Player_SetupAction(play, this, actionFunc, 1);
|
|
}
|
|
|
|
void func_8083A060(Player* this, PlayState* play) {
|
|
func_80839FFC(this, play);
|
|
if (func_8008E9C4(this)) {
|
|
this->av2.actionVar2 = 1;
|
|
}
|
|
}
|
|
|
|
void func_8083A098(Player* this, LinkAnimationHeader* anim, PlayState* play) {
|
|
func_8083A060(this, play);
|
|
func_8083328C(play, this, anim);
|
|
}
|
|
|
|
s32 func_8083A0D4(Player* this) {
|
|
return (this->interactRangeActor != NULL) && (this->heldActor == NULL);
|
|
}
|
|
|
|
void func_8083A0F4(PlayState* play, Player* this) {
|
|
if (func_8083A0D4(this)) {
|
|
Actor* interactRangeActor = this->interactRangeActor;
|
|
s32 interactActorId = interactRangeActor->id;
|
|
|
|
if (interactActorId == ACTOR_BG_TOKI_SWD) {
|
|
this->interactRangeActor->parent = &this->actor;
|
|
Player_SetupAction(play, this, Player_Action_8084F608, 0);
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
|
sMaskMemory = PLAYER_MASK_NONE;
|
|
} else {
|
|
LinkAnimationHeader* anim;
|
|
|
|
if (interactActorId == ACTOR_BG_HEAVY_BLOCK) {
|
|
Player_SetupAction(play, this, Player_Action_80846120, 0);
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
|
anim = &gPlayerAnim_link_normal_heavy_carry;
|
|
} else if ((interactActorId == ACTOR_EN_ISHI) && ((interactRangeActor->params & 0xF) == 1)) {
|
|
Player_SetupAction(play, this, Player_Action_80846260, 0);
|
|
anim = &gPlayerAnim_link_silver_carry;
|
|
} else if (((interactActorId == ACTOR_EN_BOMBF) || (interactActorId == ACTOR_EN_KUSA)) &&
|
|
(Player_GetStrength() <= PLAYER_STR_NONE)) {
|
|
Player_SetupAction(play, this, Player_Action_80846408, 0);
|
|
this->actor.world.pos.x =
|
|
(Math_SinS(interactRangeActor->yawTowardsPlayer) * 20.0f) + interactRangeActor->world.pos.x;
|
|
this->actor.world.pos.z =
|
|
(Math_CosS(interactRangeActor->yawTowardsPlayer) * 20.0f) + interactRangeActor->world.pos.z;
|
|
this->yaw = this->actor.shape.rot.y = interactRangeActor->yawTowardsPlayer + 0x8000;
|
|
anim = &gPlayerAnim_link_normal_nocarry_free;
|
|
} else {
|
|
Player_SetupAction(play, this, Player_Action_80846050, 0);
|
|
anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_carryB, this->modelAnimType);
|
|
}
|
|
|
|
// Same actor is used for small and large silver rocks, use actor params to identify large ones
|
|
bool isLargeSilverRock = interactActorId == ACTOR_EN_ISHI && interactRangeActor->params & 1 == 1;
|
|
if (CVarGetInteger("gFasterHeavyBlockLift", 0) && (isLargeSilverRock || interactActorId == ACTOR_BG_HEAVY_BLOCK)) {
|
|
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, anim, 5.0f);
|
|
} else {
|
|
LinkAnimation_PlayOnce(play, &this->skelAnime, anim);
|
|
}
|
|
}
|
|
} else {
|
|
func_80839F90(this, play);
|
|
this->stateFlags1 &= ~PLAYER_STATE1_ITEM_OVER_HEAD;
|
|
}
|
|
}
|
|
|
|
void func_8083A2F8(PlayState* play, Player* this) {
|
|
func_80835DAC(play, this, Player_Action_8084B530, 0);
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_TEXT_ON_SCREEN | PLAYER_STATE1_IN_CUTSCENE;
|
|
|
|
if (this->actor.textId != 0) {
|
|
Message_StartTextbox(play, this->actor.textId, this->targetActor);
|
|
this->unk_664 = this->targetActor;
|
|
}
|
|
}
|
|
|
|
void func_8083A360(PlayState* play, Player* this) {
|
|
func_80835DAC(play, this, Player_Action_8084CC98, 0);
|
|
}
|
|
|
|
void func_8083A388(PlayState* play, Player* this) {
|
|
Player_SetupAction(play, this, Player_Action_8084B78C, 0);
|
|
}
|
|
|
|
void func_8083A3B0(PlayState* play, Player* this) {
|
|
s32 sp1C = this->av2.actionVar2;
|
|
s32 sp18 = this->av1.actionVar1;
|
|
|
|
func_80835DAC(play, this, Player_Action_8084BF1C, 0);
|
|
this->actor.velocity.y = 0.0f;
|
|
|
|
this->av2.actionVar2 = sp1C;
|
|
this->av1.actionVar1 = sp18;
|
|
}
|
|
|
|
void func_8083A40C(PlayState* play, Player* this) {
|
|
func_80835DAC(play, this, Player_Action_8084C760, 0);
|
|
}
|
|
|
|
void func_8083A434(PlayState* play, Player* this) {
|
|
func_80835DAC(play, this, Player_Action_8084E6D4, 0);
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_IN_CUTSCENE;
|
|
|
|
if (this->getItemId == GI_HEART_CONTAINER_2) {
|
|
this->av2.actionVar2 = 20;
|
|
} else if (this->getItemId >= 0 || (this->getItemEntry.objectId != OBJECT_INVALID && this->getItemEntry.getItemId >= 0)) {
|
|
this->av2.actionVar2 = 1;
|
|
} else {
|
|
this->getItemId = -this->getItemId;
|
|
this->getItemEntry.getItemId = -this->getItemEntry.getItemId;
|
|
}
|
|
}
|
|
|
|
s32 func_8083A4A8(Player* this, PlayState* play) {
|
|
s16 yawDiff;
|
|
LinkAnimationHeader* anim;
|
|
f32 temp;
|
|
|
|
yawDiff = this->yaw - this->actor.shape.rot.y;
|
|
|
|
if ((ABS(yawDiff) < 0x1000) && (this->linearVelocity > 4.0f)) {
|
|
anim = &gPlayerAnim_link_normal_run_jump;
|
|
} else {
|
|
anim = &gPlayerAnim_link_normal_jump;
|
|
}
|
|
|
|
if (this->linearVelocity > (IREG(66) / 100.0f)) {
|
|
temp = IREG(67) / 100.0f;
|
|
} else {
|
|
temp = (IREG(68) / 100.0f) + ((IREG(69) * this->linearVelocity) / 1000.0f);
|
|
}
|
|
|
|
func_80838940(this, anim, temp, play, NA_SE_VO_LI_AUTO_JUMP);
|
|
this->av2.actionVar2 = 1;
|
|
|
|
return 1;
|
|
}
|
|
|
|
void func_8083A5C4(PlayState* play, Player* this, CollisionPoly* arg2, f32 arg3, LinkAnimationHeader* anim) {
|
|
f32 nx = COLPOLY_GET_NORMAL(arg2->normal.x);
|
|
f32 nz = COLPOLY_GET_NORMAL(arg2->normal.z);
|
|
|
|
Player_SetupAction(play, this, Player_Action_8084BBE4, 0);
|
|
func_80832564(play, this);
|
|
Player_AnimPlayOnce(play, this, anim);
|
|
|
|
this->actor.world.pos.x -= (arg3 + 1.0f) * nx;
|
|
this->actor.world.pos.z -= (arg3 + 1.0f) * nz;
|
|
this->actor.shape.rot.y = this->yaw = Math_Atan2S(nz, nx);
|
|
|
|
func_80832224(this);
|
|
Player_SkelAnimeResetPrevTranslRot(this);
|
|
}
|
|
|
|
s32 func_8083A6AC(Player* this, PlayState* play) {
|
|
CollisionPoly* sp84;
|
|
s32 sp80;
|
|
Vec3f sp74;
|
|
Vec3f sp68;
|
|
f32 temp1;
|
|
|
|
//! @bug `floorPitch` and `floorPitchAlt` are cleared to 0 before this function is called, because the player
|
|
//! left the ground. The angles will always be zero and therefore will always pass these checks.
|
|
//! The intention seems to be to prevent ledge hanging or vine grabbing when walking off of a steep enough slope.
|
|
if ((this->actor.yDistToWater < -80.0f) && (ABS(this->floorPitch) < 2730) && (ABS(this->floorPitchAlt) < 2730)) {
|
|
sp74.x = this->actor.prevPos.x - this->actor.world.pos.x;
|
|
sp74.z = this->actor.prevPos.z - this->actor.world.pos.z;
|
|
|
|
temp1 = sqrtf(SQ(sp74.x) + SQ(sp74.z));
|
|
if (temp1 != 0.0f) {
|
|
temp1 = 5.0f / temp1;
|
|
} else {
|
|
temp1 = 0.0f;
|
|
}
|
|
|
|
sp74.x = this->actor.prevPos.x + (sp74.x * temp1);
|
|
sp74.y = this->actor.world.pos.y;
|
|
sp74.z = this->actor.prevPos.z + (sp74.z * temp1);
|
|
|
|
if (BgCheck_EntityLineTest1(&play->colCtx, &this->actor.world.pos, &sp74, &sp68, &sp84, true, false, false,
|
|
true, &sp80) &&
|
|
((ABS(sp84->normal.y) < 600) || (CVarGetInteger("gClimbEverything", 0) != 0))) {
|
|
f32 nx = COLPOLY_GET_NORMAL(sp84->normal.x);
|
|
f32 ny = COLPOLY_GET_NORMAL(sp84->normal.y);
|
|
f32 nz = COLPOLY_GET_NORMAL(sp84->normal.z);
|
|
f32 sp54;
|
|
s32 sp50;
|
|
|
|
sp54 = Math3D_UDistPlaneToPos(nx, ny, nz, sp84->dist, &this->actor.world.pos);
|
|
|
|
sp50 = sPrevFloorProperty == 6;
|
|
if (!sp50 && (func_80041DB8(&play->colCtx, sp84, sp80) & 8)) {
|
|
sp50 = 1;
|
|
}
|
|
|
|
func_8083A5C4(play, this, sp84, sp54,
|
|
sp50 ? &gPlayerAnim_link_normal_Fclimb_startB : &gPlayerAnim_link_normal_fall);
|
|
|
|
if (sp50) {
|
|
func_80836898(play, this, func_8083A3B0);
|
|
|
|
this->yaw += 0x8000;
|
|
this->actor.shape.rot.y = this->yaw;
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_CLIMBING_LADDER;
|
|
Player_AnimReplaceApplyFlags(play, this, 0x9F);
|
|
|
|
this->av2.actionVar2 = -1;
|
|
this->av1.actionVar1 = sp50;
|
|
} else {
|
|
this->stateFlags1 |= PLAYER_STATE1_HANGING_OFF_LEDGE;
|
|
this->stateFlags1 &= ~PLAYER_STATE1_TARGET_NOTHING;
|
|
}
|
|
|
|
Player_PlaySfx(this, NA_SE_PL_SLIPDOWN);
|
|
func_80832698(this, NA_SE_VO_LI_HANG);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8083A9B8(Player* this, LinkAnimationHeader* anim, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_8084BDFC, 0);
|
|
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, anim, 1.3f);
|
|
}
|
|
|
|
static Vec3f D_8085451C = { 0.0f, 0.0f, 100.0f };
|
|
|
|
void func_8083AA10(Player* this, PlayState* play) {
|
|
s32 sp5C;
|
|
CollisionPoly* sp58;
|
|
s32 sp54;
|
|
WaterBox* sp50;
|
|
Vec3f sp44;
|
|
f32 sp40;
|
|
f32 sp3C;
|
|
|
|
this->fallDistance = this->fallStartHeight - (s32)this->actor.world.pos.y;
|
|
|
|
if (!(this->stateFlags1 & (PLAYER_STATE1_IN_WATER | PLAYER_STATE1_IN_CUTSCENE)) && !(this->actor.bgCheckFlags & 1)) {
|
|
if (!func_80838FB8(play, this)) {
|
|
if (sPrevFloorProperty == 8) {
|
|
this->actor.world.pos.x = this->actor.prevPos.x;
|
|
this->actor.world.pos.z = this->actor.prevPos.z;
|
|
return;
|
|
}
|
|
|
|
if (!(this->stateFlags3 & PLAYER_STATE3_MIDAIR) && !(this->skelAnime.moveFlags & 0x80) &&
|
|
(Player_Action_8084411C != this->actionFunc) && (Player_Action_80844A44 != this->actionFunc)) {
|
|
|
|
if ((sPrevFloorProperty == 7) || (this->meleeWeaponState != 0)) {
|
|
Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.prevPos);
|
|
Player_ZeroSpeedXZ(this);
|
|
return;
|
|
}
|
|
|
|
if (this->hoverBootsTimer != 0) {
|
|
this->actor.velocity.y = 1.0f;
|
|
sPrevFloorProperty = 9;
|
|
return;
|
|
}
|
|
|
|
sp5C = (s16)(this->yaw - this->actor.shape.rot.y);
|
|
|
|
Player_SetupAction(play, this, Player_Action_8084411C, 1);
|
|
func_80832440(play, this);
|
|
|
|
this->floorSfxOffset = this->prevFloorSfxOffset;
|
|
|
|
if ((this->actor.bgCheckFlags & 4) && !(this->stateFlags1 & PLAYER_STATE1_IN_WATER) && (sPrevFloorProperty != 6) &&
|
|
(sPrevFloorProperty != 9) && (sYDistToFloor > 20.0f) && (this->meleeWeaponState == 0) && (ABS(sp5C) < 0x2000) &&
|
|
(this->linearVelocity > 3.0f)) {
|
|
|
|
if ((sPrevFloorProperty == 11) && !(this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD)) {
|
|
|
|
sp40 = func_808396F4(play, this, &D_8085451C, &sp44, &sp58, &sp54);
|
|
sp3C = this->actor.world.pos.y;
|
|
|
|
if (WaterBox_GetSurface1(play, &play->colCtx, sp44.x, sp44.z, &sp3C, &sp50) &&
|
|
((sp3C - sp40) > 50.0f)) {
|
|
func_808389E8(this, &gPlayerAnim_link_normal_run_jump_water_fall, 6.0f, play);
|
|
Player_SetupAction(play, this, Player_Action_80844A44, 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
func_8083A4A8(this, play);
|
|
return;
|
|
}
|
|
|
|
if ((sPrevFloorProperty == 9) || (sYDistToFloor <= this->ageProperties->unk_34) ||
|
|
!func_8083A6AC(this, play)) {
|
|
Player_AnimPlayLoop(play, this, &gPlayerAnim_link_normal_landing_wait);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
this->fallStartHeight = this->actor.world.pos.y;
|
|
}
|
|
}
|
|
|
|
s32 func_8083AD4C(PlayState* play, Player* this) {
|
|
s32 cameraMode;
|
|
|
|
if (this->unk_6AD == 2) {
|
|
if (func_8002DD6C(this)) {
|
|
bool shouldUseBowCamera = LINK_IS_ADULT;
|
|
|
|
if(CVarGetInteger("gBowSlingShotAmmoFix", 0)){
|
|
shouldUseBowCamera = this->heldItemAction != PLAYER_IA_SLINGSHOT;
|
|
}
|
|
|
|
cameraMode = shouldUseBowCamera ? CAM_MODE_BOWARROW : CAM_MODE_SLINGSHOT;
|
|
} else {
|
|
cameraMode = CAM_MODE_BOOMERANG;
|
|
}
|
|
} else {
|
|
cameraMode = CAM_MODE_FIRSTPERSON;
|
|
}
|
|
|
|
return Camera_ChangeMode(Play_GetCamera(play, 0), cameraMode);
|
|
}
|
|
|
|
/**
|
|
* If appropriate, setup action for performing a `csAction`
|
|
*
|
|
* @return true if a `csAction` is started, false if not
|
|
*/
|
|
s32 Player_StartCsAction(PlayState* play, Player* this) {
|
|
// unk_6AD will get set to 3 in `Player_UpdateCommon` if `this->csAction` is non-zero
|
|
// (with a special case for `PLAYER_CSACTION_7`)
|
|
if (this->unk_6AD == 3) {
|
|
Player_SetupAction(play, this, Player_Action_CsAction, 0);
|
|
if (this->doorBgCamIndex != 0) {
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
|
}
|
|
func_80832318(this);
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void func_8083AE40(Player* this, s16 objectId) {
|
|
s32 pad;
|
|
size_t size;
|
|
|
|
if (objectId != OBJECT_INVALID) {
|
|
this->giObjectLoading = true;
|
|
osCreateMesgQueue(&this->giObjectLoadQueue, &this->giObjectLoadMsg, 1);
|
|
|
|
size = gObjectTable[objectId].vromEnd - gObjectTable[objectId].vromStart;
|
|
|
|
LOG_HEX("size", size);
|
|
assert(size <= 1024 * 8);
|
|
|
|
DmaMgr_SendRequest2(&this->giObjectDmaRequest, (uintptr_t)this->giObjectSegment,
|
|
gObjectTable[objectId].vromStart, size, 0, &this->giObjectLoadQueue, OS_MESG_PTR(NULL),
|
|
__FILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
void func_8083AF44(PlayState* play, Player* this, s32 magicSpell) {
|
|
func_80835DE4(play, this, Player_Action_808507F4, 0);
|
|
|
|
this->av1.actionVar1 = magicSpell - 3;
|
|
|
|
//! @bug `MAGIC_CONSUME_WAIT_PREVIEW` is not guaranteed to succeed.
|
|
//! Ideally, the return value of `Magic_RequestChange` should be checked before allowing the process of
|
|
//! using a spell to continue. If the magic state change request fails, `gSaveContext.magicTarget` will
|
|
//! never be set correctly.
|
|
//! When `MAGIC_STATE_CONSUME_SETUP` is set in `Player_Action_808507F4`, magic will eventually be
|
|
//! consumed to a stale target value. If that stale target value is higher than the current
|
|
//! magic value, it will be consumed to zero.
|
|
Magic_RequestChange(play, sMagicSpellCosts[magicSpell], MAGIC_CONSUME_WAIT_PREVIEW);
|
|
|
|
u8 isFastFarores = CVarGetInteger("gFastFarores", 0) && this->itemAction == PLAYER_IA_FARORES_WIND;
|
|
|
|
if (isFastFarores) {
|
|
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, &gPlayerAnim_link_magic_tame, 0.83f * 2);
|
|
return;
|
|
} else {
|
|
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, &gPlayerAnim_link_magic_tame, 0.83f);
|
|
}
|
|
|
|
if (magicSpell == 5) {
|
|
this->subCamId = OnePointCutscene_Init(play, 1100, -101, NULL, MAIN_CAM);
|
|
} else {
|
|
func_80835EA4(play, 10);
|
|
}
|
|
}
|
|
|
|
void func_8083B010(Player* this) {
|
|
this->actor.focus.rot.x = this->actor.focus.rot.z = this->unk_6B6 = this->unk_6B8 = this->unk_6BA = this->unk_6BC =
|
|
this->unk_6BE = this->unk_6C0 = 0;
|
|
|
|
this->actor.focus.rot.y = this->actor.shape.rot.y;
|
|
}
|
|
|
|
static u8 D_80854528[] = {
|
|
GI_LETTER_ZELDA, GI_WEIRD_EGG, GI_CHICKEN, GI_BEAN, GI_POCKET_EGG, GI_POCKET_CUCCO,
|
|
GI_COJIRO, GI_ODD_MUSHROOM, GI_ODD_POTION, GI_SAW, GI_SWORD_BROKEN, GI_PRESCRIPTION,
|
|
GI_FROG, GI_EYEDROPS, GI_CLAIM_CHECK, GI_MASK_SKULL, GI_MASK_SPOOKY, GI_MASK_KEATON,
|
|
GI_MASK_BUNNY, GI_MASK_TRUTH, GI_MASK_GORON, GI_MASK_ZORA, GI_MASK_GERUDO, GI_LETTER_RUTO,
|
|
GI_LETTER_RUTO, GI_LETTER_RUTO, GI_LETTER_RUTO, GI_LETTER_RUTO, GI_LETTER_RUTO,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_80854548[] = {
|
|
&gPlayerAnim_link_normal_give_other,
|
|
&gPlayerAnim_link_bottle_read,
|
|
&gPlayerAnim_link_normal_take_out,
|
|
};
|
|
|
|
s32 Player_ActionChange_13(Player* this, PlayState* play) {
|
|
s32 sp2C;
|
|
s32 sp28;
|
|
GetItemEntry giEntry;
|
|
Actor* targetActor;
|
|
|
|
if ((this->unk_6AD != 0) &&
|
|
(func_808332B8(this) || (this->actor.bgCheckFlags & 1) || (this->stateFlags1 & PLAYER_STATE1_ON_HORSE))) {
|
|
|
|
if (!Player_StartCsAction(play, this)) {
|
|
if (this->unk_6AD == 4) {
|
|
sp2C = Player_ActionToMagicSpell(this, this->itemAction);
|
|
if (sp2C >= 0) {
|
|
if ((sp2C != 3) || (gSaveContext.respawn[RESPAWN_MODE_TOP].data <= 0)) {
|
|
func_8083AF44(play, this, sp2C);
|
|
} else {
|
|
Player_SetupAction(play, this, Player_Action_8085063C, 1);
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE;
|
|
Player_AnimPlayOnce(play, this, func_80833338(this));
|
|
func_80835EA4(play, 4);
|
|
}
|
|
|
|
func_80832224(this);
|
|
return 1;
|
|
}
|
|
|
|
sp2C = this->itemAction - PLAYER_IA_ZELDAS_LETTER;
|
|
if ((sp2C >= 0) ||
|
|
(sp28 = Player_ActionToBottle(this, this->itemAction) - 1,
|
|
((sp28 >= 0) && (sp28 < 6) &&
|
|
((this->itemAction > PLAYER_IA_BOTTLE_POE) ||
|
|
((this->targetActor != NULL) &&
|
|
(((this->itemAction == PLAYER_IA_BOTTLE_POE) && (this->exchangeItemId == EXCH_ITEM_POE)) ||
|
|
(this->exchangeItemId == EXCH_ITEM_BLUE_FIRE))))))) {
|
|
|
|
if ((play->actorCtx.titleCtx.delayTimer == 0) && (play->actorCtx.titleCtx.alpha == 0)) {
|
|
func_80835DE4(play, this, Player_Action_8084F104, 0);
|
|
|
|
if (sp2C >= 0) {
|
|
if (this->getItemEntry.objectId == OBJECT_INVALID) {
|
|
giEntry = ItemTable_Retrieve(D_80854528[sp2C]);
|
|
} else {
|
|
giEntry = this->getItemEntry;
|
|
}
|
|
func_8083AE40(this, giEntry.objectId);
|
|
}
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_TEXT_ON_SCREEN | PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE;
|
|
|
|
if (sp2C >= 0) {
|
|
sp2C = sp2C + 1;
|
|
} else {
|
|
sp2C = sp28 + 0x18;
|
|
}
|
|
|
|
targetActor = this->targetActor;
|
|
|
|
if ((targetActor != NULL) &&
|
|
((this->exchangeItemId == sp2C) || (this->exchangeItemId == EXCH_ITEM_BLUE_FIRE) ||
|
|
((this->exchangeItemId == EXCH_ITEM_POE) &&
|
|
(this->itemAction == PLAYER_IA_BOTTLE_BIG_POE)) ||
|
|
((this->exchangeItemId == EXCH_ITEM_BEAN) &&
|
|
(this->itemAction == PLAYER_IA_BOTTLE_BUG))) &&
|
|
((this->exchangeItemId != EXCH_ITEM_BEAN) || (this->itemAction == PLAYER_IA_MAGIC_BEAN))) {
|
|
if (this->exchangeItemId == EXCH_ITEM_BEAN) {
|
|
Inventory_ChangeAmmo(ITEM_BEAN, -1);
|
|
func_80835DE4(play, this, Player_Action_8084279C, 0);
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
|
this->av2.actionVar2 = 0x50;
|
|
this->av1.actionVar1 = -1;
|
|
}
|
|
targetActor->flags |= ACTOR_FLAG_PLAYER_TALKED_TO;
|
|
this->unk_664 = this->targetActor;
|
|
} else if (sp2C == EXCH_ITEM_LETTER_RUTO) {
|
|
this->av1.actionVar1 = 1;
|
|
this->actor.textId = 0x4005;
|
|
func_80835EA4(play, 1);
|
|
} else {
|
|
this->av1.actionVar1 = 2;
|
|
this->actor.textId = 0xCF;
|
|
func_80835EA4(play, 4);
|
|
}
|
|
|
|
this->actor.flags |= ACTOR_FLAG_PLAYER_TALKED_TO;
|
|
this->exchangeItemId = sp2C;
|
|
|
|
if (this->av1.actionVar1 < 0) {
|
|
Player_AnimChangeOnceMorph(play, this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_check, this->modelAnimType));
|
|
} else {
|
|
Player_AnimPlayOnce(play, this, D_80854548[this->av1.actionVar1]);
|
|
}
|
|
|
|
func_80832224(this);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
sp2C = Player_ActionToBottle(this, this->itemAction);
|
|
if (sp2C >= 0) {
|
|
if (sp2C == 0xC) {
|
|
func_80835DE4(play, this, Player_Action_8084EED8, 0);
|
|
Player_AnimPlayOnceAdjusted(play, this, &gPlayerAnim_link_bottle_bug_out);
|
|
func_80835EA4(play, 3);
|
|
} else if ((sp2C > 0) && (sp2C < 4)) {
|
|
func_80835DE4(play, this, Player_Action_8084EFC0, 0);
|
|
Player_AnimPlayOnceAdjusted(play, this, &gPlayerAnim_link_bottle_fish_out);
|
|
func_80835EA4(play, (sp2C == 1) ? 1 : 5);
|
|
} else {
|
|
func_80835DE4(play, this, Player_Action_8084EAC0, 0);
|
|
Player_AnimChangeOnceMorphAdjusted(play, this, &gPlayerAnim_link_bottle_drink_demo_start);
|
|
func_80835EA4(play, 2);
|
|
}
|
|
} else {
|
|
func_80835DE4(play, this, Player_Action_8084E3C4, 0);
|
|
Player_AnimPlayOnceAdjusted(play, this, &gPlayerAnim_link_normal_okarina_start);
|
|
this->stateFlags2 |= PLAYER_STATE2_OCARINA_PLAYING;
|
|
func_80835EA4(play, (this->unk_6A8 != NULL) ? 0x5B : 0x5A);
|
|
if (this->unk_6A8 != NULL) {
|
|
this->stateFlags2 |= PLAYER_STATE2_PLAY_FOR_ACTOR;
|
|
Camera_SetParam(Play_GetCamera(play, 0), 8, this->unk_6A8);
|
|
}
|
|
}
|
|
} else if (func_8083AD4C(play, this)) {
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_ON_HORSE)) {
|
|
Player_SetupAction(play, this, Player_Action_8084B1D8, 1);
|
|
this->av2.actionVar2 = 13;
|
|
func_8083B010(this);
|
|
}
|
|
this->stateFlags1 |= PLAYER_STATE1_FIRST_PERSON;
|
|
func_80078884(NA_SE_SY_CAMERA_ZOOM_UP);
|
|
Player_ZeroSpeedXZ(this);
|
|
return 1;
|
|
} else {
|
|
this->unk_6AD = 0;
|
|
func_80078884(NA_SE_SY_ERROR);
|
|
return 0;
|
|
}
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE;
|
|
}
|
|
|
|
func_80832224(this);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 Player_ActionChange_4(Player* this, PlayState* play) {
|
|
Actor* sp34 = this->targetActor;
|
|
Actor* sp30 = this->unk_664;
|
|
Actor* sp2C = NULL;
|
|
s32 sp28 = 0;
|
|
s32 sp24;
|
|
|
|
sp24 = (sp30 != NULL) &&
|
|
(CHECK_FLAG_ALL(sp30->flags, ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_NAVI_HAS_INFO) || (sp30->naviEnemyId != 0xFF));
|
|
|
|
if (sp24 || (this->naviTextId != 0)) {
|
|
sp28 = (this->naviTextId < 0) && ((ABS(this->naviTextId) & 0xFF00) != 0x200);
|
|
if (sp28 || !sp24) {
|
|
sp2C = this->naviActor;
|
|
if (sp28) {
|
|
sp30 = NULL;
|
|
sp34 = NULL;
|
|
}
|
|
} else {
|
|
sp2C = sp30;
|
|
}
|
|
}
|
|
|
|
if ((sp34 != NULL) || (sp2C != NULL)) {
|
|
if ((sp30 == NULL) || (sp30 == sp34) || (sp30 == sp2C)) {
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) ||
|
|
((this->heldActor != NULL) && (sp28 || (sp34 == this->heldActor) || (sp2C == this->heldActor) ||
|
|
((sp34 != NULL) && (sp34->flags & ACTOR_FLAG_WILL_TALK))))) {
|
|
if ((this->actor.bgCheckFlags & 1) || (this->stateFlags1 & PLAYER_STATE1_ON_HORSE) ||
|
|
(func_808332B8(this) && !(this->stateFlags2 & PLAYER_STATE2_UNDERWATER))) {
|
|
|
|
if (sp34 != NULL) {
|
|
this->stateFlags2 |= PLAYER_STATE2_SPEAK_OR_CHECK;
|
|
if (CHECK_BTN_ALL(sControlInput->press.button, BTN_A) || (sp34->flags & ACTOR_FLAG_WILL_TALK)) {
|
|
sp2C = NULL;
|
|
} else if (sp2C == NULL) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (sp2C != NULL) {
|
|
if (!sp28) {
|
|
this->stateFlags2 |= PLAYER_STATE2_NAVI_ALERT;
|
|
}
|
|
|
|
if (!CHECK_BTN_ALL(sControlInput->press.button, CVarGetInteger("gNaviOnL", 0) ? BTN_L : BTN_CUP) && !sp28) {
|
|
return 0;
|
|
}
|
|
|
|
sp34 = sp2C;
|
|
this->targetActor = NULL;
|
|
|
|
if (sp28 || !sp24) {
|
|
sp2C->textId = ABS(this->naviTextId);
|
|
} else {
|
|
if (sp2C->naviEnemyId != 0xFF) {
|
|
sp2C->textId = sp2C->naviEnemyId + 0x600;
|
|
}
|
|
}
|
|
}
|
|
|
|
this->currentMask = D_80858AA4;
|
|
Player_StartTalking(play, sp34);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_8083B8F4(Player* this, PlayState* play) {
|
|
if (!(this->stateFlags1 & (PLAYER_STATE1_ITEM_OVER_HEAD | PLAYER_STATE1_ON_HORSE)) &&
|
|
Camera_CheckValidMode(Play_GetCamera(play, 0), 6)) {
|
|
if ((this->actor.bgCheckFlags & 1) ||
|
|
(func_808332B8(this) && (this->actor.yDistToWater < this->ageProperties->unk_2C))) {
|
|
this->unk_6AD = 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 Player_ActionChange_0(Player* this, PlayState* play) {
|
|
if (this->unk_6AD != 0) {
|
|
Player_ActionChange_13(this, play);
|
|
return 1;
|
|
}
|
|
|
|
if ((this->unk_664 != NULL) && (CHECK_FLAG_ALL(this->unk_664->flags, ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_NAVI_HAS_INFO) ||
|
|
(this->unk_664->naviEnemyId != 0xFF))) {
|
|
this->stateFlags2 |= PLAYER_STATE2_NAVI_ALERT;
|
|
} else if ((this->naviTextId == 0 || CVarGetInteger("gNaviOnL", 0)) && !func_8008E9C4(this) && CHECK_BTN_ALL(sControlInput->press.button, BTN_CUP) &&
|
|
(YREG(15) != 0x10) &&
|
|
(YREG(15) != 0x20) && !func_8083B8F4(this, play)) {
|
|
func_80078884(NA_SE_SY_ERROR);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8083BA90(PlayState* play, Player* this, s32 arg2, f32 xzVelocity, f32 yVelocity) {
|
|
func_80837948(play, this, arg2);
|
|
Player_SetupAction(play, this, Player_Action_80844AF4, 0);
|
|
|
|
this->stateFlags3 |= PLAYER_STATE3_MIDAIR;
|
|
|
|
this->yaw = this->actor.shape.rot.y;
|
|
this->linearVelocity = xzVelocity;
|
|
this->actor.velocity.y = yVelocity;
|
|
|
|
this->actor.bgCheckFlags &= ~1;
|
|
this->hoverBootsTimer = 0;
|
|
|
|
func_80832854(this);
|
|
func_80832698(this, NA_SE_VO_LI_SWORD_L);
|
|
}
|
|
|
|
s32 func_8083BB20(Player* this) {
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_SHIELDING) && (Player_GetMeleeWeaponHeld(this) != 0)) {
|
|
if (sUseHeldItem ||
|
|
((this->actor.category != ACTORCAT_PLAYER) && CHECK_BTN_ALL(sControlInput->press.button, BTN_B))) {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_8083BBA0(Player* this, PlayState* play) {
|
|
if (func_8083BB20(this) && (sFloorType != 7)) {
|
|
func_8083BA90(play, this, PLAYER_MWA_JUMPSLASH_START, 3.0f, 4.5f);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8083BC04(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_80844708, 0);
|
|
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime,
|
|
GET_PLAYER_ANIM(PLAYER_ANIMGROUP_landing_roll, this->modelAnimType),
|
|
1.25f * D_808535E8);
|
|
gSaveContext.sohStats.count[COUNT_ROLLS]++;
|
|
}
|
|
|
|
s32 func_8083BC7C(Player* this, PlayState* play) {
|
|
if ((this->unk_84B[this->unk_846] == 0) && (sFloorType != 7)) {
|
|
func_8083BC04(this, play);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8083BCD0(Player* this, PlayState* play, s32 arg2) {
|
|
func_80838940(this, D_80853D4C[arg2][0], !(arg2 & 1) ? 5.8f : 3.5f, play, NA_SE_VO_LI_SWORD_N);
|
|
|
|
if (arg2) {}
|
|
|
|
this->av2.actionVar2 = 1;
|
|
this->av1.actionVar1 = arg2;
|
|
|
|
this->yaw = this->actor.shape.rot.y + (arg2 << 0xE);
|
|
this->linearVelocity = !(arg2 & 1) ? 6.0f : 8.5f;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_HOPPING;
|
|
|
|
Player_PlaySfx(this, ((arg2 << 0xE) == 0x8000) ? NA_SE_PL_ROLL : NA_SE_PL_SKIP);
|
|
}
|
|
|
|
s32 Player_ActionChange_10(Player* this, PlayState* play) {
|
|
s32 sp2C;
|
|
|
|
if (CHECK_BTN_ALL(sControlInput->press.button, BTN_A) &&
|
|
(play->roomCtx.curRoom.behaviorType1 != ROOM_BEHAVIOR_TYPE1_2) && (sFloorType != 7) &&
|
|
(SurfaceType_GetSlope(&play->colCtx, this->actor.floorPoly, this->actor.floorBgId) != 1)) {
|
|
sp2C = this->unk_84B[this->unk_846];
|
|
|
|
if (sp2C <= 0) {
|
|
if (func_80833BCC(this)) {
|
|
if (this->actor.category != ACTORCAT_PLAYER) {
|
|
if (sp2C < 0) {
|
|
func_808389E8(this, &gPlayerAnim_link_normal_jump, REG(69) / 100.0f, play);
|
|
} else {
|
|
func_8083BC04(this, play);
|
|
}
|
|
} else {
|
|
if ((Player_GetMeleeWeaponHeld(this) != 0) && Player_CanUpdateItems(this)) {
|
|
func_8083BA90(play, this, PLAYER_MWA_JUMPSLASH_START, 5.0f, 5.0f);
|
|
} else {
|
|
func_8083BC04(this, play);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
} else {
|
|
func_8083BCD0(this, play, sp2C);
|
|
if (sp2C == 1 || sp2C == 3) {
|
|
gSaveContext.sohStats.count[COUNT_SIDEHOPS]++;
|
|
}
|
|
if (sp2C == 2) {
|
|
gSaveContext.sohStats.count[COUNT_BACKFLIPS]++;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8083BF50(Player* this, PlayState* play) {
|
|
LinkAnimationHeader* anim;
|
|
f32 sp30;
|
|
|
|
sp30 = this->unk_868 - 3.0f;
|
|
if (sp30 < 0.0f) {
|
|
sp30 += 29.0f;
|
|
}
|
|
|
|
if (sp30 < 14.0f) {
|
|
anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_walk_endL, this->modelAnimType);
|
|
sp30 = 11.0f - sp30;
|
|
if (sp30 < 0.0f) {
|
|
sp30 = 1.375f * -sp30;
|
|
}
|
|
sp30 /= 11.0f;
|
|
} else {
|
|
anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_walk_endR, this->modelAnimType);
|
|
sp30 = 26.0f - sp30;
|
|
if (sp30 < 0.0f) {
|
|
sp30 = 2 * -sp30;
|
|
}
|
|
sp30 /= 12.0f;
|
|
}
|
|
|
|
LinkAnimation_Change(play, &this->skelAnime, anim, 1.0f, 0.0f, Animation_GetLastFrame(anim), ANIMMODE_ONCE,
|
|
4.0f * sp30);
|
|
this->yaw = this->actor.shape.rot.y;
|
|
}
|
|
|
|
void func_8083C0B8(Player* this, PlayState* play) {
|
|
func_80839FFC(this, play);
|
|
func_8083BF50(this, play);
|
|
}
|
|
|
|
void func_8083C0E8(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_80840BC8, 1);
|
|
Player_AnimPlayOnce(play, this, func_80833338(this));
|
|
this->yaw = this->actor.shape.rot.y;
|
|
}
|
|
|
|
void func_8083C148(Player* this, PlayState* play) {
|
|
if (!(this->stateFlags3 & PLAYER_STATE3_HOOKSHOT_TRAVELLING)) {
|
|
func_8083B010(this);
|
|
if (this->stateFlags1 & PLAYER_STATE1_IN_WATER) {
|
|
func_80838F18(play, this);
|
|
} else {
|
|
func_80839F90(this, play);
|
|
}
|
|
if (this->unk_6AD < 4) {
|
|
this->unk_6AD = 0;
|
|
}
|
|
}
|
|
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_FIRST_PERSON);
|
|
}
|
|
|
|
s32 Player_ActionChange_6(Player* this, PlayState* play) {
|
|
if (!func_80833B54(this) && (D_808535E0 == 0) && !(this->stateFlags1 & PLAYER_STATE1_ON_HORSE) &&
|
|
CHECK_BTN_ALL(sControlInput->press.button, BTN_A)) {
|
|
if (func_8083BC7C(this, play)) {
|
|
return 1;
|
|
}
|
|
if ((this->unk_837 == 0) && (this->heldItemAction >= PLAYER_IA_SWORD_MASTER)) {
|
|
Player_UseItem(play, this, ITEM_NONE);
|
|
} else {
|
|
this->stateFlags2 ^= PLAYER_STATE2_NAVI_OUT;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 Player_ActionChange_11(Player* this, PlayState* play) {
|
|
LinkAnimationHeader* anim;
|
|
f32 frame;
|
|
|
|
if ((play->shootingGalleryStatus == 0) && (this->currentShield != PLAYER_SHIELD_NONE) &&
|
|
CHECK_BTN_ALL(sControlInput->cur.button, BTN_R) &&
|
|
(Player_IsChildWithHylianShield(this) || (!func_80833B2C(this) && (this->unk_664 == NULL)))) {
|
|
|
|
func_80832318(this);
|
|
Player_DetachHeldActor(play, this);
|
|
|
|
if (Player_SetupAction(play, this, Player_Action_80843188, 0)) {
|
|
this->stateFlags1 |= PLAYER_STATE1_SHIELDING;
|
|
|
|
if (!Player_IsChildWithHylianShield(this)) {
|
|
Player_SetModelsForHoldingShield(this);
|
|
anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_defense, this->modelAnimType);
|
|
} else {
|
|
anim = &gPlayerAnim_clink_normal_defense_ALL;
|
|
}
|
|
|
|
if (anim != this->skelAnime.animation) {
|
|
if (func_8008E9C4(this)) {
|
|
this->unk_86C = 1.0f;
|
|
} else {
|
|
this->unk_86C = 0.0f;
|
|
func_80833C3C(this);
|
|
}
|
|
this->unk_6BC = this->unk_6BE = this->unk_6C0 = 0;
|
|
}
|
|
|
|
frame = Animation_GetLastFrame(anim);
|
|
LinkAnimation_Change(play, &this->skelAnime, anim, 1.0f, frame, frame, ANIMMODE_ONCE, 0.0f);
|
|
|
|
if (Player_IsChildWithHylianShield(this)) {
|
|
Player_AnimReplaceApplyFlags(play, this, 4);
|
|
}
|
|
|
|
Player_PlaySfx(this, NA_SE_IT_SHIELD_POSTURE);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_8083C484(Player* this, f32* arg1, s16* arg2) {
|
|
s16 yaw = this->yaw - *arg2;
|
|
|
|
if (ABS(yaw) > 0x6000) {
|
|
if (func_8083721C(this)) {
|
|
*arg1 = 0.0f;
|
|
*arg2 = this->yaw;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8083C50C(Player* this) {
|
|
if ((this->unk_844 > 0) && !CHECK_BTN_ALL(sControlInput->cur.button, BTN_B)) {
|
|
this->unk_844 = -this->unk_844;
|
|
}
|
|
}
|
|
|
|
s32 Player_ActionChange_8(Player* this, PlayState* play) {
|
|
if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_B)) {
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_SHIELDING) && (Player_GetMeleeWeaponHeld(this) != 0) && (this->unk_844 == 1) &&
|
|
(this->heldItemAction != PLAYER_IA_DEKU_STICK)) {
|
|
if ((this->heldItemAction != PLAYER_IA_SWORD_BIGGORON) || (gSaveContext.swordHealth > 0.0f)) {
|
|
func_808377DC(play, this);
|
|
return 1;
|
|
}
|
|
}
|
|
} else {
|
|
func_8083C50C(this);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_8083C61C(PlayState* play, Player* this) {
|
|
if ((play->roomCtx.curRoom.behaviorType1 != ROOM_BEHAVIOR_TYPE1_2) && (this->actor.bgCheckFlags & 1) &&
|
|
(AMMO(ITEM_NUT) != 0)) {
|
|
Player_SetupAction(play, this, Player_Action_8084E604, 0);
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_normal_light_bom);
|
|
this->unk_6AD = 0;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct_80854554 D_80854554[] = {
|
|
{ &gPlayerAnim_link_bottle_bug_miss, &gPlayerAnim_link_bottle_bug_in, 2, 3 },
|
|
{ &gPlayerAnim_link_bottle_fish_miss, &gPlayerAnim_link_bottle_fish_in, 5, 3 },
|
|
};
|
|
|
|
s32 func_8083C6B8(PlayState* play, Player* this) {
|
|
Vec3f sp24;
|
|
|
|
if (sUseHeldItem) {
|
|
if (Player_GetBottleHeld(this) >= 0) {
|
|
Player_SetupAction(play, this, Player_Action_8084ECA4, 0);
|
|
|
|
if (this->actor.yDistToWater > 12.0f) {
|
|
this->av2.actionVar2 = 1;
|
|
}
|
|
|
|
Player_AnimPlayOnceAdjusted(play, this, D_80854554[this->av2.actionVar2].unk_00);
|
|
|
|
Player_PlaySfx(this, NA_SE_IT_SWORD_SWING);
|
|
func_80832698(this, NA_SE_VO_LI_AUTO_JUMP);
|
|
return 1;
|
|
}
|
|
|
|
if (this->heldItemAction == PLAYER_IA_FISHING_POLE) {
|
|
sp24 = this->actor.world.pos;
|
|
sp24.y += 50.0f;
|
|
|
|
if (CVarGetInteger("gHoverFishing", 0)
|
|
? 0
|
|
: !(this->actor.bgCheckFlags & 1) || (this->actor.world.pos.z > 1300.0f) ||
|
|
BgCheck_SphVsFirstPoly(&play->colCtx, &sp24, 20.0f)) {
|
|
func_80078884(NA_SE_SY_ERROR);
|
|
return 0;
|
|
}
|
|
|
|
Player_SetupAction(play, this, Player_Action_80850C68, 0);
|
|
this->unk_860 = 1;
|
|
Player_ZeroSpeedXZ(this);
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_fishing_throw);
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8083C858(Player* this, PlayState* play) {
|
|
PlayerActionFunc actionFunc;
|
|
|
|
if (func_80833BCC(this)) {
|
|
actionFunc = Player_Action_8084227C;
|
|
} else {
|
|
actionFunc = Player_Action_80842180;
|
|
}
|
|
|
|
Player_SetupAction(play, this, actionFunc, 1);
|
|
Player_AnimChangeLoopMorph(play, this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_run, this->modelAnimType));
|
|
|
|
this->unk_89C = 0;
|
|
this->unk_864 = this->unk_868 = 0.0f;
|
|
}
|
|
|
|
void func_8083C8DC(Player* this, PlayState* play, s16 arg2) {
|
|
this->actor.shape.rot.y = this->yaw = arg2;
|
|
func_8083C858(this, play);
|
|
}
|
|
|
|
s32 func_8083C910(PlayState* play, Player* this, f32 arg2) {
|
|
WaterBox* sp2C;
|
|
f32 sp28;
|
|
|
|
sp28 = this->actor.world.pos.y;
|
|
if (WaterBox_GetSurface1(play, &play->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, &sp28,
|
|
&sp2C) != 0) {
|
|
sp28 -= this->actor.world.pos.y;
|
|
if (this->ageProperties->unk_24 <= sp28) {
|
|
Player_SetupAction(play, this, Player_Action_8084D7C4, 0);
|
|
Player_AnimChangeLoopSlowMorph(play, this, &gPlayerAnim_link_swimer_swim);
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_WATER | PLAYER_STATE1_IN_CUTSCENE;
|
|
this->av2.actionVar2 = 20;
|
|
this->linearVelocity = 2.0f;
|
|
Player_SetBootData(play, this);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
func_80838E70(play, this, arg2, this->actor.shape.rot.y);
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
|
return 1;
|
|
}
|
|
|
|
void func_8083CA20(PlayState* play, Player* this) {
|
|
if (func_8083C910(play, this, 180.0f)) {
|
|
this->av2.actionVar2 = -20;
|
|
}
|
|
}
|
|
|
|
void func_8083CA54(PlayState* play, Player* this) {
|
|
this->linearVelocity = 2.0f;
|
|
gSaveContext.entranceSpeed = 2.0f;
|
|
if (func_8083C910(play, this, 120.0f)) {
|
|
this->av2.actionVar2 = -15;
|
|
}
|
|
}
|
|
|
|
void func_8083CA9C(PlayState* play, Player* this) {
|
|
if (gSaveContext.entranceSpeed < 0.1f) {
|
|
gSaveContext.entranceSpeed = 0.1f;
|
|
}
|
|
|
|
this->linearVelocity = gSaveContext.entranceSpeed;
|
|
|
|
if (func_8083C910(play, this, 800.0f)) {
|
|
this->av2.actionVar2 = -80 / this->linearVelocity;
|
|
if (this->av2.actionVar2 < -20) {
|
|
this->av2.actionVar2 = -20;
|
|
}
|
|
}
|
|
}
|
|
|
|
void func_8083CB2C(Player* this, s16 yaw, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_808414F8, 1);
|
|
LinkAnimation_CopyJointToMorph(play, &this->skelAnime);
|
|
this->unk_864 = this->unk_868 = 0.0f;
|
|
this->yaw = yaw;
|
|
}
|
|
|
|
void func_8083CB94(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_80840DE4, 1);
|
|
Player_AnimChangeLoopMorph(play, this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_walk, this->modelAnimType));
|
|
}
|
|
|
|
void func_8083CBF0(Player* this, s16 yaw, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_808423EC, 1);
|
|
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_anchor_back_walk, 2.2f, 0.0f,
|
|
Animation_GetLastFrame(&gPlayerAnim_link_anchor_back_walk), ANIMMODE_ONCE, -6.0f);
|
|
this->linearVelocity = 8.0f;
|
|
this->yaw = yaw;
|
|
}
|
|
|
|
void func_8083CC9C(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_8084193C, 1);
|
|
Player_AnimChangeLoopMorph(play, this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_side_walkR, this->modelAnimType));
|
|
this->unk_868 = 0.0f;
|
|
}
|
|
|
|
void func_8083CD00(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_8084251C, 1);
|
|
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, &gPlayerAnim_link_anchor_back_brake, 2.0f);
|
|
}
|
|
|
|
void func_8083CD54(PlayState* play, Player* this, s16 yaw) {
|
|
this->yaw = yaw;
|
|
Player_SetupAction(play, this, Player_Action_80841BA8, 1);
|
|
this->unk_87E = 1200;
|
|
this->unk_87E *= D_808535E8;
|
|
LinkAnimation_Change(play, &this->skelAnime, D_80853914[PLAYER_ANIMGROUP_45_turn][this->modelAnimType], 1.0f, 0.0f,
|
|
0.0f, ANIMMODE_LOOP, -6.0f);
|
|
}
|
|
|
|
void func_8083CE0C(Player* this, PlayState* play) {
|
|
LinkAnimationHeader* anim;
|
|
|
|
Player_SetupAction(play, this, Player_Action_80840BC8, 1);
|
|
|
|
if (this->unk_870 < 0.5f) {
|
|
anim = D_80853914[PLAYER_ANIMGROUP_waitR2wait][this->modelAnimType];
|
|
} else {
|
|
anim = D_80853914[PLAYER_ANIMGROUP_waitL2wait][this->modelAnimType];
|
|
}
|
|
Player_AnimPlayOnce(play, this, anim);
|
|
|
|
this->yaw = this->actor.shape.rot.y;
|
|
}
|
|
|
|
void func_8083CEAC(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_80840450, 1);
|
|
Player_AnimChangeOnceMorph(play, this, D_80853914[PLAYER_ANIMGROUP_wait2waitR][this->modelAnimType]);
|
|
this->av2.actionVar2 = 1;
|
|
}
|
|
|
|
void func_8083CF10(Player* this, PlayState* play) {
|
|
if (this->linearVelocity != 0.0f) {
|
|
func_8083C858(this, play);
|
|
} else {
|
|
func_8083CE0C(this, play);
|
|
}
|
|
}
|
|
|
|
void func_8083CF5C(Player* this, PlayState* play) {
|
|
if (this->linearVelocity != 0.0f) {
|
|
func_8083C858(this, play);
|
|
} else {
|
|
func_80839F90(this, play);
|
|
}
|
|
}
|
|
|
|
s32 func_8083CFA8(PlayState* play, Player* this, f32 arg2, s32 splashScale) {
|
|
f32 sp3C = fabsf(arg2);
|
|
WaterBox* sp38;
|
|
f32 sp34;
|
|
Vec3f splashPos;
|
|
s32 splashType;
|
|
|
|
if (sp3C > 2.0f) {
|
|
splashPos.x = this->bodyPartsPos[PLAYER_BODYPART_WAIST].x;
|
|
splashPos.z = this->bodyPartsPos[PLAYER_BODYPART_WAIST].z;
|
|
sp34 = this->actor.world.pos.y;
|
|
if (WaterBox_GetSurface1(play, &play->colCtx, splashPos.x, splashPos.z, &sp34, &sp38)) {
|
|
if ((sp34 - this->actor.world.pos.y) < 100.0f) {
|
|
splashType = (sp3C <= 10.0f) ? 0 : 1;
|
|
splashPos.y = sp34;
|
|
EffectSsGSplash_Spawn(play, &splashPos, NULL, NULL, splashType, splashScale);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8083D0A8(PlayState* play, Player* this, f32 arg2) {
|
|
this->stateFlags1 |= PLAYER_STATE1_JUMPING;
|
|
this->stateFlags1 &= ~PLAYER_STATE1_IN_WATER;
|
|
|
|
func_80832340(play, this);
|
|
if (func_8083CFA8(play, this, arg2, 500)) {
|
|
Player_PlaySfx(this, NA_SE_EV_JUMP_OUT_WATER);
|
|
}
|
|
|
|
Player_SetBootData(play, this);
|
|
}
|
|
|
|
s32 func_8083D12C(PlayState* play, Player* this, Input* arg2) {
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_GETTING_ITEM) && !(this->stateFlags2 & PLAYER_STATE2_UNDERWATER)) {
|
|
if ((arg2 == NULL) || (CHECK_BTN_ALL(arg2->press.button, BTN_A) && (ABS(this->unk_6C2) < 12000) &&
|
|
(this->currentBoots != PLAYER_BOOTS_IRON))) {
|
|
|
|
Player_SetupAction(play, this, Player_Action_8084DC48, 0);
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_swimer_swim_deep_start);
|
|
|
|
this->unk_6C2 = 0;
|
|
this->stateFlags2 |= PLAYER_STATE2_UNDERWATER;
|
|
this->actor.velocity.y = 0.0f;
|
|
|
|
if (arg2 != NULL) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DIVING;
|
|
Player_PlaySfx(this, NA_SE_PL_DIVE_BUBBLE);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if ((this->stateFlags1 & PLAYER_STATE1_GETTING_ITEM) || (this->stateFlags2 & PLAYER_STATE2_UNDERWATER)) {
|
|
if (this->actor.velocity.y > 0.0f) {
|
|
if (this->actor.yDistToWater < this->ageProperties->unk_30) {
|
|
|
|
this->stateFlags2 &= ~PLAYER_STATE2_UNDERWATER;
|
|
|
|
if (arg2 != NULL) {
|
|
Player_SetupAction(play, this, Player_Action_8084E1EC, 1);
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_GETTING_ITEM) {
|
|
this->stateFlags1 |= PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD | PLAYER_STATE1_IN_CUTSCENE;
|
|
}
|
|
|
|
this->av2.actionVar2 = 2;
|
|
}
|
|
|
|
func_80832340(play, this);
|
|
// Skip take breath animation on surface if Link didn't grab an item while underwater and the setting is enabled
|
|
if (CVarGetInteger("gSkipSwimDeepEndAnim", 0) && !(this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD)) {
|
|
auto lastAnimFrame = Animation_GetLastFrame(&gPlayerAnim_link_swimer_swim_deep_end);
|
|
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_swimer_swim_deep_end, 1.0f,
|
|
lastAnimFrame, lastAnimFrame, ANIMMODE_ONCE, -6.0f);
|
|
} else {
|
|
Player_AnimChangeOnceMorph(play, this,
|
|
(this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) ? &gPlayerAnim_link_swimer_swim_get
|
|
: &gPlayerAnim_link_swimer_swim_deep_end);
|
|
}
|
|
|
|
if (func_8083CFA8(play, this, this->actor.velocity.y, 500)) {
|
|
Player_PlaySfx(this, NA_SE_PL_FACE_UP);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8083D330(PlayState* play, Player* this) {
|
|
Player_AnimPlayLoop(play, this, &gPlayerAnim_link_swimer_swim);
|
|
this->unk_6C2 = 16000;
|
|
this->av2.actionVar2 = 1;
|
|
}
|
|
|
|
void func_8083D36C(PlayState* play, Player* this) {
|
|
if ((this->currentBoots != PLAYER_BOOTS_IRON) || !(this->actor.bgCheckFlags & 1)) {
|
|
func_80832564(play, this);
|
|
|
|
if ((this->currentBoots != PLAYER_BOOTS_IRON) && (this->stateFlags2 & PLAYER_STATE2_UNDERWATER)) {
|
|
this->stateFlags2 &= ~PLAYER_STATE2_UNDERWATER;
|
|
func_8083D12C(play, this, 0);
|
|
this->av1.actionVar1 = 1;
|
|
} else if (Player_Action_80844A44 == this->actionFunc) {
|
|
Player_SetupAction(play, this, Player_Action_8084DC48, 0);
|
|
func_8083D330(play, this);
|
|
} else {
|
|
Player_SetupAction(play, this, Player_Action_8084D610, 1);
|
|
Player_AnimChangeOnceMorph(play, this,
|
|
(this->actor.bgCheckFlags & 1) ? &gPlayerAnim_link_swimer_wait2swim_wait
|
|
: &gPlayerAnim_link_swimer_land2swim_wait);
|
|
}
|
|
}
|
|
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_IN_WATER) || (this->actor.yDistToWater < this->ageProperties->unk_2C)) {
|
|
if (func_8083CFA8(play, this, this->actor.velocity.y, 500)) {
|
|
Player_PlaySfx(this, NA_SE_EV_DIVE_INTO_WATER);
|
|
|
|
if (this->fallDistance > 800.0f) {
|
|
func_80832698(this, NA_SE_VO_LI_CLIMB_END);
|
|
}
|
|
}
|
|
}
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_WATER;
|
|
this->stateFlags2 |= PLAYER_STATE2_UNDERWATER;
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_JUMPING | PLAYER_STATE1_FREEFALL);
|
|
this->unk_854 = 0.0f;
|
|
|
|
Player_SetBootData(play, this);
|
|
}
|
|
|
|
void func_8083D53C(PlayState* play, Player* this) {
|
|
if (this->actor.yDistToWater < this->ageProperties->unk_2C) {
|
|
Audio_SetBaseFilter(0);
|
|
this->underwaterTimer = 0;
|
|
} else {
|
|
Audio_SetBaseFilter(0x20);
|
|
if (this->underwaterTimer < 300) {
|
|
this->underwaterTimer++;
|
|
}
|
|
}
|
|
|
|
if ((Player_Action_80845668 != this->actionFunc) && (Player_Action_8084BDFC != this->actionFunc)) {
|
|
if (this->ageProperties->unk_2C < this->actor.yDistToWater) {
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_IN_WATER) ||
|
|
(!((this->currentBoots == PLAYER_BOOTS_IRON) && (this->actor.bgCheckFlags & 1)) &&
|
|
(Player_Action_8084E30C != this->actionFunc) && (Player_Action_8084E368 != this->actionFunc) &&
|
|
(Player_Action_8084D610 != this->actionFunc) && (Player_Action_8084D84C != this->actionFunc) &&
|
|
(Player_Action_8084DAB4 != this->actionFunc) && (Player_Action_8084DC48 != this->actionFunc) &&
|
|
(Player_Action_8084E1EC != this->actionFunc) && (Player_Action_8084D7C4 != this->actionFunc))) {
|
|
func_8083D36C(play, this);
|
|
return;
|
|
}
|
|
} else if ((this->stateFlags1 & PLAYER_STATE1_IN_WATER) && (this->actor.yDistToWater < this->ageProperties->unk_24)) {
|
|
if ((this->skelAnime.moveFlags == 0) && (this->currentBoots != PLAYER_BOOTS_IRON)) {
|
|
func_8083CD54(play, this, this->actor.shape.rot.y);
|
|
}
|
|
func_8083D0A8(play, this, this->actor.velocity.y);
|
|
}
|
|
}
|
|
}
|
|
|
|
void func_8083D6EC(PlayState* play, Player* this) {
|
|
Vec3f ripplePos;
|
|
f32 temp1;
|
|
f32 temp2;
|
|
f32 temp3;
|
|
f32 temp4;
|
|
|
|
this->actor.minVelocityY = -20.0f;
|
|
this->actor.gravity = REG(68) / 100.0f;
|
|
|
|
if (func_8083816C(sFloorType)) {
|
|
temp1 = fabsf(this->linearVelocity) * 20.0f;
|
|
temp3 = 0.0f;
|
|
|
|
if (sFloorType == 4) {
|
|
if (this->unk_6C4 > 1300.0f) {
|
|
temp2 = this->unk_6C4;
|
|
} else {
|
|
temp2 = 1300.0f;
|
|
}
|
|
if (this->currentBoots == PLAYER_BOOTS_HOVER) {
|
|
temp1 += temp1;
|
|
} else if (this->currentBoots == PLAYER_BOOTS_IRON) {
|
|
temp1 *= 0.3f;
|
|
}
|
|
} else {
|
|
temp2 = 20000.0f;
|
|
if (this->currentBoots != PLAYER_BOOTS_HOVER) {
|
|
temp1 += temp1;
|
|
} else if ((sFloorType == 7) || (this->currentBoots == PLAYER_BOOTS_IRON)) {
|
|
temp1 = 0;
|
|
}
|
|
}
|
|
|
|
if (this->currentBoots != PLAYER_BOOTS_HOVER) {
|
|
temp3 = (temp2 - this->unk_6C4) * 0.02f;
|
|
temp3 = CLAMP(temp3, 0.0f, 300.0f);
|
|
if (this->currentBoots == PLAYER_BOOTS_IRON) {
|
|
temp3 += temp3;
|
|
}
|
|
}
|
|
|
|
this->unk_6C4 += temp3 - temp1;
|
|
this->unk_6C4 = CLAMP(this->unk_6C4, 0.0f, temp2);
|
|
|
|
this->actor.gravity -= this->unk_6C4 * 0.004f;
|
|
} else {
|
|
this->unk_6C4 = 0.0f;
|
|
}
|
|
|
|
if (this->actor.bgCheckFlags & 0x20) {
|
|
if (this->actor.yDistToWater < 50.0f) {
|
|
temp4 = fabsf(this->bodyPartsPos[PLAYER_BODYPART_WAIST].x - this->unk_A88.x) +
|
|
fabsf(this->bodyPartsPos[PLAYER_BODYPART_WAIST].y - this->unk_A88.y) +
|
|
fabsf(this->bodyPartsPos[PLAYER_BODYPART_WAIST].z - this->unk_A88.z);
|
|
if (temp4 > 4.0f) {
|
|
temp4 = 4.0f;
|
|
}
|
|
this->unk_854 += temp4;
|
|
|
|
if (this->unk_854 > 15.0f) {
|
|
this->unk_854 = 0.0f;
|
|
|
|
ripplePos.x = (Rand_ZeroOne() * 10.0f) + this->actor.world.pos.x;
|
|
ripplePos.y = this->actor.world.pos.y + this->actor.yDistToWater;
|
|
ripplePos.z = (Rand_ZeroOne() * 10.0f) + this->actor.world.pos.z;
|
|
EffectSsGRipple_Spawn(play, &ripplePos, 100, 500, 0);
|
|
|
|
if ((this->linearVelocity > 4.0f) && !func_808332B8(this) &&
|
|
((this->actor.world.pos.y + this->actor.yDistToWater) <
|
|
this->bodyPartsPos[PLAYER_BODYPART_WAIST].y)) {
|
|
func_8083CFA8(play, this, 20.0f,
|
|
(fabsf(this->linearVelocity) * 50.0f) + (this->actor.yDistToWater * 5.0f));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this->actor.yDistToWater > 40.0f) {
|
|
s32 numBubbles = 0;
|
|
s32 i;
|
|
|
|
if ((this->actor.velocity.y > -1.0f) || (this->actor.bgCheckFlags & 1)) {
|
|
if (Rand_ZeroOne() < 0.2f) {
|
|
numBubbles = 1;
|
|
}
|
|
} else {
|
|
numBubbles = this->actor.velocity.y * -2.0f;
|
|
}
|
|
|
|
for (i = 0; i < numBubbles; i++) {
|
|
EffectSsBubble_Spawn(play, &this->actor.world.pos, 20.0f, 10.0f, 20.0f, 0.13f);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
s32 func_8083DB98(Player* this, s32 arg1) {
|
|
Actor* unk_664 = this->unk_664;
|
|
Vec3f sp30;
|
|
s16 sp2E;
|
|
s16 sp2C;
|
|
|
|
sp30.x = this->actor.world.pos.x;
|
|
sp30.y = this->bodyPartsPos[PLAYER_BODYPART_HEAD].y + 3.0f;
|
|
sp30.z = this->actor.world.pos.z;
|
|
sp2E = Math_Vec3f_Pitch(&sp30, &unk_664->focus.pos);
|
|
sp2C = Math_Vec3f_Yaw(&sp30, &unk_664->focus.pos);
|
|
Math_SmoothStepToS(&this->actor.focus.rot.y, sp2C, 4, 10000, 0);
|
|
Math_SmoothStepToS(&this->actor.focus.rot.x, sp2E, 4, 10000, 0);
|
|
this->unk_6AE |= 2;
|
|
|
|
return func_80836AB8(this, arg1);
|
|
}
|
|
|
|
static Vec3f D_8085456C = { 0.0f, 100.0f, 40.0f };
|
|
|
|
void func_8083DC54(Player* this, PlayState* play) {
|
|
s16 sp46;
|
|
s16 temp2;
|
|
f32 temp1;
|
|
Vec3f sp34;
|
|
|
|
if (this->unk_664 != NULL) {
|
|
if (func_8002DD78(this) || func_808334B4(this)) {
|
|
func_8083DB98(this, 1);
|
|
} else {
|
|
func_8083DB98(this, 0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (sFloorType == 11) {
|
|
Math_SmoothStepToS(&this->actor.focus.rot.x, -20000, 10, 4000, 800);
|
|
} else {
|
|
sp46 = 0;
|
|
temp1 = func_8083973C(play, this, &D_8085456C, &sp34);
|
|
if (temp1 > BGCHECK_Y_MIN) {
|
|
temp2 = Math_Atan2S(40.0f, this->actor.world.pos.y - temp1);
|
|
sp46 = CLAMP(temp2, -4000, 4000);
|
|
}
|
|
this->actor.focus.rot.y = this->actor.shape.rot.y;
|
|
Math_SmoothStepToS(&this->actor.focus.rot.x, sp46, 14, 4000, 30);
|
|
}
|
|
|
|
func_80836AB8(this, func_8002DD78(this) || func_808334B4(this));
|
|
}
|
|
|
|
void func_8083DDC8(Player* this, PlayState* play) {
|
|
s16 temp1;
|
|
s16 temp2;
|
|
|
|
if (!func_8002DD78(this) && !func_808334B4(this) && (this->linearVelocity > 5.0f)) {
|
|
temp1 = this->linearVelocity * 200.0f;
|
|
temp2 = (s16)(this->yaw - this->actor.shape.rot.y) * this->linearVelocity * 0.1f;
|
|
temp1 = CLAMP(temp1, -4000, 4000);
|
|
temp2 = CLAMP(-temp2, -4000, 4000);
|
|
Math_ScaledStepToS(&this->unk_6BC, temp1, 900);
|
|
this->unk_6B6 = -(f32)this->unk_6BC * 0.5f;
|
|
Math_ScaledStepToS(&this->unk_6BA, temp2, 300);
|
|
Math_ScaledStepToS(&this->unk_6C0, temp2, 200);
|
|
this->unk_6AE |= 0x168;
|
|
} else {
|
|
func_8083DC54(this, play);
|
|
}
|
|
}
|
|
|
|
void func_8083DF68(Player* this, f32 arg1, s16 arg2) {
|
|
Math_AsymStepToF(&this->linearVelocity, arg1, REG(19) / 100.0f, 1.5f);
|
|
Math_ScaledStepToS(&this->yaw, arg2, REG(27));
|
|
}
|
|
|
|
void func_8083DFE0(Player* this, f32* arg1, s16* arg2) {
|
|
s16 yawDiff = this->yaw - *arg2;
|
|
|
|
if (this->meleeWeaponState == 0) {
|
|
float maxSpeed = R_RUN_SPEED_LIMIT / 100.0f;
|
|
|
|
int32_t giSpeedModifier = GameInteractor_RunSpeedModifier();
|
|
if (giSpeedModifier != 0) {
|
|
if (giSpeedModifier > 0) {
|
|
maxSpeed *= giSpeedModifier;
|
|
} else {
|
|
maxSpeed /= abs(giSpeedModifier);
|
|
}
|
|
}
|
|
|
|
if (CVarGetInteger("gMMBunnyHood", BUNNY_HOOD_VANILLA) == BUNNY_HOOD_FAST_AND_JUMP && this->currentMask == PLAYER_MASK_BUNNY) {
|
|
maxSpeed *= 1.5f;
|
|
}
|
|
|
|
if (CVarGetInteger("gEnableWalkModify", 0) && !CVarGetInteger("gWalkModifierDoesntChangeJump", 0)) {
|
|
if (CVarGetInteger("gWalkSpeedToggle", 0)) {
|
|
if (gWalkSpeedToggle1) {
|
|
maxSpeed *= CVarGetFloat("gWalkModifierOne", 1.0f);
|
|
} else if (gWalkSpeedToggle2) {
|
|
maxSpeed *= CVarGetFloat("gWalkModifierTwo", 1.0f);
|
|
}
|
|
} else {
|
|
if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_MODIFIER1)) {
|
|
maxSpeed *= CVarGetFloat("gWalkModifierOne", 1.0f);
|
|
} else if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_MODIFIER2)) {
|
|
maxSpeed *= CVarGetFloat("gWalkModifierTwo", 1.0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
this->linearVelocity = CLAMP(this->linearVelocity, -maxSpeed, maxSpeed);
|
|
}
|
|
|
|
if (ABS(yawDiff) > 0x6000) {
|
|
if (Math_StepToF(&this->linearVelocity, 0.0f, 1.0f)) {
|
|
this->yaw = *arg2;
|
|
}
|
|
} else {
|
|
Math_AsymStepToF(&this->linearVelocity, *arg1, 0.05f, 0.1f);
|
|
Math_ScaledStepToS(&this->yaw, *arg2, 200);
|
|
}
|
|
}
|
|
|
|
static struct_80854578 D_80854578[] = {
|
|
{ &gPlayerAnim_link_uma_left_up, 35.17f, 6.6099997f },
|
|
{ &gPlayerAnim_link_uma_right_up, -34.16f, 7.91f },
|
|
};
|
|
|
|
s32 Player_ActionChange_3(Player* this, PlayState* play) {
|
|
EnHorse* rideActor = (EnHorse*)this->rideActor;
|
|
f32 unk_04;
|
|
f32 unk_08;
|
|
f32 sp38;
|
|
f32 sp34;
|
|
s32 temp;
|
|
|
|
if ((rideActor != NULL) && CHECK_BTN_ALL(sControlInput->press.button, BTN_A)) {
|
|
sp38 = Math_CosS(rideActor->actor.shape.rot.y);
|
|
sp34 = Math_SinS(rideActor->actor.shape.rot.y);
|
|
|
|
func_80836898(play, this, func_8083A360);
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_ON_HORSE;
|
|
this->actor.bgCheckFlags &= ~0x20;
|
|
|
|
if (this->mountSide < 0) {
|
|
temp = 0;
|
|
} else {
|
|
temp = 1;
|
|
}
|
|
|
|
unk_04 = D_80854578[temp].unk_04;
|
|
unk_08 = D_80854578[temp].unk_08;
|
|
this->actor.world.pos.x =
|
|
rideActor->actor.world.pos.x + rideActor->riderPos.x + ((unk_04 * sp38) + (unk_08 * sp34));
|
|
this->actor.world.pos.z =
|
|
rideActor->actor.world.pos.z + rideActor->riderPos.z + ((unk_08 * sp38) - (unk_04 * sp34));
|
|
|
|
this->unk_878 = rideActor->actor.world.pos.y - this->actor.world.pos.y;
|
|
this->yaw = this->actor.shape.rot.y = rideActor->actor.shape.rot.y;
|
|
|
|
Actor_MountHorse(play, this, &rideActor->actor);
|
|
Player_AnimPlayOnce(play, this, D_80854578[temp].anim);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x9B);
|
|
this->actor.parent = this->rideActor;
|
|
func_80832224(this);
|
|
Actor_DisableLens(play);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Player_GetSlopeDirection(CollisionPoly* floorPoly, Vec3f* slopeNormal, s16* downwardSlopeYaw) {
|
|
slopeNormal->x = COLPOLY_GET_NORMAL(floorPoly->normal.x);
|
|
slopeNormal->y = COLPOLY_GET_NORMAL(floorPoly->normal.y);
|
|
slopeNormal->z = COLPOLY_GET_NORMAL(floorPoly->normal.z);
|
|
|
|
*downwardSlopeYaw = Math_Atan2S(slopeNormal->z, slopeNormal->x);
|
|
}
|
|
|
|
s32 Player_HandleSlopes(PlayState* play, Player* this, CollisionPoly* floorPoly) {
|
|
static LinkAnimationHeader* sSlopeSlipAnims[] = {
|
|
&gPlayerAnim_link_normal_down_slope_slip,
|
|
&gPlayerAnim_link_normal_up_slope_slip,
|
|
};
|
|
s32 pad;
|
|
s16 playerVelYaw;
|
|
Vec3f slopeNormal;
|
|
s16 downwardSlopeYaw;
|
|
f32 slopeSlowdownSpeed;
|
|
f32 slopeSlowdownSpeedStep;
|
|
s16 velYawToDownwardSlope;
|
|
|
|
if (!Player_InBlockingCsMode(play, this) && (Player_Action_8084F390 != this->actionFunc) &&
|
|
(SurfaceType_GetSlope(&play->colCtx, floorPoly, this->actor.floorBgId) == 1)) {
|
|
playerVelYaw = Math_Atan2S(this->actor.velocity.z, this->actor.velocity.x);
|
|
Player_GetSlopeDirection(floorPoly, &slopeNormal, &downwardSlopeYaw);
|
|
velYawToDownwardSlope = downwardSlopeYaw - playerVelYaw;
|
|
|
|
if (ABS(velYawToDownwardSlope) > 0x3E80) { // 87.9 degrees
|
|
// moving parallel or upwards on the slope, player does not slip but does slow down
|
|
slopeSlowdownSpeed = (1.0f - slopeNormal.y) * 40.0f;
|
|
slopeSlowdownSpeedStep = (slopeSlowdownSpeed * slopeSlowdownSpeed) * 0.015f;
|
|
|
|
if (slopeSlowdownSpeedStep < 1.2f) {
|
|
slopeSlowdownSpeedStep = 1.2f;
|
|
}
|
|
|
|
// slows down speed as player is climbing a slope
|
|
this->pushedYaw = downwardSlopeYaw;
|
|
Math_StepToF(&this->pushedSpeed, slopeSlowdownSpeed, slopeSlowdownSpeedStep);
|
|
} else {
|
|
// moving downward on the slope, causing player to slip
|
|
Player_SetupAction(play, this, Player_Action_8084F390, 0);
|
|
func_80832564(play, this);
|
|
if (sFloorShapePitch >= 0) {
|
|
this->av1.actionVar1 = 1;
|
|
}
|
|
Player_AnimChangeLoopMorph(play, this, sSlopeSlipAnims[this->av1.actionVar1]);
|
|
this->linearVelocity = sqrtf(SQ(this->actor.velocity.x) + SQ(this->actor.velocity.z));
|
|
this->yaw = playerVelYaw;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// unknown data (unused)
|
|
static s32 D_80854598[] = {
|
|
0xFFDB0871, 0xF8310000, 0x00940470, 0xF3980000, 0xFFB504A9, 0x0C9F0000, 0x08010402,
|
|
};
|
|
|
|
void func_8083E4C4(PlayState* play, Player* this, GetItemEntry* giEntry) {
|
|
s32 sp1C = giEntry->field & 0x1F;
|
|
|
|
if (!(giEntry->field & 0x80)) {
|
|
Item_DropCollectible(play, &this->actor.world.pos, sp1C | 0x8000);
|
|
if ((sp1C != 4) && (sp1C != 8) && (sp1C != 9) && (sp1C != 0xA) && (sp1C != 0) && (sp1C != 1) && (sp1C != 2) &&
|
|
(sp1C != 0x14) && (sp1C != 0x13)) {
|
|
Item_Give(play, giEntry->itemId);
|
|
}
|
|
} else {
|
|
Item_Give(play, giEntry->itemId);
|
|
}
|
|
func_80078884((this->getItemId < 0 || this->getItemEntry.getItemId < 0) ? NA_SE_SY_GET_BOXITEM : NA_SE_SY_GET_ITEM);
|
|
}
|
|
|
|
// Sets a flag according to which type of flag is specified in player->pendingFlag.flagType
|
|
// and which flag is specified in player->pendingFlag.flagID.
|
|
void Player_SetPendingFlag(Player* this, PlayState* play) {
|
|
switch (this->pendingFlag.flagType) {
|
|
case FLAG_SCENE_SWITCH:
|
|
Flags_SetSwitch(play, this->pendingFlag.flagID);
|
|
break;
|
|
case FLAG_SCENE_TREASURE:
|
|
Flags_SetTreasure(play, this->pendingFlag.flagID);
|
|
break;
|
|
case FLAG_SCENE_CLEAR:
|
|
Flags_SetClear(play, this->pendingFlag.flagID);
|
|
break;
|
|
case FLAG_SCENE_COLLECTIBLE:
|
|
Flags_SetCollectible(play, this->pendingFlag.flagID);
|
|
break;
|
|
case FLAG_EVENT_CHECK_INF:
|
|
Flags_SetEventChkInf(this->pendingFlag.flagID);
|
|
break;
|
|
case FLAG_ITEM_GET_INF:
|
|
Flags_SetItemGetInf(this->pendingFlag.flagID);
|
|
break;
|
|
case FLAG_INF_TABLE:
|
|
Flags_SetInfTable(this->pendingFlag.flagID);
|
|
break;
|
|
case FLAG_EVENT_INF:
|
|
Flags_SetEventInf(this->pendingFlag.flagID);
|
|
break;
|
|
case FLAG_RANDOMIZER_INF:
|
|
Flags_SetRandomizerInf(this->pendingFlag.flagID);
|
|
break;
|
|
case FLAG_NONE:
|
|
default:
|
|
break;
|
|
}
|
|
this->pendingFlag.flagType = FLAG_NONE;
|
|
this->pendingFlag.flagID = 0;
|
|
}
|
|
|
|
s32 Player_ActionChange_2(Player* this, PlayState* play) {
|
|
Actor* interactedActor;
|
|
|
|
if(gSaveContext.pendingIceTrapCount) {
|
|
gSaveContext.pendingIceTrapCount--;
|
|
GameInteractor_ExecuteOnItemReceiveHooks(ItemTable_RetrieveEntry(MOD_RANDOMIZER, RG_ICE_TRAP));
|
|
if (CVarGetInteger("gAddTraps.enabled", 0)) {
|
|
return 1;
|
|
}
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD);
|
|
this->actor.colChkInfo.damage = 0;
|
|
func_80837C0C(play, this, 3, 0.0f, 0.0f, 0, 20);
|
|
this->getItemId = GI_NONE;
|
|
this->getItemEntry = (GetItemEntry) GET_ITEM_NONE;
|
|
// Gameplay stats: Increment Ice Trap count
|
|
gSaveContext.sohStats.count[COUNT_ICE_TRAPS]++;
|
|
return 1;
|
|
}
|
|
|
|
if (iREG(67) || (((interactedActor = this->interactRangeActor) != NULL) &&
|
|
func_8002D53C(play, &play->actorCtx.titleCtx))) {
|
|
if (iREG(67) || (this->getItemId > GI_NONE)) {
|
|
if (iREG(67)) {
|
|
this->getItemId = iREG(68);
|
|
}
|
|
|
|
GetItemEntry giEntry;
|
|
if (this->getItemEntry.objectId == OBJECT_INVALID || (this->getItemId != this->getItemEntry.getItemId)) {
|
|
giEntry = ItemTable_Retrieve(this->getItemId);
|
|
} else {
|
|
giEntry = this->getItemEntry;
|
|
}
|
|
if (giEntry.collectable) {
|
|
if ((interactedActor != &this->actor) && !iREG(67)) {
|
|
interactedActor->parent = &this->actor;
|
|
}
|
|
|
|
iREG(67) = false;
|
|
|
|
if (IS_RANDO && giEntry.getItemId == RG_ICE_TRAP && giEntry.getItemFrom == ITEM_FROM_FREESTANDING) {
|
|
this->actor.freezeTimer = 30;
|
|
Player_SetPendingFlag(this, play);
|
|
Message_StartTextbox(play, 0xF8, NULL);
|
|
Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET);
|
|
gSaveContext.pendingIceTrapCount++;
|
|
return 1;
|
|
}
|
|
|
|
// Show the cutscene for picking up an item. In vanilla, this happens in bombchu bowling alley (because getting bombchus need to show the cutscene)
|
|
// and whenever the player doesn't have the item yet. In rando, we're overruling this because we need to keep showing the cutscene
|
|
// because those items can be randomized and thus it's important to keep showing the cutscene.
|
|
uint8_t showItemCutscene = play->sceneNum == SCENE_BOMBCHU_BOWLING_ALLEY || Item_CheckObtainability(giEntry.itemId) == ITEM_NONE || IS_RANDO;
|
|
|
|
// Only skip cutscenes for drops when they're items/consumables from bushes/rocks/enemies.
|
|
uint8_t isDropToSkip = (interactedActor->id == ACTOR_EN_ITEM00 && interactedActor->params != 6 && interactedActor->params != 17) ||
|
|
interactedActor->id == ACTOR_EN_KAREBABA ||
|
|
interactedActor->id == ACTOR_EN_DEKUBABA;
|
|
|
|
// Skip cutscenes from picking up consumables with "Fast Pickup Text" enabled, even when the player never picked it up before.
|
|
// But only for bushes/rocks/enemies because otherwise it can lead to softlocks in deku mask theatre and potentially other places.
|
|
uint8_t skipItemCutscene = CVarGetInteger("gFastDrops", 0) && isDropToSkip;
|
|
|
|
// Same as above but for rando. Rando is different because we want to enable cutscenes for items that the player already has because
|
|
// those items could be a randomized item coming from scrubs, freestanding PoH's and keys. So we need to once again overrule
|
|
// this specifically for items coming from bushes/rocks/enemies when the player has already picked that item up.
|
|
uint8_t skipItemCutsceneRando = IS_RANDO && Item_CheckObtainability(giEntry.itemId) != ITEM_NONE && isDropToSkip;
|
|
|
|
// Show cutscene when picking up a item.
|
|
if (showItemCutscene && !skipItemCutscene && !skipItemCutsceneRando) {
|
|
|
|
Player_DetachHeldActor(play, this);
|
|
func_8083AE40(this, giEntry.objectId);
|
|
|
|
if (!(this->stateFlags2 & PLAYER_STATE2_UNDERWATER) || (this->currentBoots == PLAYER_BOOTS_IRON)) {
|
|
func_80836898(play, this, func_8083A434);
|
|
Player_AnimPlayOnceAdjusted(play, this, &gPlayerAnim_link_demo_get_itemB);
|
|
func_80835EA4(play, 9);
|
|
}
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD | PLAYER_STATE1_IN_CUTSCENE;
|
|
func_80832224(this);
|
|
return 1;
|
|
}
|
|
|
|
// Don't show cutscene when picking up an item.
|
|
func_8083E4C4(play, this, &giEntry);
|
|
this->getItemId = GI_NONE;
|
|
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
|
|
}
|
|
} else if (CHECK_BTN_ALL(sControlInput->press.button, BTN_A) && !(this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) &&
|
|
!(this->stateFlags2 & PLAYER_STATE2_UNDERWATER)) {
|
|
if (this->getItemId != GI_NONE) {
|
|
GetItemEntry giEntry;
|
|
if (this->getItemEntry.objectId == OBJECT_INVALID) {
|
|
giEntry = ItemTable_Retrieve(-this->getItemId);
|
|
} else {
|
|
giEntry = this->getItemEntry;
|
|
}
|
|
EnBox* chest = (EnBox*)interactedActor;
|
|
if (CVarGetInteger("gFastChests", 0) != 0) {
|
|
giEntry.gi = -1 * abs(giEntry.gi);
|
|
}
|
|
|
|
if (giEntry.itemId != ITEM_NONE) {
|
|
if (((Item_CheckObtainability(giEntry.itemId) == ITEM_NONE) && (giEntry.field & 0x40)) ||
|
|
((Item_CheckObtainability(giEntry.itemId) != ITEM_NONE) && (giEntry.field & 0x20))) {
|
|
this->getItemId = -GI_RUPEE_BLUE;
|
|
giEntry = ItemTable_Retrieve(GI_RUPEE_BLUE);
|
|
}
|
|
}
|
|
|
|
func_80836898(play, this, func_8083A434);
|
|
this->stateFlags1 |= PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD | PLAYER_STATE1_IN_CUTSCENE;
|
|
func_8083AE40(this, giEntry.objectId);
|
|
this->actor.world.pos.x =
|
|
chest->dyna.actor.world.pos.x - (Math_SinS(chest->dyna.actor.shape.rot.y) * 29.4343f);
|
|
this->actor.world.pos.z =
|
|
chest->dyna.actor.world.pos.z - (Math_CosS(chest->dyna.actor.shape.rot.y) * 29.4343f);
|
|
this->yaw = this->actor.shape.rot.y = chest->dyna.actor.shape.rot.y;
|
|
func_80832224(this);
|
|
|
|
if ((giEntry.itemId != ITEM_NONE) && (giEntry.gi >= 0) &&
|
|
(Item_CheckObtainability(giEntry.itemId) == ITEM_NONE)) {
|
|
Player_AnimPlayOnceAdjusted(play, this, this->ageProperties->unk_98);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x28F);
|
|
chest->unk_1F4 = 1;
|
|
Camera_ChangeSetting(Play_GetCamera(play, 0), CAM_SET_SLOW_CHEST_CS);
|
|
} else {
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_normal_box_kick);
|
|
chest->unk_1F4 = -1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
if ((this->heldActor == NULL) || Player_HoldsHookshot(this)) {
|
|
if ((interactedActor->id == ACTOR_BG_TOKI_SWD) && LINK_IS_ADULT) {
|
|
s32 sp24 = this->itemAction;
|
|
|
|
this->itemAction = PLAYER_IA_NONE;
|
|
this->modelAnimType = PLAYER_ANIMTYPE_0;
|
|
this->heldItemAction = this->itemAction;
|
|
func_80836898(play, this, func_8083A0F4);
|
|
|
|
if (sp24 == PLAYER_IA_SWORD_MASTER) {
|
|
this->nextModelGroup = Player_ActionToModelGroup(this, PLAYER_IA_LAST_USED);
|
|
Player_InitItemAction(play, this, PLAYER_IA_LAST_USED);
|
|
} else {
|
|
Player_UseItem(play, this, ITEM_LAST_USED);
|
|
}
|
|
} else {
|
|
s32 strength = Player_GetStrength();
|
|
|
|
if ((interactedActor->id == ACTOR_EN_ISHI) && ((interactedActor->params & 0xF) == 1) &&
|
|
(strength < PLAYER_STR_SILVER_G)) {
|
|
return 0;
|
|
}
|
|
|
|
func_80836898(play, this, func_8083A0F4);
|
|
}
|
|
|
|
func_80832224(this);
|
|
this->stateFlags1 |= PLAYER_STATE1_ITEM_OVER_HEAD;
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8083EA94(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_80846578, 1);
|
|
Player_AnimPlayOnce(play, this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_throw, this->modelAnimType));
|
|
}
|
|
|
|
s32 func_8083EAF0(Player* this, Actor* actor) {
|
|
if ((actor != NULL) && !(actor->flags & ACTOR_FLAG_ALWAYS_THROWN) &&
|
|
((this->linearVelocity < 1.1f) || (actor->id == ACTOR_EN_BOM_CHU))) {
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 Player_ActionChange_9(Player* this, PlayState* play) {
|
|
u16 buttonsToCheck = BTN_A | BTN_B | BTN_CLEFT | BTN_CRIGHT | BTN_CDOWN;
|
|
if (CVarGetInteger("gDpadEquips", 0) != 0) {
|
|
buttonsToCheck |= BTN_DUP | BTN_DDOWN | BTN_DLEFT | BTN_DRIGHT;
|
|
}
|
|
if ((this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) && (this->heldActor != NULL) &&
|
|
CHECK_BTN_ANY(sControlInput->press.button, buttonsToCheck)) {
|
|
if (!func_80835644(play, this, this->heldActor)) {
|
|
if (!func_8083EAF0(this, this->heldActor)) {
|
|
Player_SetupAction(play, this, Player_Action_808464B0, 1);
|
|
Player_AnimPlayOnce(play, this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_put, this->modelAnimType));
|
|
} else {
|
|
func_8083EA94(this, play);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_8083EC18(Player* this, PlayState* play, u32 wallFlags) {
|
|
if (this->yDistToLedge >= 79.0f) {
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_IN_WATER) || (this->currentBoots == PLAYER_BOOTS_IRON) ||
|
|
(this->actor.yDistToWater < this->ageProperties->unk_2C)) {
|
|
s32 sp8C = (wallFlags & 8) ? 2 : 0;
|
|
|
|
if ((sp8C != 0) || (wallFlags & 2) ||
|
|
func_80041E4C(&play->colCtx, this->actor.wallPoly, this->actor.wallBgId)) {
|
|
f32 phi_f20;
|
|
CollisionPoly* wallPoly = this->actor.wallPoly;
|
|
f32 sp80;
|
|
f32 sp7C;
|
|
f32 phi_f12;
|
|
f32 phi_f14;
|
|
|
|
phi_f20 = phi_f12 = 0.0f;
|
|
|
|
if (sp8C != 0) {
|
|
sp80 = this->actor.world.pos.x;
|
|
sp7C = this->actor.world.pos.z;
|
|
} else {
|
|
Vec3f sp50[3];
|
|
s32 i;
|
|
f32 sp48;
|
|
Vec3f* sp44 = &sp50[0];
|
|
s32 pad;
|
|
|
|
CollisionPoly_GetVerticesByBgId(wallPoly, this->actor.wallBgId, &play->colCtx, sp50);
|
|
|
|
sp80 = phi_f12 = sp44->x;
|
|
sp7C = phi_f14 = sp44->z;
|
|
phi_f20 = sp44->y;
|
|
for (i = 1; i < 3; i++) {
|
|
sp44++;
|
|
if (sp80 > sp44->x) {
|
|
sp80 = sp44->x;
|
|
} else if (phi_f12 < sp44->x) {
|
|
phi_f12 = sp44->x;
|
|
}
|
|
|
|
if (sp7C > sp44->z) {
|
|
sp7C = sp44->z;
|
|
} else if (phi_f14 < sp44->z) {
|
|
phi_f14 = sp44->z;
|
|
}
|
|
|
|
if (phi_f20 > sp44->y) {
|
|
phi_f20 = sp44->y;
|
|
}
|
|
}
|
|
|
|
sp80 = (sp80 + phi_f12) * 0.5f;
|
|
sp7C = (sp7C + phi_f14) * 0.5f;
|
|
|
|
phi_f12 = ((this->actor.world.pos.x - sp80) * COLPOLY_GET_NORMAL(wallPoly->normal.z)) -
|
|
((this->actor.world.pos.z - sp7C) * COLPOLY_GET_NORMAL(wallPoly->normal.x));
|
|
sp48 = this->actor.world.pos.y - phi_f20;
|
|
|
|
phi_f20 = ((f32)(s32)((sp48 / 15.000000223517418) + 0.5) * 15.000000223517418) - sp48;
|
|
phi_f12 = fabsf(phi_f12);
|
|
}
|
|
|
|
if (phi_f12 < 8.0f) {
|
|
f32 wallPolyNormalX = COLPOLY_GET_NORMAL(wallPoly->normal.x);
|
|
f32 wallPolyNormalZ = COLPOLY_GET_NORMAL(wallPoly->normal.z);
|
|
f32 sp34 = this->distToInteractWall;
|
|
LinkAnimationHeader* anim;
|
|
|
|
func_80836898(play, this, func_8083A3B0);
|
|
this->stateFlags1 |= PLAYER_STATE1_CLIMBING_LADDER;
|
|
this->stateFlags1 &= ~PLAYER_STATE1_IN_WATER;
|
|
|
|
if ((sp8C != 0) || (wallFlags & 2)) {
|
|
if ((this->av1.actionVar1 = sp8C) != 0) {
|
|
if (this->actor.bgCheckFlags & 1) {
|
|
anim = &gPlayerAnim_link_normal_Fclimb_startA;
|
|
} else {
|
|
anim = &gPlayerAnim_link_normal_Fclimb_hold2upL;
|
|
}
|
|
sp34 = (this->ageProperties->wallCheckRadius - 1.0f) - sp34;
|
|
} else {
|
|
anim = this->ageProperties->unk_A4;
|
|
sp34 = sp34 - 1.0f;
|
|
}
|
|
this->av2.actionVar2 = -2;
|
|
this->actor.world.pos.y += phi_f20;
|
|
this->actor.shape.rot.y = this->yaw = this->actor.wallYaw + 0x8000;
|
|
} else {
|
|
anim = this->ageProperties->unk_A8;
|
|
this->av2.actionVar2 = -4;
|
|
this->actor.shape.rot.y = this->yaw = this->actor.wallYaw;
|
|
}
|
|
|
|
this->actor.world.pos.x = (sp34 * wallPolyNormalX) + sp80;
|
|
this->actor.world.pos.z = (sp34 * wallPolyNormalZ) + sp7C;
|
|
func_80832224(this);
|
|
Math_Vec3f_Copy(&this->actor.prevPos, &this->actor.world.pos);
|
|
Player_AnimPlayOnce(play, this, anim);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x9F);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void func_8083F070(Player* this, LinkAnimationHeader* anim, PlayState* play) {
|
|
func_80835DAC(play, this, Player_Action_8084C5F8, 0);
|
|
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, anim, (4.0f / 3.0f));
|
|
}
|
|
|
|
/**
|
|
* @return true if Player chooses to enter crawlspace
|
|
*/
|
|
s32 Player_TryEnteringCrawlspace(Player* this, PlayState* play, u32 interactWallFlags) {
|
|
CollisionPoly* wallPoly;
|
|
Vec3f wallVertices[3];
|
|
f32 xVertex1;
|
|
f32 xVertex2;
|
|
f32 zVertex1;
|
|
f32 zVertex2;
|
|
s32 i;
|
|
|
|
if (!LINK_IS_ADULT && !(this->stateFlags1 & PLAYER_STATE1_IN_WATER) && (interactWallFlags & 0x30)) {
|
|
wallPoly = this->actor.wallPoly;
|
|
CollisionPoly_GetVerticesByBgId(wallPoly, this->actor.wallBgId, &play->colCtx, wallVertices);
|
|
|
|
// Determines min and max vertices for x & z (edges of the crawlspace hole)
|
|
xVertex1 = xVertex2 = wallVertices[0].x;
|
|
zVertex1 = zVertex2 = wallVertices[0].z;
|
|
for (i = 1; i < 3; i++) {
|
|
if (xVertex1 > wallVertices[i].x) {
|
|
// Update x min
|
|
xVertex1 = wallVertices[i].x;
|
|
} else if (xVertex2 < wallVertices[i].x) {
|
|
// Update x max
|
|
xVertex2 = wallVertices[i].x;
|
|
}
|
|
|
|
if (zVertex1 > wallVertices[i].z) {
|
|
// Update z min
|
|
zVertex1 = wallVertices[i].z;
|
|
} else if (zVertex2 < wallVertices[i].z) {
|
|
// Update z max
|
|
zVertex2 = wallVertices[i].z;
|
|
}
|
|
}
|
|
|
|
// XZ Center of the crawlspace hole
|
|
xVertex1 = (xVertex1 + xVertex2) * 0.5f;
|
|
zVertex1 = (zVertex1 + zVertex2) * 0.5f;
|
|
|
|
// Perpendicular (sideways) XZ-Distance from player pos to crawlspace line
|
|
// Uses y-component of crossproduct formula for the distance from a point to a line
|
|
xVertex2 = ((this->actor.world.pos.x - xVertex1) * COLPOLY_GET_NORMAL(wallPoly->normal.z)) -
|
|
((this->actor.world.pos.z - zVertex1) * COLPOLY_GET_NORMAL(wallPoly->normal.x));
|
|
|
|
if (fabsf(xVertex2) < 8.0f) {
|
|
// Give do-action prompt to "Enter on A" for the crawlspace
|
|
this->stateFlags2 |= PLAYER_STATE2_DO_ACTION_ENTER;
|
|
|
|
if (CHECK_BTN_ALL(sControlInput->press.button, BTN_A)) {
|
|
// Enter Crawlspace
|
|
f32 wallPolyNormX = COLPOLY_GET_NORMAL(wallPoly->normal.x);
|
|
f32 wallPolyNormZ = COLPOLY_GET_NORMAL(wallPoly->normal.z);
|
|
f32 distToInteractWall = this->distToInteractWall;
|
|
|
|
func_80836898(play, this, func_8083A40C);
|
|
this->stateFlags2 |= PLAYER_STATE2_CRAWLING;
|
|
this->actor.shape.rot.y = this->yaw = this->actor.wallYaw + 0x8000;
|
|
this->actor.world.pos.x = xVertex1 + (distToInteractWall * wallPolyNormX);
|
|
this->actor.world.pos.z = zVertex1 + (distToInteractWall * wallPolyNormZ);
|
|
func_80832224(this);
|
|
this->actor.prevPos = this->actor.world.pos;
|
|
// #region SOH [Enhancement]
|
|
if (CVarGetInteger("gCrawlSpeed", 1) > 1) {
|
|
// increase animation speed when entering a tunnel
|
|
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start,
|
|
((CVarGetInteger("gCrawlSpeed", 1) + 1.0f) / 2.0f), 0.0f,
|
|
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), ANIMMODE_ONCE,
|
|
0.0f);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
|
// #endregion
|
|
} else {
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_child_tunnel_start);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
s32 func_8083F360(PlayState* play, Player* this, f32 arg1, f32 arg2, f32 arg3, f32 arg4) {
|
|
CollisionPoly* wallPoly;
|
|
s32 sp78;
|
|
Vec3f sp6C;
|
|
Vec3f sp60;
|
|
Vec3f sp54;
|
|
f32 yawCos;
|
|
f32 yawSin;
|
|
s32 temp;
|
|
f32 temp1;
|
|
f32 temp2;
|
|
|
|
yawCos = Math_CosS(this->actor.shape.rot.y);
|
|
yawSin = Math_SinS(this->actor.shape.rot.y);
|
|
|
|
sp6C.x = this->actor.world.pos.x + (arg4 * yawSin);
|
|
sp6C.z = this->actor.world.pos.z + (arg4 * yawCos);
|
|
sp60.x = this->actor.world.pos.x + (arg3 * yawSin);
|
|
sp60.z = this->actor.world.pos.z + (arg3 * yawCos);
|
|
sp60.y = sp6C.y = this->actor.world.pos.y + arg1;
|
|
|
|
if (BgCheck_EntityLineTest1(&play->colCtx, &sp6C, &sp60, &sp54, &this->actor.wallPoly, true, false, false,
|
|
true, &sp78)) {
|
|
wallPoly = this->actor.wallPoly;
|
|
|
|
this->actor.bgCheckFlags |= 0x200;
|
|
this->actor.wallBgId = sp78;
|
|
|
|
sTouchedWallFlags = func_80041DB8(&play->colCtx, wallPoly, sp78);
|
|
|
|
temp1 = COLPOLY_GET_NORMAL(wallPoly->normal.x);
|
|
temp2 = COLPOLY_GET_NORMAL(wallPoly->normal.z);
|
|
temp = Math_Atan2S(-temp2, -temp1);
|
|
Math_ScaledStepToS(&this->actor.shape.rot.y, temp, 800);
|
|
|
|
this->yaw = this->actor.shape.rot.y;
|
|
this->actor.world.pos.x = sp54.x - (Math_SinS(this->actor.shape.rot.y) * arg2);
|
|
this->actor.world.pos.z = sp54.z - (Math_CosS(this->actor.shape.rot.y) * arg2);
|
|
|
|
return 1;
|
|
}
|
|
|
|
this->actor.bgCheckFlags &= ~0x200;
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_8083F524(PlayState* play, Player* this) {
|
|
return func_8083F360(play, this, 26.0f, this->ageProperties->wallCheckRadius + 5.0f, 30.0f, 0.0f);
|
|
}
|
|
|
|
/**
|
|
* Two exit walls are placed at each end of the crawlspace, separate to the two entrance walls used to enter the
|
|
* crawlspace. These front and back exit walls are futher into the crawlspace than the front and
|
|
* back entrance walls. When player interacts with either of these two interior exit walls, start the leaving-crawlspace
|
|
* cutscene and return true. Else, return false
|
|
*/
|
|
s32 Player_TryLeavingCrawlspace(Player* this, PlayState* play) {
|
|
s16 temp;
|
|
|
|
if ((this->linearVelocity != 0.0f) && (this->actor.bgCheckFlags & 8) && (sTouchedWallFlags & 0x30)) {
|
|
|
|
temp = this->actor.shape.rot.y - this->actor.wallYaw;
|
|
if (this->linearVelocity < 0.0f) {
|
|
temp += 0x8000;
|
|
}
|
|
|
|
if (ABS(temp) > 0x4000) {
|
|
Player_SetupAction(play, this, Player_Action_8084C81C, 0);
|
|
|
|
if (this->linearVelocity > 0.0f) {
|
|
this->actor.shape.rot.y = this->actor.wallYaw + 0x8000;
|
|
// #region SOH [Enhancement]
|
|
if (CVarGetInteger("gCrawlSpeed", 1) > 1) {
|
|
// animation when exiting a tunnel forward
|
|
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_end,
|
|
((CVarGetInteger("gCrawlSpeed", 1) + 1.0f) / 2.0f), 0.0f,
|
|
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_end), ANIMMODE_ONCE,
|
|
0.0f);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
|
OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM);
|
|
// #endregion
|
|
} else {
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_child_tunnel_end);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
|
OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM);
|
|
}
|
|
} else {
|
|
this->actor.shape.rot.y = this->actor.wallYaw;
|
|
// #region SOH [Enhancement]
|
|
// animation when exiting a tunnel backward
|
|
if (CVarGetInteger("gCrawlSpeed",1) > 1) {
|
|
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start,
|
|
-1.0f * ((CVarGetInteger("gCrawlSpeed", 1) + 1.0f) / 2.0f),
|
|
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), 0.0f, ANIMMODE_ONCE, 0.0f);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
|
OnePointCutscene_Init(play, 9602, 999, NULL, MAIN_CAM);
|
|
// #endregion
|
|
}
|
|
else {
|
|
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start, -1.0f,
|
|
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), 0.0f, ANIMMODE_ONCE, 0.0f);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x9D);
|
|
OnePointCutscene_Init(play, 9602, 999, NULL, MAIN_CAM);
|
|
}
|
|
}
|
|
|
|
this->yaw = this->actor.shape.rot.y;
|
|
Player_ZeroSpeedXZ(this);
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8083F72C(Player* this, LinkAnimationHeader* anim, PlayState* play) {
|
|
if (!func_80836898(play, this, func_8083A388)) {
|
|
Player_SetupAction(play, this, Player_Action_8084B78C, 0);
|
|
}
|
|
|
|
Player_AnimPlayOnce(play, this, anim);
|
|
func_80832224(this);
|
|
|
|
this->actor.shape.rot.y = this->yaw = this->actor.wallYaw + 0x8000;
|
|
}
|
|
|
|
s32 Player_ActionChange_5(Player* this, PlayState* play) {
|
|
DynaPolyActor* wallPolyActor;
|
|
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) && (this->actor.bgCheckFlags & 0x200) && (sShapeYawToTouchedWall < 0x3000)) {
|
|
|
|
if (((this->linearVelocity > 0.0f) && func_8083EC18(this, play, sTouchedWallFlags)) ||
|
|
Player_TryEnteringCrawlspace(this, play, sTouchedWallFlags)) {
|
|
return 1;
|
|
}
|
|
|
|
if (!func_808332B8(this) && ((this->linearVelocity == 0.0f) || !(this->stateFlags2 & PLAYER_STATE2_DO_ACTION_CLIMB)) &&
|
|
(sTouchedWallFlags & 0x40) && (this->actor.bgCheckFlags & 1) && (this->yDistToLedge >= 39.0f)) {
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DO_ACTION_GRAB;
|
|
|
|
if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_A)) {
|
|
|
|
if ((this->actor.wallBgId != BGCHECK_SCENE) &&
|
|
((wallPolyActor = DynaPoly_GetActor(&play->colCtx, this->actor.wallBgId)) != NULL)) {
|
|
|
|
if (wallPolyActor->actor.id == ACTOR_BG_HEAVY_BLOCK) {
|
|
if (Player_GetStrength() < PLAYER_STR_GOLD_G) {
|
|
return 0;
|
|
}
|
|
|
|
func_80836898(play, this, func_8083A0F4);
|
|
this->stateFlags1 |= PLAYER_STATE1_ITEM_OVER_HEAD;
|
|
this->interactRangeActor = &wallPolyActor->actor;
|
|
this->getItemId = GI_NONE;
|
|
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
|
|
this->yaw = this->actor.wallYaw + 0x8000;
|
|
func_80832224(this);
|
|
|
|
return 1;
|
|
}
|
|
|
|
this->unk_3C4 = &wallPolyActor->actor;
|
|
} else {
|
|
this->unk_3C4 = NULL;
|
|
}
|
|
|
|
func_8083F72C(this, &gPlayerAnim_link_normal_push_wait, play);
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_8083F9D0(PlayState* play, Player* this) {
|
|
if ((this->actor.bgCheckFlags & 0x200) &&
|
|
((this->stateFlags2 & PLAYER_STATE2_MOVING_DYNAPOLY) || CHECK_BTN_ALL(sControlInput->cur.button, BTN_A))) {
|
|
DynaPolyActor* wallPolyActor = NULL;
|
|
|
|
if (this->actor.wallBgId != BGCHECK_SCENE) {
|
|
wallPolyActor = DynaPoly_GetActor(&play->colCtx, this->actor.wallBgId);
|
|
}
|
|
|
|
if (&wallPolyActor->actor == this->unk_3C4) {
|
|
if (this->stateFlags2 & PLAYER_STATE2_MOVING_DYNAPOLY) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
func_80839FFC(this, play);
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_normal_push_wait_end);
|
|
this->stateFlags2 &= ~PLAYER_STATE2_MOVING_DYNAPOLY;
|
|
return 1;
|
|
}
|
|
|
|
void func_8083FAB8(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_8084B898, 0);
|
|
this->stateFlags2 |= PLAYER_STATE2_MOVING_DYNAPOLY;
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_normal_push_start);
|
|
}
|
|
|
|
void func_8083FB14(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_8084B9E4, 0);
|
|
this->stateFlags2 |= PLAYER_STATE2_MOVING_DYNAPOLY;
|
|
Player_AnimPlayOnce(play, this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_pull_start, this->modelAnimType));
|
|
}
|
|
|
|
void func_8083FB7C(Player* this, PlayState* play) {
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_CLIMBING_LADDER | PLAYER_STATE1_IN_WATER);
|
|
func_80837B9C(this, play);
|
|
this->linearVelocity = -0.4f;
|
|
}
|
|
|
|
s32 func_8083FBC0(Player* this, PlayState* play) {
|
|
if (!CHECK_BTN_ALL(sControlInput->press.button, BTN_A) && (this->actor.bgCheckFlags & 0x200) &&
|
|
((sTouchedWallFlags & 8) || (sTouchedWallFlags & 2) ||
|
|
func_80041E4C(&play->colCtx, this->actor.wallPoly, this->actor.wallBgId))) {
|
|
return 0;
|
|
}
|
|
|
|
func_8083FB7C(this, play);
|
|
func_80832698(this, NA_SE_VO_LI_AUTO_JUMP);
|
|
return 1;
|
|
}
|
|
|
|
s32 func_8083FC68(Player* this, f32 arg1, s16 arg2) {
|
|
f32 sp1C = (s16)(arg2 - this->actor.shape.rot.y);
|
|
f32 temp;
|
|
|
|
if (this->unk_664 != NULL) {
|
|
func_8083DB98(this, func_8002DD78(this) || func_808334B4(this));
|
|
}
|
|
|
|
temp = fabsf(sp1C) / 32768.0f;
|
|
|
|
if (arg1 > (((temp * temp) * 50.0f) + 6.0f)) {
|
|
return 1;
|
|
} else if (arg1 > (((1.0f - temp) * 10.0f) + 6.8f)) {
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_8083FD78(Player* this, f32* arg1, s16* arg2, PlayState* play) {
|
|
s16 sp2E = *arg2 - this->zTargetYaw;
|
|
u16 sp2C = ABS(sp2E);
|
|
|
|
if ((func_8002DD78(this) || func_808334B4(this)) && (this->unk_664 == NULL)) {
|
|
*arg1 *= Math_SinS(sp2C);
|
|
|
|
if (*arg1 != 0.0f) {
|
|
*arg2 = (((sp2E >= 0) ? 1 : -1) << 0xE) + this->actor.shape.rot.y;
|
|
} else {
|
|
*arg2 = this->actor.shape.rot.y;
|
|
}
|
|
|
|
// #region SOH [Enhancement]
|
|
if (CVarGetInteger("gRightStickAiming", 0) || !CVarGetInteger("gInvertZAimingYAxis", 1)) {
|
|
|
|
if (this->unk_664 != NULL) {
|
|
func_8083DB98(this, 1);
|
|
} else {
|
|
int8_t relStickY;
|
|
|
|
// preserves simultaneous left/right-stick aiming
|
|
if (CVarGetInteger("gRightStickAiming", 0)) {
|
|
if ((sControlInput->rel.stick_y + sControlInput->rel.right_stick_y) >= 0) {
|
|
relStickY = (((sControlInput->rel.stick_y) > (sControlInput->rel.right_stick_y))
|
|
? (sControlInput->rel.stick_y)
|
|
: (sControlInput->rel.right_stick_y));
|
|
} else {
|
|
relStickY = (((sControlInput->rel.stick_y) < (sControlInput->rel.right_stick_y))
|
|
? (sControlInput->rel.stick_y)
|
|
: (sControlInput->rel.right_stick_y));
|
|
}
|
|
} else {
|
|
relStickY = sControlInput->rel.stick_y;
|
|
}
|
|
|
|
Math_SmoothStepToS(&this->actor.focus.rot.x,
|
|
relStickY * (CVarGetInteger("gInvertZAimingYAxis", 1) ? 1 : -1) * 240.0f, 14, 4000, 30);
|
|
func_80836AB8(this, 1);
|
|
}
|
|
// #endregion
|
|
} else {
|
|
if (this->unk_664 != NULL) {
|
|
func_8083DB98(this, 1);
|
|
} else {
|
|
Math_SmoothStepToS(&this->actor.focus.rot.x, sControlInput->rel.stick_y * 240.0f, 14, 4000, 30);
|
|
func_80836AB8(this, 1);
|
|
}
|
|
}
|
|
} else {
|
|
if (this->unk_664 != NULL) {
|
|
return func_8083FC68(this, *arg1, *arg2);
|
|
} else {
|
|
func_8083DC54(this, play);
|
|
if ((*arg1 != 0.0f) && (sp2C < 6000)) {
|
|
return 1;
|
|
} else if (*arg1 > Math_SinS((0x4000 - (sp2C >> 1))) * 200.0f) {
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_8083FFB8(Player* this, f32* arg1, s16* arg2) {
|
|
s16 temp1 = *arg2 - this->actor.shape.rot.y;
|
|
u16 temp2 = ABS(temp1);
|
|
f32 temp3 = Math_CosS(temp2);
|
|
|
|
*arg1 *= temp3;
|
|
|
|
if (*arg1 != 0.0f) {
|
|
if (temp3 > 0) {
|
|
return 1;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_80840058(Player* this, f32* arg1, s16* arg2, PlayState* play) {
|
|
func_8083DC54(this, play);
|
|
|
|
if ((*arg1 != 0.0f) || (ABS(this->unk_87C) > 400)) {
|
|
s16 temp1 = *arg2 - Camera_GetInputDirYaw(GET_ACTIVE_CAM(play));
|
|
u16 temp2 = (ABS(temp1) - 0x2000) & 0xFFFF;
|
|
|
|
if ((temp2 < 0x4000) || (this->unk_87C != 0)) {
|
|
return -1;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_80840138(Player* this, f32 arg1, s16 arg2) {
|
|
s16 temp = arg2 - this->actor.shape.rot.y;
|
|
|
|
if (arg1 > 0.0f) {
|
|
if (temp < 0) {
|
|
this->unk_874 = 0.0f;
|
|
} else {
|
|
this->unk_874 = 1.0f;
|
|
}
|
|
}
|
|
|
|
Math_StepToF(&this->unk_870, this->unk_874, 0.3f);
|
|
}
|
|
|
|
void func_808401B0(PlayState* play, Player* this) {
|
|
LinkAnimation_BlendToJoint(play, &this->skelAnime, func_808334E4(this), this->unk_868, func_80833528(this),
|
|
this->unk_868, this->unk_870, this->blendTable);
|
|
}
|
|
|
|
s32 func_8084021C(f32 arg0, f32 arg1, f32 arg2, f32 arg3) {
|
|
f32 temp;
|
|
|
|
if ((arg3 == 0.0f) && (arg1 > 0.0f)) {
|
|
arg3 = arg2;
|
|
}
|
|
|
|
temp = (arg0 + arg1) - arg3;
|
|
|
|
if (((temp * arg1) >= 0.0f) && (((temp - arg1) * arg1) < 0.0f)) {
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8084029C(Player* this, f32 arg1) {
|
|
f32 updateScale = R_UPDATE_RATE * 0.5f;
|
|
|
|
arg1 *= updateScale;
|
|
if (arg1 < -7.25) {
|
|
arg1 = -7.25;
|
|
} else if (arg1 > 7.25f) {
|
|
arg1 = 7.25f;
|
|
}
|
|
|
|
if ((this->currentBoots == PLAYER_BOOTS_HOVER ||
|
|
(CVarGetInteger("gIvanCoopModeEnabled", 0) && this->ivanFloating)) &&
|
|
!(this->actor.bgCheckFlags & 1) &&
|
|
(this->hoverBootsTimer != 0 || (CVarGetInteger("gIvanCoopModeEnabled", 0) && this->ivanFloating))) {
|
|
func_8002F8F0(&this->actor, NA_SE_PL_HOBBERBOOTS_LV - SFX_FLAG);
|
|
} else if (func_8084021C(this->unk_868, arg1, 29.0f, 10.0f) || func_8084021C(this->unk_868, arg1, 29.0f, 24.0f)) {
|
|
func_808327F8(this, this->linearVelocity);
|
|
if (this->linearVelocity > 4.0f) {
|
|
this->stateFlags2 |= PLAYER_STATE2_FOOTSTEP;
|
|
}
|
|
}
|
|
|
|
this->unk_868 += arg1;
|
|
|
|
if (this->unk_868 < 0.0f) {
|
|
this->unk_868 += 29.0f;
|
|
} else if (this->unk_868 >= 29.0f) {
|
|
this->unk_868 -= 29.0f;
|
|
}
|
|
}
|
|
|
|
void Player_Action_80840450(Player* this, PlayState* play) {
|
|
f32 speedTarget;
|
|
s16 yawTarget;
|
|
s32 temp1;
|
|
u32 temp2;
|
|
s16 temp3;
|
|
s32 temp4;
|
|
|
|
if (this->stateFlags3 & PLAYER_STATE3_FINISHED_ATTACKING) {
|
|
if (Player_GetMeleeWeaponHeld(this)) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET | PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
} else {
|
|
this->stateFlags3 &= ~PLAYER_STATE3_FINISHED_ATTACKING;
|
|
}
|
|
}
|
|
|
|
if (this->av2.actionVar2 != 0) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_80832DBC(this);
|
|
Player_AnimPlayLoop(play, this, func_808334E4(this));
|
|
this->av2.actionVar2 = 0;
|
|
this->stateFlags3 &= ~PLAYER_STATE3_FINISHED_ATTACKING;
|
|
}
|
|
func_80833C3C(this);
|
|
} else {
|
|
func_808401B0(play, this);
|
|
}
|
|
|
|
func_8083721C(this);
|
|
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList1, true)) {
|
|
if (!func_80833B54(this) && (!func_80833B2C(this) || (func_80834B5C != this->upperActionFunc))) {
|
|
func_8083CF10(this, play);
|
|
return;
|
|
}
|
|
|
|
Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_LINEAR, play);
|
|
|
|
temp1 = func_8083FC68(this, speedTarget, yawTarget);
|
|
|
|
if (temp1 > 0) {
|
|
func_8083C8DC(this, play, yawTarget);
|
|
return;
|
|
}
|
|
|
|
if (temp1 < 0) {
|
|
func_8083CBF0(this, yawTarget, play);
|
|
return;
|
|
}
|
|
|
|
if (speedTarget > 4.0f) {
|
|
func_8083CC9C(this, play);
|
|
return;
|
|
}
|
|
|
|
func_8084029C(this, (this->linearVelocity * 0.3f) + 1.0f);
|
|
func_80840138(this, speedTarget, yawTarget);
|
|
|
|
temp2 = this->unk_868;
|
|
if ((temp2 < 6) || ((temp2 - 0xE) < 6)) {
|
|
Math_StepToF(&this->linearVelocity, 0.0f, 1.5f);
|
|
return;
|
|
}
|
|
|
|
temp3 = yawTarget - this->yaw;
|
|
temp4 = ABS(temp3);
|
|
|
|
if (temp4 > 0x4000) {
|
|
if (Math_StepToF(&this->linearVelocity, 0.0f, 1.5f)) {
|
|
this->yaw = yawTarget;
|
|
}
|
|
return;
|
|
}
|
|
|
|
Math_AsymStepToF(&this->linearVelocity, speedTarget * 0.3f, 2.0f, 1.5f);
|
|
|
|
if (!(this->stateFlags3 & PLAYER_STATE3_FINISHED_ATTACKING)) {
|
|
Math_ScaledStepToS(&this->yaw, yawTarget, temp4 * 0.1f);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_808407CC(Player* this, PlayState* play) {
|
|
f32 speedTarget;
|
|
s16 yawTarget;
|
|
s32 temp1;
|
|
s16 temp2;
|
|
s32 temp3;
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_80832DBC(this);
|
|
Player_AnimPlayOnce(play, this, func_80833338(this));
|
|
}
|
|
|
|
func_8083721C(this);
|
|
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList2, true)) {
|
|
if (func_80833B54(this)) {
|
|
func_8083CEAC(this, play);
|
|
return;
|
|
}
|
|
|
|
if (!func_80833B2C(this)) {
|
|
func_80835DAC(play, this, Player_Action_80840BC8, 1);
|
|
this->yaw = this->actor.shape.rot.y;
|
|
return;
|
|
}
|
|
|
|
if (func_80834B5C == this->upperActionFunc) {
|
|
func_8083CEAC(this, play);
|
|
return;
|
|
}
|
|
|
|
Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_LINEAR, play);
|
|
|
|
temp1 = func_8083FD78(this, &speedTarget, &yawTarget, play);
|
|
|
|
if (temp1 > 0) {
|
|
func_8083C8DC(this, play, yawTarget);
|
|
return;
|
|
}
|
|
|
|
if (temp1 < 0) {
|
|
func_8083CB2C(this, yawTarget, play);
|
|
return;
|
|
}
|
|
|
|
if (speedTarget > 4.9f) {
|
|
func_8083CC9C(this, play);
|
|
func_80833C3C(this);
|
|
return;
|
|
}
|
|
if (speedTarget != 0.0f) {
|
|
func_8083CB94(this, play);
|
|
return;
|
|
}
|
|
|
|
temp2 = yawTarget - this->actor.shape.rot.y;
|
|
temp3 = ABS(temp2);
|
|
|
|
if (temp3 > 800) {
|
|
func_8083CD54(play, this, yawTarget);
|
|
}
|
|
}
|
|
}
|
|
|
|
void func_808409CC(PlayState* play, Player* this) {
|
|
LinkAnimationHeader* anim;
|
|
LinkAnimationHeader** animPtr;
|
|
s32 heathIsCritical;
|
|
s32 sp38;
|
|
s32 sp34;
|
|
|
|
if ((this->unk_664 != NULL) ||
|
|
(!(heathIsCritical = HealthMeter_IsCritical()) && ((this->unk_6AC = (this->unk_6AC + 1) & 1) != 0))) {
|
|
this->stateFlags2 &= ~PLAYER_STATE2_IDLING;
|
|
anim = func_80833338(this);
|
|
} else {
|
|
this->stateFlags2 |= PLAYER_STATE2_IDLING;
|
|
if (this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) {
|
|
anim = func_80833338(this);
|
|
} else {
|
|
sp38 = play->roomCtx.curRoom.behaviorType2;
|
|
if (heathIsCritical) {
|
|
if (this->unk_6AC >= 0) {
|
|
sp38 = 7;
|
|
this->unk_6AC = -1;
|
|
} else {
|
|
sp38 = 8;
|
|
}
|
|
} else {
|
|
sp34 = Rand_ZeroOne() * 5.0f;
|
|
if (sp34 < 4) {
|
|
if (((sp34 != 0) && (sp34 != 3)) || ((this->rightHandType == PLAYER_MODELTYPE_RH_SHIELD) &&
|
|
((sp34 == 3) || Player_GetMeleeWeaponHeld(this)))) {
|
|
if ((sp34 == 1) && Player_HoldsTwoHandedWeapon(this) && CVarGetInteger("gTwoHandedIdle", 0) == 1) {
|
|
sp34 = 4;
|
|
}
|
|
sp38 = sp34 + 9;
|
|
}
|
|
}
|
|
}
|
|
animPtr = &D_80853D7C[sp38][0];
|
|
if (this->modelAnimType != PLAYER_ANIMTYPE_1) {
|
|
animPtr = &D_80853D7C[sp38][1];
|
|
}
|
|
anim = *animPtr;
|
|
}
|
|
}
|
|
|
|
LinkAnimation_Change(play, &this->skelAnime, anim, (2.0f / 3.0f) * D_808535E8, 0.0f,
|
|
Animation_GetLastFrame(anim), ANIMMODE_ONCE, -6.0f);
|
|
}
|
|
|
|
void Player_Action_80840BC8(Player* this, PlayState* play) {
|
|
s32 sp44;
|
|
s32 sp40;
|
|
f32 speedTarget;
|
|
s16 yawTarget;
|
|
s16 temp;
|
|
|
|
sp44 = func_80833350(this);
|
|
sp40 = LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (sp44 > 0) {
|
|
func_808333FC(this, sp44 - 1);
|
|
}
|
|
|
|
if (sp40 != 0) {
|
|
if (this->av2.actionVar2 != 0) {
|
|
if (DECR(this->av2.actionVar2) == 0) {
|
|
this->skelAnime.endFrame = this->skelAnime.animLength - 1.0f;
|
|
}
|
|
this->skelAnime.jointTable[0].y = (this->skelAnime.jointTable[0].y + ((this->av2.actionVar2 & 1) * 0x50)) - 0x28;
|
|
} else {
|
|
func_80832DBC(this);
|
|
func_808409CC(play, this);
|
|
}
|
|
}
|
|
|
|
func_8083721C(this);
|
|
|
|
if (this->av2.actionVar2 == 0) {
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList7, true)) {
|
|
if (func_80833B54(this)) {
|
|
func_8083CEAC(this, play);
|
|
return;
|
|
}
|
|
|
|
if (func_80833B2C(this)) {
|
|
func_80839F30(this, play);
|
|
return;
|
|
}
|
|
|
|
Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_CURVED, play);
|
|
|
|
if (speedTarget != 0.0f) {
|
|
func_8083C8DC(this, play, yawTarget);
|
|
return;
|
|
}
|
|
|
|
temp = yawTarget - this->actor.shape.rot.y;
|
|
if (ABS(temp) > 800) {
|
|
func_8083CD54(play, this, yawTarget);
|
|
return;
|
|
}
|
|
|
|
Math_ScaledStepToS(&this->actor.shape.rot.y, yawTarget, 1200);
|
|
this->yaw = this->actor.shape.rot.y;
|
|
if (func_80833338(this) == this->skelAnime.animation) {
|
|
func_8083DC54(this, play);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_80840DE4(Player* this, PlayState* play) {
|
|
f32 frames;
|
|
f32 coeff;
|
|
f32 speedTarget;
|
|
s16 yawTarget;
|
|
s32 temp1;
|
|
s16 temp2;
|
|
s32 temp3;
|
|
s32 direction;
|
|
|
|
this->skelAnime.mode = 0;
|
|
LinkAnimation_SetUpdateFunction(&this->skelAnime);
|
|
|
|
this->skelAnime.animation = func_8083356C(this);
|
|
|
|
if (this->skelAnime.animation == &gPlayerAnim_link_bow_side_walk) {
|
|
frames = 24.0f;
|
|
coeff = -(MREG(95) / 100.0f);
|
|
} else {
|
|
frames = 29.0f;
|
|
coeff = MREG(95) / 100.0f;
|
|
}
|
|
|
|
this->skelAnime.animLength = frames;
|
|
this->skelAnime.endFrame = frames - 1.0f;
|
|
|
|
if ((s16)(this->yaw - this->actor.shape.rot.y) >= 0) {
|
|
direction = 1;
|
|
} else {
|
|
direction = -1;
|
|
}
|
|
|
|
this->skelAnime.playSpeed = direction * (this->linearVelocity * coeff);
|
|
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 0.0f) || LinkAnimation_OnFrame(&this->skelAnime, frames * 0.5f)) {
|
|
func_808327F8(this, this->linearVelocity);
|
|
}
|
|
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList3, true)) {
|
|
if (func_80833B54(this)) {
|
|
func_8083CEAC(this, play);
|
|
return;
|
|
}
|
|
|
|
if (!func_80833B2C(this)) {
|
|
func_80853080(this, play);
|
|
return;
|
|
}
|
|
|
|
Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_LINEAR, play);
|
|
temp1 = func_8083FD78(this, &speedTarget, &yawTarget, play);
|
|
|
|
if (temp1 > 0) {
|
|
func_8083C8DC(this, play, yawTarget);
|
|
return;
|
|
}
|
|
|
|
if (temp1 < 0) {
|
|
func_8083CB2C(this, yawTarget, play);
|
|
return;
|
|
}
|
|
|
|
if (speedTarget > 4.9f) {
|
|
func_8083CC9C(this, play);
|
|
func_80833C3C(this);
|
|
return;
|
|
}
|
|
|
|
if ((speedTarget == 0.0f) && (this->linearVelocity == 0.0f)) {
|
|
func_80839F30(this, play);
|
|
return;
|
|
}
|
|
|
|
temp2 = yawTarget - this->yaw;
|
|
temp3 = ABS(temp2);
|
|
|
|
if (temp3 > 0x4000) {
|
|
if (Math_StepToF(&this->linearVelocity, 0.0f, 1.5f)) {
|
|
this->yaw = yawTarget;
|
|
}
|
|
return;
|
|
}
|
|
|
|
Math_AsymStepToF(&this->linearVelocity, speedTarget * 0.4f, 1.5f, 1.5f);
|
|
Math_ScaledStepToS(&this->yaw, yawTarget, temp3 * 0.1f);
|
|
}
|
|
}
|
|
|
|
void func_80841138(Player* this, PlayState* play) {
|
|
f32 temp1;
|
|
f32 temp2;
|
|
|
|
if (this->unk_864 < 1.0f) {
|
|
temp1 = R_UPDATE_RATE * 0.5f;
|
|
func_8084029C(this, REG(35) / 1000.0f);
|
|
LinkAnimation_LoadToJoint(play, &this->skelAnime, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_back_walk, this->modelAnimType),
|
|
this->unk_868);
|
|
this->unk_864 += 1 * temp1;
|
|
if (this->unk_864 >= 1.0f) {
|
|
this->unk_864 = 1.0f;
|
|
}
|
|
temp1 = this->unk_864;
|
|
} else {
|
|
temp2 = this->linearVelocity - (REG(48) / 100.0f);
|
|
if (temp2 < 0.0f) {
|
|
temp1 = 1.0f;
|
|
func_8084029C(this, (REG(35) / 1000.0f) + ((REG(36) / 1000.0f) * this->linearVelocity));
|
|
LinkAnimation_LoadToJoint(play, &this->skelAnime, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_back_walk, this->modelAnimType),
|
|
this->unk_868);
|
|
} else {
|
|
temp1 = (REG(37) / 1000.0f) * temp2;
|
|
if (temp1 < 1.0f) {
|
|
func_8084029C(this, (REG(35) / 1000.0f) + ((REG(36) / 1000.0f) * this->linearVelocity));
|
|
} else {
|
|
temp1 = 1.0f;
|
|
func_8084029C(this, 1.2f + ((REG(38) / 1000.0f) * temp2));
|
|
}
|
|
LinkAnimation_LoadToMorph(play, &this->skelAnime, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_back_walk, this->modelAnimType),
|
|
this->unk_868);
|
|
LinkAnimation_LoadToJoint(play, &this->skelAnime, &gPlayerAnim_link_normal_back_run,
|
|
this->unk_868 * (16.0f / 29.0f));
|
|
}
|
|
}
|
|
|
|
if (temp1 < 1.0f) {
|
|
LinkAnimation_InterpJointMorph(play, &this->skelAnime, 1.0f - temp1);
|
|
}
|
|
}
|
|
|
|
void func_8084140C(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_8084170C, 1);
|
|
Player_AnimChangeOnceMorph(play, this, &gPlayerAnim_link_normal_back_brake);
|
|
}
|
|
|
|
s32 func_80841458(Player* this, f32* arg1, s16* arg2, PlayState* play) {
|
|
if (this->linearVelocity > 6.0f) {
|
|
func_8084140C(this, play);
|
|
return 1;
|
|
}
|
|
|
|
if (*arg1 != 0.0f) {
|
|
if (func_8083721C(this)) {
|
|
*arg1 = 0.0f;
|
|
*arg2 = this->yaw;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Player_Action_808414F8(Player* this, PlayState* play) {
|
|
f32 speedTarget;
|
|
s16 yawTarget;
|
|
s32 sp2C;
|
|
s16 sp2A;
|
|
|
|
func_80841138(this, play);
|
|
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList4, true)) {
|
|
if (!func_80833C04(this)) {
|
|
func_8083C8DC(this, play, this->yaw);
|
|
return;
|
|
}
|
|
|
|
Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_LINEAR, play);
|
|
sp2C = func_8083FD78(this, &speedTarget, &yawTarget, play);
|
|
|
|
if (sp2C >= 0) {
|
|
if (!func_80841458(this, &speedTarget, &yawTarget, play)) {
|
|
if (sp2C != 0) {
|
|
func_8083C858(this, play);
|
|
} else if (speedTarget > 4.9f) {
|
|
func_8083CC9C(this, play);
|
|
} else {
|
|
func_8083CB94(this, play);
|
|
}
|
|
}
|
|
} else {
|
|
sp2A = yawTarget - this->yaw;
|
|
|
|
Math_AsymStepToF(&this->linearVelocity, speedTarget * 1.5f, 1.5f, 2.0f);
|
|
Math_ScaledStepToS(&this->yaw, yawTarget, sp2A * 0.1f);
|
|
|
|
if ((speedTarget == 0.0f) && (this->linearVelocity == 0.0f)) {
|
|
func_80839F30(this, play);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void func_808416C0(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_808417FC, 1);
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_normal_back_brake_end);
|
|
}
|
|
|
|
void Player_Action_8084170C(Player* this, PlayState* play) {
|
|
s32 sp34;
|
|
f32 speedTarget;
|
|
s16 yawTarget;
|
|
|
|
sp34 = LinkAnimation_Update(play, &this->skelAnime);
|
|
func_8083721C(this);
|
|
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList4, true)) {
|
|
Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_LINEAR, play);
|
|
|
|
if (this->linearVelocity == 0.0f) {
|
|
this->yaw = this->actor.shape.rot.y;
|
|
|
|
if (func_8083FD78(this, &speedTarget, &yawTarget, play) > 0) {
|
|
func_8083C858(this, play);
|
|
} else if ((speedTarget != 0.0f) || (sp34 != 0)) {
|
|
func_808416C0(this, play);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_808417FC(Player* this, PlayState* play) {
|
|
s32 sp1C;
|
|
|
|
sp1C = LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList4, true)) {
|
|
if (sp1C != 0) {
|
|
func_80839F30(this, play);
|
|
}
|
|
}
|
|
}
|
|
|
|
void func_80841860(PlayState* play, Player* this) {
|
|
f32 frame;
|
|
// fake match? see Player_InitItemActionWithAnim
|
|
LinkAnimationHeader* sp38 = D_80853914[0][this->modelAnimType + PLAYER_ANIMGROUP_side_walkL * ARRAY_COUNT(D_80853914[0])];
|
|
LinkAnimationHeader* sp34 = D_80853914[0][this->modelAnimType + PLAYER_ANIMGROUP_side_walkR * ARRAY_COUNT(D_80853914[0])];
|
|
|
|
this->skelAnime.animation = sp38;
|
|
|
|
func_8084029C(this, (REG(30) / 1000.0f) + ((REG(32) / 1000.0f) * this->linearVelocity));
|
|
|
|
frame = this->unk_868 * (16.0f / 29.0f);
|
|
LinkAnimation_BlendToJoint(play, &this->skelAnime, sp34, frame, sp38, frame, this->unk_870, this->blendTable);
|
|
}
|
|
|
|
void Player_Action_8084193C(Player* this, PlayState* play) {
|
|
f32 speedTarget;
|
|
s16 yawTarget;
|
|
s32 temp1;
|
|
s16 temp2;
|
|
s32 temp3;
|
|
|
|
func_80841860(play, this);
|
|
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList5, true)) {
|
|
if (!func_80833C04(this)) {
|
|
func_8083C858(this, play);
|
|
return;
|
|
}
|
|
|
|
Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_LINEAR, play);
|
|
|
|
if (func_80833B2C(this)) {
|
|
temp1 = func_8083FD78(this, &speedTarget, &yawTarget, play);
|
|
} else {
|
|
temp1 = func_8083FC68(this, speedTarget, yawTarget);
|
|
}
|
|
|
|
if (temp1 > 0) {
|
|
func_8083C858(this, play);
|
|
return;
|
|
}
|
|
|
|
if (temp1 < 0) {
|
|
if (func_80833B2C(this)) {
|
|
func_8083CB2C(this, yawTarget, play);
|
|
} else {
|
|
func_8083CBF0(this, yawTarget, play);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if ((this->linearVelocity < 3.6f) && (speedTarget < 4.0f)) {
|
|
if (!func_8008E9C4(this) && func_80833B2C(this)) {
|
|
func_8083CB94(this, play);
|
|
} else {
|
|
func_80839F90(this, play);
|
|
}
|
|
return;
|
|
}
|
|
|
|
func_80840138(this, speedTarget, yawTarget);
|
|
|
|
temp2 = yawTarget - this->yaw;
|
|
temp3 = ABS(temp2);
|
|
|
|
if (temp3 > 0x4000) {
|
|
if (Math_StepToF(&this->linearVelocity, 0.0f, 3.0f) != 0) {
|
|
this->yaw = yawTarget;
|
|
}
|
|
return;
|
|
}
|
|
|
|
speedTarget *= 0.9f;
|
|
Math_AsymStepToF(&this->linearVelocity, speedTarget, 2.0f, 3.0f);
|
|
Math_ScaledStepToS(&this->yaw, yawTarget, temp3 * 0.1f);
|
|
}
|
|
}
|
|
|
|
void Player_Action_80841BA8(Player* this, PlayState* play) {
|
|
f32 sp34;
|
|
s16 sp32;
|
|
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (Player_HoldsTwoHandedWeapon(this)) {
|
|
AnimationContext_SetLoadFrame(play, func_80833338(this), 0, this->skelAnime.limbCount,
|
|
this->skelAnime.morphTable);
|
|
AnimationContext_SetCopyTrue(play, this->skelAnime.limbCount, this->skelAnime.jointTable,
|
|
this->skelAnime.morphTable, sUpperBodyLimbCopyMap);
|
|
}
|
|
|
|
Player_GetMovementSpeedAndYaw(this, &sp34, &sp32, SPEED_MODE_CURVED, play);
|
|
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList6, true)) {
|
|
if (sp34 != 0.0f) {
|
|
this->actor.shape.rot.y = sp32;
|
|
func_8083C858(this, play);
|
|
} else if (Math_ScaledStepToS(&this->actor.shape.rot.y, sp32, this->unk_87E)) {
|
|
func_8083C0E8(this, play);
|
|
}
|
|
|
|
this->yaw = this->actor.shape.rot.y;
|
|
}
|
|
}
|
|
|
|
void func_80841CC4(Player* this, s32 arg1, PlayState* play) {
|
|
LinkAnimationHeader* anim;
|
|
s16 target;
|
|
f32 rate;
|
|
|
|
if (ABS(sFloorShapePitch) < 3640) {
|
|
target = 0;
|
|
} else {
|
|
target = CLAMP(sFloorShapePitch, -10922, 10922);
|
|
}
|
|
|
|
Math_ScaledStepToS(&this->unk_89C, target, 400);
|
|
|
|
if ((this->modelAnimType == PLAYER_ANIMTYPE_3) || ((this->unk_89C == 0) && (this->unk_6C4 <= 0.0f))) {
|
|
if (arg1 == 0) {
|
|
LinkAnimation_LoadToJoint(play, &this->skelAnime, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_walk, this->modelAnimType),
|
|
this->unk_868);
|
|
} else {
|
|
LinkAnimation_LoadToMorph(play, &this->skelAnime, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_walk, this->modelAnimType),
|
|
this->unk_868);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (this->unk_89C != 0) {
|
|
rate = this->unk_89C / 10922.0f;
|
|
} else {
|
|
rate = this->unk_6C4 * 0.0006f;
|
|
}
|
|
|
|
rate *= fabsf(this->linearVelocity) * 0.5f;
|
|
|
|
if (rate > 1.0f) {
|
|
rate = 1.0f;
|
|
}
|
|
|
|
if (rate < 0.0f) {
|
|
anim = &gPlayerAnim_link_normal_climb_down;
|
|
rate = -rate;
|
|
} else {
|
|
anim = &gPlayerAnim_link_normal_climb_up;
|
|
}
|
|
|
|
if (arg1 == 0) {
|
|
LinkAnimation_BlendToJoint(play, &this->skelAnime, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_walk, this->modelAnimType),
|
|
this->unk_868, anim, this->unk_868, rate, this->blendTable);
|
|
} else {
|
|
LinkAnimation_BlendToMorph(play, &this->skelAnime, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_walk, this->modelAnimType),
|
|
this->unk_868, anim, this->unk_868, rate, this->blendTable);
|
|
}
|
|
}
|
|
|
|
void func_80841EE4(Player* this, PlayState* play) {
|
|
f32 temp1;
|
|
f32 temp2;
|
|
|
|
if (this->unk_864 < 1.0f) {
|
|
temp1 = R_UPDATE_RATE * 0.5f;
|
|
|
|
func_8084029C(this, REG(35) / 1000.0f);
|
|
LinkAnimation_LoadToJoint(play, &this->skelAnime, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_walk, this->modelAnimType),
|
|
this->unk_868);
|
|
|
|
this->unk_864 += 1 * temp1;
|
|
if (this->unk_864 >= 1.0f) {
|
|
this->unk_864 = 1.0f;
|
|
}
|
|
|
|
temp1 = this->unk_864;
|
|
} else {
|
|
temp2 = this->linearVelocity - (REG(48) / 100.0f);
|
|
|
|
if (temp2 < 0.0f) {
|
|
temp1 = 1.0f;
|
|
func_8084029C(this, (REG(35) / 1000.0f) + ((REG(36) / 1000.0f) * this->linearVelocity));
|
|
|
|
func_80841CC4(this, 0, play);
|
|
} else {
|
|
temp1 = (REG(37) / 1000.0f) * temp2;
|
|
if (temp1 < 1.0f) {
|
|
func_8084029C(this, (REG(35) / 1000.0f) + ((REG(36) / 1000.0f) * this->linearVelocity));
|
|
} else {
|
|
temp1 = 1.0f;
|
|
func_8084029C(this, 1.2f + ((REG(38) / 1000.0f) * temp2));
|
|
}
|
|
|
|
func_80841CC4(this, 1, play);
|
|
|
|
LinkAnimation_LoadToJoint(play, &this->skelAnime, func_80833438(this),
|
|
this->unk_868 * (20.0f / 29.0f));
|
|
}
|
|
}
|
|
|
|
if (temp1 < 1.0f) {
|
|
LinkAnimation_InterpJointMorph(play, &this->skelAnime, 1.0f - temp1);
|
|
}
|
|
}
|
|
|
|
void Player_Action_80842180(Player* this, PlayState* play) {
|
|
f32 sp2C;
|
|
s16 sp2A;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
func_80841EE4(this, play);
|
|
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList8, true)) {
|
|
if (func_80833C04(this)) {
|
|
func_8083C858(this, play);
|
|
return;
|
|
}
|
|
|
|
Player_GetMovementSpeedAndYaw(this, &sp2C, &sp2A, SPEED_MODE_CURVED, play);
|
|
|
|
if (!func_8083C484(this, &sp2C, &sp2A)) {
|
|
int32_t giSpeedModifier = GameInteractor_RunSpeedModifier();
|
|
if (giSpeedModifier != 0) {
|
|
if (giSpeedModifier > 0) {
|
|
sp2C *= giSpeedModifier;
|
|
} else {
|
|
sp2C /= abs(giSpeedModifier);
|
|
}
|
|
}
|
|
|
|
if (CVarGetInteger("gMMBunnyHood", BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA && this->currentMask == PLAYER_MASK_BUNNY) {
|
|
sp2C *= 1.5f;
|
|
}
|
|
|
|
if (CVarGetInteger("gEnableWalkModify", 0)) {
|
|
if (CVarGetInteger("gWalkSpeedToggle", 0)) {
|
|
if (gWalkSpeedToggle1) {
|
|
sp2C *= CVarGetFloat("gWalkModifierOne", 1.0f);
|
|
} else if (gWalkSpeedToggle2) {
|
|
sp2C *= CVarGetFloat("gWalkModifierTwo", 1.0f);
|
|
}
|
|
} else {
|
|
if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_MODIFIER1)) {
|
|
sp2C *= CVarGetFloat("gWalkModifierOne", 1.0f);
|
|
} else if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_MODIFIER2)) {
|
|
sp2C *= CVarGetFloat("gWalkModifierTwo", 1.0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
func_8083DF68(this, sp2C, sp2A);
|
|
func_8083DDC8(this, play);
|
|
|
|
if ((this->linearVelocity == 0.0f) && (sp2C == 0.0f)) {
|
|
func_8083C0B8(this, play);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084227C(Player* this, PlayState* play) {
|
|
f32 sp2C;
|
|
s16 sp2A;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
func_80841EE4(this, play);
|
|
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList9, true)) {
|
|
if (!func_80833C04(this)) {
|
|
func_8083C858(this, play);
|
|
return;
|
|
}
|
|
|
|
Player_GetMovementSpeedAndYaw(this, &sp2C, &sp2A, SPEED_MODE_LINEAR, play);
|
|
|
|
if (!func_8083C484(this, &sp2C, &sp2A)) {
|
|
if ((func_80833B2C(this) && (sp2C != 0.0f) && (func_8083FD78(this, &sp2C, &sp2A, play) <= 0)) ||
|
|
(!func_80833B2C(this) && (func_8083FC68(this, sp2C, sp2A) <= 0))) {
|
|
func_80839F90(this, play);
|
|
return;
|
|
}
|
|
|
|
func_8083DF68(this, sp2C, sp2A);
|
|
func_8083DDC8(this, play);
|
|
|
|
if ((this->linearVelocity == 0) && (sp2C == 0)) {
|
|
func_80839F90(this, play);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_808423EC(Player* this, PlayState* play) {
|
|
s32 sp34;
|
|
f32 sp30;
|
|
s16 sp2E;
|
|
|
|
sp34 = LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList5, true)) {
|
|
if (!func_80833C04(this)) {
|
|
func_8083C858(this, play);
|
|
return;
|
|
}
|
|
|
|
Player_GetMovementSpeedAndYaw(this, &sp30, &sp2E, SPEED_MODE_LINEAR, play);
|
|
|
|
if ((this->skelAnime.morphWeight == 0.0f) && (this->skelAnime.curFrame > 5.0f)) {
|
|
func_8083721C(this);
|
|
|
|
if ((this->skelAnime.curFrame > 10.0f) && (func_8083FC68(this, sp30, sp2E) < 0)) {
|
|
func_8083CBF0(this, sp2E, play);
|
|
return;
|
|
}
|
|
|
|
if (sp34 != 0) {
|
|
func_8083CD00(this, play);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084251C(Player* this, PlayState* play) {
|
|
s32 sp34;
|
|
f32 speedTarget;
|
|
s16 yawTarget;
|
|
|
|
sp34 = LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
func_8083721C(this);
|
|
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList10, true)) {
|
|
Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_LINEAR, play);
|
|
|
|
if (this->linearVelocity == 0.0f) {
|
|
this->yaw = this->actor.shape.rot.y;
|
|
|
|
if (func_8083FC68(this, speedTarget, yawTarget) > 0) {
|
|
func_8083C858(this, play);
|
|
return;
|
|
}
|
|
|
|
if ((speedTarget != 0.0f) || (sp34 != 0)) {
|
|
func_80839F90(this, play);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void func_8084260C(Vec3f* src, Vec3f* dest, f32 arg2, f32 arg3, f32 arg4) {
|
|
dest->x = (Rand_ZeroOne() * arg3) + src->x;
|
|
dest->y = (Rand_ZeroOne() * arg4) + (src->y + arg2);
|
|
dest->z = (Rand_ZeroOne() * arg3) + src->z;
|
|
}
|
|
|
|
static Vec3f D_808545B4 = { 0.0f, 0.0f, 0.0f };
|
|
static Vec3f D_808545C0 = { 0.0f, 0.0f, 0.0f };
|
|
|
|
s32 func_8084269C(PlayState* play, Player* this) {
|
|
Vec3f sp2C;
|
|
|
|
if ((this->floorSfxOffset == 0) || (this->floorSfxOffset == 1)) {
|
|
func_8084260C(&this->actor.shape.feetPos[FOOT_LEFT], &sp2C,
|
|
this->actor.floorHeight - this->actor.shape.feetPos[FOOT_LEFT].y, 7.0f, 5.0f);
|
|
func_800286CC(play, &sp2C, &D_808545B4, &D_808545C0, 50, 30);
|
|
func_8084260C(&this->actor.shape.feetPos[FOOT_RIGHT], &sp2C,
|
|
this->actor.floorHeight - this->actor.shape.feetPos[FOOT_RIGHT].y, 7.0f, 5.0f);
|
|
func_800286CC(play, &this->actor.shape.feetPos[FOOT_RIGHT], &D_808545B4, &D_808545C0, 50, 30);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Player_Action_8084279C(Player* this, PlayState* play) {
|
|
func_80832CB0(play, this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_check_wait, this->modelAnimType));
|
|
|
|
if (DECR(this->av2.actionVar2) == 0) {
|
|
if (!Player_ActionChange_13(this, play)) {
|
|
func_8083A098(this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_check_end, this->modelAnimType), play);
|
|
}
|
|
|
|
this->actor.flags &= ~ACTOR_FLAG_PLAYER_TALKED_TO;
|
|
func_8005B1A4(Play_GetCamera(play, 0));
|
|
}
|
|
}
|
|
|
|
s32 func_8084285C(Player* this, f32 arg1, f32 arg2, f32 arg3) {
|
|
if ((arg1 <= this->skelAnime.curFrame) && (this->skelAnime.curFrame <= arg3)) {
|
|
func_80833A20(this, (arg2 <= this->skelAnime.curFrame) ? 1 : -1);
|
|
return 1;
|
|
}
|
|
|
|
func_80832318(this);
|
|
return 0;
|
|
}
|
|
|
|
s32 func_808428D8(Player* this, PlayState* play) {
|
|
if (Player_IsChildWithHylianShield(this) || !Player_GetMeleeWeaponHeld(this) || !sUseHeldItem) {
|
|
return 0;
|
|
}
|
|
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_normal_defense_kiru);
|
|
this->av1.actionVar1 = 1;
|
|
this->meleeWeaponAnimation = PLAYER_MWA_STAB_1H;
|
|
this->yaw = this->actor.shape.rot.y + this->unk_6BE;
|
|
|
|
if (!CVarGetInteger("gCrouchStabHammerFix", 0)) {
|
|
return 1;
|
|
}
|
|
|
|
u32 swordId;
|
|
if (Player_HoldsBrokenKnife(this)) {
|
|
swordId = 1;
|
|
} else {
|
|
swordId = Player_GetMeleeWeaponHeld(this) - 1;
|
|
}
|
|
|
|
if (swordId != 4 && !CVarGetInteger("gCrouchStabFix", 0)) { // 4 = Megaton Hammer
|
|
return 1;
|
|
}
|
|
|
|
u32 flags = D_80854488[swordId][0];
|
|
func_80837918(this, 0, flags);
|
|
func_80837918(this, 1, flags);
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 func_80842964(Player* this, PlayState* play) {
|
|
return Player_ActionChange_13(this, play) || Player_ActionChange_4(this, play) || Player_ActionChange_2(this, play);
|
|
}
|
|
|
|
void Player_RequestQuake(PlayState* play, s32 speed, s32 y, s32 countdown) {
|
|
s32 quakeIndex = Quake_Add(Play_GetCamera(play, 0), 3);
|
|
|
|
Quake_SetSpeed(quakeIndex, speed);
|
|
Quake_SetQuakeValues(quakeIndex, y, 0, 0, 0);
|
|
Quake_SetCountdown(quakeIndex, countdown);
|
|
}
|
|
|
|
void func_80842A28(PlayState* play, Player* this) {
|
|
Player_RequestQuake(play, 27767, 7, 20);
|
|
play->actorCtx.unk_02 = 4;
|
|
Player_RequestRumble(this, 255, 20, 150, 0);
|
|
Player_PlaySfx(this, NA_SE_IT_HAMMER_HIT);
|
|
}
|
|
|
|
void func_80842A88(PlayState* play, Player* this) {
|
|
if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) {
|
|
Inventory_ChangeAmmo(ITEM_STICK, -1);
|
|
Player_UseItem(play, this, ITEM_NONE);
|
|
}
|
|
}
|
|
|
|
s32 func_80842AC4(PlayState* play, Player* this) {
|
|
if ((this->heldItemAction == PLAYER_IA_DEKU_STICK) && (this->unk_85C > 0.5f)) {
|
|
if (AMMO(ITEM_STICK) != 0 && CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) {
|
|
EffectSsStick_Spawn(play, &this->bodyPartsPos[PLAYER_BODYPART_R_HAND],
|
|
this->actor.shape.rot.y + 0x8000);
|
|
this->unk_85C = 0.5f;
|
|
func_80842A88(play, this);
|
|
Player_PlaySfx(this, NA_SE_IT_WOODSTICK_BROKEN);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_80842B7C(PlayState* play, Player* this) {
|
|
if (this->heldItemAction == PLAYER_IA_SWORD_BIGGORON) {
|
|
if (!gSaveContext.bgsFlag && (gSaveContext.swordHealth > 0.0f)) {
|
|
if ((gSaveContext.swordHealth -= 1.0f) <= 0.0f) {
|
|
EffectSsStick_Spawn(play, &this->bodyPartsPos[PLAYER_BODYPART_R_HAND],
|
|
this->actor.shape.rot.y + 0x8000);
|
|
func_800849EC(play);
|
|
Player_PlaySfx(this, NA_SE_IT_MAJIN_SWORD_BROKEN);
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_80842CF0(PlayState* play, Player* this) {
|
|
func_80842AC4(play, this);
|
|
func_80842B7C(play, this);
|
|
}
|
|
|
|
static LinkAnimationHeader* D_808545CC[] = {
|
|
&gPlayerAnim_link_fighter_rebound,
|
|
&gPlayerAnim_link_fighter_rebound_long,
|
|
&gPlayerAnim_link_fighter_reboundR,
|
|
&gPlayerAnim_link_fighter_rebound_longR,
|
|
};
|
|
|
|
void func_80842D20(PlayState* play, Player* this) {
|
|
s32 pad;
|
|
s32 sp28;
|
|
|
|
if (Player_Action_80843188 != this->actionFunc) {
|
|
func_80832440(play, this);
|
|
Player_SetupAction(play, this, Player_Action_808505DC, 0);
|
|
|
|
if (func_8008E9C4(this)) {
|
|
sp28 = 2;
|
|
} else {
|
|
sp28 = 0;
|
|
}
|
|
|
|
Player_AnimPlayOnceAdjusted(play, this, D_808545CC[Player_HoldsTwoHandedWeapon(this) + sp28]);
|
|
}
|
|
|
|
Player_RequestRumble(this, 180, 20, 100, 0);
|
|
this->linearVelocity = -18.0f;
|
|
func_80842CF0(play, this);
|
|
}
|
|
|
|
s32 func_80842DF4(PlayState* play, Player* this) {
|
|
f32 phi_f2;
|
|
CollisionPoly* sp78;
|
|
s32 sp74;
|
|
Vec3f sp68;
|
|
Vec3f sp5C;
|
|
Vec3f sp50;
|
|
s32 temp1;
|
|
s32 sp48;
|
|
|
|
if (this->meleeWeaponState > 0) {
|
|
if (this->meleeWeaponAnimation < PLAYER_MWA_SPIN_ATTACK_1H) {
|
|
if (!(this->meleeWeaponQuads[0].base.atFlags & AT_BOUNCED) && !(this->meleeWeaponQuads[1].base.atFlags & AT_BOUNCED)) {
|
|
if (this->skelAnime.curFrame >= 2.0f) {
|
|
|
|
phi_f2 = Math_Vec3f_DistXYZAndStoreDiff(&this->meleeWeaponInfo[0].tip, &this->meleeWeaponInfo[0].base, &sp50);
|
|
if (phi_f2 != 0.0f) {
|
|
phi_f2 = (phi_f2 + 10.0f) / phi_f2;
|
|
}
|
|
|
|
sp68.x = this->meleeWeaponInfo[0].tip.x + (sp50.x * phi_f2);
|
|
sp68.y = this->meleeWeaponInfo[0].tip.y + (sp50.y * phi_f2);
|
|
sp68.z = this->meleeWeaponInfo[0].tip.z + (sp50.z * phi_f2);
|
|
|
|
if (BgCheck_EntityLineTest1(&play->colCtx, &sp68, &this->meleeWeaponInfo[0].tip, &sp5C, &sp78, true,
|
|
false, false, true, &sp74) &&
|
|
!SurfaceType_IsIgnoredByEntities(&play->colCtx, sp78, sp74) &&
|
|
(func_80041D4C(&play->colCtx, sp78, sp74) != 6) &&
|
|
(func_8002F9EC(play, &this->actor, sp78, sp74, &sp5C) == 0)) {
|
|
|
|
if (this->heldItemAction == PLAYER_IA_HAMMER) {
|
|
func_80832630(play);
|
|
func_80842A28(play, this);
|
|
func_80842D20(play, this);
|
|
return 1;
|
|
}
|
|
|
|
if (this->linearVelocity >= 0.0f) {
|
|
sp48 = func_80041F10(&play->colCtx, sp78, sp74);
|
|
|
|
if (sp48 == 0xA) {
|
|
CollisionCheck_SpawnShieldParticlesWood(play, &sp5C, &this->actor.projectedPos);
|
|
} else {
|
|
CollisionCheck_SpawnShieldParticles(play, &sp5C);
|
|
if (sp48 == 0xB) {
|
|
Player_PlaySfx(this, NA_SE_IT_WALL_HIT_SOFT);
|
|
} else {
|
|
Player_PlaySfx(this, NA_SE_IT_WALL_HIT_HARD);
|
|
}
|
|
}
|
|
|
|
func_80842CF0(play, this);
|
|
this->linearVelocity = -14.0f;
|
|
Player_RequestRumble(this, 180, 20, 100, 0);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
func_80842D20(play, this);
|
|
func_80832630(play);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
temp1 = (this->meleeWeaponQuads[0].base.atFlags & AT_HIT) || (this->meleeWeaponQuads[1].base.atFlags & AT_HIT);
|
|
|
|
if (temp1) {
|
|
if (this->meleeWeaponAnimation < PLAYER_MWA_SPIN_ATTACK_1H) {
|
|
Actor* at = this->meleeWeaponQuads[temp1 ? 1 : 0].base.at;
|
|
|
|
if ((at != NULL) && (at->id != ACTOR_EN_KANBAN)) {
|
|
func_80832630(play);
|
|
}
|
|
}
|
|
|
|
if ((func_80842AC4(play, this) == 0) && (this->heldItemAction != PLAYER_IA_HAMMER)) {
|
|
func_80842B7C(play, this);
|
|
|
|
if (this->actor.colChkInfo.atHitEffect == 1) {
|
|
this->actor.colChkInfo.damage = 8;
|
|
func_80837C0C(play, this, 4, 0.0f, 0.0f, this->actor.shape.rot.y, 20);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Player_Action_80843188(Player* this, PlayState* play) {
|
|
f32 sp54;
|
|
f32 sp50;
|
|
s16 sp4E;
|
|
s16 sp4C;
|
|
s16 sp4A;
|
|
s16 sp48;
|
|
s16 sp46;
|
|
f32 sp40;
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (!Player_IsChildWithHylianShield(this)) {
|
|
Player_AnimPlayLoop(play, this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_defense_wait, this->modelAnimType));
|
|
}
|
|
this->av2.actionVar2 = 1;
|
|
this->av1.actionVar1 = 0;
|
|
}
|
|
|
|
if (!Player_IsChildWithHylianShield(this)) {
|
|
this->stateFlags1 |= PLAYER_STATE1_SHIELDING;
|
|
Player_UpdateUpperBody(this, play);
|
|
this->stateFlags1 &= ~PLAYER_STATE1_SHIELDING;
|
|
}
|
|
|
|
func_8083721C(this);
|
|
|
|
if (this->av2.actionVar2 != 0) {
|
|
sp54 = sControlInput->rel.stick_y * 100 * (CVarGetInteger("gInvertShieldAimingYAxis", 1) ? 1 : -1);
|
|
sp50 = sControlInput->rel.stick_x * (CVarGetInteger("gMirroredWorld", 0) ? 120 : -120) * (CVarGetInteger("gInvertShieldAimingXAxis", 0) ? -1 : 1);
|
|
sp4E = this->actor.shape.rot.y - Camera_GetInputDirYaw(GET_ACTIVE_CAM(play));
|
|
|
|
sp40 = Math_CosS(sp4E);
|
|
sp4C = (Math_SinS(sp4E) * sp50) + (sp54 * sp40);
|
|
sp40 = Math_CosS(sp4E);
|
|
sp4A = (sp50 * sp40) - (Math_SinS(sp4E) * sp54);
|
|
|
|
if (sp4C > 3500) {
|
|
sp4C = 3500;
|
|
}
|
|
|
|
sp48 = ABS(sp4C - this->actor.focus.rot.x) * 0.25f;
|
|
if (sp48 < 100) {
|
|
sp48 = 100;
|
|
}
|
|
|
|
sp46 = ABS(sp4A - this->unk_6BE) * 0.25f;
|
|
if (sp46 < 50) {
|
|
sp46 = 50;
|
|
}
|
|
|
|
Math_ScaledStepToS(&this->actor.focus.rot.x, sp4C, sp48);
|
|
this->unk_6BC = this->actor.focus.rot.x;
|
|
Math_ScaledStepToS(&this->unk_6BE, sp4A, sp46);
|
|
|
|
if (this->av1.actionVar1 != 0) {
|
|
if (!func_80842DF4(play, this)) {
|
|
if (this->skelAnime.curFrame < 2.0f) {
|
|
func_80833A20(this, 1);
|
|
}
|
|
} else {
|
|
this->av2.actionVar2 = 1;
|
|
this->av1.actionVar1 = 0;
|
|
}
|
|
} else if (!func_80842964(this, play)) {
|
|
if (Player_ActionChange_11(this, play)) {
|
|
func_808428D8(this, play);
|
|
} else {
|
|
this->stateFlags1 &= ~PLAYER_STATE1_SHIELDING;
|
|
func_80832318(this);
|
|
|
|
if (Player_IsChildWithHylianShield(this)) {
|
|
func_8083A060(this, play);
|
|
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_clink_normal_defense_ALL, 1.0f,
|
|
Animation_GetLastFrame(&gPlayerAnim_clink_normal_defense_ALL), 0.0f,
|
|
ANIMMODE_ONCE, 0.0f);
|
|
Player_AnimReplaceApplyFlags(play, this, 4);
|
|
} else {
|
|
if (this->itemAction < 0) {
|
|
func_8008EC70(this);
|
|
}
|
|
func_8083A098(this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_defense_end, this->modelAnimType), play);
|
|
}
|
|
|
|
Player_PlaySfx(this, NA_SE_IT_SHIELD_REMOVE);
|
|
return;
|
|
}
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_SHIELDING;
|
|
Player_SetModelsForHoldingShield(this);
|
|
|
|
this->unk_6AE |= 0xC1;
|
|
}
|
|
|
|
void Player_Action_808435C4(Player* this, PlayState* play) {
|
|
s32 temp;
|
|
LinkAnimationHeader* anim;
|
|
f32 frames;
|
|
|
|
func_8083721C(this);
|
|
|
|
if (this->av1.actionVar1 == 0) {
|
|
D_808535E0 = Player_UpdateUpperBody(this, play);
|
|
if ((func_80834B5C == this->upperActionFunc) || (func_808374A0(play, this, &this->upperSkelAnime, 4.0f) > 0)) {
|
|
Player_SetupAction(play, this, Player_Action_80840450, 1);
|
|
}
|
|
} else {
|
|
temp = func_808374A0(play, this, &this->skelAnime, 4.0f);
|
|
if ((temp != 0) && ((temp > 0) || LinkAnimation_Update(play, &this->skelAnime))) {
|
|
Player_SetupAction(play, this, Player_Action_80843188, 1);
|
|
this->stateFlags1 |= PLAYER_STATE1_SHIELDING;
|
|
Player_SetModelsForHoldingShield(this);
|
|
anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_defense, this->modelAnimType);
|
|
frames = Animation_GetLastFrame(anim);
|
|
LinkAnimation_Change(play, &this->skelAnime, anim, 1.0f, frames, frames, ANIMMODE_ONCE, 0.0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084370C(Player* this, PlayState* play) {
|
|
s32 sp1C;
|
|
|
|
func_8083721C(this);
|
|
|
|
sp1C = func_808374A0(play, this, &this->skelAnime, 16.0f);
|
|
if ((sp1C != 0) && (LinkAnimation_Update(play, &this->skelAnime) || (sp1C > 0))) {
|
|
func_80839F90(this, play);
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084377C(Player* this, PlayState* play) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET | PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
|
|
func_808382BC(this);
|
|
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_IN_CUTSCENE) && (this->av2.actionVar2 == 0) && (this->unk_8A1 != 0)) {
|
|
s16 temp = this->actor.shape.rot.y - this->unk_8A2;
|
|
|
|
this->yaw = this->actor.shape.rot.y = this->unk_8A2;
|
|
this->linearVelocity = this->unk_8A4;
|
|
|
|
if (ABS(temp) > 0x4000) {
|
|
this->actor.shape.rot.y = this->unk_8A2 + 0x8000;
|
|
}
|
|
|
|
if (this->actor.velocity.y < 0.0f) {
|
|
this->actor.gravity = 0.0f;
|
|
this->actor.velocity.y = 0.0f;
|
|
}
|
|
}
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime) && (this->actor.bgCheckFlags & 1)) {
|
|
if (this->av2.actionVar2 != 0) {
|
|
this->av2.actionVar2--;
|
|
if (this->av2.actionVar2 == 0) {
|
|
func_80853080(this, play);
|
|
}
|
|
} else if ((this->stateFlags1 & PLAYER_STATE1_IN_CUTSCENE) ||
|
|
(!(this->cylinder.base.acFlags & AC_HIT) && (this->unk_8A1 == 0))) {
|
|
if (this->stateFlags1 & PLAYER_STATE1_IN_CUTSCENE) {
|
|
this->av2.actionVar2++;
|
|
} else {
|
|
Player_SetupAction(play, this, Player_Action_80843954, 0);
|
|
this->stateFlags1 |= PLAYER_STATE1_DAMAGED;
|
|
}
|
|
|
|
Player_AnimPlayOnce(play, this,
|
|
(this->yaw != this->actor.shape.rot.y) ? &gPlayerAnim_link_normal_front_downB
|
|
: &gPlayerAnim_link_normal_back_downB);
|
|
func_80832698(this, NA_SE_VO_LI_FREEZE);
|
|
}
|
|
}
|
|
|
|
if (this->actor.bgCheckFlags & 2) {
|
|
func_80832770(this, NA_SE_PL_BOUND);
|
|
}
|
|
}
|
|
|
|
void Player_Action_80843954(Player* this, PlayState* play) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET | PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
func_808382BC(this);
|
|
|
|
func_8083721C(this);
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime) && (this->linearVelocity == 0.0f)) {
|
|
if (this->stateFlags1 & PLAYER_STATE1_IN_CUTSCENE) {
|
|
this->av2.actionVar2++;
|
|
} else {
|
|
Player_SetupAction(play, this, Player_Action_80843A38, 0);
|
|
this->stateFlags1 |= PLAYER_STATE1_DAMAGED;
|
|
}
|
|
|
|
Player_AnimPlayOnceAdjusted(play, this,
|
|
(this->yaw != this->actor.shape.rot.y) ? &gPlayerAnim_link_normal_front_down_wake
|
|
: &gPlayerAnim_link_normal_back_down_wake);
|
|
this->yaw = this->actor.shape.rot.y;
|
|
}
|
|
}
|
|
|
|
static AnimSfxEntry D_808545DC[] = {
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_8, 20) },
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_8, 30) },
|
|
};
|
|
|
|
void Player_Action_80843A38(Player* this, PlayState* play) {
|
|
s32 sp24;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
func_808382BC(this);
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_IN_CUTSCENE) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
} else {
|
|
sp24 = func_808374A0(play, this, &this->skelAnime, 16.0f);
|
|
if ((sp24 != 0) && (LinkAnimation_Update(play, &this->skelAnime) || (sp24 > 0))) {
|
|
func_80839F90(this, play);
|
|
}
|
|
}
|
|
|
|
Player_ProcessAnimSfxList(this, D_808545DC);
|
|
}
|
|
|
|
static Vec3f D_808545E4 = { 0.0f, 0.0f, 5.0f };
|
|
|
|
void func_80843AE8(PlayState* play, Player* this) {
|
|
if (this->av2.actionVar2 != 0) {
|
|
if (this->av2.actionVar2 > 0) {
|
|
this->av2.actionVar2--;
|
|
if (this->av2.actionVar2 == 0) {
|
|
if (this->stateFlags1 & PLAYER_STATE1_IN_WATER) {
|
|
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_swimer_swim_wait, 1.0f, 0.0f,
|
|
Animation_GetLastFrame(&gPlayerAnim_link_swimer_swim_wait), ANIMMODE_ONCE,
|
|
-16.0f);
|
|
} else {
|
|
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_derth_rebirth, 1.0f, 99.0f,
|
|
Animation_GetLastFrame(&gPlayerAnim_link_derth_rebirth), ANIMMODE_ONCE, 0.0f);
|
|
}
|
|
if (CVarGetInteger("gFairyReviveEffect", 0)) {
|
|
if (CVarGetInteger("gFairyRevivePercentRestore", 0)) {
|
|
gSaveContext.healthAccumulator =
|
|
(gSaveContext.healthCapacity * CVarGetInteger("gFairyReviveHealth", 100) / 100 + 15) / 16 * 16;
|
|
} else {
|
|
gSaveContext.healthAccumulator = CVarGetInteger("gFairyReviveHealth", 20) * 16;
|
|
}
|
|
} else {
|
|
gSaveContext.healthAccumulator = 0x140;
|
|
}
|
|
this->av2.actionVar2 = -1;
|
|
}
|
|
} else if (gSaveContext.healthAccumulator == 0) {
|
|
this->stateFlags1 &= ~PLAYER_STATE1_DEAD;
|
|
if (this->stateFlags1 & PLAYER_STATE1_IN_WATER) {
|
|
func_80838F18(play, this);
|
|
} else {
|
|
func_80853080(this, play);
|
|
}
|
|
this->unk_A87 = 20;
|
|
func_80837AFC(this, -20);
|
|
func_800F47FC();
|
|
}
|
|
} else if (this->av1.actionVar1 != 0) {
|
|
this->av2.actionVar2 = 60;
|
|
Player_SpawnFairy(play, this, &this->actor.world.pos, &D_808545E4, FAIRY_REVIVE_DEATH);
|
|
Player_PlaySfx(this, NA_SE_EV_FIATY_HEAL - SFX_FLAG);
|
|
OnePointCutscene_Init(play, 9908, 125, &this->actor, MAIN_CAM);
|
|
} else if (play->gameOverCtx.state == GAMEOVER_DEATH_WAIT_GROUND) {
|
|
play->gameOverCtx.state = GAMEOVER_DEATH_DELAY_MENU;
|
|
sMaskMemory = PLAYER_MASK_NONE;
|
|
}
|
|
}
|
|
|
|
static AnimSfxEntry D_808545F0[] = {
|
|
{ NA_SE_PL_BOUND, ANIMSFX_DATA(ANIMSFX_TYPE_2, 60) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_8, 140) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_8, 164) },
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_8, 170) },
|
|
};
|
|
|
|
void Player_Action_80843CEC(Player* this, PlayState* play) {
|
|
if (this->currentTunic != PLAYER_TUNIC_GORON && CVarGetInteger("gSuperTunic", 0) == 0) {
|
|
if ((play->roomCtx.curRoom.behaviorType2 == ROOM_BEHAVIOR_TYPE2_3) || (sFloorType == 9) ||
|
|
((func_80838144(sFloorType) >= 0) &&
|
|
!SurfaceType_IsWallDamage(&play->colCtx, this->actor.floorPoly, this->actor.floorBgId))) {
|
|
func_8083821C(this);
|
|
}
|
|
}
|
|
|
|
func_8083721C(this);
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (this->actor.category == ACTORCAT_PLAYER) {
|
|
func_80843AE8(play, this);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (this->skelAnime.animation == &gPlayerAnim_link_derth_rebirth) {
|
|
Player_ProcessAnimSfxList(this, D_808545F0);
|
|
} else if (this->skelAnime.animation == &gPlayerAnim_link_normal_electric_shock_end) {
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 88.0f)) {
|
|
func_80832770(this, NA_SE_PL_BOUND);
|
|
}
|
|
}
|
|
}
|
|
|
|
void func_80843E14(Player* this, u16 sfxId) {
|
|
func_80832698(this, sfxId);
|
|
|
|
if ((this->heldActor != NULL) && (this->heldActor->id == ACTOR_EN_RU1)) {
|
|
Audio_PlayActorSound2(this->heldActor, NA_SE_VO_RT_FALL);
|
|
}
|
|
}
|
|
|
|
static FallImpactInfo D_80854600[] = {
|
|
{ -8, 180, 40, 100, NA_SE_VO_LI_LAND_DAMAGE_S },
|
|
{ -16, 255, 140, 150, NA_SE_VO_LI_LAND_DAMAGE_S },
|
|
};
|
|
|
|
s32 func_80843E64(PlayState* play, Player* this) {
|
|
s32 sp34;
|
|
|
|
if ((sFloorType == 6) || (sFloorType == 9)) {
|
|
sp34 = 0;
|
|
} else {
|
|
sp34 = this->fallDistance;
|
|
}
|
|
|
|
Math_StepToF(&this->linearVelocity, 0.0f, 1.0f);
|
|
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_JUMPING | PLAYER_STATE1_FREEFALL);
|
|
|
|
if (sp34 >= 400) {
|
|
s32 impactIndex;
|
|
FallImpactInfo* impactInfo;
|
|
|
|
if (this->fallDistance < 800) {
|
|
impactIndex = 0;
|
|
} else {
|
|
impactIndex = 1;
|
|
}
|
|
|
|
impactInfo = &D_80854600[impactIndex];
|
|
|
|
if (Player_InflictDamageModified(play, impactInfo->damage * (1 << CVarGetInteger("gFallDamageMul", 0)),
|
|
false)) {
|
|
return -1;
|
|
}
|
|
|
|
func_80837AE0(this, 40);
|
|
Player_RequestQuake(play, 32967, 2, 30);
|
|
Player_RequestRumble(this, impactInfo->rumbleStrength, impactInfo->rumbleDuration, impactInfo->rumbleDecreaseRate, 0);
|
|
Player_PlaySfx(this, NA_SE_PL_BODY_HIT);
|
|
func_80832698(this, impactInfo->sfxId);
|
|
|
|
return impactIndex + 1;
|
|
}
|
|
|
|
if (sp34 > 200) {
|
|
sp34 *= 2;
|
|
|
|
if (sp34 > 255) {
|
|
sp34 = 255;
|
|
}
|
|
|
|
Player_RequestRumble(this, (u8)sp34, (u8)(sp34 * 0.1f), (u8)sp34, 0);
|
|
|
|
if (sFloorType == 6) {
|
|
func_80832698(this, NA_SE_VO_LI_CLIMB_END);
|
|
}
|
|
}
|
|
|
|
func_808328A0(this);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8084409C(PlayState* play, Player* this, f32 speedXZ, f32 velocityY) {
|
|
Actor* heldActor = this->heldActor;
|
|
|
|
if (!func_80835644(play, this, heldActor)) {
|
|
heldActor->world.rot.y = this->actor.shape.rot.y;
|
|
heldActor->speedXZ = speedXZ;
|
|
heldActor->velocity.y = velocityY;
|
|
func_80834644(play, this);
|
|
Player_PlaySfx(this, NA_SE_PL_THROW);
|
|
func_80832698(this, NA_SE_VO_LI_SWORD_N);
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084411C(Player* this, PlayState* play) {
|
|
f32 sp4C;
|
|
s16 sp4A;
|
|
|
|
if (gSaveContext.respawn[RESPAWN_MODE_TOP].data > 40) {
|
|
this->actor.gravity = 0.0f;
|
|
} else if (func_8008E9C4(this)) {
|
|
this->actor.gravity = -1.2f;
|
|
}
|
|
|
|
Player_GetMovementSpeedAndYaw(this, &sp4C, &sp4A, SPEED_MODE_LINEAR, play);
|
|
|
|
if (!(this->actor.bgCheckFlags & 1)) {
|
|
if (this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) {
|
|
Actor* heldActor = this->heldActor;
|
|
|
|
u16 buttonsToCheck = BTN_A | BTN_B | BTN_CLEFT | BTN_CRIGHT | BTN_CDOWN;
|
|
if (CVarGetInteger("gDpadEquips", 0) != 0) {
|
|
buttonsToCheck |= BTN_DUP | BTN_DDOWN | BTN_DLEFT | BTN_DRIGHT;
|
|
}
|
|
if (!func_80835644(play, this, heldActor) && (heldActor->id == ACTOR_EN_NIW) &&
|
|
CHECK_BTN_ANY(sControlInput->press.button, buttonsToCheck)) {
|
|
func_8084409C(play, this, this->linearVelocity + 2.0f, this->actor.velocity.y + 2.0f);
|
|
}
|
|
}
|
|
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (!(this->stateFlags2 & PLAYER_STATE2_HOPPING)) {
|
|
func_8083DFE0(this, &sp4C, &sp4A);
|
|
}
|
|
|
|
Player_UpdateUpperBody(this, play);
|
|
|
|
if (((this->stateFlags2 & PLAYER_STATE2_HOPPING) && (this->av1.actionVar1 == 2)) || !func_8083BBA0(this, play)) {
|
|
if (this->actor.velocity.y < 0.0f) {
|
|
if (this->av2.actionVar2 >= 0) {
|
|
if ((this->actor.bgCheckFlags & 8) || (this->av2.actionVar2 == 0) || (this->fallDistance > 0)) {
|
|
if ((sYDistToFloor > 800.0f) || (this->stateFlags1 & PLAYER_STATE1_HOOKSHOT_FALLING)) {
|
|
func_80843E14(this, NA_SE_VO_LI_FALL_S);
|
|
this->stateFlags1 &= ~PLAYER_STATE1_HOOKSHOT_FALLING;
|
|
}
|
|
|
|
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_normal_landing, 1.0f, 0.0f,
|
|
0.0f, ANIMMODE_ONCE, 8.0f);
|
|
this->av2.actionVar2 = -1;
|
|
}
|
|
} else {
|
|
if ((this->av2.actionVar2 == -1) && (this->fallDistance > 120.0f) && (sYDistToFloor > 280.0f)) {
|
|
this->av2.actionVar2 = -2;
|
|
func_80843E14(this, NA_SE_VO_LI_FALL_L);
|
|
}
|
|
|
|
if (!GameInteractor_GetDisableLedgeGrabsActive() && (this->actor.bgCheckFlags & 0x200) &&
|
|
!(this->stateFlags2 & PLAYER_STATE2_HOPPING) &&
|
|
!(this->stateFlags1 & (PLAYER_STATE1_ITEM_OVER_HEAD | PLAYER_STATE1_IN_WATER)) && (this->linearVelocity > 0.0f)) {
|
|
if ((this->yDistToLedge >= 150.0f) && (this->unk_84B[this->unk_846] == 0)) {
|
|
func_8083EC18(this, play, sTouchedWallFlags);
|
|
} else if ((this->ledgeClimbType >= 2) && (this->yDistToLedge < 150.0f) &&
|
|
(((this->actor.world.pos.y - this->actor.floorHeight) + this->yDistToLedge) >
|
|
(70.0f * this->ageProperties->unk_08))) {
|
|
AnimationContext_DisableQueue(play);
|
|
if (this->stateFlags1 & PLAYER_STATE1_HOOKSHOT_FALLING) {
|
|
func_80832698(this, NA_SE_VO_LI_HOOKSHOT_HANG);
|
|
} else {
|
|
func_80832698(this, NA_SE_VO_LI_HANG);
|
|
}
|
|
this->actor.world.pos.y += this->yDistToLedge;
|
|
func_8083A5C4(play, this, this->actor.wallPoly, this->distToInteractWall,
|
|
GET_PLAYER_ANIM(PLAYER_ANIMGROUP_jump_climb_hold, this->modelAnimType));
|
|
this->actor.shape.rot.y = this->yaw += 0x8000;
|
|
this->stateFlags1 |= PLAYER_STATE1_HANGING_OFF_LEDGE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
LinkAnimationHeader* anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_landing, this->modelAnimType);
|
|
s32 sp3C;
|
|
|
|
if (this->stateFlags2 & PLAYER_STATE2_HOPPING) {
|
|
if (func_8008E9C4(this)) {
|
|
anim = D_80853D4C[this->av1.actionVar1][2];
|
|
} else {
|
|
anim = D_80853D4C[this->av1.actionVar1][1];
|
|
}
|
|
} else if (this->skelAnime.animation == &gPlayerAnim_link_normal_run_jump) {
|
|
anim = &gPlayerAnim_link_normal_run_jump_end;
|
|
} else if (func_8008E9C4(this)) {
|
|
anim = &gPlayerAnim_link_anchor_landingR;
|
|
func_80833C3C(this);
|
|
} else if (this->fallDistance <= 80) {
|
|
anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_short_landing, this->modelAnimType);
|
|
} else if ((this->fallDistance < 800) && (this->unk_84B[this->unk_846] == 0) &&
|
|
!(this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD)) {
|
|
func_8083BC04(this, play);
|
|
return;
|
|
}
|
|
|
|
sp3C = func_80843E64(play, this);
|
|
|
|
if (sp3C > 0) {
|
|
func_8083A098(this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_landing, this->modelAnimType), play);
|
|
this->skelAnime.endFrame = 8.0f;
|
|
if (sp3C == 1) {
|
|
this->av2.actionVar2 = 10;
|
|
} else {
|
|
this->av2.actionVar2 = 20;
|
|
}
|
|
} else if (sp3C == 0) {
|
|
func_8083A098(this, anim, play);
|
|
}
|
|
}
|
|
}
|
|
|
|
static AnimSfxEntry D_8085460C[] = {
|
|
{ NA_SE_VO_LI_SWORD_N, ANIMSFX_DATA(ANIMSFX_TYPE_4, 1) },
|
|
{ NA_SE_PL_WALK_GROUND, ANIMSFX_DATA(ANIMSFX_TYPE_3, 6) },
|
|
{ NA_SE_PL_ROLL, ANIMSFX_DATA(ANIMSFX_TYPE_1, 6) },
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_5, 18) },
|
|
};
|
|
|
|
void Player_Action_80844708(Player* this, PlayState* play) {
|
|
Actor* cylinderOc;
|
|
s32 temp;
|
|
s32 sp44;
|
|
DynaPolyActor* wallPolyActor;
|
|
s32 pad;
|
|
f32 sp38;
|
|
s16 sp36;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
|
|
cylinderOc = NULL;
|
|
sp44 = LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 8.0f)) {
|
|
func_80837AFC(this, -10);
|
|
}
|
|
|
|
if (func_80842964(this, play) == 0) {
|
|
if (this->av2.actionVar2 != 0) {
|
|
Math_StepToF(&this->linearVelocity, 0.0f, 2.0f);
|
|
|
|
temp = func_808374A0(play, this, &this->skelAnime, 5.0f);
|
|
if ((temp != 0) && ((temp > 0) || sp44)) {
|
|
func_8083A060(this, play);
|
|
}
|
|
} else {
|
|
f32 rand = Rand_ZeroOne();
|
|
uint8_t randomBonk = (rand <= .05) && GameInteractor_GetRandomBonksActive();
|
|
if (this->linearVelocity >= 7.0f) {
|
|
if (randomBonk || ((this->actor.bgCheckFlags & 0x200) && (sWorldYawToTouchedWall < 0x2000)) ||
|
|
((this->cylinder.base.ocFlags1 & OC1_HIT) &&
|
|
(cylinderOc = this->cylinder.base.oc,
|
|
((cylinderOc->id == ACTOR_EN_WOOD02) &&
|
|
(ABS((s16)(this->actor.world.rot.y - cylinderOc->yawTowardsPlayer)) > 0x6000))))) {
|
|
|
|
if (cylinderOc != NULL) {
|
|
cylinderOc->home.rot.y = 1;
|
|
} else if (this->actor.wallBgId != BGCHECK_SCENE) {
|
|
wallPolyActor = DynaPoly_GetActor(&play->colCtx, this->actor.wallBgId);
|
|
if ((wallPolyActor != NULL) && (wallPolyActor->actor.id == ACTOR_OBJ_KIBAKO2)) {
|
|
wallPolyActor->actor.home.rot.z = 1;
|
|
}
|
|
}
|
|
|
|
Player_AnimPlayOnce(play, this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_hip_down, this->modelAnimType));
|
|
this->linearVelocity = -this->linearVelocity;
|
|
Player_RequestQuake(play, 33267, 3, 12);
|
|
Player_RequestRumble(this, 255, 20, 150, 0);
|
|
Player_PlaySfx(this, NA_SE_PL_BODY_HIT);
|
|
func_80832698(this, NA_SE_VO_LI_CLIMB_END);
|
|
this->av2.actionVar2 = 1;
|
|
gSaveContext.sohStats.count[COUNT_BONKS]++;
|
|
GameInteractor_ExecuteOnPlayerBonk();
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ((this->skelAnime.curFrame < 15.0f) || !Player_ActionChange_7(this, play)) {
|
|
if (this->skelAnime.curFrame >= 20.0f) {
|
|
func_8083A060(this, play);
|
|
return;
|
|
}
|
|
|
|
Player_GetMovementSpeedAndYaw(this, &sp38, &sp36, SPEED_MODE_CURVED, play);
|
|
|
|
sp38 *= 1.5f;
|
|
if ((sp38 < 3.0f) || (this->unk_84B[this->unk_846] != 0)) {
|
|
sp38 = 3.0f;
|
|
}
|
|
|
|
func_8083DF68(this, sp38, this->actor.shape.rot.y);
|
|
|
|
if (func_8084269C(play, this)) {
|
|
func_8002F8F0(&this->actor, NA_SE_PL_ROLL_DUST - SFX_FLAG);
|
|
}
|
|
|
|
Player_ProcessAnimSfxList(this, D_8085460C);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_80844A44(Player* this, PlayState* play) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimPlayLoop(play, this, &gPlayerAnim_link_normal_run_jump_water_fall_wait);
|
|
}
|
|
|
|
Math_StepToF(&this->linearVelocity, 0.0f, 0.05f);
|
|
|
|
if (this->actor.bgCheckFlags & 1) {
|
|
this->actor.colChkInfo.damage = 0x10;
|
|
func_80837C0C(play, this, 1, 4.0f, 5.0f, this->actor.shape.rot.y, 20);
|
|
}
|
|
}
|
|
|
|
void Player_Action_80844AF4(Player* this, PlayState* play) {
|
|
f32 sp2C;
|
|
s16 sp2A;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
|
|
this->actor.gravity = -1.2f;
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (!func_80842DF4(play, this)) {
|
|
func_8084285C(this, 6.0f, 7.0f, 99.0f);
|
|
|
|
if (!(this->actor.bgCheckFlags & 1)) {
|
|
Player_GetMovementSpeedAndYaw(this, &sp2C, &sp2A, SPEED_MODE_LINEAR, play);
|
|
func_8083DFE0(this, &sp2C, &this->yaw);
|
|
return;
|
|
}
|
|
|
|
if (func_80843E64(play, this) >= 0) {
|
|
this->meleeWeaponAnimation += 2;
|
|
func_80837948(play, this, this->meleeWeaponAnimation);
|
|
this->unk_845 = 3;
|
|
func_808328A0(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
s32 func_80844BE4(Player* this, PlayState* play) {
|
|
s32 temp;
|
|
|
|
if (Player_StartCsAction(play, this)) {
|
|
this->stateFlags2 |= PLAYER_STATE2_SPIN_ATTACKING;
|
|
} else {
|
|
if (!CHECK_BTN_ALL(sControlInput->cur.button, BTN_B)) {
|
|
if ((this->unk_858 >= 0.85f) || func_808375D8(this)) {
|
|
temp = D_80854384[Player_HoldsTwoHandedWeapon(this)];
|
|
} else {
|
|
temp = D_80854380[Player_HoldsTwoHandedWeapon(this)];
|
|
}
|
|
|
|
func_80837948(play, this, temp);
|
|
func_80837AFC(this, -8);
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_SPIN_ATTACKING;
|
|
if (this->unk_84B[this->unk_846] == 0) {
|
|
this->stateFlags2 |= PLAYER_STATE2_SWORD_LUNGE;
|
|
}
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void func_80844CF8(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_80845000, 1);
|
|
}
|
|
|
|
void func_80844D30(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_80845308, 1);
|
|
}
|
|
|
|
void func_80844D68(Player* this, PlayState* play) {
|
|
func_80839FFC(this, play);
|
|
func_80832318(this);
|
|
Player_AnimChangeOnceMorph(play, this, D_80854368[Player_HoldsTwoHandedWeapon(this)]);
|
|
this->yaw = this->actor.shape.rot.y;
|
|
}
|
|
|
|
void func_80844DC8(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_80844E68, 1);
|
|
this->unk_868 = 0.0f;
|
|
Player_AnimPlayLoop(play, this, D_80854360[Player_HoldsTwoHandedWeapon(this)]);
|
|
this->av2.actionVar2 = 1;
|
|
}
|
|
|
|
void func_80844E3C(Player* this) {
|
|
Math_StepToF(&this->unk_858, 1.0f, 0.02f);
|
|
}
|
|
|
|
void Player_Action_80844E68(Player* this, PlayState* play) {
|
|
f32 sp34;
|
|
s16 sp32;
|
|
s32 temp;
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_CHARGING_SPIN_ATTACK;
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_80832DBC(this);
|
|
func_808355DC(this);
|
|
this->stateFlags1 &= ~PLAYER_STATE1_TARGET_NOTHING;
|
|
Player_AnimPlayLoop(play, this, D_80854360[Player_HoldsTwoHandedWeapon(this)]);
|
|
this->av2.actionVar2 = -1;
|
|
}
|
|
|
|
func_8083721C(this);
|
|
|
|
if (!func_80842964(this, play) && (this->av2.actionVar2 != 0)) {
|
|
func_80844E3C(this);
|
|
|
|
if (this->av2.actionVar2 < 0) {
|
|
if (this->unk_858 >= 0.1f) {
|
|
this->unk_845 = 0;
|
|
this->av2.actionVar2 = 1;
|
|
} else if (!CHECK_BTN_ALL(sControlInput->cur.button, BTN_B)) {
|
|
func_80844D68(this, play);
|
|
}
|
|
} else if (!func_80844BE4(this, play)) {
|
|
Player_GetMovementSpeedAndYaw(this, &sp34, &sp32, SPEED_MODE_LINEAR, play);
|
|
|
|
temp = func_80840058(this, &sp34, &sp32, play);
|
|
if (temp > 0) {
|
|
func_80844CF8(this, play);
|
|
} else if (temp < 0) {
|
|
func_80844D30(this, play);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_80845000(Player* this, PlayState* play) {
|
|
s16 temp1;
|
|
s32 temp2;
|
|
f32 sp5C;
|
|
f32 sp58;
|
|
f32 sp54;
|
|
s16 sp52;
|
|
s32 temp4;
|
|
s16 temp5;
|
|
s32 sp44;
|
|
|
|
temp1 = this->yaw - this->actor.shape.rot.y;
|
|
temp2 = ABS(temp1);
|
|
|
|
sp5C = fabsf(this->linearVelocity);
|
|
sp58 = sp5C * 1.5f;
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_CHARGING_SPIN_ATTACK;
|
|
|
|
if (sp58 < 1.5f) {
|
|
sp58 = 1.5f;
|
|
}
|
|
|
|
sp58 = ((temp2 < 0x4000) ? -1.0f : 1.0f) * sp58;
|
|
|
|
func_8084029C(this, sp58);
|
|
|
|
sp58 = CLAMP(sp5C * 0.5f, 0.5f, 1.0f);
|
|
|
|
LinkAnimation_BlendToJoint(play, &this->skelAnime, D_80854360[Player_HoldsTwoHandedWeapon(this)], 0.0f,
|
|
D_80854370[Player_HoldsTwoHandedWeapon(this)], this->unk_868 * (21.0f / 29.0f), sp58,
|
|
this->blendTable);
|
|
|
|
if (!func_80842964(this, play) && !func_80844BE4(this, play)) {
|
|
func_80844E3C(this);
|
|
Player_GetMovementSpeedAndYaw(this, &sp54, &sp52, SPEED_MODE_LINEAR, play);
|
|
|
|
temp4 = func_80840058(this, &sp54, &sp52, play);
|
|
|
|
if (temp4 < 0) {
|
|
func_80844D30(this, play);
|
|
return;
|
|
}
|
|
|
|
if (temp4 == 0) {
|
|
sp54 = 0.0f;
|
|
sp52 = this->yaw;
|
|
}
|
|
|
|
temp5 = sp52 - this->yaw;
|
|
sp44 = ABS(temp5);
|
|
|
|
if (sp44 > 0x4000) {
|
|
if (Math_StepToF(&this->linearVelocity, 0.0f, 1.0f)) {
|
|
this->yaw = sp52;
|
|
}
|
|
return;
|
|
}
|
|
|
|
Math_AsymStepToF(&this->linearVelocity, sp54 * 0.2f, 1.0f, 0.5f);
|
|
Math_ScaledStepToS(&this->yaw, sp52, sp44 * 0.1f);
|
|
|
|
if ((sp54 == 0.0f) && (this->linearVelocity == 0.0f)) {
|
|
func_80844DC8(this, play);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_80845308(Player* this, PlayState* play) {
|
|
f32 sp5C;
|
|
f32 sp58;
|
|
f32 sp54;
|
|
s16 sp52;
|
|
s32 temp4;
|
|
s16 temp5;
|
|
s32 sp44;
|
|
|
|
sp5C = fabsf(this->linearVelocity);
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_CHARGING_SPIN_ATTACK;
|
|
|
|
if (sp5C == 0.0f) {
|
|
sp5C = ABS(this->unk_87C) * 0.0015f;
|
|
if (sp5C < 400.0f) {
|
|
sp5C = 0.0f;
|
|
}
|
|
func_8084029C(this, ((this->unk_87C >= 0) ? 1 : -1) * sp5C);
|
|
} else {
|
|
sp58 = sp5C * 1.5f;
|
|
if (sp58 < 1.5f) {
|
|
sp58 = 1.5f;
|
|
}
|
|
func_8084029C(this, sp58);
|
|
}
|
|
|
|
sp58 = CLAMP(sp5C * 0.5f, 0.5f, 1.0f);
|
|
|
|
LinkAnimation_BlendToJoint(play, &this->skelAnime, D_80854360[Player_HoldsTwoHandedWeapon(this)], 0.0f,
|
|
D_80854378[Player_HoldsTwoHandedWeapon(this)], this->unk_868 * (21.0f / 29.0f), sp58,
|
|
this->blendTable);
|
|
|
|
if (!func_80842964(this, play) && !func_80844BE4(this, play)) {
|
|
func_80844E3C(this);
|
|
Player_GetMovementSpeedAndYaw(this, &sp54, &sp52, SPEED_MODE_LINEAR, play);
|
|
|
|
temp4 = func_80840058(this, &sp54, &sp52, play);
|
|
|
|
if (temp4 > 0) {
|
|
func_80844CF8(this, play);
|
|
return;
|
|
}
|
|
|
|
if (temp4 == 0) {
|
|
sp54 = 0.0f;
|
|
sp52 = this->yaw;
|
|
}
|
|
|
|
temp5 = sp52 - this->yaw;
|
|
sp44 = ABS(temp5);
|
|
|
|
if (sp44 > 0x4000) {
|
|
if (Math_StepToF(&this->linearVelocity, 0.0f, 1.0f)) {
|
|
this->yaw = sp52;
|
|
}
|
|
return;
|
|
}
|
|
|
|
Math_AsymStepToF(&this->linearVelocity, sp54 * 0.2f, 1.0f, 0.5f);
|
|
Math_ScaledStepToS(&this->yaw, sp52, sp44 * 0.1f);
|
|
|
|
if ((sp54 == 0.0f) && (this->linearVelocity == 0.0f) && (sp5C == 0.0f)) {
|
|
func_80844DC8(this, play);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_80845668(Player* this, PlayState* play) {
|
|
s32 sp3C;
|
|
f32 temp1;
|
|
s32 temp2;
|
|
f32 temp3;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
sp3C = LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (this->skelAnime.animation == &gPlayerAnim_link_normal_250jump_start) {
|
|
this->linearVelocity = 1.0f;
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 8.0f)) {
|
|
temp1 = this->yDistToLedge;
|
|
|
|
if (temp1 > this->ageProperties->unk_0C) {
|
|
temp1 = this->ageProperties->unk_0C;
|
|
}
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_IN_WATER) {
|
|
temp1 *= 0.085f;
|
|
} else {
|
|
temp1 *= 0.072f;
|
|
}
|
|
|
|
if (!LINK_IS_ADULT) {
|
|
temp1 += 1.0f;
|
|
}
|
|
|
|
func_80838940(this, NULL, temp1, play, NA_SE_VO_LI_AUTO_JUMP);
|
|
this->av2.actionVar2 = -1;
|
|
return;
|
|
}
|
|
} else {
|
|
temp2 = func_808374A0(play, this, &this->skelAnime, 4.0f);
|
|
|
|
if (temp2 == 0) {
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_JUMPING);
|
|
return;
|
|
}
|
|
|
|
if ((sp3C != 0) || (temp2 > 0)) {
|
|
func_8083C0E8(this, play);
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_JUMPING);
|
|
return;
|
|
}
|
|
|
|
temp3 = 0.0f;
|
|
|
|
if (this->skelAnime.animation == &gPlayerAnim_link_swimer_swim_15step_up) {
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 30.0f)) {
|
|
func_8083D0A8(play, this, 10.0f);
|
|
}
|
|
temp3 = 50.0f;
|
|
} else if (this->skelAnime.animation == &gPlayerAnim_link_normal_150step_up) {
|
|
temp3 = 30.0f;
|
|
} else if (this->skelAnime.animation == &gPlayerAnim_link_normal_100step_up) {
|
|
temp3 = 16.0f;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, temp3)) {
|
|
func_808328A0(this);
|
|
func_80832698(this, NA_SE_VO_LI_CLIMB_END);
|
|
}
|
|
|
|
if ((this->skelAnime.animation == &gPlayerAnim_link_normal_100step_up) || (this->skelAnime.curFrame > 5.0f)) {
|
|
if (this->av2.actionVar2 == 0) {
|
|
func_80832854(this);
|
|
this->av2.actionVar2 = 1;
|
|
}
|
|
Math_StepToF(&this->actor.shape.yOffset, 0.0f, 150.0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_808458D0(Player* this, PlayState* play) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET | PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (((this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) && (this->heldActor != NULL) && (this->getItemId == GI_NONE)) ||
|
|
!Player_UpdateUpperBody(this, play)) {
|
|
this->func_A74(play, this);
|
|
}
|
|
}
|
|
|
|
s32 func_80845964(PlayState* play, Player* this, CsCmdActorAction* arg2, f32 arg3, s16 arg4, s32 arg5) {
|
|
if ((arg5 != 0) && (this->linearVelocity == 0.0f)) {
|
|
return LinkAnimation_Update(play, &this->skelAnime);
|
|
}
|
|
|
|
if (arg5 != 2) {
|
|
f32 sp34 = R_UPDATE_RATE * 0.5f;
|
|
f32 selfDistX = arg2->endPos.x - this->actor.world.pos.x;
|
|
f32 selfDistZ = arg2->endPos.z - this->actor.world.pos.z;
|
|
f32 sp28 = sqrtf(SQ(selfDistX) + SQ(selfDistZ)) / sp34;
|
|
s32 sp24 = (arg2->endFrame - play->csCtx.frames) + 1;
|
|
|
|
arg4 = Math_Atan2S(selfDistZ, selfDistX);
|
|
|
|
if (arg5 == 1) {
|
|
f32 distX = arg2->endPos.x - arg2->startPos.x;
|
|
f32 distZ = arg2->endPos.z - arg2->startPos.z;
|
|
s32 temp = (((sqrtf(SQ(distX) + SQ(distZ)) / sp34) / (arg2->endFrame - arg2->startFrame)) / 1.5f) * 4.0f;
|
|
|
|
if (temp >= sp24) {
|
|
arg4 = this->actor.shape.rot.y;
|
|
arg3 = 0.0f;
|
|
} else {
|
|
arg3 = sp28 / ((sp24 - temp) + 1);
|
|
}
|
|
} else {
|
|
arg3 = sp28 / sp24;
|
|
}
|
|
}
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
func_80841EE4(this, play);
|
|
func_8083DF68(this, arg3, arg4);
|
|
|
|
if ((arg3 == 0.0f) && (this->linearVelocity == 0.0f)) {
|
|
func_8083BF50(this, play);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
s32 func_80845BA0(PlayState* play, Player* this, f32* arg2, s32 arg3) {
|
|
f32 dx = this->unk_450.x - this->actor.world.pos.x;
|
|
f32 dz = this->unk_450.z - this->actor.world.pos.z;
|
|
s32 sp2C = sqrtf(SQ(dx) + SQ(dz));
|
|
s16 yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_450);
|
|
|
|
if (sp2C < arg3) {
|
|
*arg2 = 0.0f;
|
|
yaw = this->actor.shape.rot.y;
|
|
}
|
|
|
|
if (func_80845964(play, this, NULL, *arg2, yaw, 2)) {
|
|
return 0;
|
|
}
|
|
|
|
return sp2C;
|
|
}
|
|
|
|
s32 func_80845C68(PlayState* play, s32 arg1) {
|
|
if (arg1 == 0) {
|
|
Play_SetupRespawnPoint(play, RESPAWN_MODE_DOWN, 0xDFF);
|
|
}
|
|
gSaveContext.respawn[RESPAWN_MODE_DOWN].data = 0;
|
|
return arg1;
|
|
}
|
|
|
|
void Player_Action_80845CA4(Player* this, PlayState* play) {
|
|
f32 sp3C;
|
|
s32 temp;
|
|
f32 sp34;
|
|
s32 sp30;
|
|
s32 pad;
|
|
|
|
if (!Player_ActionChange_13(this, play)) {
|
|
if (this->av2.actionVar2 == 0) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (DECR(this->doorTimer) == 0) {
|
|
this->linearVelocity = 0.1f;
|
|
this->av2.actionVar2 = 1;
|
|
}
|
|
} else if (this->av1.actionVar1 == 0) {
|
|
sp3C = 5.0f * D_808535E8;
|
|
|
|
if (func_80845BA0(play, this, &sp3C, -1) < 30) {
|
|
this->av1.actionVar1 = 1;
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
|
|
|
this->unk_450.x = this->unk_45C.x;
|
|
this->unk_450.z = this->unk_45C.z;
|
|
}
|
|
} else {
|
|
sp34 = 5.0f;
|
|
sp30 = 20;
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_LOADING) {
|
|
sp34 = gSaveContext.entranceSpeed;
|
|
|
|
if (sConveyorSpeed != 0) {
|
|
this->unk_450.x = (Math_SinS(sConveyorYaw) * 400.0f) + this->actor.world.pos.x;
|
|
this->unk_450.z = (Math_CosS(sConveyorYaw) * 400.0f) + this->actor.world.pos.z;
|
|
}
|
|
} else if (this->av2.actionVar2 < 0) {
|
|
this->av2.actionVar2++;
|
|
|
|
sp34 = gSaveContext.entranceSpeed;
|
|
sp30 = -1;
|
|
}
|
|
|
|
temp = func_80845BA0(play, this, &sp34, sp30);
|
|
|
|
if ((this->av2.actionVar2 == 0) ||
|
|
((temp == 0) && (this->linearVelocity == 0.0f) && (Play_GetCamera(play, 0)->unk_14C & 0x10))) {
|
|
|
|
func_8005B1A4(Play_GetCamera(play, 0));
|
|
func_80845C68(play, gSaveContext.respawn[RESPAWN_MODE_DOWN].data);
|
|
|
|
if (!Player_ActionChange_4(this, play)) {
|
|
func_8083CF5C(this, play);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) {
|
|
Player_UpdateUpperBody(this, play);
|
|
}
|
|
}
|
|
|
|
void Player_Action_80845EF8(Player* this, PlayState* play) {
|
|
s32 sp2C;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
sp2C = LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
Player_UpdateUpperBody(this, play);
|
|
|
|
if (sp2C) {
|
|
if (this->av2.actionVar2 == 0) {
|
|
if (DECR(this->doorTimer) == 0) {
|
|
this->av2.actionVar2 = 1;
|
|
this->skelAnime.endFrame = this->skelAnime.animLength - 1.0f;
|
|
}
|
|
} else {
|
|
func_8083C0E8(this, play);
|
|
if (play->roomCtx.prevRoom.num >= 0) {
|
|
func_80097534(play, &play->roomCtx);
|
|
}
|
|
func_8005B1A4(Play_GetCamera(play, 0));
|
|
Play_SetupRespawnPoint(play, 0, 0xDFF);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_IN_CUTSCENE) && LinkAnimation_OnFrame(&this->skelAnime, 15.0f)) {
|
|
play->func_11D54(this, play);
|
|
}
|
|
}
|
|
|
|
void Player_Action_80846050(Player* this, PlayState* play) {
|
|
func_8083721C(this);
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_80839F90(this, play);
|
|
func_80835688(this, play);
|
|
return;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 4.0f)) {
|
|
Actor* interactRangeActor = this->interactRangeActor;
|
|
|
|
if (!func_80835644(play, this, interactRangeActor)) {
|
|
this->heldActor = interactRangeActor;
|
|
this->actor.child = interactRangeActor;
|
|
interactRangeActor->parent = &this->actor;
|
|
interactRangeActor->bgCheckFlags &= 0xFF00;
|
|
this->unk_3BC.y = interactRangeActor->shape.rot.y - this->actor.shape.rot.y;
|
|
}
|
|
return;
|
|
}
|
|
|
|
Math_ScaledStepToS(&this->unk_3BC.y, 0, 4000);
|
|
}
|
|
|
|
static AnimSfxEntry D_8085461C[] = {
|
|
{ NA_SE_VO_LI_SWORD_L, ANIMSFX_DATA(ANIMSFX_TYPE_4, 49) },
|
|
{ NA_SE_VO_LI_SWORD_N, -ANIMSFX_DATA(ANIMSFX_TYPE_4, 230) },
|
|
};
|
|
|
|
void Player_Action_80846120(Player* this, PlayState* play) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime) && (this->av2.actionVar2++ > 20)) {
|
|
if (!Player_ActionChange_13(this, play)) {
|
|
func_8083A098(this, &gPlayerAnim_link_normal_heavy_carry_end, play);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 41.0f)) {
|
|
BgHeavyBlock* heavyBlock = (BgHeavyBlock*)this->interactRangeActor;
|
|
|
|
this->heldActor = &heavyBlock->dyna.actor;
|
|
this->actor.child = &heavyBlock->dyna.actor;
|
|
heavyBlock->dyna.actor.parent = &this->actor;
|
|
func_8002DBD0(&heavyBlock->dyna.actor, &heavyBlock->unk_164, &this->leftHandPos);
|
|
return;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 229.0f)) {
|
|
Actor* heldActor = this->heldActor;
|
|
|
|
if (CVarGetInteger("gFasterHeavyBlockLift", 0)) {
|
|
// This is the difference in rotation when the animation is sped up 5x
|
|
heldActor->shape.rot.x -= 3510;
|
|
}
|
|
heldActor->speedXZ = Math_SinS(heldActor->shape.rot.x) * 40.0f;
|
|
heldActor->velocity.y = Math_CosS(heldActor->shape.rot.x) * 40.0f;
|
|
heldActor->gravity = -2.0f;
|
|
heldActor->minVelocityY = -30.0f;
|
|
Player_DetachHeldActor(play, this);
|
|
return;
|
|
}
|
|
|
|
Player_ProcessAnimSfxList(this, D_8085461C);
|
|
}
|
|
|
|
void Player_Action_80846260(Player* this, PlayState* play) {
|
|
func_8083721C(this);
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimPlayLoop(play, this, &gPlayerAnim_link_silver_wait);
|
|
this->av2.actionVar2 = 1;
|
|
return;
|
|
}
|
|
|
|
u16 buttonsToCheck = BTN_A | BTN_B | BTN_CLEFT | BTN_CRIGHT | BTN_CDOWN;
|
|
if (CVarGetInteger("gDpadEquips", 0) != 0) {
|
|
buttonsToCheck |= BTN_DUP | BTN_DDOWN | BTN_DLEFT | BTN_DRIGHT;
|
|
}
|
|
if (this->av2.actionVar2 == 0) {
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 27.0f)) {
|
|
Actor* interactRangeActor = this->interactRangeActor;
|
|
|
|
this->heldActor = interactRangeActor;
|
|
this->actor.child = interactRangeActor;
|
|
interactRangeActor->parent = &this->actor;
|
|
return;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 25.0f)) {
|
|
func_80832698(this, NA_SE_VO_LI_SWORD_L);
|
|
return;
|
|
}
|
|
|
|
} else if (CHECK_BTN_ANY(sControlInput->press.button, buttonsToCheck)) {
|
|
Player_SetupAction(play, this, Player_Action_80846358, 1);
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_silver_throw);
|
|
}
|
|
}
|
|
|
|
void Player_Action_80846358(Player* this, PlayState* play) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_80839F90(this, play);
|
|
return;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 6.0f)) {
|
|
Actor* heldActor = this->heldActor;
|
|
|
|
heldActor->world.rot.y = this->actor.shape.rot.y;
|
|
heldActor->speedXZ = 10.0f;
|
|
heldActor->velocity.y = 20.0f;
|
|
func_80834644(play, this);
|
|
Player_PlaySfx(this, NA_SE_PL_THROW);
|
|
func_80832698(this, NA_SE_VO_LI_SWORD_N);
|
|
}
|
|
}
|
|
|
|
void Player_Action_80846408(Player* this, PlayState* play) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimPlayLoop(play, this, &gPlayerAnim_link_normal_nocarry_free_wait);
|
|
this->av2.actionVar2 = 15;
|
|
return;
|
|
}
|
|
|
|
if (this->av2.actionVar2 != 0) {
|
|
this->av2.actionVar2--;
|
|
if (this->av2.actionVar2 == 0) {
|
|
func_8083A098(this, &gPlayerAnim_link_normal_nocarry_free_end, play);
|
|
this->stateFlags1 &= ~PLAYER_STATE1_ITEM_OVER_HEAD;
|
|
func_80832698(this, NA_SE_VO_LI_DAMAGE_S);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_808464B0(Player* this, PlayState* play) {
|
|
func_8083721C(this);
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_80839F90(this, play);
|
|
return;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 4.0f)) {
|
|
Actor* heldActor = this->heldActor;
|
|
|
|
if (!func_80835644(play, this, heldActor)) {
|
|
heldActor->velocity.y = 0.0f;
|
|
heldActor->speedXZ = 0.0f;
|
|
func_80834644(play, this);
|
|
if (heldActor->id == ACTOR_EN_BOM_CHU && !CVarGetInteger("gDisableFirstPersonChus", 0)) {
|
|
func_8083B8F4(this, play);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_80846578(Player* this, PlayState* play) {
|
|
f32 sp34;
|
|
s16 sp32;
|
|
|
|
func_8083721C(this);
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime) ||
|
|
((this->skelAnime.curFrame >= 8.0f) && Player_GetMovementSpeedAndYaw(this, &sp34, &sp32, SPEED_MODE_CURVED, play))) {
|
|
func_80839F90(this, play);
|
|
return;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 3.0f)) {
|
|
func_8084409C(play, this, this->linearVelocity + 8.0f, 12.0f);
|
|
}
|
|
}
|
|
|
|
static ColliderCylinderInit D_80854624 = {
|
|
{
|
|
COLTYPE_HIT5,
|
|
AT_NONE,
|
|
AC_ON | AC_TYPE_ENEMY,
|
|
OC1_ON | OC1_TYPE_ALL,
|
|
OC2_TYPE_PLAYER,
|
|
COLSHAPE_CYLINDER,
|
|
},
|
|
{
|
|
ELEMTYPE_UNK1,
|
|
{ 0x00000000, 0x00, 0x00 },
|
|
{ 0xFFCFFFFF, 0x00, 0x00 },
|
|
TOUCH_NONE,
|
|
BUMP_ON,
|
|
OCELEM_ON,
|
|
},
|
|
{ 12, 60, 0, { 0, 0, 0 } },
|
|
};
|
|
|
|
static ColliderQuadInit D_80854650 = {
|
|
{
|
|
COLTYPE_NONE,
|
|
AT_ON | AT_TYPE_PLAYER,
|
|
AC_NONE,
|
|
OC1_NONE,
|
|
OC2_TYPE_PLAYER,
|
|
COLSHAPE_QUAD,
|
|
},
|
|
{
|
|
ELEMTYPE_UNK2,
|
|
{ 0x00000100, 0x00, 0x01 },
|
|
{ 0xFFCFFFFF, 0x00, 0x00 },
|
|
TOUCH_ON | TOUCH_SFX_NORMAL,
|
|
BUMP_NONE,
|
|
OCELEM_NONE,
|
|
},
|
|
{ { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } },
|
|
};
|
|
|
|
static ColliderQuadInit D_808546A0 = {
|
|
{
|
|
COLTYPE_METAL,
|
|
AT_ON | AT_TYPE_PLAYER,
|
|
AC_ON | AC_HARD | AC_TYPE_ENEMY,
|
|
OC1_NONE,
|
|
OC2_TYPE_PLAYER,
|
|
COLSHAPE_QUAD,
|
|
},
|
|
{
|
|
ELEMTYPE_UNK2,
|
|
{ 0x00100000, 0x00, 0x00 },
|
|
{ 0xDFCFFFFF, 0x00, 0x00 },
|
|
TOUCH_ON | TOUCH_SFX_NORMAL,
|
|
BUMP_ON,
|
|
OCELEM_NONE,
|
|
},
|
|
{ { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } },
|
|
};
|
|
|
|
void func_8084663C(Actor* thisx, PlayState* play) {
|
|
}
|
|
|
|
void func_80846648(PlayState* play, Player* this) {
|
|
this->actor.update = func_8084663C;
|
|
this->actor.draw = NULL;
|
|
}
|
|
|
|
void func_80846660(PlayState* play, Player* this) {
|
|
Player_SetupAction(play, this, Player_Action_8084F710, 0);
|
|
if ((play->sceneNum == SCENE_LAKE_HYLIA) && (gSaveContext.sceneSetupIndex >= 4)) {
|
|
this->av1.actionVar1 = 1;
|
|
}
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
|
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_okarina_warp_goal, 2.0f / 3.0f, 0.0f, 24.0f,
|
|
ANIMMODE_ONCE, 0.0f);
|
|
this->actor.world.pos.y += 800.0f;
|
|
}
|
|
|
|
static u8 D_808546F0[] = { ITEM_SWORD_MASTER, ITEM_SWORD_KOKIRI };
|
|
|
|
void func_80846720(PlayState* play, Player* this, s32 arg2) {
|
|
s32 item = D_808546F0[(void)0, gSaveContext.linkAge];
|
|
s32 itemAction = sItemActions[item];
|
|
|
|
Player_DestroyHookshot(this);
|
|
Player_DetachHeldActor(play, this);
|
|
|
|
this->heldItemId = item;
|
|
this->nextModelGroup = Player_ActionToModelGroup(this, itemAction);
|
|
|
|
Player_InitItemAction(play, this, itemAction);
|
|
func_80834644(play, this);
|
|
|
|
if (arg2 != 0) {
|
|
Player_PlaySfx(this, NA_SE_IT_SWORD_PICKOUT);
|
|
}
|
|
}
|
|
|
|
static Vec3f D_808546F4 = { -1.0f, 69.0f, 20.0f };
|
|
|
|
void func_808467D4(PlayState* play, Player* this) {
|
|
Player_SetupAction(play, this, Player_Action_8084E9AC, 0);
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
|
Math_Vec3f_Copy(&this->actor.world.pos, &D_808546F4);
|
|
this->yaw = this->actor.shape.rot.y = -0x8000;
|
|
LinkAnimation_Change(play, &this->skelAnime, this->ageProperties->unk_A0, 2.0f / 3.0f, 0.0f, 0.0f,
|
|
ANIMMODE_ONCE, 0.0f);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x28F);
|
|
if (LINK_IS_ADULT) {
|
|
func_80846720(play, this, 0);
|
|
}
|
|
this->av2.actionVar2 = 20;
|
|
}
|
|
|
|
void func_808468A8(PlayState* play, Player* this) {
|
|
Player_SetupAction(play, this, Player_Action_8084F9A0, 0);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x9B);
|
|
}
|
|
|
|
void func_808468E8(PlayState* play, Player* this) {
|
|
func_808389E8(this, &gPlayerAnim_link_normal_jump, 12.0f, play);
|
|
Player_SetupAction(play, this, Player_Action_8084F9C0, 0);
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
|
this->fallStartHeight = this->actor.world.pos.y;
|
|
OnePointCutscene_Init(play, 5110, 40, &this->actor, MAIN_CAM);
|
|
}
|
|
|
|
void func_80846978(PlayState* play, Player* this) {
|
|
func_80837C0C(play, this, 1, 2.0f, 2.0f, this->actor.shape.rot.y + 0x8000, 0);
|
|
}
|
|
|
|
void func_808469BC(PlayState* play, Player* this) {
|
|
Player_SetupAction(play, this, Player_Action_8084F698, 0);
|
|
this->actor.draw = NULL;
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
|
}
|
|
|
|
static s16 D_80854700[] = { ACTOR_MAGIC_WIND, ACTOR_MAGIC_DARK, ACTOR_MAGIC_FIRE };
|
|
|
|
Actor* func_80846A00(PlayState* play, Player* this, s32 arg2) {
|
|
return Actor_Spawn(&play->actorCtx, play, D_80854700[arg2], this->actor.world.pos.x,
|
|
this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0, true);
|
|
}
|
|
|
|
void func_80846A68(PlayState* play, Player* this) {
|
|
this->actor.draw = NULL;
|
|
Player_SetupAction(play, this, Player_Action_8085076C, 0);
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE;
|
|
}
|
|
|
|
static InitChainEntry sInitChain[] = {
|
|
ICHAIN_F32(targetArrowOffset, 500, ICHAIN_STOP),
|
|
};
|
|
|
|
static EffectBlureInit2 blureSword = {
|
|
0, 8, 0, { 255, 255, 255, 255 }, { 255, 255, 255, 64 }, { 255, 255, 255, 0 }, { 255, 255, 255, 0 }, 4,
|
|
0, 2, 0, { 255, 255, 255, 255 }, { 255, 255, 255, 64 }, 1,
|
|
};
|
|
|
|
static Vec3s D_80854730 = { -57, 3377, 0 };
|
|
|
|
void Player_InitCommon(Player* this, PlayState* play, FlexSkeletonHeader* skelHeader) {
|
|
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
|
|
this->ageProperties = &sAgeProperties[gSaveContext.linkAge];
|
|
Actor_ProcessInitChain(&this->actor, sInitChain);
|
|
this->meleeWeaponEffectIndex = TOTAL_EFFECT_COUNT;
|
|
this->yaw = this->actor.world.rot.y;
|
|
func_80834644(play, this);
|
|
|
|
SkelAnime_InitLink(play, &this->skelAnime, skelHeader, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_wait, this->modelAnimType), 9,
|
|
this->jointTable, this->morphTable, PLAYER_LIMB_MAX);
|
|
this->skelAnime.baseTransl = D_80854730;
|
|
SkelAnime_InitLink(play, &this->upperSkelAnime, skelHeader, func_80833338(this), 9, this->upperJointTable,
|
|
this->upperMorphTable, PLAYER_LIMB_MAX);
|
|
this->upperSkelAnime.baseTransl = D_80854730;
|
|
|
|
Effect_Add(play, &this->meleeWeaponEffectIndex, EFFECT_BLURE2, 0, 0, &blureSword);
|
|
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawFeet, this->ageProperties->unk_04);
|
|
this->subCamId = SUBCAM_NONE;
|
|
Collider_InitCylinder(play, &this->cylinder);
|
|
Collider_SetCylinder(play, &this->cylinder, &this->actor, &D_80854624);
|
|
Collider_InitQuad(play, &this->meleeWeaponQuads[0]);
|
|
Collider_SetQuad(play, &this->meleeWeaponQuads[0], &this->actor, &D_80854650);
|
|
Collider_InitQuad(play, &this->meleeWeaponQuads[1]);
|
|
Collider_SetQuad(play, &this->meleeWeaponQuads[1], &this->actor, &D_80854650);
|
|
Collider_InitQuad(play, &this->shieldQuad);
|
|
Collider_SetQuad(play, &this->shieldQuad, &this->actor, &D_808546A0);
|
|
|
|
this->ivanDamageMultiplier = 1;
|
|
}
|
|
|
|
static void (*D_80854738[])(PlayState* play, Player* this) = {
|
|
func_80846648, func_808467D4, func_80846660, func_808468A8, func_808468E8, func_808469BC,
|
|
func_80846A68, func_80846978, func_8083CA54, func_8083CA54, func_8083CA54, func_8083CA54,
|
|
func_8083CA54, func_8083CA20, func_8083CA54, func_8083CA9C,
|
|
};
|
|
|
|
static Vec3f D_80854778 = { 0.0f, 50.0f, 0.0f };
|
|
|
|
void Player_Init(Actor* thisx, PlayState* play2) {
|
|
Player* this = (Player*)thisx;
|
|
PlayState* play = play2;
|
|
SceneTableEntry* scene = play->loadedScene;
|
|
u32 titleFileSize;
|
|
s32 initMode;
|
|
s32 sp50;
|
|
s32 sp4C;
|
|
|
|
// In ER, once Link has spawned we know the scene has loaded, so we can sanitize the last known entrance type
|
|
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
|
|
Grotto_SanitizeEntranceType();
|
|
}
|
|
|
|
play->shootingGalleryStatus = play->bombchuBowlingStatus = 0;
|
|
|
|
play->playerInit = Player_InitCommon;
|
|
play->playerUpdate = Player_UpdateCommon;
|
|
play->isPlayerDroppingFish = Player_IsDroppingFish;
|
|
play->startPlayerFishing = Player_StartFishing;
|
|
play->grabPlayer = func_80852F38;
|
|
play->startPlayerCutscene = Player_TryCsAction;
|
|
play->func_11D54 = func_80853080;
|
|
play->damagePlayer = Player_InflictDamage;
|
|
play->talkWithPlayer = Player_StartTalking;
|
|
|
|
thisx->room = -1;
|
|
this->ageProperties = &sAgeProperties[gSaveContext.linkAge];
|
|
this->itemAction = this->heldItemAction = -1;
|
|
this->heldItemId = ITEM_NONE;
|
|
|
|
Player_UseItem(play, this, ITEM_NONE);
|
|
Player_SetEquipmentData(play, this);
|
|
this->prevBoots = this->currentBoots;
|
|
if (CVarGetInteger("gMMBunnyHood", BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA) {
|
|
if (INV_CONTENT(ITEM_TRADE_CHILD) == ITEM_SOLD_OUT) {
|
|
sMaskMemory = PLAYER_MASK_NONE;
|
|
}
|
|
this->currentMask = sMaskMemory;
|
|
}
|
|
Player_InitCommon(this, play, gPlayerSkelHeaders[((void)0, gSaveContext.linkAge)]);
|
|
this->giObjectSegment = (void*)(((uintptr_t)ZELDA_ARENA_MALLOC_DEBUG(0x3008) + 8) & ~0xF);
|
|
|
|
sp50 = gSaveContext.respawnFlag;
|
|
|
|
if (sp50 != 0) {
|
|
if (sp50 == -3) {
|
|
thisx->params = gSaveContext.respawn[RESPAWN_MODE_RETURN].playerParams;
|
|
} else {
|
|
if ((sp50 == 1) || (sp50 == -1)) {
|
|
this->unk_A86 = -2;
|
|
}
|
|
|
|
if (sp50 < 0) {
|
|
sp4C = 0;
|
|
} else {
|
|
sp4C = sp50 - 1;
|
|
Math_Vec3f_Copy(&thisx->world.pos, &gSaveContext.respawn[sp50 - 1].pos);
|
|
Math_Vec3f_Copy(&thisx->home.pos, &thisx->world.pos);
|
|
Math_Vec3f_Copy(&thisx->prevPos, &thisx->world.pos);
|
|
this->fallStartHeight = thisx->world.pos.y;
|
|
this->yaw = thisx->shape.rot.y = gSaveContext.respawn[sp4C].yaw;
|
|
thisx->params = gSaveContext.respawn[sp4C].playerParams;
|
|
}
|
|
|
|
play->actorCtx.flags.tempSwch = gSaveContext.respawn[sp4C].tempSwchFlags & 0xFFFFFF;
|
|
play->actorCtx.flags.tempCollect = gSaveContext.respawn[sp4C].tempCollectFlags;
|
|
}
|
|
}
|
|
|
|
if ((sp50 == 0) || (sp50 < -1)) {
|
|
titleFileSize = scene->titleFile.vromEnd - scene->titleFile.vromStart;
|
|
if (gSaveContext.showTitleCard) {
|
|
if ((gSaveContext.sceneSetupIndex < 4) &&
|
|
(gEntranceTable[((void)0, gSaveContext.entranceIndex) + ((void)0, gSaveContext.sceneSetupIndex)].field &
|
|
ENTRANCE_INFO_DISPLAY_TITLE_CARD_FLAG) &&
|
|
((play->sceneNum != SCENE_DODONGOS_CAVERN) || (Flags_GetEventChkInf(EVENTCHKINF_ENTERED_DODONGOS_CAVERN))) &&
|
|
((play->sceneNum != SCENE_BOMBCHU_SHOP) || (Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)))) {
|
|
TitleCard_InitPlaceName(play, &play->actorCtx.titleCtx, this->giObjectSegment, 160, 120, 144,
|
|
24, 20);
|
|
}
|
|
}
|
|
gSaveContext.showTitleCard = true;
|
|
}
|
|
|
|
if (func_80845C68(play, (sp50 == 2) ? 1 : 0) == 0) {
|
|
gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = (thisx->params & 0xFF) | 0xD00;
|
|
}
|
|
|
|
gSaveContext.respawn[RESPAWN_MODE_DOWN].data = 1;
|
|
|
|
if (play->sceneNum <= SCENE_INSIDE_GANONS_CASTLE_COLLAPSE) {
|
|
gSaveContext.infTable[26] |= gBitFlags[play->sceneNum];
|
|
}
|
|
|
|
initMode = (thisx->params & 0xF00) >> 8;
|
|
if ((initMode == 5) || (initMode == 6)) {
|
|
if (gSaveContext.cutsceneIndex >= 0xFFF0) {
|
|
initMode = 13;
|
|
}
|
|
}
|
|
|
|
D_80854738[initMode](play, this);
|
|
|
|
if (initMode != 0) {
|
|
if ((gSaveContext.gameMode == 0) || (gSaveContext.gameMode == 3)) {
|
|
this->naviActor = Player_SpawnFairy(play, this, &thisx->world.pos, &D_80854778, FAIRY_NAVI);
|
|
if (gSaveContext.dogParams != 0) {
|
|
gSaveContext.dogParams |= 0x8000;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (gSaveContext.nayrusLoveTimer != 0) {
|
|
gSaveContext.magicState = MAGIC_STATE_METER_FLASH_1;
|
|
func_80846A00(play, this, 1);
|
|
this->stateFlags3 &= ~PLAYER_STATE3_RESTORE_NAYRUS_LOVE;
|
|
}
|
|
|
|
if (gSaveContext.entranceSound != 0) {
|
|
Audio_PlayActorSound2(&this->actor, ((void)0, gSaveContext.entranceSound));
|
|
gSaveContext.entranceSound = 0;
|
|
}
|
|
|
|
Map_SavePlayerInitialInfo(play);
|
|
MREG(64) = 0;
|
|
}
|
|
|
|
void func_808471F4(s16* pValue) {
|
|
s16 step;
|
|
|
|
step = (ABS(*pValue) * 100.0f) / 1000.0f;
|
|
step = CLAMP(step, 400, 4000);
|
|
|
|
Math_ScaledStepToS(pValue, 0, step);
|
|
}
|
|
|
|
void func_80847298(Player* this) {
|
|
s16 sp26;
|
|
|
|
if (!(this->unk_6AE & 2)) {
|
|
sp26 = this->actor.focus.rot.y - this->actor.shape.rot.y;
|
|
func_808471F4(&sp26);
|
|
this->actor.focus.rot.y = this->actor.shape.rot.y + sp26;
|
|
}
|
|
|
|
if (!(this->unk_6AE & 1)) {
|
|
func_808471F4(&this->actor.focus.rot.x);
|
|
}
|
|
|
|
if (!(this->unk_6AE & 8)) {
|
|
func_808471F4(&this->unk_6B6);
|
|
}
|
|
|
|
if (!(this->unk_6AE & 0x40)) {
|
|
func_808471F4(&this->unk_6BC);
|
|
}
|
|
|
|
if (!(this->unk_6AE & 4)) {
|
|
func_808471F4(&this->actor.focus.rot.z);
|
|
}
|
|
|
|
if (!(this->unk_6AE & 0x10)) {
|
|
func_808471F4(&this->unk_6B8);
|
|
}
|
|
|
|
if (!(this->unk_6AE & 0x20)) {
|
|
func_808471F4(&this->unk_6BA);
|
|
}
|
|
|
|
if (!(this->unk_6AE & 0x80)) {
|
|
if (this->unk_6B0 != 0) {
|
|
func_808471F4(&this->unk_6B0);
|
|
} else {
|
|
func_808471F4(&this->unk_6BE);
|
|
}
|
|
}
|
|
|
|
if (!(this->unk_6AE & 0x100)) {
|
|
func_808471F4(&this->unk_6C0);
|
|
}
|
|
|
|
this->unk_6AE = 0;
|
|
}
|
|
|
|
static f32 D_80854784[] = { 120.0f, 240.0f, 360.0f };
|
|
|
|
static u8 sDiveDoActions[] = { DO_ACTION_1, DO_ACTION_2, DO_ACTION_3, DO_ACTION_4,
|
|
DO_ACTION_5, DO_ACTION_6, DO_ACTION_7, DO_ACTION_8 };
|
|
|
|
void func_808473D4(PlayState* play, Player* this) {
|
|
if ((Message_GetState(&play->msgCtx) == TEXT_STATE_NONE) && (this->actor.category == ACTORCAT_PLAYER)) {
|
|
Actor* heldActor = this->heldActor;
|
|
Actor* interactRangeActor = this->interactRangeActor;
|
|
s32 sp24;
|
|
s32 sp20 = this->unk_84B[this->unk_846];
|
|
s32 sp1C = func_808332B8(this);
|
|
s32 doAction = DO_ACTION_NONE;
|
|
|
|
if (!Player_InBlockingCsMode(play, this)) {
|
|
if (this->stateFlags1 & PLAYER_STATE1_FIRST_PERSON) {
|
|
doAction = DO_ACTION_RETURN;
|
|
} else if ((this->heldItemAction == PLAYER_IA_FISHING_POLE) && (this->unk_860 != 0)) {
|
|
if (this->unk_860 == 2) {
|
|
doAction = DO_ACTION_REEL;
|
|
}
|
|
} else if ((Player_Action_8084E3C4 != this->actionFunc) && !(this->stateFlags2 & PLAYER_STATE2_CRAWLING)) {
|
|
if ((this->doorType != PLAYER_DOORTYPE_NONE) &&
|
|
(!(this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) ||
|
|
((heldActor != NULL) && (heldActor->id == ACTOR_EN_RU1)))) {
|
|
doAction = DO_ACTION_OPEN;
|
|
} else if ((!(this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) || (heldActor == NULL)) &&
|
|
(interactRangeActor != NULL) &&
|
|
((!sp1C && (this->getItemId == GI_NONE)) ||
|
|
(this->getItemId < 0 && !(this->stateFlags1 & PLAYER_STATE1_IN_WATER)))) {
|
|
if (this->getItemId < 0) {
|
|
doAction = DO_ACTION_OPEN;
|
|
} else if ((interactRangeActor->id == ACTOR_BG_TOKI_SWD) && LINK_IS_ADULT) {
|
|
doAction = DO_ACTION_DROP;
|
|
} else {
|
|
doAction = DO_ACTION_GRAB;
|
|
}
|
|
} else if (!sp1C && (this->stateFlags2 & PLAYER_STATE2_DO_ACTION_GRAB)) {
|
|
doAction = DO_ACTION_GRAB;
|
|
} else if ((this->stateFlags2 & PLAYER_STATE2_DO_ACTION_CLIMB) ||
|
|
(!(this->stateFlags1 & PLAYER_STATE1_ON_HORSE) && (this->rideActor != NULL))) {
|
|
doAction = DO_ACTION_CLIMB;
|
|
} else if ((this->stateFlags1 & PLAYER_STATE1_ON_HORSE) && !EN_HORSE_CHECK_4((EnHorse*)this->rideActor) &&
|
|
(Player_Action_8084D3E4 != this->actionFunc)) {
|
|
if ((this->stateFlags2 & PLAYER_STATE2_SPEAK_OR_CHECK) && (this->targetActor != NULL)) {
|
|
if (this->targetActor->category == ACTORCAT_NPC) {
|
|
doAction = DO_ACTION_SPEAK;
|
|
} else {
|
|
doAction = DO_ACTION_CHECK;
|
|
}
|
|
} else if (!func_8002DD78(this) && !(this->stateFlags1 & PLAYER_STATE1_FIRST_PERSON)) {
|
|
doAction = DO_ACTION_FASTER;
|
|
}
|
|
} else if ((this->stateFlags2 & PLAYER_STATE2_SPEAK_OR_CHECK) && (this->targetActor != NULL)) {
|
|
if (this->targetActor->category == ACTORCAT_NPC) {
|
|
doAction = DO_ACTION_SPEAK;
|
|
} else {
|
|
doAction = DO_ACTION_CHECK;
|
|
}
|
|
} else if ((this->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LADDER)) ||
|
|
((this->stateFlags1 & PLAYER_STATE1_ON_HORSE) && (this->stateFlags2 & PLAYER_STATE2_DO_ACTION_DOWN))) {
|
|
doAction = DO_ACTION_DOWN;
|
|
} else if (this->stateFlags2 & PLAYER_STATE2_DO_ACTION_ENTER) {
|
|
doAction = DO_ACTION_ENTER;
|
|
} else if ((this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) && (this->getItemId == GI_NONE) &&
|
|
(heldActor != NULL)) {
|
|
if ((this->actor.bgCheckFlags & 1) || (heldActor->id == ACTOR_EN_NIW)) {
|
|
if (func_8083EAF0(this, heldActor) == 0) {
|
|
doAction = DO_ACTION_DROP;
|
|
} else {
|
|
doAction = DO_ACTION_THROW;
|
|
}
|
|
}
|
|
} else if (!(this->stateFlags1 & PLAYER_STATE1_IN_WATER) && func_8083A0D4(this) &&
|
|
(this->getItemId < GI_MAX)) {
|
|
doAction = DO_ACTION_GRAB;
|
|
} else if (this->stateFlags2 & PLAYER_STATE2_DIVING) {
|
|
sp24 = (D_80854784[CUR_UPG_VALUE(UPG_SCALE)] - this->actor.yDistToWater) / 40.0f;
|
|
sp24 = CLAMP(sp24, 0, 7);
|
|
doAction = sDiveDoActions[sp24];
|
|
} else if (sp1C && !(this->stateFlags2 & PLAYER_STATE2_UNDERWATER)) {
|
|
doAction = DO_ACTION_DIVE;
|
|
} else if (!sp1C && (!(this->stateFlags1 & PLAYER_STATE1_SHIELDING) || func_80833BCC(this) ||
|
|
!Player_IsChildWithHylianShield(this))) {
|
|
if ((!(this->stateFlags1 & PLAYER_STATE1_CLIMBING_LEDGE) && (sp20 <= 0) &&
|
|
(func_8008E9C4(this) ||
|
|
((sFloorType != 7) && (func_80833B2C(this) ||
|
|
((play->roomCtx.curRoom.behaviorType1 != ROOM_BEHAVIOR_TYPE1_2) &&
|
|
!(this->stateFlags1 & PLAYER_STATE1_SHIELDING) && (sp20 == 0))))))) {
|
|
doAction = DO_ACTION_ATTACK;
|
|
} else if ((play->roomCtx.curRoom.behaviorType1 != ROOM_BEHAVIOR_TYPE1_2) &&
|
|
func_80833BCC(this) && (sp20 > 0)) {
|
|
doAction = DO_ACTION_JUMP;
|
|
} else if ((this->heldItemAction >= PLAYER_IA_SWORD_MASTER) ||
|
|
((this->stateFlags2 & PLAYER_STATE2_NAVI_OUT) &&
|
|
(play->actorCtx.targetCtx.arrowPointedActor == NULL))) {
|
|
doAction = DO_ACTION_PUTAWAY;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (doAction != DO_ACTION_PUTAWAY) {
|
|
this->unk_837 = 20;
|
|
} else if (this->unk_837 != 0) {
|
|
if (CVarGetInteger("gInstantPutaway", 0) != 0) {
|
|
this->unk_837 = 0;
|
|
} else {
|
|
doAction = DO_ACTION_NONE;
|
|
this->unk_837--;
|
|
}
|
|
}
|
|
|
|
Interface_SetDoAction(play, doAction);
|
|
|
|
if (this->stateFlags2 & PLAYER_STATE2_NAVI_ALERT) {
|
|
if (this->unk_664 != NULL) {
|
|
Interface_SetNaviCall(play, 0x1E);
|
|
} else {
|
|
Interface_SetNaviCall(play, 0x1D);
|
|
}
|
|
Interface_SetNaviCall(play, 0x1E);
|
|
} else {
|
|
Interface_SetNaviCall(play, 0x1F);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates state related to the Hover Boots.
|
|
* Handles a special case where the Hover Boots are able to activate when standing on certain floor types even if the
|
|
* player is standing on the ground.
|
|
*
|
|
* If the player is not on the ground, regardless of the usage of the Hover Boots, various floor related variables are
|
|
* reset.
|
|
*
|
|
* @return true if not on the ground, false otherwise. Note this is independent of the Hover Boots state.
|
|
*/
|
|
s32 Player_UpdateHoverBoots(Player* this) {
|
|
s32 cond;
|
|
|
|
if ((this->currentBoots == PLAYER_BOOTS_HOVER ||
|
|
(CVarGetInteger("gIvanCoopModeEnabled", 0) && this->ivanFloating)) &&
|
|
(this->hoverBootsTimer != 0)) {
|
|
this->hoverBootsTimer--;
|
|
} else {
|
|
this->hoverBootsTimer = 0;
|
|
}
|
|
|
|
cond = (this->currentBoots == PLAYER_BOOTS_HOVER ||
|
|
(CVarGetInteger("gIvanCoopModeEnabled", 0) && this->ivanFloating)) &&
|
|
((this->actor.yDistToWater >= 0.0f) || (func_80838144(sFloorType) >= 0) || func_8083816C(sFloorType));
|
|
|
|
if (cond && (this->actor.bgCheckFlags & 1) && (this->hoverBootsTimer != 0)) {
|
|
this->actor.bgCheckFlags &= ~1;
|
|
}
|
|
|
|
if (this->actor.bgCheckFlags & 1) {
|
|
if (!cond) {
|
|
this->hoverBootsTimer = 19;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
sFloorType = 0;
|
|
this->floorPitch = this->floorPitchAlt = sFloorShapePitch = 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* Peforms various tasks related to scene collision.
|
|
*
|
|
* This includes:
|
|
* - Update BgCheckInfo, parameters adjusted due to various state flags
|
|
* - Update floor type, floor property and floor sfx offset
|
|
* - Update conveyor, reverb and light settings according to the current floor poly
|
|
* - Handle exits and voids
|
|
* - Update information relating to the "interact wall"
|
|
* - Update information for ledge climbing
|
|
* - Update hover boots
|
|
* - Calculate floor poly angles
|
|
*
|
|
*/
|
|
void Player_ProcessSceneCollision(PlayState* play, Player* this) {
|
|
static Vec3f sInteractWallCheckOffset = { 0.0f, 18.0f, 0.0f };
|
|
u8 nextLedgeClimbType = 0;
|
|
CollisionPoly* floorPoly;
|
|
Vec3f unusedWorldPos;
|
|
f32 spB0;
|
|
f32 spAC;
|
|
f32 ceilingCheckHeight;
|
|
u32 flags;
|
|
|
|
sPrevFloorProperty = this->floorProperty;
|
|
|
|
if (this->stateFlags2 & PLAYER_STATE2_CRAWLING) {
|
|
spB0 = 10.0f;
|
|
spAC = 15.0f;
|
|
ceilingCheckHeight = 30.0f;
|
|
} else {
|
|
spB0 = this->ageProperties->wallCheckRadius;
|
|
spAC = 26.0f;
|
|
ceilingCheckHeight = this->ageProperties->ceilingCheckHeight;
|
|
}
|
|
|
|
if (this->stateFlags1 & (PLAYER_STATE1_IN_CUTSCENE | PLAYER_STATE1_FLOOR_DISABLED)) {
|
|
if (this->stateFlags1 & PLAYER_STATE1_FLOOR_DISABLED) {
|
|
this->actor.bgCheckFlags &= ~1;
|
|
flags = 0x38;
|
|
} else if ((this->stateFlags1 & PLAYER_STATE1_LOADING) && ((this->unk_A84 - (s32)this->actor.world.pos.y) >= 100)) {
|
|
flags = 0x39;
|
|
} else if (!(this->stateFlags1 & PLAYER_STATE1_LOADING) &&
|
|
((Player_Action_80845EF8 == this->actionFunc) || (Player_Action_80845CA4 == this->actionFunc))) {
|
|
this->actor.bgCheckFlags &= ~0x208;
|
|
flags = 0x3C;
|
|
} else {
|
|
flags = 0x3F;
|
|
}
|
|
} else {
|
|
flags = 0x3F;
|
|
}
|
|
|
|
if (this->stateFlags3 & PLAYER_STATE3_IGNORE_CEILING_FLOOR_WATER) {
|
|
flags &= ~6;
|
|
}
|
|
|
|
if (flags & 4) {
|
|
this->stateFlags3 |= PLAYER_STATE3_CHECK_FLOOR_WATER_COLLISION;
|
|
}
|
|
|
|
Math_Vec3f_Copy(&unusedWorldPos, &this->actor.world.pos);
|
|
Actor_UpdateBgCheckInfo(play, &this->actor, spAC, spB0, ceilingCheckHeight, flags);
|
|
|
|
if (this->actor.bgCheckFlags & 0x10) {
|
|
this->actor.velocity.y = 0.0f;
|
|
}
|
|
|
|
sYDistToFloor = this->actor.world.pos.y - this->actor.floorHeight;
|
|
sConveyorSpeed = 0;
|
|
|
|
floorPoly = this->actor.floorPoly;
|
|
|
|
if (floorPoly != NULL) {
|
|
this->floorProperty = func_80041EA4(&play->colCtx, floorPoly, this->actor.floorBgId);
|
|
this->prevFloorSfxOffset = this->floorSfxOffset;
|
|
|
|
if (this->actor.bgCheckFlags & 0x20) {
|
|
if (this->actor.yDistToWater < 20.0f) {
|
|
this->floorSfxOffset = 4;
|
|
} else {
|
|
this->floorSfxOffset = 5;
|
|
}
|
|
} else {
|
|
if (this->stateFlags2 & PLAYER_STATE2_SPAWN_DUST) {
|
|
this->floorSfxOffset = 1;
|
|
} else {
|
|
this->floorSfxOffset = SurfaceType_GetSfx(&play->colCtx, floorPoly, this->actor.floorBgId);
|
|
}
|
|
}
|
|
|
|
if (this->actor.category == ACTORCAT_PLAYER) {
|
|
Audio_SetCodeReverb(SurfaceType_GetEcho(&play->colCtx, floorPoly, this->actor.floorBgId));
|
|
|
|
if (this->actor.floorBgId == BGCHECK_SCENE) {
|
|
func_80074CE8(play,
|
|
SurfaceType_GetLightSettingIndex(&play->colCtx, floorPoly, this->actor.floorBgId));
|
|
} else {
|
|
func_80043508(&play->colCtx, this->actor.floorBgId);
|
|
}
|
|
}
|
|
|
|
sConveyorSpeed = SurfaceType_GetConveyorSpeed(&play->colCtx, floorPoly, this->actor.floorBgId);
|
|
if (sConveyorSpeed != 0) {
|
|
sIsFloorConveyor = SurfaceType_IsConveyor(&play->colCtx, floorPoly, this->actor.floorBgId);
|
|
if (((sIsFloorConveyor == 0) && (this->actor.yDistToWater > 20.0f) &&
|
|
(this->currentBoots != PLAYER_BOOTS_IRON)) ||
|
|
((sIsFloorConveyor != 0) && (this->actor.bgCheckFlags & 1))) {
|
|
sConveyorYaw = SurfaceType_GetConveyorDirection(&play->colCtx, floorPoly, this->actor.floorBgId) << 10;
|
|
} else {
|
|
sConveyorSpeed = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
Player_HandleExitsAndVoids(play, this, floorPoly, this->actor.floorBgId);
|
|
|
|
this->actor.bgCheckFlags &= ~0x200;
|
|
|
|
if (this->actor.bgCheckFlags & 8) {
|
|
CollisionPoly* wallPoly;
|
|
s32 wallBgId;
|
|
s16 yawDiff;
|
|
s32 pad;
|
|
|
|
sInteractWallCheckOffset.y = 18.0f;
|
|
sInteractWallCheckOffset.z = this->ageProperties->wallCheckRadius + 10.0f;
|
|
|
|
if (!(this->stateFlags2 & PLAYER_STATE2_CRAWLING) &&
|
|
Player_PosVsWallLineTest(play, this, &sInteractWallCheckOffset, &wallPoly, &wallBgId, &sInteractWallCheckResult)) {
|
|
this->actor.bgCheckFlags |= 0x200;
|
|
if (this->actor.wallPoly != wallPoly) {
|
|
this->actor.wallPoly = wallPoly;
|
|
this->actor.wallBgId = wallBgId;
|
|
this->actor.wallYaw = Math_Atan2S(wallPoly->normal.z, wallPoly->normal.x);
|
|
}
|
|
}
|
|
|
|
yawDiff = this->actor.shape.rot.y - (s16)(this->actor.wallYaw + 0x8000);
|
|
|
|
sTouchedWallFlags = func_80041DB8(&play->colCtx, this->actor.wallPoly, this->actor.wallBgId);
|
|
|
|
// conflicts arise from these two being enabled at once, and with ClimbEverything on, FixVineFall is redundant anyway
|
|
if (CVarGetInteger("gFixVineFall", 0) && !CVarGetInteger("gClimbEverything", 0)) {
|
|
/* This fixes the "started climbing a wall and then immediately fell off" bug.
|
|
* The main idea is if a climbing wall is detected, double-check that it will
|
|
* still be valid once climbing begins by doing a second raycast with a small
|
|
* margin to make sure it still hits a climbable poly. Then update the flags
|
|
* in sTouchedWallFlags again and proceed as normal.
|
|
*/
|
|
if (sTouchedWallFlags & 8) {
|
|
Vec3f checkPosA;
|
|
Vec3f checkPosB;
|
|
f32 yawCos;
|
|
f32 yawSin;
|
|
s32 hitWall;
|
|
|
|
/* Angle the raycast slightly out towards the side based on the angle of
|
|
* attack the player takes coming at the climb wall. This is necessary because
|
|
* the player's XZ position actually wobbles very slightly while climbing
|
|
* due to small rounding errors in the sin/cos lookup tables. This wobble
|
|
* can cause wall checks while climbing to be slightly left or right of
|
|
* the wall check to start the climb. By adding this buffer it accounts for
|
|
* any possible wobble. The end result is the player has to be further than
|
|
* some epsilon distance from the edge of the climbing poly to actually
|
|
* start the climb. I divide it by 2 to make that epsilon slightly smaller,
|
|
* mainly for visuals. Using the full yawDiff leaves a noticeable gap on
|
|
* the edges that can't be climbed. But with the half distance it looks like
|
|
* the player is climbing right on the edge, and still works.
|
|
*/
|
|
yawCos = Math_CosS(this->actor.wallYaw - (yawDiff / 2) + 0x8000);
|
|
yawSin = Math_SinS(this->actor.wallYaw - (yawDiff / 2) + 0x8000);
|
|
checkPosA.x = this->actor.world.pos.x + (-20.0f * yawSin);
|
|
checkPosA.z = this->actor.world.pos.z + (-20.0f * yawCos);
|
|
checkPosB.x = this->actor.world.pos.x + (50.0f * yawSin);
|
|
checkPosB.z = this->actor.world.pos.z + (50.0f * yawCos);
|
|
checkPosB.y = checkPosA.y = this->actor.world.pos.y + 26.0f;
|
|
|
|
hitWall = BgCheck_EntityLineTest1(&play->colCtx, &checkPosA, &checkPosB,
|
|
&sInteractWallCheckResult, &wallPoly, true, false, false, true, &wallBgId);
|
|
|
|
if (hitWall) {
|
|
this->actor.wallPoly = wallPoly;
|
|
this->actor.wallBgId = wallBgId;
|
|
this->actor.wallYaw = Math_Atan2S(wallPoly->normal.z, wallPoly->normal.x);
|
|
yawDiff = this->actor.shape.rot.y - (s16)(this->actor.wallYaw + 0x8000);
|
|
|
|
sTouchedWallFlags = func_80041DB8(&play->colCtx, this->actor.wallPoly, this->actor.wallBgId);
|
|
}
|
|
}
|
|
}
|
|
|
|
sShapeYawToTouchedWall = ABS(yawDiff);
|
|
|
|
yawDiff = this->yaw - (s16)(this->actor.wallYaw + 0x8000);
|
|
|
|
sWorldYawToTouchedWall = ABS(yawDiff);
|
|
|
|
spB0 = sWorldYawToTouchedWall * 0.00008f;
|
|
if (!(this->actor.bgCheckFlags & 1) || spB0 >= 1.0f) {
|
|
this->unk_880 = R_RUN_SPEED_LIMIT / 100.0f;
|
|
} else {
|
|
spAC = (R_RUN_SPEED_LIMIT / 100.0f * spB0);
|
|
this->unk_880 = spAC;
|
|
if (spAC < 0.1f) {
|
|
this->unk_880 = 0.1f;
|
|
}
|
|
}
|
|
|
|
if ((this->actor.bgCheckFlags & 0x200) && (sShapeYawToTouchedWall < 0x3000)) {
|
|
CollisionPoly* wallPoly = this->actor.wallPoly;
|
|
|
|
if ((ABS(wallPoly->normal.y) < 600) || (CVarGetInteger("gClimbEverything", 0) != 0)) {
|
|
f32 sp8C = COLPOLY_GET_NORMAL(wallPoly->normal.x);
|
|
f32 sp88 = COLPOLY_GET_NORMAL(wallPoly->normal.y);
|
|
f32 sp84 = COLPOLY_GET_NORMAL(wallPoly->normal.z);
|
|
f32 yDistToLedge;
|
|
CollisionPoly* sp7C;
|
|
CollisionPoly* sp78;
|
|
s32 sp74;
|
|
Vec3f sp68;
|
|
f32 sp64;
|
|
f32 sp60;
|
|
s32 temp3;
|
|
|
|
this->distToInteractWall = Math3D_UDistPlaneToPos(sp8C, sp88, sp84, wallPoly->dist, &this->actor.world.pos);
|
|
|
|
spB0 = this->distToInteractWall + 10.0f;
|
|
sp68.x = this->actor.world.pos.x - (spB0 * sp8C);
|
|
sp68.z = this->actor.world.pos.z - (spB0 * sp84);
|
|
sp68.y = this->actor.world.pos.y + this->ageProperties->unk_0C;
|
|
|
|
sp64 = BgCheck_EntityRaycastFloor1(&play->colCtx, &sp7C, &sp68);
|
|
yDistToLedge = sp64 - this->actor.world.pos.y;
|
|
this->yDistToLedge = yDistToLedge;
|
|
|
|
if ((this->yDistToLedge < 18.0f) ||
|
|
BgCheck_EntityCheckCeiling(&play->colCtx, &sp60, &this->actor.world.pos,
|
|
(sp64 - this->actor.world.pos.y) + 20.0f, &sp78, &sp74, &this->actor)) {
|
|
this->yDistToLedge = 399.96002f;
|
|
} else {
|
|
sInteractWallCheckOffset.y = (sp64 + 5.0f) - this->actor.world.pos.y;
|
|
|
|
if (Player_PosVsWallLineTest(play, this, &sInteractWallCheckOffset, &sp78, &sp74, &sInteractWallCheckResult) &&
|
|
(temp3 = this->actor.wallYaw - Math_Atan2S(sp78->normal.z, sp78->normal.x),
|
|
ABS(temp3) < 0x4000) &&
|
|
!func_80041E18(&play->colCtx, sp78, sp74)) {
|
|
this->yDistToLedge = 399.96002f;
|
|
} else if (func_80041DE4(&play->colCtx, wallPoly, this->actor.wallBgId) == 0) {
|
|
if (this->ageProperties->unk_1C <= this->yDistToLedge) {
|
|
if (ABS(sp7C->normal.y) > 28000) {
|
|
if (this->ageProperties->unk_14 <= this->yDistToLedge) {
|
|
nextLedgeClimbType = 4;
|
|
} else if (this->ageProperties->unk_18 <= this->yDistToLedge) {
|
|
nextLedgeClimbType = 3;
|
|
} else {
|
|
nextLedgeClimbType = 2;
|
|
}
|
|
}
|
|
} else {
|
|
nextLedgeClimbType = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
this->unk_880 = R_RUN_SPEED_LIMIT / 100.0f;
|
|
this->ledgeClimbDelayTimer = 0;
|
|
this->yDistToLedge = 0.0f;
|
|
}
|
|
|
|
if (nextLedgeClimbType == this->ledgeClimbType) {
|
|
if ((this->linearVelocity != 0.0f) && (this->ledgeClimbDelayTimer < 100)) {
|
|
this->ledgeClimbDelayTimer++;
|
|
}
|
|
} else {
|
|
this->ledgeClimbType = nextLedgeClimbType;
|
|
this->ledgeClimbDelayTimer = 0;
|
|
}
|
|
|
|
if (this->actor.bgCheckFlags & 1) {
|
|
sFloorType = func_80041D4C(&play->colCtx, floorPoly, this->actor.floorBgId);
|
|
|
|
if (!Player_UpdateHoverBoots(this)) {
|
|
f32 sp58;
|
|
f32 sp54;
|
|
f32 sp50;
|
|
f32 sp4C;
|
|
s32 pad2;
|
|
f32 sp44;
|
|
s32 pad3;
|
|
|
|
if (this->actor.floorBgId != BGCHECK_SCENE) {
|
|
func_800434C8(&play->colCtx, this->actor.floorBgId);
|
|
}
|
|
|
|
sp58 = COLPOLY_GET_NORMAL(floorPoly->normal.x);
|
|
sp54 = 1.0f / COLPOLY_GET_NORMAL(floorPoly->normal.y);
|
|
sp50 = COLPOLY_GET_NORMAL(floorPoly->normal.z);
|
|
|
|
sp4C = Math_SinS(this->yaw);
|
|
sp44 = Math_CosS(this->yaw);
|
|
|
|
this->floorPitch = Math_Atan2S(1.0f, (-(sp58 * sp4C) - (sp50 * sp44)) * sp54);
|
|
this->floorPitchAlt = Math_Atan2S(1.0f, (-(sp58 * sp44) - (sp50 * sp4C)) * sp54);
|
|
|
|
sp4C = Math_SinS(this->actor.shape.rot.y);
|
|
sp44 = Math_CosS(this->actor.shape.rot.y);
|
|
|
|
sFloorShapePitch = Math_Atan2S(1.0f, (-(sp58 * sp4C) - (sp50 * sp44)) * sp54);
|
|
|
|
Player_HandleSlopes(play, this, floorPoly);
|
|
}
|
|
} else {
|
|
Player_UpdateHoverBoots(this);
|
|
}
|
|
|
|
if (this->prevFloorType == sFloorType) {
|
|
this->floorTypeTimer++;
|
|
} else {
|
|
this->prevFloorType = sFloorType;
|
|
this->floorTypeTimer = 0;
|
|
}
|
|
}
|
|
|
|
void Player_UpdateCamAndSeqModes(PlayState* play, Player* this) {
|
|
u8 seqMode;
|
|
s32 pad;
|
|
Actor* unk_664;
|
|
s32 camMode;
|
|
|
|
if (this->actor.category == ACTORCAT_PLAYER) {
|
|
seqMode = SEQ_MODE_DEFAULT;
|
|
|
|
if (this->csAction != 0) {
|
|
Camera_ChangeMode(Play_GetCamera(play, 0), CAM_MODE_NORMAL);
|
|
} else if (!(this->stateFlags1 & PLAYER_STATE1_FIRST_PERSON)) {
|
|
if ((this->actor.parent != NULL) && (this->stateFlags3 & PLAYER_STATE3_HOOKSHOT_TRAVELLING)) {
|
|
camMode = CAM_MODE_HOOKSHOT;
|
|
Camera_SetParam(Play_GetCamera(play, 0), 8, this->actor.parent);
|
|
} else if (Player_Action_8084377C == this->actionFunc) {
|
|
camMode = CAM_MODE_STILL;
|
|
} else if (this->stateFlags2 & PLAYER_STATE2_GRABBING_DYNAPOLY) {
|
|
camMode = CAM_MODE_PUSHPULL;
|
|
} else if ((unk_664 = this->unk_664) != NULL) {
|
|
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_PLAYER_TALKED_TO)) {
|
|
camMode = CAM_MODE_TALK;
|
|
} else if (this->stateFlags1 & PLAYER_STATE1_TARGET_LOCKED) {
|
|
if (this->stateFlags1 & PLAYER_STATE1_THREW_BOOMERANG) {
|
|
camMode = CAM_MODE_FOLLOWBOOMERANG;
|
|
} else {
|
|
camMode = CAM_MODE_FOLLOWTARGET;
|
|
}
|
|
} else {
|
|
camMode = CAM_MODE_BATTLE;
|
|
}
|
|
Camera_SetParam(Play_GetCamera(play, 0), 8, unk_664);
|
|
} else if (this->stateFlags1 & PLAYER_STATE1_CHARGING_SPIN_ATTACK) {
|
|
camMode = CAM_MODE_CHARGE;
|
|
} else if (this->stateFlags1 & PLAYER_STATE1_THREW_BOOMERANG) {
|
|
camMode = CAM_MODE_FOLLOWBOOMERANG;
|
|
Camera_SetParam(Play_GetCamera(play, 0), 8, this->boomerangActor);
|
|
} else if (this->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE)) {
|
|
if (func_80833B2C(this)) {
|
|
camMode = CAM_MODE_HANGZ;
|
|
} else {
|
|
camMode = CAM_MODE_HANG;
|
|
}
|
|
} else if (this->stateFlags1 & (PLAYER_STATE1_TARGET_NOTHING | PLAYER_STATE1_30)) {
|
|
if (func_8002DD78(this) || func_808334B4(this)) {
|
|
camMode = CAM_MODE_BOWARROWZ;
|
|
} else if (this->stateFlags1 & PLAYER_STATE1_CLIMBING_LADDER) {
|
|
camMode = CAM_MODE_CLIMBZ;
|
|
} else {
|
|
camMode = CAM_MODE_TARGET;
|
|
}
|
|
} else if (this->stateFlags1 & (PLAYER_STATE1_JUMPING | PLAYER_STATE1_CLIMBING_LADDER)) {
|
|
if ((Player_Action_80845668 == this->actionFunc) || (this->stateFlags1 & PLAYER_STATE1_CLIMBING_LADDER)) {
|
|
camMode = CAM_MODE_CLIMB;
|
|
} else {
|
|
camMode = CAM_MODE_JUMP;
|
|
}
|
|
} else if (this->stateFlags1 & PLAYER_STATE1_FREEFALL) {
|
|
camMode = CAM_MODE_FREEFALL;
|
|
} else if ((this->meleeWeaponState != 0) && (this->meleeWeaponAnimation >= PLAYER_MWA_FORWARD_SLASH_1H) &&
|
|
(this->meleeWeaponAnimation < PLAYER_MWA_SPIN_ATTACK_1H)) {
|
|
camMode = CAM_MODE_STILL;
|
|
} else {
|
|
camMode = CAM_MODE_NORMAL;
|
|
if ((this->linearVelocity == 0.0f) &&
|
|
(!(this->stateFlags1 & PLAYER_STATE1_ON_HORSE) || (this->rideActor->speedXZ == 0.0f))) {
|
|
// not moving
|
|
seqMode = SEQ_MODE_STILL;
|
|
}
|
|
}
|
|
|
|
Camera_ChangeMode(Play_GetCamera(play, 0), camMode);
|
|
} else {
|
|
// First person mode
|
|
seqMode = SEQ_MODE_STILL;
|
|
}
|
|
|
|
if (play->actorCtx.targetCtx.bgmEnemy != NULL && !CVarGetInteger("gEnemyBGMDisable", 0)) {
|
|
seqMode = SEQ_MODE_ENEMY;
|
|
Audio_SetBgmEnemyVolume(sqrtf(play->actorCtx.targetCtx.bgmEnemy->xyzDistToPlayerSq));
|
|
}
|
|
|
|
if (play->sceneNum != SCENE_FISHING_POND) {
|
|
Audio_SetSequenceMode(seqMode);
|
|
}
|
|
}
|
|
}
|
|
|
|
static Vec3f D_808547A4 = { 0.0f, 0.5f, 0.0f };
|
|
static Vec3f D_808547B0 = { 0.0f, 0.5f, 0.0f };
|
|
|
|
static Color_RGBA8 D_808547BC = { 255, 255, 100, 255 };
|
|
static Color_RGBA8 D_808547C0 = { 255, 50, 0, 0 };
|
|
|
|
void func_80848A04(PlayState* play, Player* this) {
|
|
f32 temp;
|
|
|
|
if (CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE) {
|
|
f32 temp2 = 1.0f; // Secondary temporary variable to use with the alleged draw flame function
|
|
this->unk_860 = 200; // Keeps the stick's flame lit
|
|
this->unk_85C = 1.0f; // Ensures the stick is the proper length
|
|
func_8002836C(play, &this->meleeWeaponInfo[0].tip, &D_808547A4, &D_808547B0, &D_808547BC, &D_808547C0, temp2 * 200.0f,
|
|
0, 8); // I believe this draws the flame effect
|
|
}
|
|
|
|
if (this->unk_85C == 0.0f && CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) {
|
|
Player_UseItem(play, this, 0xFF);
|
|
return;
|
|
}
|
|
|
|
temp = 1.0f;
|
|
if (DECR(this->unk_860) == 0 && CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) {
|
|
Inventory_ChangeAmmo(ITEM_STICK, -1);
|
|
this->unk_860 = 1;
|
|
temp = 0.0f;
|
|
this->unk_85C = temp;
|
|
} else if (this->unk_860 > 200) {
|
|
temp = (210 - this->unk_860) / 10.0f;
|
|
} else if (this->unk_860 < 20 && CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_NORMAL) {
|
|
temp = this->unk_860 / 20.0f;
|
|
this->unk_85C = temp;
|
|
}
|
|
|
|
func_8002836C(play, &this->meleeWeaponInfo[0].tip, &D_808547A4, &D_808547B0, &D_808547BC, &D_808547C0, temp * 200.0f,
|
|
0, 8);
|
|
}
|
|
|
|
void Player_UpdateBodyShock(PlayState* play, Player* this) {
|
|
Vec3f shockPos;
|
|
Vec3f* randBodyPart;
|
|
s32 shockScale;
|
|
|
|
this->bodyShockTimer--;
|
|
this->unk_892 += this->bodyShockTimer;
|
|
|
|
if (this->unk_892 > 20) {
|
|
shockScale = this->bodyShockTimer * 2;
|
|
this->unk_892 -= 20;
|
|
|
|
if (shockScale > 40) {
|
|
shockScale = 40;
|
|
}
|
|
|
|
randBodyPart = this->bodyPartsPos + (s32)Rand_ZeroFloat(ARRAY_COUNT(this->bodyPartsPos) - 0.1f);
|
|
shockPos.x = (Rand_CenteredFloat(5.0f) + randBodyPart->x) - this->actor.world.pos.x;
|
|
shockPos.y = (Rand_CenteredFloat(5.0f) + randBodyPart->y) - this->actor.world.pos.y;
|
|
shockPos.z = (Rand_CenteredFloat(5.0f) + randBodyPart->z) - this->actor.world.pos.z;
|
|
|
|
EffectSsFhgFlash_SpawnShock(play, &this->actor, &shockPos, shockScale, FHGFLASH_SHOCK_PLAYER);
|
|
func_8002F8F0(&this->actor, NA_SE_PL_SPARK - SFX_FLAG);
|
|
}
|
|
}
|
|
|
|
void Player_UpdateBodyBurn(PlayState* play, Player* this) {
|
|
s32 spawnedFlame;
|
|
u8* timerPtr;
|
|
s32 timerStep;
|
|
f32 flameScale;
|
|
f32 flameIntensity;
|
|
s32 dmgCooldown;
|
|
s32 i;
|
|
s32 sp58;
|
|
s32 sp54;
|
|
|
|
if (this->currentTunic == PLAYER_TUNIC_GORON || CVarGetInteger("gSuperTunic", 0) != 0) {
|
|
sp54 = 20;
|
|
} else {
|
|
sp54 = (s32)(this->linearVelocity * 0.4f) + 1;
|
|
}
|
|
|
|
spawnedFlame = false;
|
|
timerPtr = this->bodyFlameTimers;
|
|
|
|
if (this->stateFlags2 & PLAYER_STATE2_FOOTSTEP) {
|
|
sp58 = 100;
|
|
} else {
|
|
sp58 = 0;
|
|
}
|
|
|
|
func_8083819C(this, play);
|
|
|
|
for (i = 0; i < PLAYER_BODYPART_MAX; i++, timerPtr++) {
|
|
timerStep = sp58 + sp54;
|
|
|
|
if (*timerPtr <= timerStep) {
|
|
*timerPtr = 0;
|
|
} else {
|
|
spawnedFlame = true;
|
|
*timerPtr -= timerStep;
|
|
|
|
if (*timerPtr > 20.0f) {
|
|
flameIntensity = (*timerPtr - 20.0f) * 0.01f;
|
|
flameScale = CLAMP(flameIntensity, 0.19999999f, 0.2f);
|
|
} else {
|
|
flameScale = *timerPtr * 0.01f;
|
|
}
|
|
|
|
flameIntensity = (*timerPtr - 25.0f) * 0.02f;
|
|
flameIntensity = CLAMP(flameIntensity, 0.0f, 1.0f);
|
|
EffectSsFireTail_SpawnFlameOnPlayer(play, flameScale, i, flameIntensity);
|
|
}
|
|
}
|
|
|
|
if (spawnedFlame) {
|
|
Player_PlaySfx(this, NA_SE_EV_TORCH - SFX_FLAG);
|
|
|
|
if (play->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) {
|
|
dmgCooldown = 0;
|
|
} else {
|
|
dmgCooldown = 7;
|
|
}
|
|
|
|
if ((dmgCooldown & play->gameplayFrames) == 0) {
|
|
Player_InflictDamage(play, -1);
|
|
}
|
|
} else {
|
|
this->bodyIsBurning = false;
|
|
}
|
|
}
|
|
|
|
void func_80848EF8(Player* this, PlayState* play) {
|
|
if (CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)) {
|
|
f32 temp = 200000.0f - (this->closestSecretDistSq * 5.0f);
|
|
|
|
if (temp < 0.0f) {
|
|
temp = 0.0f;
|
|
}
|
|
|
|
this->unk_6A0 += temp;
|
|
|
|
/*Prevent it on horse, while jumping and on title screen.
|
|
If you fly around no stone of agony for you! */
|
|
Color_RGB8 stoneOfAgonyColor = { 255, 255, 255 };
|
|
if (CVarGetInteger("gCosmetics.Hud_StoneOfAgony.Changed", 0)) {
|
|
stoneOfAgonyColor = CVarGetColor24("gCosmetics.Hud_StoneOfAgony.Value", stoneOfAgonyColor);
|
|
}
|
|
if (CVarGetInteger("gVisualAgony", 0) && !this->stateFlags1 && !GameInteractor_NoUIActive()) {
|
|
s16 Top_Margins = (CVarGetInteger("gHUDMargin_T", 0) * -1);
|
|
s16 Left_Margins = CVarGetInteger("gHUDMargin_L", 0);
|
|
s16 Right_Margins = CVarGetInteger("gHUDMargin_R", 0);
|
|
s16 X_Margins_VSOA;
|
|
s16 Y_Margins_VSOA;
|
|
if (CVarGetInteger("gVSOAUseMargins", 0) != 0) {
|
|
if (CVarGetInteger("gVSOAPosType", 0) == ORIGINAL_LOCATION) {
|
|
X_Margins_VSOA = Left_Margins;
|
|
};
|
|
Y_Margins_VSOA = Top_Margins;
|
|
} else {
|
|
X_Margins_VSOA = 0;
|
|
Y_Margins_VSOA = 0;
|
|
}
|
|
s16 PosX_VSOA_ori = OTRGetRectDimensionFromLeftEdge(26) + X_Margins_VSOA;
|
|
s16 PosY_VSOA_ori = 60 + Y_Margins_VSOA;
|
|
s16 PosX_VSOA;
|
|
s16 PosY_VSOA;
|
|
if (CVarGetInteger("gVSOAPosType", 0) != ORIGINAL_LOCATION) {
|
|
PosY_VSOA = CVarGetInteger("gVSOAPosY", 0) + Y_Margins_VSOA;
|
|
if (CVarGetInteger("gVSOAPosType", 0) == ANCHOR_LEFT) {
|
|
if (CVarGetInteger("gVSOAUseMargins", 0) != 0) {
|
|
X_Margins_VSOA = Left_Margins;
|
|
};
|
|
PosX_VSOA = OTRGetDimensionFromLeftEdge(CVarGetInteger("gVSOAPosX", 0) + X_Margins_VSOA);
|
|
} else if (CVarGetInteger("gVSOAPosType", 0) == ANCHOR_RIGHT) {
|
|
if (CVarGetInteger("gVSOAUseMargins", 0) != 0) {
|
|
X_Margins_VSOA = Right_Margins;
|
|
};
|
|
PosX_VSOA = OTRGetDimensionFromRightEdge(CVarGetInteger("gVSOAPosX", 0) + X_Margins_VSOA);
|
|
} else if (CVarGetInteger("gVSOAPosType", 0) == ANCHOR_NONE) {
|
|
PosX_VSOA = CVarGetInteger("gVSOAPosX", 0);
|
|
} else if (CVarGetInteger("gVSOAPosType", 0) == HIDDEN) {
|
|
PosX_VSOA = -9999;
|
|
}
|
|
} else {
|
|
PosY_VSOA = PosY_VSOA_ori;
|
|
PosX_VSOA = PosX_VSOA_ori;
|
|
}
|
|
|
|
int rectLeft = PosX_VSOA; // Left X Pos
|
|
int rectTop = PosY_VSOA; // Top Y Pos
|
|
int rectWidth = 24; // Texture Width
|
|
int rectHeight = 24; // Texture Heigh
|
|
int DefaultIconA = 50; // Default icon alpha (55 on 255)
|
|
|
|
OPEN_DISPS(play->state.gfxCtx);
|
|
gDPPipeSync(OVERLAY_DISP++);
|
|
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, stoneOfAgonyColor.r, stoneOfAgonyColor.g, stoneOfAgonyColor.b, DefaultIconA);
|
|
|
|
gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0,
|
|
PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
|
|
if (this->unk_6A0 > 4000000.0f) {
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, stoneOfAgonyColor.r, stoneOfAgonyColor.g, stoneOfAgonyColor.b, 255);
|
|
} else {
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, stoneOfAgonyColor.r, stoneOfAgonyColor.g, stoneOfAgonyColor.b, DefaultIconA);
|
|
}
|
|
if (temp == 0 || temp <= 0.1f) {
|
|
/*Fail check, it is used to draw off the icon when
|
|
link is standing out range but do not refresh unk_6A0.
|
|
Also used to make a default value in my case.*/
|
|
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, stoneOfAgonyColor.r, stoneOfAgonyColor.g, stoneOfAgonyColor.b, DefaultIconA);
|
|
}
|
|
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255);
|
|
gDPSetOtherMode(OVERLAY_DISP++,
|
|
G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_IA16 | G_TL_TILE |
|
|
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
|
G_AC_NONE | G_ZS_PRIM | G_RM_XLU_SURF | G_RM_XLU_SURF2);
|
|
gDPLoadTextureBlock(OVERLAY_DISP++, gQuestIconStoneOfAgonyTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 24, 24, 0,
|
|
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
|
|
G_TX_NOLOD, G_TX_NOLOD);
|
|
gDPSetOtherMode(OVERLAY_DISP++,
|
|
G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_IA16 | G_TL_TILE |
|
|
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
|
G_AC_NONE | G_ZS_PRIM | G_RM_XLU_SURF | G_RM_XLU_SURF2);
|
|
gSPWideTextureRectangle(OVERLAY_DISP++, rectLeft << 2, rectTop << 2, (rectLeft + rectWidth) << 2,
|
|
(rectTop + rectHeight) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
|
CLOSE_DISPS(play->state.gfxCtx);
|
|
}
|
|
|
|
if (this->unk_6A0 > 4000000.0f) {
|
|
this->unk_6A0 = 0.0f;
|
|
if (CVarGetInteger("gVisualAgony", 0) && !this->stateFlags1 && !GameInteractor_NoUIActive()) {
|
|
// This audio is placed here and not in previous CVar check to prevent ears ra.. :)
|
|
Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_WOMAN, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E0);
|
|
}
|
|
Player_RequestRumble(this, 120, 20, 10, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
static s8 D_808547C4[] = {
|
|
0, 3, 3, 5, 4, 8, 9, 13, 14, 15, 16, 17, 18, -22, 23, 24, 25, 26, 27, 28, 29, 31, 32, 33, 34, -35,
|
|
30, 36, 38, -39, -40, -41, 42, 43, 45, 46, 0, 0, 0, 67, 48, 47, -50, 51, -52, -53, 54, 55, 56, 57, 58, 59,
|
|
60, 61, 62, 63, 64, -65, -66, 68, 11, 69, 70, 71, 8, 8, 72, 73, 78, 79, 80, 89, 90, 91, 92, 77, 19, 94,
|
|
};
|
|
|
|
static Vec3f D_80854814 = { 0.0f, 0.0f, 200.0f };
|
|
|
|
static f32 D_80854820[] = { 2.0f, 4.0f, 7.0f };
|
|
static f32 D_8085482C[] = { 0.5f, 1.0f, 3.0f };
|
|
|
|
void Player_UseTunicBoots(Player* this, PlayState* play) {
|
|
// Boots and tunics equip despite state
|
|
if (
|
|
this->stateFlags1 & (PLAYER_STATE1_INPUT_DISABLED | PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE | PLAYER_STATE1_TEXT_ON_SCREEN | PLAYER_STATE1_DEAD) ||
|
|
this->stateFlags2 & PLAYER_STATE2_OCARINA_PLAYING
|
|
) {
|
|
return;
|
|
}
|
|
|
|
s32 i;
|
|
for (i = 0; i < ARRAY_COUNT(sItemButtons); i++) {
|
|
if (CHECK_BTN_ALL(sControlInput->press.button, sItemButtons[i])) {
|
|
break;
|
|
}
|
|
}
|
|
s32 item = Player_GetItemOnButton(play, i);
|
|
if (item >= ITEM_TUNIC_KOKIRI && item <= ITEM_BOOTS_HOVER) {
|
|
if (item >= ITEM_BOOTS_KOKIRI) {
|
|
u16 bootsValue = item - ITEM_BOOTS_KOKIRI + 1;
|
|
if (CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) == bootsValue) {
|
|
Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_KOKIRI);
|
|
} else {
|
|
Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, bootsValue);
|
|
}
|
|
Player_SetEquipmentData(play, this);
|
|
func_808328EC(this, CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) == EQUIP_VALUE_BOOTS_IRON ? NA_SE_PL_WALK_HEAVYBOOTS : NA_SE_PL_CHANGE_ARMS);
|
|
} else {
|
|
u16 tunicValue = item - ITEM_TUNIC_KOKIRI + 1;
|
|
if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) == tunicValue) {
|
|
Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_KOKIRI);
|
|
} else {
|
|
Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, tunicValue);
|
|
}
|
|
Player_SetEquipmentData(play, this);
|
|
func_808328EC(this, NA_SE_PL_CHANGE_ARMS);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_UpdateCommon(Player* this, PlayState* play, Input* input) {
|
|
s32 pad;
|
|
|
|
sControlInput = input;
|
|
|
|
if (this->unk_A86 < 0) {
|
|
this->unk_A86++;
|
|
if (this->unk_A86 == 0) {
|
|
this->unk_A86 = 1;
|
|
func_80078884(NA_SE_OC_REVENGE);
|
|
}
|
|
}
|
|
|
|
Math_Vec3f_Copy(&this->actor.prevPos, &this->actor.home.pos);
|
|
|
|
if (this->unk_A73 != 0) {
|
|
this->unk_A73--;
|
|
}
|
|
|
|
if (this->unk_88E != 0) {
|
|
this->unk_88E--;
|
|
}
|
|
|
|
if (this->unk_A87 != 0) {
|
|
this->unk_A87--;
|
|
}
|
|
|
|
if (this->invincibilityTimer < 0) {
|
|
this->invincibilityTimer++;
|
|
} else if (this->invincibilityTimer > 0) {
|
|
this->invincibilityTimer--;
|
|
}
|
|
|
|
if (this->unk_890 != 0) {
|
|
this->unk_890--;
|
|
}
|
|
|
|
func_808473D4(play, this);
|
|
func_80836BEC(this, play);
|
|
|
|
if ((this->heldItemAction == PLAYER_IA_DEKU_STICK) && ((this->unk_860 != 0) || CVarGetInteger("gDekuStickCheat", DEKU_STICK_NORMAL) == DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE)) {
|
|
func_80848A04(play, this);
|
|
} else if ((this->heldItemAction == PLAYER_IA_FISHING_POLE) && (this->unk_860 < 0)) {
|
|
this->unk_860++;
|
|
}
|
|
|
|
if (this->bodyShockTimer != 0) {
|
|
Player_UpdateBodyShock(play, this);
|
|
}
|
|
|
|
if (this->bodyIsBurning) {
|
|
Player_UpdateBodyBurn(play, this);
|
|
}
|
|
|
|
if ((this->stateFlags3 & PLAYER_STATE3_RESTORE_NAYRUS_LOVE) && (gSaveContext.nayrusLoveTimer != 0) && (gSaveContext.magicState == MAGIC_STATE_IDLE)) {
|
|
gSaveContext.magicState = MAGIC_STATE_METER_FLASH_1;
|
|
func_80846A00(play, this, 1);
|
|
this->stateFlags3 &= ~PLAYER_STATE3_RESTORE_NAYRUS_LOVE;
|
|
}
|
|
|
|
if (this->stateFlags2 & PLAYER_STATE2_PAUSE_MOST_UPDATING) {
|
|
if (!(this->actor.bgCheckFlags & 1)) {
|
|
Player_ZeroSpeedXZ(this);
|
|
Actor_MoveForward(&this->actor);
|
|
}
|
|
|
|
Player_ProcessSceneCollision(play, this);
|
|
} else {
|
|
f32 temp_f0;
|
|
f32 phi_f12;
|
|
|
|
if (this->currentBoots != this->prevBoots) {
|
|
if (this->currentBoots == PLAYER_BOOTS_IRON) {
|
|
if (this->stateFlags1 & PLAYER_STATE1_IN_WATER) {
|
|
func_80832340(play, this);
|
|
if (this->ageProperties->unk_2C < this->actor.yDistToWater) {
|
|
this->stateFlags2 |= PLAYER_STATE2_UNDERWATER;
|
|
}
|
|
}
|
|
} else {
|
|
if (this->stateFlags1 & PLAYER_STATE1_IN_WATER) {
|
|
if ((this->prevBoots == PLAYER_BOOTS_IRON) || (this->actor.bgCheckFlags & 1)) {
|
|
func_8083D36C(play, this);
|
|
this->stateFlags2 &= ~PLAYER_STATE2_UNDERWATER;
|
|
}
|
|
}
|
|
}
|
|
|
|
this->prevBoots = this->currentBoots;
|
|
}
|
|
|
|
if ((this->actor.parent == NULL) && (this->stateFlags1 & PLAYER_STATE1_ON_HORSE)) {
|
|
this->actor.parent = this->rideActor;
|
|
func_8083A360(play, this);
|
|
this->stateFlags1 |= PLAYER_STATE1_ON_HORSE;
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_uma_wait_1);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x9B);
|
|
this->av2.actionVar2 = 99;
|
|
}
|
|
|
|
if (this->unk_844 == 0) {
|
|
this->unk_845 = 0;
|
|
} else if (this->unk_844 < 0) {
|
|
this->unk_844++;
|
|
} else {
|
|
this->unk_844--;
|
|
}
|
|
|
|
Math_ScaledStepToS(&this->unk_6C2, 0, 400);
|
|
func_80032CB4(this->unk_3A8, 20, 80, 6);
|
|
|
|
this->actor.shape.face = this->unk_3A8[0] + ((play->gameplayFrames & 32) ? 0 : 3);
|
|
|
|
if (this->currentMask == PLAYER_MASK_BUNNY) {
|
|
Player_UpdateBunnyEars(this);
|
|
}
|
|
|
|
if (func_8002DD6C(this) != 0) {
|
|
func_8084FF7C(this);
|
|
}
|
|
|
|
if (!(this->skelAnime.moveFlags & 0x80)) {
|
|
if (((this->actor.bgCheckFlags & 1) && (sFloorType == 5) && (this->currentBoots != PLAYER_BOOTS_IRON)) ||
|
|
((this->currentBoots == PLAYER_BOOTS_HOVER || GameInteractor_GetSlipperyFloorActive()) &&
|
|
!(this->stateFlags1 & (PLAYER_STATE1_IN_WATER | PLAYER_STATE1_IN_CUTSCENE)))) {
|
|
f32 sp70 = this->linearVelocity;
|
|
s16 sp6E = this->yaw;
|
|
s16 yawDiff = this->actor.world.rot.y - sp6E;
|
|
s32 pad;
|
|
|
|
if ((ABS(yawDiff) > 0x6000) && (this->actor.speedXZ != 0.0f)) {
|
|
sp70 = 0.0f;
|
|
sp6E += 0x8000;
|
|
}
|
|
|
|
if (Math_StepToF(&this->actor.speedXZ, sp70, 0.35f) && (sp70 == 0.0f)) {
|
|
this->actor.world.rot.y = this->yaw;
|
|
}
|
|
|
|
if (this->linearVelocity != 0.0f) {
|
|
s32 phi_v0;
|
|
|
|
phi_v0 = (fabsf(this->linearVelocity) * 700.0f) - (fabsf(this->actor.speedXZ) * 100.0f);
|
|
phi_v0 = CLAMP(phi_v0, 0, 1350);
|
|
|
|
Math_ScaledStepToS(&this->actor.world.rot.y, sp6E, phi_v0);
|
|
}
|
|
|
|
if ((this->linearVelocity == 0.0f) && (this->actor.speedXZ != 0.0f)) {
|
|
func_800F4138(&this->actor.projectedPos, 0xD0, this->actor.speedXZ);
|
|
}
|
|
} else {
|
|
this->actor.speedXZ = this->linearVelocity;
|
|
this->actor.world.rot.y = this->yaw;
|
|
}
|
|
|
|
func_8002D868(&this->actor);
|
|
|
|
if ((this->pushedSpeed != 0.0f) && !Player_InCsMode(play) &&
|
|
!(this->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_CLIMBING_LADDER)) &&
|
|
(Player_Action_80845668 != this->actionFunc) && (Player_Action_808507F4 != this->actionFunc)) {
|
|
this->actor.velocity.x += this->pushedSpeed * Math_SinS(this->pushedYaw);
|
|
this->actor.velocity.z += this->pushedSpeed * Math_CosS(this->pushedYaw);
|
|
}
|
|
|
|
func_8002D7EC(&this->actor);
|
|
Player_ProcessSceneCollision(play, this);
|
|
} else {
|
|
sFloorType = 0;
|
|
this->floorProperty = 0;
|
|
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_LOADING) && (this->stateFlags1 & PLAYER_STATE1_ON_HORSE)) {
|
|
EnHorse* rideActor = (EnHorse*)this->rideActor;
|
|
CollisionPoly* sp5C;
|
|
s32 sp58;
|
|
Vec3f sp4C;
|
|
|
|
if (!(rideActor->actor.bgCheckFlags & 1)) {
|
|
func_808396F4(play, this, &D_80854814, &sp4C, &sp5C, &sp58);
|
|
} else {
|
|
sp5C = rideActor->actor.floorPoly;
|
|
sp58 = rideActor->actor.floorBgId;
|
|
}
|
|
|
|
if ((sp5C != NULL) && Player_HandleExitsAndVoids(play, this, sp5C, sp58)) {
|
|
if (DREG(25) != 0) {
|
|
DREG(25) = 0;
|
|
} else {
|
|
AREG(6) = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
sConveyorSpeed = 0;
|
|
this->pushedSpeed = 0.0f;
|
|
}
|
|
|
|
if ((sConveyorSpeed != 0) && (this->currentBoots != PLAYER_BOOTS_IRON)) {
|
|
f32 sp48;
|
|
|
|
sConveyorSpeed--;
|
|
|
|
if (sIsFloorConveyor == 0) {
|
|
sp48 = D_80854820[sConveyorSpeed];
|
|
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_IN_WATER)) {
|
|
sp48 *= 0.25f;
|
|
}
|
|
} else {
|
|
sp48 = D_8085482C[sConveyorSpeed];
|
|
}
|
|
|
|
Math_StepToF(&this->pushedSpeed, sp48, sp48 * 0.1f);
|
|
|
|
Math_ScaledStepToS(&this->pushedYaw, sConveyorYaw,
|
|
((this->stateFlags1 & PLAYER_STATE1_IN_WATER) ? 400.0f : 800.0f) * sp48);
|
|
} else if (this->pushedSpeed != 0.0f) {
|
|
Math_StepToF(&this->pushedSpeed, 0.0f, (this->stateFlags1 & PLAYER_STATE1_IN_WATER) ? 0.5f : 1.0f);
|
|
}
|
|
|
|
if (!Player_InBlockingCsMode(play, this) && !(this->stateFlags2 & PLAYER_STATE2_CRAWLING)) {
|
|
func_8083D53C(play, this);
|
|
|
|
if ((this->actor.category == ACTORCAT_PLAYER) && (gSaveContext.health == 0)) {
|
|
if (this->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_CLIMBING_LADDER)) {
|
|
func_80832440(play, this);
|
|
func_80837B9C(this, play);
|
|
} else if ((this->actor.bgCheckFlags & 1) || (this->stateFlags1 & PLAYER_STATE1_IN_WATER)) {
|
|
func_80836448(play, this,
|
|
func_808332B8(this) ? &gPlayerAnim_link_swimer_swim_down
|
|
: (this->bodyShockTimer != 0) ? &gPlayerAnim_link_normal_electric_shock_end
|
|
: &gPlayerAnim_link_derth_rebirth);
|
|
}
|
|
} else {
|
|
if ((this->actor.parent == NULL) &&
|
|
((play->transitionTrigger == TRANS_TRIGGER_START) || (this->unk_A87 != 0) || !func_808382DC(this, play))) {
|
|
func_8083AA10(this, play);
|
|
} else {
|
|
this->fallStartHeight = this->actor.world.pos.y;
|
|
}
|
|
func_80848EF8(this, play);
|
|
}
|
|
}
|
|
|
|
if ((play->csCtx.state != CS_STATE_IDLE) && (this->csAction != 6) &&
|
|
!(this->stateFlags1 & PLAYER_STATE1_ON_HORSE) && !(this->stateFlags2 & PLAYER_STATE2_GRABBED_BY_ENEMY) &&
|
|
(this->actor.category == ACTORCAT_PLAYER)) {
|
|
CsCmdActorAction* linkActionCsCmd = play->csCtx.linkAction;
|
|
|
|
if ((linkActionCsCmd != NULL) && (D_808547C4[linkActionCsCmd->action] != 0)) {
|
|
func_8002DF54(play, NULL, 6);
|
|
Player_ZeroSpeedXZ(this);
|
|
} else if ((this->csAction == 0) && !(this->stateFlags2 & PLAYER_STATE2_UNDERWATER) &&
|
|
(play->csCtx.state != CS_STATE_UNSKIPPABLE_INIT)) {
|
|
func_8002DF54(play, NULL, 0x31);
|
|
Player_ZeroSpeedXZ(this);
|
|
}
|
|
}
|
|
|
|
if (this->csAction != 0) {
|
|
if ((this->csAction != 7) ||
|
|
!(this->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_CLIMBING_LADDER | PLAYER_STATE1_DAMAGED))) {
|
|
this->unk_6AD = 3;
|
|
} else if (Player_Action_CsAction != this->actionFunc) {
|
|
func_80852944(play, this, NULL);
|
|
}
|
|
} else {
|
|
this->prevCsAction = 0;
|
|
}
|
|
|
|
func_8083D6EC(play, this);
|
|
|
|
if ((this->unk_664 == NULL) && (this->naviTextId == 0)) {
|
|
this->stateFlags2 &= ~(PLAYER_STATE2_SPEAK_OR_CHECK | PLAYER_STATE2_NAVI_ALERT);
|
|
}
|
|
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_SWINGING_BOTTLE | PLAYER_STATE1_READY_TO_FIRE | PLAYER_STATE1_CHARGING_SPIN_ATTACK | PLAYER_STATE1_SHIELDING);
|
|
this->stateFlags2 &= ~(PLAYER_STATE2_DO_ACTION_GRAB | PLAYER_STATE2_DO_ACTION_CLIMB | PLAYER_STATE2_FOOTSTEP | PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET | PLAYER_STATE2_DISABLE_ROTATION_ALWAYS |
|
|
PLAYER_STATE2_GRABBING_DYNAPOLY | PLAYER_STATE2_SPAWN_DUST | PLAYER_STATE2_STATIONARY_LADDER | PLAYER_STATE2_FROZEN |
|
|
PLAYER_STATE2_DO_ACTION_ENTER | PLAYER_STATE2_DO_ACTION_DOWN | PLAYER_STATE2_REFLECTION);
|
|
this->stateFlags3 &= ~PLAYER_STATE3_CHECK_FLOOR_WATER_COLLISION;
|
|
|
|
func_80847298(this);
|
|
Player_ProcessControlStick(play, this);
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_IN_WATER) {
|
|
D_808535E8 = 0.5f;
|
|
} else {
|
|
D_808535E8 = 1.0f;
|
|
}
|
|
|
|
D_808535EC = 1.0f / D_808535E8;
|
|
sUseHeldItem = sHeldItemButtonIsHeldDown = 0;
|
|
D_80858AA4 = this->currentMask;
|
|
|
|
if (!(this->stateFlags3 & PLAYER_STATE3_PAUSE_ACTION_FUNC)) {
|
|
this->actionFunc(this, play);
|
|
Player_UseTunicBoots(this, play);
|
|
}
|
|
|
|
Player_UpdateCamAndSeqModes(play, this);
|
|
|
|
if (this->skelAnime.moveFlags & 8) {
|
|
AnimationContext_SetMoveActor(play, &this->actor, &this->skelAnime,
|
|
(this->skelAnime.moveFlags & 4) ? 1.0f : this->ageProperties->unk_08);
|
|
}
|
|
|
|
func_808368EC(this, play);
|
|
|
|
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_PLAYER_TALKED_TO)) {
|
|
this->targetActorDistance = 0.0f;
|
|
} else {
|
|
this->targetActor = NULL;
|
|
this->targetActorDistance = FLT_MAX;
|
|
this->exchangeItemId = EXCH_ITEM_NONE;
|
|
}
|
|
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD)) {
|
|
this->interactRangeActor = NULL;
|
|
this->getItemDirection = 0x6000;
|
|
}
|
|
|
|
if (this->actor.parent == NULL) {
|
|
this->rideActor = NULL;
|
|
}
|
|
|
|
this->naviTextId = 0;
|
|
|
|
if (!(this->stateFlags2 & PLAYER_STATE2_PLAY_FOR_ACTOR)) {
|
|
this->unk_6A8 = NULL;
|
|
}
|
|
|
|
this->stateFlags2 &= ~PLAYER_STATE2_NEAR_OCARINA_ACTOR;
|
|
this->closestSecretDistSq = FLT_MAX;
|
|
|
|
temp_f0 = this->actor.world.pos.y - this->actor.prevPos.y;
|
|
|
|
this->doorType = PLAYER_DOORTYPE_NONE;
|
|
this->unk_8A1 = 0;
|
|
this->unk_684 = NULL;
|
|
|
|
phi_f12 =
|
|
((this->bodyPartsPos[PLAYER_BODYPART_L_FOOT].y + this->bodyPartsPos[PLAYER_BODYPART_R_FOOT].y) * 0.5f) +
|
|
temp_f0;
|
|
temp_f0 += this->bodyPartsPos[PLAYER_BODYPART_HEAD].y + 10.0f;
|
|
|
|
this->cylinder.dim.height = temp_f0 - phi_f12;
|
|
|
|
if (this->cylinder.dim.height < 0) {
|
|
phi_f12 = temp_f0;
|
|
this->cylinder.dim.height = -this->cylinder.dim.height;
|
|
}
|
|
|
|
this->cylinder.dim.yShift = phi_f12 - this->actor.world.pos.y;
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_SHIELDING) {
|
|
this->cylinder.dim.height = this->cylinder.dim.height * 0.8f;
|
|
}
|
|
|
|
Collider_UpdateCylinder(&this->actor, &this->cylinder);
|
|
|
|
if (!(this->stateFlags2 & PLAYER_STATE2_FROZEN)) {
|
|
if (!(this->stateFlags1 & (PLAYER_STATE1_DEAD | PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_ON_HORSE))) {
|
|
CollisionCheck_SetOC(play, &play->colChkCtx, &this->cylinder.base);
|
|
}
|
|
|
|
if (!(this->stateFlags1 & (PLAYER_STATE1_DEAD | PLAYER_STATE1_DAMAGED)) && (this->invincibilityTimer <= 0)) {
|
|
CollisionCheck_SetAC(play, &play->colChkCtx, &this->cylinder.base);
|
|
|
|
if (this->invincibilityTimer < 0) {
|
|
CollisionCheck_SetAT(play, &play->colChkCtx, &this->cylinder.base);
|
|
}
|
|
}
|
|
}
|
|
|
|
AnimationContext_SetNextQueue(play);
|
|
}
|
|
|
|
Math_Vec3f_Copy(&this->actor.home.pos, &this->actor.world.pos);
|
|
Math_Vec3f_Copy(&this->unk_A88, &this->bodyPartsPos[PLAYER_BODYPART_WAIST]);
|
|
|
|
if (this->stateFlags1 & (PLAYER_STATE1_DEAD | PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE)) {
|
|
this->actor.colChkInfo.mass = MASS_IMMOVABLE;
|
|
} else {
|
|
this->actor.colChkInfo.mass = 50;
|
|
}
|
|
|
|
this->stateFlags3 &= ~PLAYER_STATE3_PAUSE_ACTION_FUNC;
|
|
|
|
Collider_ResetCylinderAC(play, &this->cylinder.base);
|
|
|
|
Collider_ResetQuadAT(play, &this->meleeWeaponQuads[0].base);
|
|
Collider_ResetQuadAT(play, &this->meleeWeaponQuads[1].base);
|
|
|
|
Collider_ResetQuadAC(play, &this->shieldQuad.base);
|
|
Collider_ResetQuadAT(play, &this->shieldQuad.base);
|
|
}
|
|
|
|
static Vec3f D_80854838 = { 0.0f, 0.0f, -30.0f };
|
|
|
|
void Player_Update(Actor* thisx, PlayState* play) {
|
|
static Vec3f sDogSpawnPos;
|
|
Player* this = (Player*)thisx;
|
|
s32 dogParams;
|
|
s32 pad;
|
|
Input sp44;
|
|
Actor* dog;
|
|
|
|
if (func_8084FCAC(this, play)) {
|
|
if (gSaveContext.dogParams < 0) {
|
|
// Disable object dependency to prevent losing dog in scenes other than market
|
|
if (Object_GetIndex(&play->objectCtx, OBJECT_DOG) < 0 && !CVarGetInteger("gDogFollowsEverywhere", 0)) {
|
|
gSaveContext.dogParams = 0;
|
|
} else {
|
|
gSaveContext.dogParams &= 0x7FFF;
|
|
Player_GetRelativePosition(this, &this->actor.world.pos, &D_80854838, &sDogSpawnPos);
|
|
dogParams = gSaveContext.dogParams;
|
|
|
|
dog = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_DOG, sDogSpawnPos.x, sDogSpawnPos.y,
|
|
sDogSpawnPos.z, 0, this->actor.shape.rot.y, 0, dogParams | 0x8000, true);
|
|
if (dog != NULL) {
|
|
// Room -1 allows actor to cross between rooms, similar to Navi
|
|
dog->room = CVarGetInteger("gDogFollowsEverywhere", 0) ? -1 : 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((this->interactRangeActor != NULL) && (this->interactRangeActor->update == NULL)) {
|
|
this->interactRangeActor = NULL;
|
|
}
|
|
|
|
if ((this->heldActor != NULL) && (this->heldActor->update == NULL)) {
|
|
Player_DetachHeldActor(play, this);
|
|
}
|
|
|
|
if (this->stateFlags1 & (PLAYER_STATE1_INPUT_DISABLED | PLAYER_STATE1_IN_CUTSCENE)) {
|
|
memset(&sp44, 0, sizeof(sp44));
|
|
} else {
|
|
sp44 = play->state.input[0];
|
|
if (this->unk_88E != 0) {
|
|
sp44.cur.button &= ~(BTN_A | BTN_B | BTN_CUP);
|
|
sp44.press.button &= ~(BTN_A | BTN_B | BTN_CUP);
|
|
}
|
|
}
|
|
|
|
if (CVarGetInteger("gEnableWalkModify", 0) && CVarGetInteger("gWalkSpeedToggle", 0)) {
|
|
if (CHECK_BTN_ALL(sControlInput->press.button, BTN_MODIFIER1)) {
|
|
gWalkSpeedToggle1 = !gWalkSpeedToggle1;
|
|
}
|
|
if (CHECK_BTN_ALL(sControlInput->press.button, BTN_MODIFIER2)) {
|
|
gWalkSpeedToggle2 = !gWalkSpeedToggle2;
|
|
}
|
|
}
|
|
|
|
Player_UpdateCommon(this, play, &sp44);
|
|
}
|
|
|
|
MREG(52) = this->actor.world.pos.x;
|
|
MREG(53) = this->actor.world.pos.y;
|
|
MREG(54) = this->actor.world.pos.z;
|
|
MREG(55) = this->actor.world.rot.y;
|
|
|
|
// Make Link normal size when going through doors and crawlspaces and when climbing ladders.
|
|
// Otherwise Link can glitch out, being in unloaded rooms or falling OoB.
|
|
if (this->stateFlags1 & PLAYER_STATE1_CLIMBING_LADDER || this->stateFlags1 & PLAYER_STATE1_IN_CUTSCENE ||
|
|
this->stateFlags2 & PLAYER_STATE2_CRAWLING) {
|
|
this->actor.scale.x = 0.01f;
|
|
this->actor.scale.y = 0.01f;
|
|
this->actor.scale.z = 0.01f;
|
|
} else {
|
|
switch (GameInteractor_GetLinkSize()) {
|
|
case GI_LINK_SIZE_RESET:
|
|
this->actor.scale.x = 0.01f;
|
|
this->actor.scale.y = 0.01f;
|
|
this->actor.scale.z = 0.01f;
|
|
GameInteractor_SetLinkSize(GI_LINK_SIZE_NORMAL);
|
|
break;
|
|
case GI_LINK_SIZE_GIANT:
|
|
this->actor.scale.x = 0.02f;
|
|
this->actor.scale.y = 0.02f;
|
|
this->actor.scale.z = 0.02f;
|
|
break;
|
|
case GI_LINK_SIZE_MINISH:
|
|
this->actor.scale.x = 0.001f;
|
|
this->actor.scale.y = 0.001f;
|
|
this->actor.scale.z = 0.001f;
|
|
break;
|
|
case GI_LINK_SIZE_PAPER:
|
|
this->actor.scale.x = 0.001f;
|
|
this->actor.scale.y = 0.01f;
|
|
this->actor.scale.z = 0.01f;
|
|
break;
|
|
case GI_LINK_SIZE_SQUISHED:
|
|
this->actor.scale.x = 0.015f;
|
|
this->actor.scale.y = 0.001f;
|
|
this->actor.scale.z = 0.015f;
|
|
break;
|
|
case GI_LINK_SIZE_NORMAL:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Don't apply gravity when Link is in water, otherwise
|
|
// it makes him sink instead of float.
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_IN_WATER)) {
|
|
switch (GameInteractor_GravityLevel()) {
|
|
case GI_GRAVITY_LEVEL_HEAVY:
|
|
this->actor.gravity = -4.0f;
|
|
break;
|
|
case GI_GRAVITY_LEVEL_LIGHT:
|
|
this->actor.gravity = -0.3f;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (GameInteractor_GetRandomWindActive()) {
|
|
Player* player = GET_PLAYER(play);
|
|
player->pushedSpeed = 3.0f;
|
|
// Play fan sound (too annoying)
|
|
//func_8002F974(&player->actor, NA_SE_EV_WIND_TRAP - SFX_FLAG);
|
|
}
|
|
|
|
GameInteractor_ExecuteOnPlayerUpdate();
|
|
}
|
|
|
|
typedef struct {
|
|
/* 0x0 */ Vec3s rot;
|
|
/* 0x6 */ Vec3s angVel;
|
|
} BunnyEarKinematics; // size = 0xC
|
|
|
|
static BunnyEarKinematics sBunnyEarKinematics;
|
|
|
|
static Vec3s D_80858AD8[25];
|
|
|
|
static Gfx* sMaskDlists[PLAYER_MASK_MAX - 1] = {
|
|
gLinkChildKeatonMaskDL, gLinkChildSkullMaskDL, gLinkChildSpookyMaskDL, gLinkChildBunnyHoodDL,
|
|
gLinkChildGoronMaskDL, gLinkChildZoraMaskDL, gLinkChildGerudoMaskDL, gLinkChildMaskOfTruthDL,
|
|
};
|
|
|
|
static Vec3s D_80854864 = { 0, 0, 0 };
|
|
|
|
void Player_DrawGameplay(PlayState* play, Player* this, s32 lod, Gfx* cullDList, OverrideLimbDrawOpa overrideLimbDraw) {
|
|
static s32 D_8085486C = 255;
|
|
|
|
OPEN_DISPS(play->state.gfxCtx);
|
|
|
|
gSPSegment(POLY_OPA_DISP++, 0x0C, cullDList);
|
|
gSPSegment(POLY_XLU_DISP++, 0x0C, cullDList);
|
|
|
|
Player_DrawImpl(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, lod,
|
|
this->currentTunic, this->currentBoots, this->actor.shape.face, overrideLimbDraw, Player_PostLimbDrawGameplay,
|
|
this);
|
|
|
|
if ((overrideLimbDraw == Player_OverrideLimbDrawGameplayDefault) && (this->currentMask != PLAYER_MASK_NONE)) {
|
|
// Fixes a bug in vanilla where ice traps are rendered extremely large while wearing a bunny hood
|
|
if (CVarGetInteger("gFixIceTrapWithBunnyHood", 1)) Matrix_Push();
|
|
Mtx* bunnyEarMtx = Graph_Alloc(play->state.gfxCtx, 2 * sizeof(Mtx));
|
|
|
|
if (this->currentMask == PLAYER_MASK_BUNNY) {
|
|
Vec3s earRot;
|
|
|
|
FrameInterpolation_RecordActorPosRotMatrix();
|
|
gSPSegment(POLY_OPA_DISP++, 0x0B, bunnyEarMtx);
|
|
|
|
// Right ear
|
|
earRot.x = sBunnyEarKinematics.rot.y + 0x3E2;
|
|
earRot.y = sBunnyEarKinematics.rot.z + 0xDBE;
|
|
earRot.z = sBunnyEarKinematics.rot.x - 0x348A;
|
|
Matrix_SetTranslateRotateYXZ(97.0f, -1203.0f - CVarGetFloat("gCosmetics.BunnyHood_EarLength", 0.0f), -240.0f - CVarGetFloat("gCosmetics.BunnyHood_EarSpread", 0.0f), &earRot);
|
|
MATRIX_TOMTX(bunnyEarMtx++);
|
|
|
|
// Left ear
|
|
earRot.x = sBunnyEarKinematics.rot.y - 0x3E2;
|
|
earRot.y = -0xDBE - sBunnyEarKinematics.rot.z;
|
|
earRot.z = sBunnyEarKinematics.rot.x - 0x348A;
|
|
Matrix_SetTranslateRotateYXZ(97.0f, -1203.0f - CVarGetFloat("gCosmetics.BunnyHood_EarLength", 0.0f), 240.0f + CVarGetFloat("gCosmetics.BunnyHood_EarSpread", 0.0f), &earRot);
|
|
MATRIX_TOMTX(bunnyEarMtx);
|
|
}
|
|
|
|
|
|
if (this->currentMask != PLAYER_MASK_BUNNY || !CVarGetInteger("gHideBunnyHood", 0)) {
|
|
gSPDisplayList(POLY_OPA_DISP++, sMaskDlists[this->currentMask - 1]);
|
|
}
|
|
|
|
if (CVarGetInteger("gFixIceTrapWithBunnyHood", 1)) Matrix_Pop();
|
|
}
|
|
|
|
if ((this->currentBoots == PLAYER_BOOTS_HOVER ||
|
|
(CVarGetInteger("gIvanCoopModeEnabled", 0) && this->ivanFloating)) &&
|
|
!(this->actor.bgCheckFlags & 1) &&
|
|
!(this->stateFlags1 & PLAYER_STATE1_ON_HORSE) && (this->hoverBootsTimer != 0)) {
|
|
s32 sp5C;
|
|
s32 hoverBootsTimer = this->hoverBootsTimer;
|
|
|
|
if (this->hoverBootsTimer < 19) {
|
|
if (hoverBootsTimer >= 15) {
|
|
D_8085486C = (19 - hoverBootsTimer) * 51.0f;
|
|
} else if (hoverBootsTimer < 19) {
|
|
sp5C = hoverBootsTimer;
|
|
|
|
if (sp5C > 9) {
|
|
sp5C = 9;
|
|
}
|
|
|
|
D_8085486C = (-sp5C * 4) + 36;
|
|
D_8085486C = D_8085486C * D_8085486C;
|
|
D_8085486C = (s32)((Math_CosS(D_8085486C) * 100.0f) + 100.0f) + 55.0f;
|
|
D_8085486C = D_8085486C * (sp5C * (1.0f / 9.0f));
|
|
}
|
|
|
|
FrameInterpolation_RecordActorPosRotMatrix();
|
|
Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x, this->actor.world.pos.y + 2.0f,
|
|
this->actor.world.pos.z, &D_80854864);
|
|
Matrix_Scale(4.0f, 4.0f, 4.0f, MTXMODE_APPLY);
|
|
|
|
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
|
|
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
gSPSegment(POLY_XLU_DISP++, 0x08,
|
|
Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 16, 32, 1, 0,
|
|
(play->gameplayFrames * -15) % 128, 16, 32));
|
|
gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 255, D_8085486C);
|
|
gDPSetEnvColor(POLY_XLU_DISP++, 120, 90, 30, 128);
|
|
gSPDisplayList(POLY_XLU_DISP++, gHoverBootsCircleDL);
|
|
}
|
|
}
|
|
|
|
CLOSE_DISPS(play->state.gfxCtx);
|
|
}
|
|
|
|
void Player_Draw(Actor* thisx, PlayState* play2) {
|
|
PlayState* play = play2;
|
|
Player* this = (Player*)thisx;
|
|
|
|
Vec3f pos;
|
|
Vec3s rot;
|
|
f32 scale;
|
|
|
|
// OTRTODO: This is crashing randomly, so its temporarily been disabled
|
|
// return;
|
|
|
|
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
|
|
pos.x = 2.0f;
|
|
pos.y = -130.0f;
|
|
pos.z = -150.0f;
|
|
scale = 0.046f;
|
|
} else if (CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) != EQUIP_VALUE_SWORD_MASTER) {
|
|
pos.x = 25.0f;
|
|
pos.y = -228.0f;
|
|
pos.z = 60.0f;
|
|
scale = 0.056f;
|
|
} else {
|
|
pos.x = 20.0f;
|
|
pos.y = -180.0f;
|
|
pos.z = -40.0f;
|
|
scale = 0.047f;
|
|
}
|
|
|
|
rot.y = 32300;
|
|
rot.x = rot.z = 0;
|
|
|
|
OPEN_DISPS(play->state.gfxCtx);
|
|
|
|
if (!(this->stateFlags2 & PLAYER_STATE2_DISABLE_DRAW)) {
|
|
OverrideLimbDrawOpa overrideLimbDraw = Player_OverrideLimbDrawGameplayDefault;
|
|
s32 lod;
|
|
s32 pad;
|
|
|
|
if ((this->csAction != 0) || (func_8008E9C4(this) && 0) || (this->actor.projectedPos.z < 160.0f)) {
|
|
lod = 0;
|
|
} else {
|
|
lod = 1;
|
|
}
|
|
|
|
if (CVarGetInteger("gDisableLOD", 0) != 0) {
|
|
lod = 0;
|
|
}
|
|
|
|
func_80093C80(play);
|
|
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
|
|
|
|
if (this->invincibilityTimer > 0) {
|
|
this->unk_88F += CLAMP(50 - this->invincibilityTimer, 8, 40);
|
|
POLY_OPA_DISP =
|
|
Gfx_SetFog2(POLY_OPA_DISP, 255, 0, 0, 0, 0, 4000 - (s32)(Math_CosS(this->unk_88F * 256) * 2000.0f));
|
|
}
|
|
|
|
func_8002EBCC(&this->actor, play, 0);
|
|
func_8002ED80(&this->actor, play, 0);
|
|
|
|
if (this->unk_6AD != 0) {
|
|
Vec3f projectedHeadPos;
|
|
|
|
SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &this->actor.focus.pos, &projectedHeadPos);
|
|
if (projectedHeadPos.z < -4.0f) {
|
|
overrideLimbDraw = Player_OverrideLimbDrawGameplayFirstPerson;
|
|
}
|
|
} else if (this->stateFlags2 & PLAYER_STATE2_CRAWLING) {
|
|
if (this->actor.projectedPos.z < 0.0f) {
|
|
overrideLimbDraw = Player_OverrideLimbDrawGameplayCrawling;
|
|
}
|
|
}
|
|
|
|
if (this->stateFlags2 & PLAYER_STATE2_REFLECTION) {
|
|
f32 sp78 = ((u16)(play->gameplayFrames * 600) * M_PI) / 0x8000;
|
|
f32 sp74 = ((u16)(play->gameplayFrames * 1000) * M_PI) / 0x8000;
|
|
|
|
Matrix_Push();
|
|
this->actor.scale.y = -this->actor.scale.y;
|
|
Matrix_SetTranslateRotateYXZ(
|
|
this->actor.world.pos.x,
|
|
(this->actor.floorHeight + (this->actor.floorHeight - this->actor.world.pos.y)) +
|
|
(this->actor.shape.yOffset * this->actor.scale.y),
|
|
this->actor.world.pos.z, &this->actor.shape.rot);
|
|
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
|
|
Matrix_RotateX(sp78, MTXMODE_APPLY);
|
|
Matrix_RotateY(sp74, MTXMODE_APPLY);
|
|
Matrix_Scale(1.1f, 0.95f, 1.05f, MTXMODE_APPLY);
|
|
Matrix_RotateY(-sp74, MTXMODE_APPLY);
|
|
Matrix_RotateX(-sp78, MTXMODE_APPLY);
|
|
Player_DrawGameplay(play, this, lod, gCullFrontDList, overrideLimbDraw);
|
|
this->actor.scale.y = -this->actor.scale.y;
|
|
Matrix_Pop();
|
|
}
|
|
|
|
gSPClearGeometryMode(POLY_OPA_DISP++, G_CULL_BOTH);
|
|
gSPClearGeometryMode(POLY_XLU_DISP++, G_CULL_BOTH);
|
|
|
|
Player_DrawGameplay(play, this, lod, gCullBackDList, overrideLimbDraw);
|
|
|
|
if (this->invincibilityTimer > 0) {
|
|
POLY_OPA_DISP = Play_SetFog(play, POLY_OPA_DISP);
|
|
}
|
|
|
|
if (this->stateFlags2 & PLAYER_STATE2_FROZEN) {
|
|
f32 scale = (this->av1.actionVar1 >> 1) * 22.0f;
|
|
|
|
gSPSegment(POLY_XLU_DISP++, 0x08,
|
|
Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, (0 - play->gameplayFrames) % 128, 32, 32, 1,
|
|
0, (play->gameplayFrames * -2) % 128, 32, 32));
|
|
|
|
Matrix_Scale(scale, scale, scale, 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, 50, 100, 255);
|
|
gSPDisplayList(POLY_XLU_DISP++, gEffIceFragment3DL);
|
|
}
|
|
|
|
if (this->unk_862 > 0) {
|
|
Player_DrawGetItem(play, this);
|
|
}
|
|
}
|
|
|
|
CLOSE_DISPS(play->state.gfxCtx);
|
|
}
|
|
|
|
void Player_Destroy(Actor* thisx, PlayState* play) {
|
|
Player* this = (Player*)thisx;
|
|
|
|
Effect_Delete(play, this->meleeWeaponEffectIndex);
|
|
|
|
Collider_DestroyCylinder(play, &this->cylinder);
|
|
Collider_DestroyQuad(play, &this->meleeWeaponQuads[0]);
|
|
Collider_DestroyQuad(play, &this->meleeWeaponQuads[1]);
|
|
Collider_DestroyQuad(play, &this->shieldQuad);
|
|
|
|
Magic_Reset(play);
|
|
|
|
gSaveContext.linkAge = play->linkAgeOnLoad;
|
|
|
|
ResourceMgr_UnregisterSkeleton(&this->skelAnime);
|
|
ResourceMgr_UnregisterSkeleton(&this->upperSkelAnime);
|
|
}
|
|
|
|
//first person manipulate player actor
|
|
s16 func_8084ABD8(PlayState* play, Player* this, s32 arg2, s16 arg3) {
|
|
s32 temp1 = 0;
|
|
s16 temp2 = 0;
|
|
s16 temp3 = 0;
|
|
s8 invertXAxisMulti = ((CVarGetInteger("gInvertAimingXAxis", 0) && !CVarGetInteger("gMirroredWorld", 0)) || (!CVarGetInteger("gInvertAimingXAxis", 0) && CVarGetInteger("gMirroredWorld", 0))) ? -1 : 1;
|
|
s8 invertYAxisMulti = CVarGetInteger("gInvertAimingYAxis", 1) ? 1 : -1;
|
|
f32 xAxisMulti = CVarGetFloat("gFirstPersonCameraSensitivityX", 1.0f);
|
|
f32 yAxisMulti = CVarGetFloat("gFirstPersonCameraSensitivityY", 1.0f);
|
|
|
|
if (!func_8002DD78(this) && !func_808334B4(this) && (arg2 == 0)) { // First person without weapon
|
|
// Y Axis
|
|
if (!CVarGetInteger("gMoveWhileFirstPerson", 0)) {
|
|
temp2 += sControlInput->rel.stick_y * 240.0f * invertYAxisMulti * yAxisMulti;
|
|
}
|
|
if (CVarGetInteger("gRightStickAiming", 0) && fabsf(sControlInput->cur.right_stick_y) > 15.0f) {
|
|
temp2 += sControlInput->cur.right_stick_y * 240.0f * invertYAxisMulti * yAxisMulti;
|
|
}
|
|
if (fabsf(sControlInput->cur.gyro_x) > 0.01f) {
|
|
temp2 += (-sControlInput->cur.gyro_x) * 750.0f;
|
|
}
|
|
if (CVarGetInteger("gDisableAutoCenterViewFirstPerson", 0)) {
|
|
this->actor.focus.rot.x += temp2 * 0.1f;
|
|
this->actor.focus.rot.x = CLAMP(this->actor.focus.rot.x, -14000, 14000);
|
|
} else {
|
|
Math_SmoothStepToS(&this->actor.focus.rot.x, temp2, 14, 4000, 30);
|
|
}
|
|
|
|
// X Axis
|
|
temp2 = 0;
|
|
if (!CVarGetInteger("gMoveWhileFirstPerson", 0)) {
|
|
temp2 += sControlInput->rel.stick_x * -16.0f * invertXAxisMulti * xAxisMulti;
|
|
}
|
|
if (CVarGetInteger("gRightStickAiming", 0) && fabsf(sControlInput->cur.right_stick_x) > 15.0f) {
|
|
temp2 += sControlInput->cur.right_stick_x * -16.0f * invertXAxisMulti * xAxisMulti;
|
|
}
|
|
if (fabsf(sControlInput->cur.gyro_y) > 0.01f) {
|
|
temp2 += (sControlInput->cur.gyro_y) * 750.0f * invertXAxisMulti;
|
|
}
|
|
temp2 = CLAMP(temp2, -3000, 3000);
|
|
this->actor.focus.rot.y += temp2;
|
|
} else { // First person with weapon
|
|
// Y Axis
|
|
temp1 = (this->stateFlags1 & PLAYER_STATE1_ON_HORSE) ? 3500 : 14000;
|
|
|
|
if (!CVarGetInteger("gMoveWhileFirstPerson", 0)) {
|
|
temp3 += ((sControlInput->rel.stick_y >= 0) ? 1 : -1) *
|
|
(s32)((1.0f - Math_CosS(sControlInput->rel.stick_y * 200)) * 1500.0f) * invertYAxisMulti * yAxisMulti;
|
|
}
|
|
if (CVarGetInteger("gRightStickAiming", 0) && fabsf(sControlInput->cur.right_stick_y) > 15.0f) {
|
|
temp3 += ((sControlInput->cur.right_stick_y >= 0) ? 1 : -1) *
|
|
(s32)((1.0f - Math_CosS(sControlInput->cur.right_stick_y * 200)) * 1500.0f) * invertYAxisMulti * yAxisMulti;
|
|
}
|
|
if (fabsf(sControlInput->cur.gyro_x) > 0.01f) {
|
|
temp3 += (-sControlInput->cur.gyro_x) * 750.0f;
|
|
}
|
|
this->actor.focus.rot.x += temp3;
|
|
this->actor.focus.rot.x = CLAMP(this->actor.focus.rot.x, -temp1, temp1);
|
|
|
|
// X Axis
|
|
temp1 = 19114;
|
|
temp2 = this->actor.focus.rot.y - this->actor.shape.rot.y;
|
|
temp3 = 0;
|
|
if (!CVarGetInteger("gMoveWhileFirstPerson", 0)) {
|
|
temp3 = ((sControlInput->rel.stick_x >= 0) ? 1 : -1) *
|
|
(s32)((1.0f - Math_CosS(sControlInput->rel.stick_x * 200)) * -1500.0f) * invertXAxisMulti * xAxisMulti;
|
|
}
|
|
if (CVarGetInteger("gRightStickAiming", 0) && fabsf(sControlInput->cur.right_stick_x) > 15.0f) {
|
|
temp3 += ((sControlInput->cur.right_stick_x >= 0) ? 1 : -1) *
|
|
(s32)((1.0f - Math_CosS(sControlInput->cur.right_stick_x * 200)) * -1500.0f) * invertXAxisMulti * xAxisMulti;
|
|
}
|
|
if (fabsf(sControlInput->cur.gyro_y) > 0.01f) {
|
|
temp3 += (sControlInput->cur.gyro_y) * 750.0f * invertXAxisMulti;
|
|
}
|
|
temp2 += temp3;
|
|
this->actor.focus.rot.y = CLAMP(temp2, -temp1, temp1) + this->actor.shape.rot.y;
|
|
}
|
|
|
|
if (CVarGetInteger("gMoveWhileFirstPerson", 0)) {
|
|
f32 movementSpeed = LINK_IS_ADULT ? 9.0f : 8.25f;
|
|
if (CVarGetInteger("gMMBunnyHood", BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA && this->currentMask == PLAYER_MASK_BUNNY) {
|
|
movementSpeed *= 1.5f;
|
|
}
|
|
|
|
f32 relX = (sControlInput->rel.stick_x / 10 * -invertXAxisMulti);
|
|
f32 relY = (sControlInput->rel.stick_y / 10);
|
|
|
|
// Normalize so that diagonal movement isn't faster
|
|
f32 relMag = sqrtf((relX * relX) + (relY * relY));
|
|
if (relMag > 1.0f) {
|
|
relX /= relMag;
|
|
relY /= relMag;
|
|
}
|
|
|
|
// Determine what left and right mean based on camera angle
|
|
f32 relX2 = relX * Math_CosS(this->actor.focus.rot.y) + relY * Math_SinS(this->actor.focus.rot.y);
|
|
f32 relY2 = relY * Math_CosS(this->actor.focus.rot.y) - relX * Math_SinS(this->actor.focus.rot.y);
|
|
|
|
// Calculate distance for footstep sound
|
|
f32 distance = sqrtf((relX2 * relX2) + (relY2 * relY2)) * movementSpeed;
|
|
func_8084029C(this, distance / 4.5f);
|
|
|
|
this->actor.world.pos.x += (relX2 * movementSpeed) + this->actor.colChkInfo.displacement.x;
|
|
this->actor.world.pos.z += (relY2 * movementSpeed) + this->actor.colChkInfo.displacement.z;
|
|
}
|
|
|
|
this->unk_6AE |= 2;
|
|
return func_80836AB8(this, (play->shootingGalleryStatus != 0) || func_8002DD78(this) || func_808334B4(this)) - arg3;
|
|
}
|
|
|
|
void func_8084AEEC(Player* this, f32* arg1, f32 arg2, s16 arg3) {
|
|
f32 temp1;
|
|
f32 temp2;
|
|
|
|
// #region SOH [Enhancement]
|
|
f32 swimMod = 1.0f;
|
|
|
|
if (CVarGetInteger("gEnableWalkModify", 0) == 1) {
|
|
if (CVarGetInteger("gWalkSpeedToggle", 0) == 1) {
|
|
if (gWalkSpeedToggle1) {
|
|
swimMod *= CVarGetFloat("gSwimModifierOne", 1.0f);
|
|
} else if (gWalkSpeedToggle2) {
|
|
swimMod *= CVarGetFloat("gSwimModifierTwo", 1.0f);
|
|
}
|
|
} else {
|
|
if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_MODIFIER1)) {
|
|
swimMod *= CVarGetFloat("gSwimModifierOne", 1.0f);
|
|
} else if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_MODIFIER2)) {
|
|
swimMod *= CVarGetFloat("gSwimModifierTwo", 1.0f);
|
|
}
|
|
}
|
|
temp1 = this->skelAnime.curFrame - 10.0f;
|
|
|
|
temp2 = (R_RUN_SPEED_LIMIT / 100.0f) * 0.8f * swimMod;
|
|
if (*arg1 > temp2) {
|
|
*arg1 = temp2;
|
|
}
|
|
|
|
if ((0.0f < temp1) && (temp1 < 10.0f)) {
|
|
temp1 *= 6.0f;
|
|
} else {
|
|
temp1 = 0.0f;
|
|
arg2 = 0.0f;
|
|
}
|
|
|
|
Math_AsymStepToF(arg1, arg2 * 0.8f * swimMod, temp1, (fabsf(*arg1) * 0.02f) + 0.05f);
|
|
Math_ScaledStepToS(&this->yaw, arg3, 1600);
|
|
// #endregion
|
|
} else {
|
|
|
|
temp1 = this->skelAnime.curFrame - 10.0f;
|
|
|
|
temp2 = (R_RUN_SPEED_LIMIT / 100.0f) * 0.8f;
|
|
if (*arg1 > temp2) {
|
|
*arg1 = temp2;
|
|
}
|
|
|
|
if ((0.0f < temp1) && (temp1 < 10.0f)) {
|
|
temp1 *= 6.0f;
|
|
} else {
|
|
temp1 = 0.0f;
|
|
arg2 = 0.0f;
|
|
}
|
|
|
|
Math_AsymStepToF(arg1, arg2 * 0.8f, temp1, (fabsf(*arg1) * 0.02f) + 0.05f);
|
|
Math_ScaledStepToS(&this->yaw, arg3, 1600);
|
|
}
|
|
}
|
|
|
|
// #region SOH [Enhancement]
|
|
//Diving uses function func_8084AEEC to calculate changes both xz and y velocity (via func_8084DBC4)
|
|
//Provide original calculation for y velocity when swim speed mod is active
|
|
void SurfaceWithoutSwimMod(Player* this, f32* arg1, f32 arg2, s16 arg3) {
|
|
f32 temp1;
|
|
f32 temp2;
|
|
|
|
temp1 = this->skelAnime.curFrame - 10.0f;
|
|
|
|
temp2 = (R_RUN_SPEED_LIMIT / 100.0f) * 0.8f;
|
|
if (*arg1 > temp2) {
|
|
*arg1 = temp2;
|
|
}
|
|
|
|
if ((0.0f < temp1) && (temp1 < 10.0f)) {
|
|
temp1 *= 6.0f;
|
|
} else {
|
|
temp1 = 0.0f;
|
|
arg2 = 0.0f;
|
|
}
|
|
|
|
Math_AsymStepToF(arg1, arg2 * 0.8f, temp1, (fabsf(*arg1) * 0.02f) + 0.05f);
|
|
Math_ScaledStepToS(&this->yaw, arg3, 1600);
|
|
}
|
|
// #endregion
|
|
|
|
void func_8084B000(Player* this) {
|
|
f32 phi_f18;
|
|
f32 phi_f16;
|
|
f32 phi_f14;
|
|
f32 yDistToWater;
|
|
|
|
phi_f14 = -5.0f;
|
|
|
|
phi_f16 = this->ageProperties->unk_28;
|
|
if (this->actor.velocity.y < 0.0f) {
|
|
phi_f16 += 1.0f;
|
|
}
|
|
|
|
if (this->actor.yDistToWater < phi_f16) {
|
|
if (this->actor.velocity.y <= 0.0f) {
|
|
phi_f16 = 0.0f;
|
|
} else {
|
|
phi_f16 = this->actor.velocity.y * 0.5f;
|
|
}
|
|
phi_f18 = -0.1f - phi_f16;
|
|
} else {
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_DEAD) && (this->currentBoots == PLAYER_BOOTS_IRON) &&
|
|
(this->actor.velocity.y >= -3.0f)) {
|
|
phi_f18 = -0.2f;
|
|
} else {
|
|
phi_f14 = 2.0f;
|
|
if (this->actor.velocity.y >= 0.0f) {
|
|
phi_f16 = 0.0f;
|
|
} else {
|
|
phi_f16 = this->actor.velocity.y * -0.3f;
|
|
}
|
|
phi_f18 = phi_f16 + 0.1f;
|
|
}
|
|
|
|
yDistToWater = this->actor.yDistToWater;
|
|
if (yDistToWater > 100.0f) {
|
|
this->stateFlags2 |= PLAYER_STATE2_UNDERWATER;
|
|
}
|
|
}
|
|
|
|
this->actor.velocity.y += phi_f18;
|
|
|
|
if (((this->actor.velocity.y - phi_f14) * phi_f18) > 0) {
|
|
this->actor.velocity.y = phi_f14;
|
|
}
|
|
|
|
this->actor.gravity = 0.0f;
|
|
}
|
|
|
|
void func_8084B158(PlayState* play, Player* this, Input* input, f32 arg3) {
|
|
f32 temp;
|
|
|
|
if ((input != NULL) && CHECK_BTN_ANY(input->press.button, BTN_A | BTN_B)) {
|
|
temp = 1.0f;
|
|
} else {
|
|
temp = 0.5f;
|
|
}
|
|
|
|
temp *= arg3;
|
|
|
|
if (temp < 1.0f) {
|
|
temp = 1.0f;
|
|
}
|
|
|
|
this->skelAnime.playSpeed = temp;
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
}
|
|
|
|
void Player_Action_8084B1D8(Player* this, PlayState* play) {
|
|
if (this->stateFlags1 & PLAYER_STATE1_IN_WATER) {
|
|
func_8084B000(this);
|
|
func_8084AEEC(this, &this->linearVelocity, 0, this->actor.shape.rot.y);
|
|
} else {
|
|
func_8083721C(this);
|
|
}
|
|
|
|
if ((this->unk_6AD == 2) && (func_8002DD6C(this) || func_808332E4(this))) {
|
|
Player_UpdateUpperBody(this, play);
|
|
}
|
|
|
|
u16 buttonsToCheck = BTN_A | BTN_B | BTN_R | BTN_CUP | BTN_CLEFT | BTN_CRIGHT | BTN_CDOWN;
|
|
if (CVarGetInteger("gDpadEquips", 0) != 0) {
|
|
buttonsToCheck |= BTN_DUP | BTN_DDOWN | BTN_DLEFT | BTN_DRIGHT;
|
|
}
|
|
if ((this->csAction != 0) || (this->unk_6AD == 0) || (this->unk_6AD >= 4) || func_80833B54(this) ||
|
|
(this->unk_664 != NULL) || !func_8083AD4C(play, this) ||
|
|
(((this->unk_6AD == 2) && (CHECK_BTN_ANY(sControlInput->press.button, BTN_A | BTN_B | BTN_R) ||
|
|
func_80833B2C(this) || (!func_8002DD78(this) && !func_808334B4(this)))) ||
|
|
((this->unk_6AD == 1) && CHECK_BTN_ANY(sControlInput->press.button, buttonsToCheck)))) {
|
|
func_8083C148(this, play);
|
|
func_80078884(NA_SE_SY_CAMERA_ZOOM_UP);
|
|
} else if ((DECR(this->av2.actionVar2) == 0) || (this->unk_6AD != 2)) {
|
|
if (func_8008F128(this)) {
|
|
this->unk_6AE |= 0x43;
|
|
} else {
|
|
this->actor.shape.rot.y = func_8084ABD8(play, this, 0, 0);
|
|
}
|
|
}
|
|
|
|
this->yaw = this->actor.shape.rot.y;
|
|
}
|
|
|
|
s32 func_8084B3CC(PlayState* play, Player* this) {
|
|
if (play->shootingGalleryStatus != 0) {
|
|
func_80832564(play, this);
|
|
Player_SetupAction(play, this, Player_Action_8084FA54, 0);
|
|
|
|
if (!func_8002DD6C(this) || Player_HoldsHookshot(this)) {
|
|
s32 projectileItemToUse = ITEM_BOW;
|
|
if(CVarGetInteger("gBowSlingShotAmmoFix", 0)){
|
|
projectileItemToUse = LINK_IS_ADULT ? ITEM_BOW : ITEM_SLINGSHOT;
|
|
}
|
|
|
|
Player_UseItem(play, this, projectileItemToUse);
|
|
}
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_FIRST_PERSON;
|
|
Player_AnimPlayOnce(play, this, func_80833338(this));
|
|
Player_ZeroSpeedXZ(this);
|
|
func_8083B010(this);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8084B498(Player* this) {
|
|
this->itemAction =
|
|
(INV_CONTENT(ITEM_OCARINA_FAIRY) == ITEM_OCARINA_FAIRY) ? PLAYER_IA_OCARINA_FAIRY : PLAYER_IA_OCARINA_OF_TIME;
|
|
}
|
|
|
|
s32 func_8084B4D4(PlayState* play, Player* this) {
|
|
if (this->stateFlags3 & PLAYER_STATE3_FORCE_PULL_OCARINA) {
|
|
this->stateFlags3 &= ~PLAYER_STATE3_FORCE_PULL_OCARINA;
|
|
func_8084B498(this);
|
|
this->unk_6AD = 4;
|
|
Player_ActionChange_13(this, play);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Player_Action_8084B530(Player* this, PlayState* play) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
Player_UpdateUpperBody(this, play);
|
|
|
|
if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) {
|
|
this->actor.flags &= ~ACTOR_FLAG_PLAYER_TALKED_TO;
|
|
|
|
if (!CHECK_FLAG_ALL(this->targetActor->flags, ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE)) {
|
|
this->stateFlags2 &= ~PLAYER_STATE2_SWITCH_TARGETING;
|
|
}
|
|
|
|
func_8005B1A4(Play_GetCamera(play, 0));
|
|
|
|
if (!func_8084B4D4(play, this) && !func_8084B3CC(play, this) && !Player_StartCsAction(play, this)) {
|
|
if ((this->targetActor != this->interactRangeActor) || !Player_ActionChange_2(this, play)) {
|
|
if (this->stateFlags1 & PLAYER_STATE1_ON_HORSE) {
|
|
s32 sp24 = this->av2.actionVar2;
|
|
func_8083A360(play, this);
|
|
this->av2.actionVar2 = sp24;
|
|
} else if (func_808332B8(this)) {
|
|
func_80838F18(play, this);
|
|
} else {
|
|
func_80853080(this, play);
|
|
}
|
|
}
|
|
}
|
|
|
|
this->unk_88E = 10;
|
|
return;
|
|
}
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_ON_HORSE) {
|
|
Player_Action_8084CC98(this, play);
|
|
} else if (func_808332B8(this)) {
|
|
Player_Action_8084D610(this, play);
|
|
} else if (!func_8008E9C4(this) && LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (this->skelAnime.moveFlags != 0) {
|
|
func_80832DBC(this);
|
|
if ((this->targetActor->category == ACTORCAT_NPC) &&
|
|
(this->heldItemAction != PLAYER_IA_FISHING_POLE)) {
|
|
Player_AnimPlayOnceAdjusted(play, this, &gPlayerAnim_link_normal_talk_free);
|
|
} else {
|
|
Player_AnimPlayLoop(play, this, func_80833338(this));
|
|
}
|
|
} else {
|
|
Player_AnimPlayLoopAdjusted(play, this, &gPlayerAnim_link_normal_talk_free_wait);
|
|
}
|
|
}
|
|
|
|
if (this->unk_664 != NULL) {
|
|
this->yaw = this->actor.shape.rot.y = func_8083DB98(this, 0);
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084B78C(Player* this, PlayState* play) {
|
|
f32 sp34;
|
|
s16 sp32;
|
|
s32 temp;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DO_ACTION_GRAB | PLAYER_STATE2_DISABLE_ROTATION_ALWAYS | PLAYER_STATE2_GRABBING_DYNAPOLY;
|
|
func_8083F524(play, this);
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (!func_8083F9D0(play, this)) {
|
|
Player_GetMovementSpeedAndYaw(this, &sp34, &sp32, SPEED_MODE_LINEAR, play);
|
|
temp = func_8083FFB8(this, &sp34, &sp32);
|
|
if (temp > 0) {
|
|
func_8083FAB8(this, play);
|
|
} else if (temp < 0) {
|
|
func_8083FB14(this, play);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void func_8084B840(PlayState* play, Player* this, f32 arg2) {
|
|
if (this->actor.wallBgId != BGCHECK_SCENE) {
|
|
DynaPolyActor* dynaPolyActor = DynaPoly_GetActor(&play->colCtx, this->actor.wallBgId);
|
|
|
|
if (dynaPolyActor != NULL) {
|
|
func_8002DFA4(dynaPolyActor, arg2, this->actor.world.rot.y);
|
|
}
|
|
}
|
|
}
|
|
|
|
static AnimSfxEntry D_80854870[] = {
|
|
{ NA_SE_PL_SLIP, ANIMSFX_DATA(ANIMSFX_TYPE_2, 3) },
|
|
{ NA_SE_PL_SLIP, -ANIMSFX_DATA(ANIMSFX_TYPE_2, 21) },
|
|
};
|
|
|
|
void Player_Action_8084B898(Player* this, PlayState* play) {
|
|
f32 sp34;
|
|
s16 sp32;
|
|
s32 temp;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DO_ACTION_GRAB | PLAYER_STATE2_DISABLE_ROTATION_ALWAYS | PLAYER_STATE2_GRABBING_DYNAPOLY;
|
|
|
|
if (func_80832CB0(play, this, &gPlayerAnim_link_normal_pushing)) {
|
|
this->av2.actionVar2 = 1;
|
|
} else if (this->av2.actionVar2 == 0) {
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 11.0f)) {
|
|
func_80832698(this, NA_SE_VO_LI_PUSH);
|
|
}
|
|
}
|
|
|
|
Player_ProcessAnimSfxList(this, D_80854870);
|
|
func_8083F524(play, this);
|
|
|
|
if (!func_8083F9D0(play, this)) {
|
|
Player_GetMovementSpeedAndYaw(this, &sp34, &sp32, SPEED_MODE_LINEAR, play);
|
|
temp = func_8083FFB8(this, &sp34, &sp32);
|
|
if (temp < 0) {
|
|
func_8083FB14(this, play);
|
|
} else if (temp == 0) {
|
|
func_8083F72C(this, &gPlayerAnim_link_normal_push_end, play);
|
|
} else {
|
|
this->stateFlags2 |= PLAYER_STATE2_MOVING_DYNAPOLY;
|
|
}
|
|
}
|
|
|
|
if (this->stateFlags2 & PLAYER_STATE2_MOVING_DYNAPOLY) {
|
|
func_8084B840(play, this, 2.0f);
|
|
this->linearVelocity = 2.0f;
|
|
}
|
|
}
|
|
|
|
static AnimSfxEntry D_80854878[] = {
|
|
{ NA_SE_PL_SLIP, ANIMSFX_DATA(ANIMSFX_TYPE_2, 4) },
|
|
{ NA_SE_PL_SLIP, -ANIMSFX_DATA(ANIMSFX_TYPE_2, 24) },
|
|
};
|
|
|
|
static Vec3f D_80854880 = { 0.0f, 26.0f, -40.0f };
|
|
|
|
void Player_Action_8084B9E4(Player* this, PlayState* play) {
|
|
LinkAnimationHeader* anim;
|
|
f32 sp70;
|
|
s16 sp6E;
|
|
s32 temp1;
|
|
Vec3f sp5C;
|
|
f32 temp2;
|
|
CollisionPoly* sp54;
|
|
s32 sp50;
|
|
Vec3f sp44;
|
|
Vec3f sp38;
|
|
|
|
anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_pulling, this->modelAnimType);
|
|
this->stateFlags2 |= PLAYER_STATE2_DO_ACTION_GRAB | PLAYER_STATE2_DISABLE_ROTATION_ALWAYS | PLAYER_STATE2_GRABBING_DYNAPOLY;
|
|
|
|
if (func_80832CB0(play, this, anim)) {
|
|
this->av2.actionVar2 = 1;
|
|
} else {
|
|
if (this->av2.actionVar2 == 0) {
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 11.0f)) {
|
|
func_80832698(this, NA_SE_VO_LI_PUSH);
|
|
}
|
|
} else {
|
|
Player_ProcessAnimSfxList(this, D_80854878);
|
|
}
|
|
}
|
|
|
|
func_8083F524(play, this);
|
|
|
|
if (!func_8083F9D0(play, this)) {
|
|
Player_GetMovementSpeedAndYaw(this, &sp70, &sp6E, SPEED_MODE_LINEAR, play);
|
|
temp1 = func_8083FFB8(this, &sp70, &sp6E);
|
|
if (temp1 > 0) {
|
|
func_8083FAB8(this, play);
|
|
} else if (temp1 == 0) {
|
|
func_8083F72C(this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_pull_end, this->modelAnimType), play);
|
|
} else {
|
|
this->stateFlags2 |= PLAYER_STATE2_MOVING_DYNAPOLY;
|
|
}
|
|
}
|
|
|
|
if (this->stateFlags2 & PLAYER_STATE2_MOVING_DYNAPOLY) {
|
|
temp2 = func_8083973C(play, this, &D_80854880, &sp5C) - this->actor.world.pos.y;
|
|
if (fabsf(temp2) < 20.0f) {
|
|
sp44.x = this->actor.world.pos.x;
|
|
sp44.z = this->actor.world.pos.z;
|
|
sp44.y = sp5C.y;
|
|
if (!BgCheck_EntityLineTest1(&play->colCtx, &sp44, &sp5C, &sp38, &sp54, true, false, false, true,
|
|
&sp50)) {
|
|
func_8084B840(play, this, -2.0f);
|
|
return;
|
|
}
|
|
}
|
|
this->stateFlags2 &= ~PLAYER_STATE2_MOVING_DYNAPOLY;
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084BBE4(Player* this, PlayState* play) {
|
|
f32 sp3C;
|
|
s16 sp3A;
|
|
LinkAnimationHeader* anim;
|
|
f32 temp;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
// clang-format off
|
|
anim = (this->av1.actionVar1 > 0) ? &gPlayerAnim_link_normal_fall_wait : GET_PLAYER_ANIM(PLAYER_ANIMGROUP_jump_climb_wait, this->modelAnimType); Player_AnimPlayLoop(play, this, anim);
|
|
// clang-format on
|
|
} else if (this->av1.actionVar1 == 0) {
|
|
if (this->skelAnime.animation == &gPlayerAnim_link_normal_fall) {
|
|
temp = 11.0f;
|
|
} else {
|
|
temp = 1.0f;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, temp)) {
|
|
func_80832770(this, NA_SE_PL_WALK_GROUND);
|
|
if (this->skelAnime.animation == &gPlayerAnim_link_normal_fall) {
|
|
this->av1.actionVar1 = 1;
|
|
} else {
|
|
this->av1.actionVar1 = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
Math_ScaledStepToS(&this->actor.shape.rot.y, this->yaw, 0x800);
|
|
|
|
if (this->av1.actionVar1 != 0) {
|
|
Player_GetMovementSpeedAndYaw(this, &sp3C, &sp3A, SPEED_MODE_LINEAR, play);
|
|
if (this->unk_847[this->unk_846] >= 0) {
|
|
if (this->av1.actionVar1 > 0) {
|
|
anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_fall_up, this->modelAnimType);
|
|
} else {
|
|
anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_jump_climb_up, this->modelAnimType);
|
|
}
|
|
func_8083A9B8(this, anim, play);
|
|
return;
|
|
}
|
|
|
|
if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_A) || (this->actor.shape.feetFloorFlags != 0)) {
|
|
func_80837B60(this);
|
|
if (this->av1.actionVar1 < 0) {
|
|
this->linearVelocity = -0.8f;
|
|
} else {
|
|
this->linearVelocity = 0.8f;
|
|
}
|
|
func_80837B9C(this, play);
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084BDFC(Player* this, PlayState* play) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_80832E48(this, 1);
|
|
func_8083C0E8(this, play);
|
|
return;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, this->skelAnime.endFrame - 6.0f)) {
|
|
func_808328A0(this);
|
|
} else if (LinkAnimation_OnFrame(&this->skelAnime, this->skelAnime.endFrame - 34.0f)) {
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE);
|
|
Player_PlaySfx(this, NA_SE_PL_CLIMB_CLIFF);
|
|
func_80832698(this, NA_SE_VO_LI_CLIMB_END);
|
|
}
|
|
}
|
|
|
|
void func_8084BEE4(Player* this) {
|
|
Player_PlaySfx(this, (this->av1.actionVar1 != 0) ? NA_SE_PL_WALK_WALL : NA_SE_PL_WALK_LADDER);
|
|
}
|
|
|
|
void Player_Action_8084BF1C(Player* this, PlayState* play) {
|
|
static Vec3f D_8085488C = { 0.0f, 0.0f, 26.0f };
|
|
s32 sp84;
|
|
s32 sp80;
|
|
f32 phi_f0;
|
|
f32 phi_f2;
|
|
Vec3f sp6C;
|
|
s32 sp68;
|
|
Vec3f sp5C;
|
|
f32 temp_f0;
|
|
LinkAnimationHeader* anim1;
|
|
LinkAnimationHeader* anim2;
|
|
|
|
sp84 = sControlInput->rel.stick_y;
|
|
sp80 = sControlInput->rel.stick_x;
|
|
|
|
this->fallStartHeight = this->actor.world.pos.y;
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
|
|
if ((this->av1.actionVar1 != 0) && (ABS(sp84) < ABS(sp80))) {
|
|
phi_f0 = ABS(sp80) * 0.0325f;
|
|
sp84 = 0;
|
|
} else {
|
|
phi_f0 = ABS(sp84) * 0.05f;
|
|
sp80 = 0;
|
|
}
|
|
|
|
if (phi_f0 < 1.0f) {
|
|
phi_f0 = 1.0f;
|
|
} else if (phi_f0 > 3.35f) {
|
|
phi_f0 = 3.35f;
|
|
}
|
|
|
|
if (this->skelAnime.playSpeed >= 0.0f) {
|
|
phi_f2 = 1.0f;
|
|
} else {
|
|
phi_f2 = -1.0f;
|
|
}
|
|
|
|
this->skelAnime.playSpeed = phi_f2 * phi_f0 + phi_f2 * CVarGetInteger("gClimbSpeed", 0);
|
|
|
|
if (this->av2.actionVar2 >= 0) {
|
|
if ((this->actor.wallPoly != NULL) && (this->actor.wallBgId != BGCHECK_SCENE)) {
|
|
DynaPolyActor* wallPolyActor = DynaPoly_GetActor(&play->colCtx, this->actor.wallBgId);
|
|
if (wallPolyActor != NULL) {
|
|
Math_Vec3f_Diff(&wallPolyActor->actor.world.pos, &wallPolyActor->actor.prevPos, &sp6C);
|
|
Math_Vec3f_Sum(&this->actor.world.pos, &sp6C, &this->actor.world.pos);
|
|
}
|
|
}
|
|
|
|
Actor_UpdateBgCheckInfo(play, &this->actor, 26.0f, 6.0f, this->ageProperties->ceilingCheckHeight, 7);
|
|
func_8083F360(play, this, 26.0f, this->ageProperties->unk_3C, 50.0f, -20.0f);
|
|
}
|
|
|
|
if ((this->av2.actionVar2 < 0) || !func_8083FBC0(this, play)) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime) != 0) {
|
|
if (this->av2.actionVar2 < 0) {
|
|
this->av2.actionVar2 = ABS(this->av2.actionVar2) & 1;
|
|
return;
|
|
}
|
|
|
|
if (sp84 != 0) {
|
|
sp68 = this->av1.actionVar1 + this->av2.actionVar2;
|
|
|
|
if (sp84 > 0) {
|
|
D_8085488C.y = this->ageProperties->unk_40;
|
|
temp_f0 = func_8083973C(play, this, &D_8085488C, &sp5C);
|
|
|
|
if (this->actor.world.pos.y < temp_f0) {
|
|
if (this->av1.actionVar1 != 0) {
|
|
this->actor.world.pos.y = temp_f0;
|
|
this->stateFlags1 &= ~PLAYER_STATE1_CLIMBING_LADDER;
|
|
func_8083A5C4(play, this, this->actor.wallPoly, this->ageProperties->unk_3C,
|
|
&gPlayerAnim_link_normal_jump_climb_up_free);
|
|
this->yaw += 0x8000;
|
|
this->actor.shape.rot.y = this->yaw;
|
|
func_8083A9B8(this, &gPlayerAnim_link_normal_jump_climb_up_free, play);
|
|
this->stateFlags1 |= PLAYER_STATE1_CLIMBING_LEDGE;
|
|
} else {
|
|
func_8083F070(this, this->ageProperties->unk_CC[this->av2.actionVar2], play);
|
|
}
|
|
} else {
|
|
this->skelAnime.prevTransl = this->ageProperties->unk_4A[sp68];
|
|
Player_AnimPlayOnce(play, this, this->ageProperties->unk_AC[sp68]);
|
|
}
|
|
} else {
|
|
if ((this->actor.world.pos.y - this->actor.floorHeight) < 15.0f) {
|
|
if (this->av1.actionVar1 != 0) {
|
|
func_8083FB7C(this, play);
|
|
} else {
|
|
if (this->av2.actionVar2 != 0) {
|
|
this->skelAnime.prevTransl = this->ageProperties->unk_44;
|
|
}
|
|
func_8083F070(this, this->ageProperties->unk_C4[this->av2.actionVar2], play);
|
|
this->av2.actionVar2 = 1;
|
|
}
|
|
} else {
|
|
sp68 ^= 1;
|
|
this->skelAnime.prevTransl = this->ageProperties->unk_62[sp68];
|
|
anim1 = this->ageProperties->unk_AC[sp68];
|
|
LinkAnimation_Change(play, &this->skelAnime, anim1, -1.0f, Animation_GetLastFrame(anim1),
|
|
0.0f, ANIMMODE_ONCE, 0.0f);
|
|
}
|
|
}
|
|
this->av2.actionVar2 ^= 1;
|
|
} else {
|
|
if ((this->av1.actionVar1 != 0) && (sp80 != 0)) {
|
|
anim2 = this->ageProperties->unk_BC[this->av2.actionVar2];
|
|
|
|
if (CVarGetInteger("gMirroredWorld", 0) ? (sp80 < 0) : (sp80 > 0)) {
|
|
this->skelAnime.prevTransl = this->ageProperties->unk_7A[this->av2.actionVar2];
|
|
Player_AnimPlayOnce(play, this, anim2);
|
|
} else {
|
|
this->skelAnime.prevTransl = this->ageProperties->unk_86[this->av2.actionVar2];
|
|
LinkAnimation_Change(play, &this->skelAnime, anim2, -1.0f, Animation_GetLastFrame(anim2),
|
|
0.0f, ANIMMODE_ONCE, 0.0f);
|
|
}
|
|
} else {
|
|
this->stateFlags2 |= PLAYER_STATE2_STATIONARY_LADDER;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (this->av2.actionVar2 < 0) {
|
|
if (((this->av2.actionVar2 == -2) &&
|
|
(LinkAnimation_OnFrame(&this->skelAnime, 14.0f) || LinkAnimation_OnFrame(&this->skelAnime, 29.0f))) ||
|
|
((this->av2.actionVar2 == -4) &&
|
|
(LinkAnimation_OnFrame(&this->skelAnime, 22.0f) || LinkAnimation_OnFrame(&this->skelAnime, 35.0f) ||
|
|
LinkAnimation_OnFrame(&this->skelAnime, 49.0f) || LinkAnimation_OnFrame(&this->skelAnime, 55.0f)))) {
|
|
func_8084BEE4(this);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, (this->skelAnime.playSpeed > 0.0f) ? 20.0f : 0.0f)) {
|
|
func_8084BEE4(this);
|
|
}
|
|
}
|
|
|
|
static f32 D_80854898[] = { 10.0f, 20.0f };
|
|
static f32 D_808548A0[] = { 40.0f, 50.0f };
|
|
|
|
static AnimSfxEntry D_808548A8[] = {
|
|
{ NA_SE_PL_WALK_LADDER, ANIMSFX_DATA(ANIMSFX_TYPE_1, 10) },
|
|
{ NA_SE_PL_WALK_LADDER, ANIMSFX_DATA(ANIMSFX_TYPE_1, 20) },
|
|
{ NA_SE_PL_WALK_LADDER, -ANIMSFX_DATA(ANIMSFX_TYPE_1, 30) },
|
|
};
|
|
|
|
void Player_Action_8084C5F8(Player* this, PlayState* play) {
|
|
s32 temp;
|
|
f32* sp38;
|
|
CollisionPoly* sp34;
|
|
s32 sp30;
|
|
Vec3f sp24;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
|
|
temp = func_808374A0(play, this, &this->skelAnime, 4.0f);
|
|
|
|
if (temp == 0) {
|
|
this->stateFlags1 &= ~PLAYER_STATE1_CLIMBING_LADDER;
|
|
return;
|
|
}
|
|
|
|
if ((temp > 0) || LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_8083C0E8(this, play);
|
|
this->stateFlags1 &= ~PLAYER_STATE1_CLIMBING_LADDER;
|
|
return;
|
|
}
|
|
|
|
sp38 = D_80854898;
|
|
|
|
if (this->av2.actionVar2 != 0) {
|
|
Player_ProcessAnimSfxList(this, D_808548A8);
|
|
sp38 = D_808548A0;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, sp38[0]) || LinkAnimation_OnFrame(&this->skelAnime, sp38[1])) {
|
|
sp24.x = this->actor.world.pos.x;
|
|
sp24.y = this->actor.world.pos.y + 20.0f;
|
|
sp24.z = this->actor.world.pos.z;
|
|
if (BgCheck_EntityRaycastFloor3(&play->colCtx, &sp34, &sp30, &sp24) != 0.0f) {
|
|
this->floorSfxOffset = func_80041F10(&play->colCtx, sp34, sp30);
|
|
func_808328A0(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
static AnimSfxEntry D_808548B4[] = {
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 40) }, { 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 48) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 56) }, { 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 64) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 72) }, { 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 80) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 88) }, { 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 96) },
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_6, 104) },
|
|
};
|
|
|
|
void Player_Action_8084C760(Player* this, PlayState* play) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_LOADING)) {
|
|
if (this->skelAnime.moveFlags != 0) {
|
|
this->skelAnime.moveFlags = 0;
|
|
return;
|
|
}
|
|
|
|
// player speed in a tunnel
|
|
if (!Player_TryLeavingCrawlspace(this, play)) {
|
|
// #region SOH [Enhancement]
|
|
if (CVarGetInteger("gCrawlSpeed", 1) > 1) {
|
|
this->linearVelocity = sControlInput->rel.stick_y * 0.03f * CVarGetInteger("gCrawlSpeed", 1);
|
|
// #endregion
|
|
} else {
|
|
this->linearVelocity = sControlInput->rel.stick_y * 0.03f;
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
Player_ProcessAnimSfxList(this, D_808548B4);
|
|
}
|
|
|
|
static AnimSfxEntry D_808548D8[] = {
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 10) }, { 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 18) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 26) }, { 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 34) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 52) }, { 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 60) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 68) }, { 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 76) },
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_6, 84) },
|
|
};
|
|
|
|
void Player_Action_8084C81C(Player* this, PlayState* play) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_8083C0E8(this, play);
|
|
this->stateFlags2 &= ~PLAYER_STATE2_CRAWLING;
|
|
return;
|
|
}
|
|
|
|
Player_ProcessAnimSfxList(this, D_808548D8);
|
|
}
|
|
|
|
static Vec3f D_808548FC[] = {
|
|
{ 40.0f, 0.0f, 0.0f },
|
|
{ -40.0f, 0.0f, 0.0f },
|
|
};
|
|
|
|
static Vec3f D_80854914[] = {
|
|
{ 60.0f, 20.0f, 0.0f },
|
|
{ -60.0f, 20.0f, 0.0f },
|
|
};
|
|
|
|
static Vec3f D_8085492C[] = {
|
|
{ 60.0f, -20.0f, 0.0f },
|
|
{ -60.0f, -20.0f, 0.0f },
|
|
};
|
|
|
|
s32 func_8084C89C(PlayState* play, Player* this, s32 arg2, f32* arg3) {
|
|
EnHorse* rideActor = (EnHorse*)this->rideActor;
|
|
f32 sp50;
|
|
f32 sp4C;
|
|
Vec3f sp40;
|
|
Vec3f sp34;
|
|
CollisionPoly* sp30;
|
|
s32 sp2C;
|
|
|
|
sp50 = rideActor->actor.world.pos.y + 20.0f;
|
|
sp4C = rideActor->actor.world.pos.y - 20.0f;
|
|
|
|
*arg3 = func_8083973C(play, this, &D_808548FC[arg2], &sp40);
|
|
|
|
return (sp4C < *arg3) && (*arg3 < sp50) &&
|
|
!Player_PosVsWallLineTest(play, this, &D_80854914[arg2], &sp30, &sp2C, &sp34) &&
|
|
!Player_PosVsWallLineTest(play, this, &D_8085492C[arg2], &sp30, &sp2C, &sp34);
|
|
}
|
|
|
|
s32 func_8084C9BC(Player* this, PlayState* play) {
|
|
EnHorse* rideActor = (EnHorse*)this->rideActor;
|
|
s32 sp38;
|
|
f32 sp34;
|
|
|
|
if (this->av2.actionVar2 < 0) {
|
|
this->av2.actionVar2 = 99;
|
|
} else {
|
|
sp38 = (this->mountSide < 0) ? 0 : 1;
|
|
if (!func_8084C89C(play, this, sp38, &sp34)) {
|
|
sp38 ^= 1;
|
|
if (!func_8084C89C(play, this, sp38, &sp34)) {
|
|
return 0;
|
|
} else {
|
|
this->mountSide = -this->mountSide;
|
|
}
|
|
}
|
|
|
|
if ((play->csCtx.state == CS_STATE_IDLE) && (play->transitionMode == TRANS_MODE_OFF) &&
|
|
(EN_HORSE_CHECK_1(rideActor) || EN_HORSE_CHECK_4(rideActor))) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DO_ACTION_DOWN;
|
|
|
|
if (EN_HORSE_CHECK_1(rideActor) ||
|
|
(EN_HORSE_CHECK_4(rideActor) && CHECK_BTN_ALL(sControlInput->press.button, BTN_A))) {
|
|
rideActor->actor.child = NULL;
|
|
func_80835DAC(play, this, Player_Action_8084D3E4, 0);
|
|
this->unk_878 = sp34 - rideActor->actor.world.pos.y;
|
|
Player_AnimPlayOnce(play, this,
|
|
(this->mountSide < 0) ? &gPlayerAnim_link_uma_left_down
|
|
: &gPlayerAnim_link_uma_right_down);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func_8084CBF4(Player* this, f32 arg1, f32 arg2) {
|
|
f32 temp;
|
|
f32 dir;
|
|
|
|
if ((this->unk_878 != 0.0f) && (arg2 <= this->skelAnime.curFrame)) {
|
|
if (arg1 < fabsf(this->unk_878)) {
|
|
if (this->unk_878 >= 0.0f) {
|
|
dir = 1;
|
|
} else {
|
|
dir = -1;
|
|
}
|
|
temp = dir * arg1;
|
|
} else {
|
|
temp = this->unk_878;
|
|
}
|
|
this->actor.world.pos.y += temp;
|
|
this->unk_878 -= temp;
|
|
}
|
|
}
|
|
|
|
static LinkAnimationHeader* D_80854944[] = {
|
|
&gPlayerAnim_link_uma_anim_stop,
|
|
&gPlayerAnim_link_uma_anim_stand,
|
|
&gPlayerAnim_link_uma_anim_walk,
|
|
&gPlayerAnim_link_uma_anim_slowrun,
|
|
&gPlayerAnim_link_uma_anim_fastrun,
|
|
&gPlayerAnim_link_uma_anim_jump100,
|
|
&gPlayerAnim_link_uma_anim_jump200,
|
|
NULL,
|
|
NULL,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_80854968[] = {
|
|
&gPlayerAnim_link_uma_anim_walk_muti,
|
|
&gPlayerAnim_link_uma_anim_walk_muti,
|
|
&gPlayerAnim_link_uma_anim_walk_muti,
|
|
&gPlayerAnim_link_uma_anim_slowrun_muti,
|
|
&gPlayerAnim_link_uma_anim_fastrun_muti,
|
|
&gPlayerAnim_link_uma_anim_fastrun_muti,
|
|
&gPlayerAnim_link_uma_anim_fastrun_muti,
|
|
NULL,
|
|
NULL,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_8085498C[] = {
|
|
&gPlayerAnim_link_uma_wait_3,
|
|
&gPlayerAnim_link_uma_wait_1,
|
|
&gPlayerAnim_link_uma_wait_2,
|
|
};
|
|
|
|
static u8 D_80854998[2][2] = {
|
|
{ 32, 58 },
|
|
{ 25, 42 },
|
|
};
|
|
|
|
static Vec3s D_8085499C = { -69, 7146, -266 };
|
|
|
|
static AnimSfxEntry D_808549A4[] = {
|
|
{ NA_SE_PL_CALM_HIT, ANIMSFX_DATA(ANIMSFX_TYPE_1, 48) }, { NA_SE_PL_CALM_HIT, ANIMSFX_DATA(ANIMSFX_TYPE_1, 58) },
|
|
{ NA_SE_PL_CALM_HIT, ANIMSFX_DATA(ANIMSFX_TYPE_1, 68) }, { NA_SE_PL_CALM_PAT, ANIMSFX_DATA(ANIMSFX_TYPE_1, 92) },
|
|
{ NA_SE_PL_CALM_PAT, ANIMSFX_DATA(ANIMSFX_TYPE_1, 110) }, { NA_SE_PL_CALM_PAT, ANIMSFX_DATA(ANIMSFX_TYPE_1, 126) },
|
|
{ NA_SE_PL_CALM_PAT, ANIMSFX_DATA(ANIMSFX_TYPE_1, 132) }, { NA_SE_PL_CALM_PAT, -ANIMSFX_DATA(ANIMSFX_TYPE_1, 136) },
|
|
};
|
|
|
|
void Player_Action_8084CC98(Player* this, PlayState* play) {
|
|
EnHorse* rideActor = (EnHorse*)this->rideActor;
|
|
u8* arr;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
|
|
func_8084CBF4(this, 1.0f, 10.0f);
|
|
|
|
if (this->av2.actionVar2 == 0) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
this->skelAnime.animation = &gPlayerAnim_link_uma_wait_1;
|
|
this->av2.actionVar2 = 99;
|
|
return;
|
|
}
|
|
|
|
arr = D_80854998[(this->mountSide < 0) ? 0 : 1];
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, arr[0])) {
|
|
Player_PlaySfx(this, NA_SE_PL_CLIMB_CLIFF);
|
|
return;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, arr[1])) {
|
|
func_8002DE74(play, this);
|
|
Player_PlaySfx(this, NA_SE_PL_SIT_ON_HORSE);
|
|
return;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
func_8002DE74(play, this);
|
|
this->skelAnime.prevTransl = D_8085499C;
|
|
|
|
if ((rideActor->animationIdx != this->av2.actionVar2) && ((rideActor->animationIdx >= 2) || (this->av2.actionVar2 >= 2))) {
|
|
if ((this->av2.actionVar2 = rideActor->animationIdx) < 2) {
|
|
f32 rand = Rand_ZeroOne();
|
|
s32 temp = 0;
|
|
|
|
this->av2.actionVar2 = 1;
|
|
|
|
if (rand < 0.1f) {
|
|
temp = 2;
|
|
} else if (rand < 0.2f) {
|
|
temp = 1;
|
|
}
|
|
Player_AnimPlayOnce(play, this, D_8085498C[temp]);
|
|
} else {
|
|
this->skelAnime.animation = D_80854944[this->av2.actionVar2 - 2];
|
|
Animation_SetMorph(play, &this->skelAnime, 8.0f);
|
|
if (this->av2.actionVar2 < 4) {
|
|
func_80834644(play, this);
|
|
this->av1.actionVar1 = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this->av2.actionVar2 == 1) {
|
|
if ((D_808535E0 != 0) || func_8083224C(play)) {
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_uma_wait_3);
|
|
} else if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
this->av2.actionVar2 = 99;
|
|
} else if (this->skelAnime.animation == &gPlayerAnim_link_uma_wait_1) {
|
|
Player_ProcessAnimSfxList(this, D_808549A4);
|
|
}
|
|
} else {
|
|
this->skelAnime.curFrame = rideActor->curFrame;
|
|
LinkAnimation_AnimateFrame(play, &this->skelAnime);
|
|
}
|
|
|
|
AnimationContext_SetCopyAll(play, this->skelAnime.limbCount, this->skelAnime.morphTable,
|
|
this->skelAnime.jointTable);
|
|
|
|
if ((play->csCtx.state != CS_STATE_IDLE) || (this->csAction != 0)) {
|
|
if (this->csAction == 7) {
|
|
this->csAction = 0;
|
|
}
|
|
this->unk_6AD = 0;
|
|
this->av1.actionVar1 = 0;
|
|
} else if ((this->av2.actionVar2 < 2) || (this->av2.actionVar2 >= 4)) {
|
|
D_808535E0 = Player_UpdateUpperBody(this, play);
|
|
if (D_808535E0 != 0) {
|
|
this->av1.actionVar1 = 0;
|
|
}
|
|
}
|
|
|
|
this->actor.world.pos.x = rideActor->actor.world.pos.x + rideActor->riderPos.x;
|
|
this->actor.world.pos.y = (rideActor->actor.world.pos.y + rideActor->riderPos.y) - 27.0f;
|
|
this->actor.world.pos.z = rideActor->actor.world.pos.z + rideActor->riderPos.z;
|
|
|
|
this->yaw = this->actor.shape.rot.y = rideActor->actor.shape.rot.y;
|
|
|
|
if ((this->csAction != 0) ||
|
|
(!func_8083224C(play) && ((rideActor->actor.speedXZ != 0.0f) || !Player_ActionChange_4(this, play)) &&
|
|
!Player_ActionChange_6(this, play))) {
|
|
if (D_808535E0 == 0) {
|
|
if (this->av1.actionVar1 != 0) {
|
|
if (LinkAnimation_Update(play, &this->upperSkelAnime)) {
|
|
rideActor->stateFlags &= ~ENHORSE_FLAG_8;
|
|
this->av1.actionVar1 = 0;
|
|
}
|
|
|
|
if (this->upperSkelAnime.animation == &gPlayerAnim_link_uma_stop_muti) {
|
|
if (LinkAnimation_OnFrame(&this->upperSkelAnime, 23.0f)) {
|
|
Player_PlaySfx(this, NA_SE_IT_LASH);
|
|
func_80832698(this, NA_SE_VO_LI_LASH);
|
|
}
|
|
|
|
AnimationContext_SetCopyAll(play, this->skelAnime.limbCount, this->skelAnime.jointTable,
|
|
this->upperSkelAnime.jointTable);
|
|
} else {
|
|
if (LinkAnimation_OnFrame(&this->upperSkelAnime, 10.0f)) {
|
|
Player_PlaySfx(this, NA_SE_IT_LASH);
|
|
func_80832698(this, NA_SE_VO_LI_LASH);
|
|
}
|
|
|
|
AnimationContext_SetCopyTrue(play, this->skelAnime.limbCount, this->skelAnime.jointTable,
|
|
this->upperSkelAnime.jointTable, sUpperBodyLimbCopyMap);
|
|
}
|
|
} else {
|
|
LinkAnimationHeader* anim = NULL;
|
|
|
|
if (EN_HORSE_CHECK_3(rideActor)) {
|
|
anim = &gPlayerAnim_link_uma_stop_muti;
|
|
} else if (EN_HORSE_CHECK_2(rideActor)) {
|
|
if ((this->av2.actionVar2 >= 2) && (this->av2.actionVar2 != 99)) {
|
|
anim = D_80854968[this->av2.actionVar2 - 2];
|
|
}
|
|
}
|
|
|
|
if (anim != NULL) {
|
|
LinkAnimation_PlayOnce(play, &this->upperSkelAnime, anim);
|
|
this->av1.actionVar1 = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_FIRST_PERSON) {
|
|
if (!func_8083AD4C(play, this) || CHECK_BTN_ANY(sControlInput->press.button, BTN_A) ||
|
|
func_80833BCC(this)) {
|
|
this->unk_6AD = 0;
|
|
this->stateFlags1 &= ~PLAYER_STATE1_FIRST_PERSON;
|
|
} else {
|
|
this->unk_6BE = func_8084ABD8(play, this, 1, -5000) - this->actor.shape.rot.y;
|
|
this->unk_6BE += 5000;
|
|
this->unk_6B0 = -5000;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if ((this->csAction != 0) || (!func_8084C9BC(this, play) && !Player_ActionChange_13(this, play))) {
|
|
if (this->unk_664 != NULL) {
|
|
if (func_8002DD78(this) != 0) {
|
|
this->unk_6BE = func_8083DB98(this, 1) - this->actor.shape.rot.y;
|
|
this->unk_6BE = CLAMP(this->unk_6BE, -0x4AAA, 0x4AAA);
|
|
this->actor.focus.rot.y = this->actor.shape.rot.y + this->unk_6BE;
|
|
this->unk_6BE += 5000;
|
|
this->unk_6AE |= 0x80;
|
|
} else {
|
|
func_8083DB98(this, 0);
|
|
}
|
|
} else {
|
|
if (func_8002DD78(this) != 0) {
|
|
this->unk_6BE = func_8084ABD8(play, this, 1, -5000) - this->actor.shape.rot.y;
|
|
this->unk_6BE += 5000;
|
|
this->unk_6B0 = -5000;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static AnimSfxEntry D_808549C4[] = {
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_5, 0) },
|
|
{ NA_SE_PL_GET_OFF_HORSE, ANIMSFX_DATA(ANIMSFX_TYPE_1, 10) },
|
|
{ NA_SE_PL_SLIPDOWN, -ANIMSFX_DATA(ANIMSFX_TYPE_1, 25) },
|
|
};
|
|
|
|
void Player_Action_8084D3E4(Player* this, PlayState* play) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
func_8084CBF4(this, 1.0f, 10.0f);
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
EnHorse* rideActor = (EnHorse*)this->rideActor;
|
|
|
|
func_8083C0E8(this, play);
|
|
this->stateFlags1 &= ~PLAYER_STATE1_ON_HORSE;
|
|
this->actor.parent = NULL;
|
|
AREG(6) = 0;
|
|
|
|
if (Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) || (DREG(1) != 0)) {
|
|
gSaveContext.horseData.pos.x = rideActor->actor.world.pos.x;
|
|
gSaveContext.horseData.pos.y = rideActor->actor.world.pos.y;
|
|
gSaveContext.horseData.pos.z = rideActor->actor.world.pos.z;
|
|
gSaveContext.horseData.angle = rideActor->actor.shape.rot.y;
|
|
}
|
|
} else {
|
|
Camera_ChangeSetting(Play_GetCamera(play, 0), CAM_SET_NORMAL0);
|
|
|
|
if (this->mountSide < 0) {
|
|
D_808549C4[0].data = ANIMSFX_DATA(ANIMSFX_TYPE_5, 40);
|
|
} else {
|
|
D_808549C4[0].data = ANIMSFX_DATA(ANIMSFX_TYPE_5, 29);
|
|
}
|
|
Player_ProcessAnimSfxList(this, D_808549C4);
|
|
}
|
|
}
|
|
|
|
static AnimSfxEntry D_808549D0[] = {
|
|
{ NA_SE_PL_SWIM, -ANIMSFX_DATA(ANIMSFX_TYPE_1, 0) },
|
|
};
|
|
|
|
void func_8084D530(Player* this, f32* arg1, f32 arg2, s16 arg3) {
|
|
func_8084AEEC(this, arg1, arg2, arg3);
|
|
Player_ProcessAnimSfxList(this, D_808549D0);
|
|
}
|
|
|
|
void func_8084D574(PlayState* play, Player* this, s16 arg2) {
|
|
Player_SetupAction(play, this, Player_Action_8084D84C, 0);
|
|
this->actor.shape.rot.y = this->yaw = arg2;
|
|
Player_AnimChangeLoopSlowMorph(play, this, &gPlayerAnim_link_swimer_swim);
|
|
}
|
|
|
|
void func_8084D5CC(PlayState* play, Player* this) {
|
|
Player_SetupAction(play, this, Player_Action_8084DAB4, 0);
|
|
Player_AnimChangeLoopSlowMorph(play, this, &gPlayerAnim_link_swimer_swim);
|
|
}
|
|
|
|
void Player_Action_8084D610(Player* this, PlayState* play) {
|
|
f32 sp34;
|
|
s16 sp32;
|
|
|
|
func_80832CB0(play, this, &gPlayerAnim_link_swimer_swim_wait);
|
|
func_8084B000(this);
|
|
|
|
if (!func_8083224C(play) && !Player_TryActionChangeList(play, this, sActionChangeList11, true) &&
|
|
!func_8083D12C(play, this, sControlInput)) {
|
|
if (this->unk_6AD != 1) {
|
|
this->unk_6AD = 0;
|
|
}
|
|
|
|
if (this->currentBoots == PLAYER_BOOTS_IRON) {
|
|
sp34 = 0.0f;
|
|
sp32 = this->actor.shape.rot.y;
|
|
|
|
if (this->actor.bgCheckFlags & 1) {
|
|
func_8083A098(this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_short_landing, this->modelAnimType), play);
|
|
func_808328A0(this);
|
|
}
|
|
} else {
|
|
Player_GetMovementSpeedAndYaw(this, &sp34, &sp32, SPEED_MODE_LINEAR, play);
|
|
|
|
if (sp34 != 0.0f) {
|
|
s16 temp = this->actor.shape.rot.y - sp32;
|
|
|
|
if ((ABS(temp) > 0x6000) && !Math_StepToF(&this->linearVelocity, 0.0f, 1.0f)) {
|
|
return;
|
|
}
|
|
|
|
if (func_80833C04(this)) {
|
|
func_8084D5CC(play, this);
|
|
} else {
|
|
func_8084D574(play, this, sp32);
|
|
}
|
|
}
|
|
}
|
|
|
|
func_8084AEEC(this, &this->linearVelocity, sp34, sp32);
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084D7C4(Player* this, PlayState* play) {
|
|
if (!Player_ActionChange_13(this, play)) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
|
|
func_8084B158(play, this, NULL, this->linearVelocity);
|
|
func_8084B000(this);
|
|
|
|
if (DECR(this->av2.actionVar2) == 0) {
|
|
func_80838F18(play, this);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084D84C(Player* this, PlayState* play) {
|
|
f32 sp34;
|
|
s16 sp32;
|
|
s16 temp;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
|
|
func_8084B158(play, this, sControlInput, this->linearVelocity);
|
|
func_8084B000(this);
|
|
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList11, true) && !func_8083D12C(play, this, sControlInput)) {
|
|
Player_GetMovementSpeedAndYaw(this, &sp34, &sp32, SPEED_MODE_LINEAR, play);
|
|
|
|
temp = this->actor.shape.rot.y - sp32;
|
|
if ((sp34 == 0.0f) || (ABS(temp) > 0x6000) || (this->currentBoots == PLAYER_BOOTS_IRON)) {
|
|
func_80838F18(play, this);
|
|
} else if (func_80833C04(this)) {
|
|
func_8084D5CC(play, this);
|
|
}
|
|
|
|
func_8084D530(this, &this->linearVelocity, sp34, sp32);
|
|
}
|
|
}
|
|
|
|
s32 func_8084D980(PlayState* play, Player* this, f32* arg2, s16* arg3) {
|
|
LinkAnimationHeader* anim;
|
|
s16 temp1;
|
|
s32 temp2;
|
|
|
|
temp1 = this->yaw - *arg3;
|
|
|
|
if (ABS(temp1) > 0x6000) {
|
|
anim = &gPlayerAnim_link_swimer_swim_wait;
|
|
|
|
if (Math_StepToF(&this->linearVelocity, 0.0f, 1.0f)) {
|
|
this->yaw = *arg3;
|
|
} else {
|
|
*arg2 = 0.0f;
|
|
*arg3 = this->yaw;
|
|
}
|
|
} else {
|
|
temp2 = func_8083FD78(this, arg2, arg3, play);
|
|
|
|
if (temp2 > 0) {
|
|
anim = &gPlayerAnim_link_swimer_swim;
|
|
} else if (temp2 < 0) {
|
|
anim = &gPlayerAnim_link_swimer_back_swim;
|
|
} else if ((temp1 = this->actor.shape.rot.y - *arg3) > 0) {
|
|
anim = &gPlayerAnim_link_swimer_Rside_swim;
|
|
} else {
|
|
anim = &gPlayerAnim_link_swimer_Lside_swim;
|
|
}
|
|
}
|
|
|
|
if (anim != this->skelAnime.animation) {
|
|
Player_AnimChangeLoopSlowMorph(play, this, anim);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Player_Action_8084DAB4(Player* this, PlayState* play) {
|
|
f32 sp2C;
|
|
s16 sp2A;
|
|
|
|
func_8084B158(play, this, sControlInput, this->linearVelocity);
|
|
func_8084B000(this);
|
|
|
|
if (!Player_TryActionChangeList(play, this, sActionChangeList11, true) && !func_8083D12C(play, this, sControlInput)) {
|
|
Player_GetMovementSpeedAndYaw(this, &sp2C, &sp2A, SPEED_MODE_LINEAR, play);
|
|
|
|
if (sp2C == 0.0f) {
|
|
func_80838F18(play, this);
|
|
} else if (!func_80833C04(this)) {
|
|
func_8084D574(play, this, sp2A);
|
|
} else {
|
|
func_8084D980(play, this, &sp2C, &sp2A);
|
|
}
|
|
|
|
func_8084D530(this, &this->linearVelocity, sp2C, sp2A);
|
|
}
|
|
}
|
|
|
|
void func_8084DBC4(PlayState* play, Player* this, f32 arg2) {
|
|
f32 sp2C;
|
|
s16 sp2A;
|
|
|
|
Player_GetMovementSpeedAndYaw(this, &sp2C, &sp2A, SPEED_MODE_LINEAR, play);
|
|
func_8084AEEC(this, &this->linearVelocity, sp2C * 0.5f, sp2A);
|
|
// Original implementation of func_8084AEEC (SurfaceWithoutSwimMod) to prevent velocity increases via swim mod which push Link into the air
|
|
// #region SOH [Enhancement]
|
|
if (CVarGetInteger("gEnableWalkModify", 0)) {
|
|
SurfaceWithoutSwimMod(this, &this->actor.velocity.y, arg2, this->yaw);
|
|
// #endregion
|
|
} else {
|
|
func_8084AEEC(this, &this->actor.velocity.y, arg2, this->yaw);
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084DC48(Player* this, PlayState* play) {
|
|
f32 sp2C;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
this->actor.gravity = 0.0f;
|
|
Player_UpdateUpperBody(this, play);
|
|
|
|
if (!Player_ActionChange_13(this, play)) {
|
|
if (this->currentBoots == PLAYER_BOOTS_IRON) {
|
|
func_80838F18(play, this);
|
|
return;
|
|
}
|
|
|
|
if (this->av1.actionVar1 == 0) {
|
|
if (this->av2.actionVar2 == 0) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime) ||
|
|
((this->skelAnime.curFrame >= 22.0f) && !CHECK_BTN_ALL(sControlInput->cur.button, BTN_A))) {
|
|
func_8083D330(play, this);
|
|
} else if (LinkAnimation_OnFrame(&this->skelAnime, 20.0f) != 0) {
|
|
this->actor.velocity.y = -2.0f;
|
|
}
|
|
|
|
func_8083721C(this);
|
|
return;
|
|
}
|
|
|
|
func_8084B158(play, this, sControlInput, this->actor.velocity.y);
|
|
this->unk_6C2 = 16000;
|
|
|
|
if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_A) && !Player_ActionChange_2(this, play) &&
|
|
!(this->actor.bgCheckFlags & 1) && (this->actor.yDistToWater < D_80854784[CUR_UPG_VALUE(UPG_SCALE)])) {
|
|
func_8084DBC4(play, this, -2.0f);
|
|
} else {
|
|
this->av1.actionVar1++;
|
|
Player_AnimChangeLoopSlowMorph(play, this, &gPlayerAnim_link_swimer_swim_wait);
|
|
}
|
|
} else if (this->av1.actionVar1 == 1) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
func_8084B000(this);
|
|
|
|
if (this->unk_6C2 < 10000) {
|
|
this->av1.actionVar1++;
|
|
this->av2.actionVar2 = this->actor.yDistToWater;
|
|
Player_AnimChangeLoopSlowMorph(play, this, &gPlayerAnim_link_swimer_swim);
|
|
}
|
|
} else if (!func_8083D12C(play, this, sControlInput)) {
|
|
sp2C = (this->av2.actionVar2 * 0.018f) + 4.0f;
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD) {
|
|
sControlInput = NULL;
|
|
}
|
|
|
|
func_8084B158(play, this, sControlInput, fabsf(this->actor.velocity.y));
|
|
Math_ScaledStepToS(&this->unk_6C2, -10000, 800);
|
|
|
|
if (sp2C > 8.0f) {
|
|
sp2C = 8.0f;
|
|
}
|
|
|
|
func_8084DBC4(play, this, sp2C);
|
|
}
|
|
}
|
|
}
|
|
|
|
void func_8084DF6C(PlayState* play, Player* this) {
|
|
this->unk_862 = 0;
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD);
|
|
this->getItemId = GI_NONE;
|
|
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
|
|
func_8005B1A4(Play_GetCamera(play, 0));
|
|
}
|
|
|
|
void func_8084DFAC(PlayState* play, Player* this) {
|
|
func_8084DF6C(play, this);
|
|
func_808322FC(this);
|
|
func_8083C0E8(this, play);
|
|
this->yaw = this->actor.shape.rot.y;
|
|
}
|
|
|
|
s32 func_8084DFF4(PlayState* play, Player* this) {
|
|
GetItemEntry giEntry;
|
|
s32 temp1;
|
|
s32 temp2;
|
|
static s32 equipItem;
|
|
static bool equipNow;
|
|
|
|
if (this->getItemId == GI_NONE && this->getItemEntry.objectId == OBJECT_INVALID) {
|
|
return 1;
|
|
}
|
|
|
|
if (this->av1.actionVar1 == 0) {
|
|
if (this->getItemEntry.objectId == OBJECT_INVALID || (this->getItemId != this->getItemEntry.getItemId)) {
|
|
giEntry = ItemTable_Retrieve(this->getItemId);
|
|
} else {
|
|
giEntry = this->getItemEntry;
|
|
}
|
|
this->av1.actionVar1 = 1;
|
|
equipItem = giEntry.itemId;
|
|
equipNow = CVarGetInteger("gAskToEquip", 0) && giEntry.modIndex == MOD_NONE &&
|
|
equipItem >= ITEM_SWORD_KOKIRI && equipItem <= ITEM_TUNIC_ZORA &&
|
|
CHECK_AGE_REQ_ITEM(equipItem);
|
|
|
|
Message_StartTextbox(play, giEntry.textId, &this->actor);
|
|
// RANDOTODO: Macro this boolean check.
|
|
if (!(giEntry.modIndex == MOD_RANDOMIZER && giEntry.itemId == RG_ICE_TRAP)) {
|
|
if (giEntry.modIndex == MOD_NONE) {
|
|
// RANDOTOD: Move this into Item_Give() or some other more central location
|
|
if (giEntry.getItemId == GI_SWORD_BGS) {
|
|
gSaveContext.bgsFlag = true;
|
|
gSaveContext.swordHealth = 8;
|
|
}
|
|
Item_Give(play, giEntry.itemId);
|
|
} else {
|
|
Randomizer_Item_Give(play, giEntry);
|
|
}
|
|
Player_SetPendingFlag(this, play);
|
|
}
|
|
|
|
// Use this if we do have a getItemEntry
|
|
if (giEntry.modIndex == MOD_NONE) {
|
|
if (IS_RANDO) {
|
|
Audio_PlayFanfare_Rando(giEntry);
|
|
} else if (((giEntry.itemId >= ITEM_RUPEE_GREEN) && (giEntry.itemId <= ITEM_RUPEE_RED)) ||
|
|
((giEntry.itemId >= ITEM_RUPEE_PURPLE) && (giEntry.itemId <= ITEM_RUPEE_GOLD)) ||
|
|
(giEntry.itemId == ITEM_HEART)) {
|
|
Audio_PlaySoundGeneral(NA_SE_SY_GET_BOXITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
|
} else {
|
|
if ((giEntry.itemId == ITEM_HEART_CONTAINER) ||
|
|
((giEntry.itemId == ITEM_HEART_PIECE_2) &&
|
|
((gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000))) {
|
|
temp1 = NA_BGM_HEART_GET | 0x900;
|
|
} else {
|
|
temp1 = temp2 =
|
|
(giEntry.itemId == ITEM_HEART_PIECE_2) ? NA_BGM_SMALL_ITEM_GET : NA_BGM_ITEM_GET | 0x900;
|
|
}
|
|
Audio_PlayFanfare(temp1);
|
|
}
|
|
} else if (giEntry.modIndex == MOD_RANDOMIZER) {
|
|
if (IS_RANDO) {
|
|
Audio_PlayFanfare_Rando(giEntry);
|
|
} else if (giEntry.itemId == RG_DOUBLE_DEFENSE || giEntry.itemId == RG_MAGIC_SINGLE ||
|
|
giEntry.itemId == RG_MAGIC_DOUBLE) {
|
|
Audio_PlayFanfare(NA_BGM_HEART_GET | 0x900);
|
|
} else {
|
|
// Just in case something weird happens with MOD_INDEX
|
|
Audio_PlayFanfare(NA_BGM_ITEM_GET | 0x900);
|
|
}
|
|
} else {
|
|
// Just in case something weird happens with modIndex.
|
|
Audio_PlayFanfare(NA_BGM_ITEM_GET | 0x900);
|
|
}
|
|
}
|
|
else if (equipNow && Message_ShouldAdvanceSilent(play) &&
|
|
Message_GetState(&play->msgCtx) == TEXT_STATE_CHOICE) {
|
|
if (play->msgCtx.choiceIndex == 0) { // Equip now? Yes
|
|
|
|
if (equipItem >= ITEM_SWORD_KOKIRI && equipItem <= ITEM_SWORD_BGS) {
|
|
gSaveContext.equips.buttonItems[0] = equipItem;
|
|
Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, equipItem - ITEM_SWORD_KOKIRI + 1);
|
|
func_808328EC(this, NA_SE_IT_SWORD_PUTAWAY);
|
|
|
|
} else if (equipItem >= ITEM_SHIELD_DEKU && equipItem <= ITEM_SHIELD_MIRROR) {
|
|
Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, equipItem - ITEM_SHIELD_DEKU + 1);
|
|
func_808328EC(&this->actor, NA_SE_IT_SHIELD_REMOVE);
|
|
Player_SetEquipmentData(play, this);
|
|
|
|
} else if (equipItem == ITEM_TUNIC_GORON || equipItem == ITEM_TUNIC_ZORA) {
|
|
Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, equipItem - ITEM_TUNIC_KOKIRI + 1);
|
|
func_808328EC(this, NA_SE_PL_CHANGE_ARMS);
|
|
Player_SetEquipmentData(play, this);
|
|
}
|
|
}
|
|
equipNow = false;
|
|
Message_CloseTextbox(play);
|
|
play->msgCtx.msgMode = MSGMODE_TEXT_DONE;
|
|
} else {
|
|
if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) {
|
|
if (this->getItemId == GI_GAUNTLETS_SILVER && !IS_RANDO) {
|
|
play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_0;
|
|
play->transitionTrigger = TRANS_TRIGGER_START;
|
|
gSaveContext.nextCutsceneIndex = 0xFFF1;
|
|
play->transitionType = TRANS_TYPE_SANDSTORM_END;
|
|
this->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE;
|
|
Player_TryCsAction(play, NULL, 8);
|
|
}
|
|
|
|
// Set unk_862 to 0 early to not have the game draw non-custom colored models for a split second.
|
|
// This unk is what the game normally uses to decide what item to draw when holding up an item above Link's head.
|
|
// Only do this when the item actually has a custom draw function.
|
|
if (this->getItemEntry.drawFunc != NULL) {
|
|
this->unk_862 = 0;
|
|
}
|
|
|
|
if (this->getItemEntry.itemId == RG_ICE_TRAP && this->getItemEntry.modIndex == MOD_RANDOMIZER) {
|
|
this->unk_862 = 0;
|
|
gSaveContext.pendingIceTrapCount++;
|
|
Player_SetPendingFlag(this, play);
|
|
}
|
|
|
|
this->getItemId = GI_NONE;
|
|
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Player_Action_8084E1EC(Player* this, PlayState* play) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (!(this->stateFlags1 & PLAYER_STATE1_GETTING_ITEM) || func_8084DFF4(play, this)) {
|
|
func_8084DF6C(play, this);
|
|
func_80838F18(play, this);
|
|
func_80832340(play, this);
|
|
}
|
|
} else {
|
|
if ((this->stateFlags1 & PLAYER_STATE1_GETTING_ITEM) && LinkAnimation_OnFrame(&this->skelAnime, 10.0f)) {
|
|
func_808332F4(this, play);
|
|
func_80832340(play, this);
|
|
func_80835EA4(play, 8);
|
|
} else if (LinkAnimation_OnFrame(&this->skelAnime, 5.0f)) {
|
|
func_80832698(this, NA_SE_VO_LI_BREATH_DRINK);
|
|
}
|
|
}
|
|
|
|
func_8084B000(this);
|
|
func_8084AEEC(this, &this->linearVelocity, 0.0f, this->actor.shape.rot.y);
|
|
}
|
|
|
|
void Player_Action_8084E30C(Player* this, PlayState* play) {
|
|
func_8084B000(this);
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_80838F18(play, this);
|
|
}
|
|
|
|
func_8084AEEC(this, &this->linearVelocity, 0.0f, this->actor.shape.rot.y);
|
|
}
|
|
|
|
void Player_Action_8084E368(Player* this, PlayState* play) {
|
|
func_8084B000(this);
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_80843AE8(play, this);
|
|
}
|
|
|
|
func_8084AEEC(this, &this->linearVelocity, 0.0f, this->actor.shape.rot.y);
|
|
}
|
|
|
|
static s16 sWarpSongEntrances[] = {
|
|
ENTR_SACRED_FOREST_MEADOW_2,
|
|
ENTR_DEATH_MOUNTAIN_CRATER_4,
|
|
ENTR_LAKE_HYLIA_8,
|
|
ENTR_DESERT_COLOSSUS_5,
|
|
ENTR_GRAVEYARD_7,
|
|
ENTR_TEMPLE_OF_TIME_7,
|
|
};
|
|
|
|
void Player_Action_8084E3C4(Player* this, PlayState* play) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimPlayLoopAdjusted(play, this, &gPlayerAnim_link_normal_okarina_swing);
|
|
this->av2.actionVar2 = 1;
|
|
if (this->stateFlags2 & (PLAYER_STATE2_NEAR_OCARINA_ACTOR | PLAYER_STATE2_PLAY_FOR_ACTOR)) {
|
|
this->stateFlags2 |= PLAYER_STATE2_ATTEMPT_PLAY_FOR_ACTOR;
|
|
} else {
|
|
func_8010BD58(play, OCARINA_ACTION_FREE_PLAY);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (this->av2.actionVar2 == 0) {
|
|
return;
|
|
}
|
|
|
|
if (play->msgCtx.ocarinaMode == OCARINA_MODE_04) {
|
|
func_8005B1A4(Play_GetCamera(play, 0));
|
|
|
|
if ((this->targetActor != NULL) && (this->targetActor == this->unk_6A8)) {
|
|
Player_StartTalking(play, this->targetActor);
|
|
} else if (this->naviTextId < 0) {
|
|
this->targetActor = this->naviActor;
|
|
this->naviActor->textId = -this->naviTextId;
|
|
Player_StartTalking(play, this->targetActor);
|
|
} else if (!Player_ActionChange_13(this, play)) {
|
|
func_8083A098(this, &gPlayerAnim_link_normal_okarina_end, play);
|
|
}
|
|
|
|
this->stateFlags2 &= ~(PLAYER_STATE2_NEAR_OCARINA_ACTOR | PLAYER_STATE2_ATTEMPT_PLAY_FOR_ACTOR | PLAYER_STATE2_PLAY_FOR_ACTOR);
|
|
this->unk_6A8 = NULL;
|
|
} else if (play->msgCtx.ocarinaMode == OCARINA_MODE_02) {
|
|
gSaveContext.respawn[RESPAWN_MODE_RETURN].entranceIndex = sWarpSongEntrances[play->msgCtx.lastPlayedSong];
|
|
gSaveContext.respawn[RESPAWN_MODE_RETURN].playerParams = 0x5FF;
|
|
gSaveContext.respawn[RESPAWN_MODE_RETURN].data = play->msgCtx.lastPlayedSong;
|
|
|
|
this->csAction = 0;
|
|
this->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE;
|
|
|
|
Player_TryCsAction(play, NULL, 8);
|
|
play->mainCamera.unk_14C &= ~8;
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE;
|
|
this->stateFlags2 |= PLAYER_STATE2_OCARINA_PLAYING;
|
|
|
|
if (Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_KANKYO, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0xF, true) == NULL) {
|
|
Environment_WarpSongLeave(play);
|
|
}
|
|
|
|
gSaveContext.seqId = (u8)NA_BGM_DISABLED;
|
|
gSaveContext.natureAmbienceId = NATURE_ID_DISABLED;
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084E604(Player* this, PlayState* play) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_8083A098(this, &gPlayerAnim_link_normal_light_bom_end, play);
|
|
} else if (LinkAnimation_OnFrame(&this->skelAnime, 3.0f)) {
|
|
Inventory_ChangeAmmo(ITEM_NUT, -1);
|
|
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ARROW, this->bodyPartsPos[PLAYER_BODYPART_R_HAND].x,
|
|
this->bodyPartsPos[PLAYER_BODYPART_R_HAND].y, this->bodyPartsPos[PLAYER_BODYPART_R_HAND].z, 4000,
|
|
this->actor.shape.rot.y, 0, ARROW_NUT, true);
|
|
func_80832698(this, NA_SE_VO_LI_SWORD_N);
|
|
}
|
|
|
|
func_8083721C(this);
|
|
}
|
|
|
|
static AnimSfxEntry D_808549E0[] = {
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_7, 87) },
|
|
{ NA_SE_VO_LI_CLIMB_END, ANIMSFX_DATA(ANIMSFX_TYPE_4, 87) },
|
|
{ NA_SE_VO_LI_AUTO_JUMP, ANIMSFX_DATA(ANIMSFX_TYPE_4, 69) },
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_5, 123) },
|
|
};
|
|
|
|
void Player_Action_8084E6D4(Player* this, PlayState* play) {
|
|
s32 cond;
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (this->av2.actionVar2 != 0) {
|
|
if (this->av2.actionVar2 >= 2) {
|
|
this->av2.actionVar2--;
|
|
}
|
|
|
|
if (func_8084DFF4(play, this) && (this->av2.actionVar2 == 1)) {
|
|
cond = ((this->targetActor != NULL) && (this->exchangeItemId < 0)) ||
|
|
(this->stateFlags3 & PLAYER_STATE3_FORCE_PULL_OCARINA);
|
|
|
|
if (cond || (gSaveContext.healthAccumulator == 0)) {
|
|
if (cond) {
|
|
func_8084DF6C(play, this);
|
|
this->exchangeItemId = EXCH_ITEM_NONE;
|
|
|
|
if (func_8084B4D4(play, this) == 0) {
|
|
Player_StartTalking(play, this->targetActor);
|
|
}
|
|
} else {
|
|
func_8084DFAC(play, this);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
func_80832DBC(this);
|
|
if ((this->getItemId == GI_ICE_TRAP && !IS_RANDO) ||
|
|
(IS_RANDO && (this->getItemId == RG_ICE_TRAP || this->getItemEntry.getItemId == RG_ICE_TRAP))) {
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD);
|
|
|
|
if ((this->getItemId != GI_ICE_TRAP && !IS_RANDO) ||
|
|
(IS_RANDO && (this->getItemId != RG_ICE_TRAP || this->getItemEntry.getItemId != RG_ICE_TRAP))) {
|
|
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x,
|
|
this->actor.world.pos.y + 100.0f, this->actor.world.pos.z, 0, 0, 0, 0, true);
|
|
func_8083C0E8(this, play);
|
|
} else if (IS_RANDO) {
|
|
gSaveContext.pendingIceTrapCount++;
|
|
Player_SetPendingFlag(this, play);
|
|
func_8083C0E8(this, play);
|
|
} else {
|
|
this->actor.colChkInfo.damage = 0;
|
|
func_80837C0C(play, this, 3, 0.0f, 0.0f, 0, 20);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (this->skelAnime.animation == &gPlayerAnim_link_normal_box_kick) {
|
|
Player_AnimPlayOnceAdjusted(play, this, &gPlayerAnim_link_demo_get_itemB);
|
|
} else {
|
|
Player_AnimPlayOnceAdjusted(play, this, &gPlayerAnim_link_demo_get_itemA);
|
|
}
|
|
|
|
this->av2.actionVar2 = 2;
|
|
func_80835EA4(play, 9);
|
|
}
|
|
} else {
|
|
if (this->av2.actionVar2 == 0) {
|
|
if (!LINK_IS_ADULT) {
|
|
Player_ProcessAnimSfxList(this, D_808549E0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (this->skelAnime.animation == &gPlayerAnim_link_demo_get_itemB) {
|
|
Math_ScaledStepToS(&this->actor.shape.rot.y, Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) + 0x8000, 4000);
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 21.0f)) {
|
|
func_808332F4(this, play);
|
|
}
|
|
}
|
|
}
|
|
|
|
static AnimSfxEntry D_808549F0[] = {
|
|
{ NA_SE_IT_MASTER_SWORD_SWING, -ANIMSFX_DATA(ANIMSFX_TYPE_1, 60) },
|
|
};
|
|
|
|
void func_8084E988(Player* this) {
|
|
Player_ProcessAnimSfxList(this, D_808549F0);
|
|
}
|
|
|
|
static AnimSfxEntry D_808549F4[] = {
|
|
{ NA_SE_VO_LI_AUTO_JUMP, ANIMSFX_DATA(ANIMSFX_TYPE_4, 5) },
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_5, 15) },
|
|
};
|
|
|
|
void Player_Action_8084E9AC(Player* this, PlayState* play) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (this->av1.actionVar1 == 0) {
|
|
if (DECR(this->av2.actionVar2) == 0) {
|
|
this->av1.actionVar1 = 1;
|
|
this->skelAnime.endFrame = this->skelAnime.animLength - 1.0f;
|
|
}
|
|
} else {
|
|
func_8083C0E8(this, play);
|
|
}
|
|
} else {
|
|
if (LINK_IS_ADULT && LinkAnimation_OnFrame(&this->skelAnime, 158.0f)) {
|
|
func_80832698(this, NA_SE_VO_LI_SWORD_N);
|
|
return;
|
|
}
|
|
|
|
if (!LINK_IS_ADULT) {
|
|
Player_ProcessAnimSfxList(this, D_808549F4);
|
|
} else {
|
|
func_8084E988(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
static u8 D_808549FC[] = {
|
|
0x01, 0x03, 0x02, 0x04, 0x04,
|
|
};
|
|
|
|
void Player_Action_8084EAC0(Player* this, PlayState* play) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (this->av2.actionVar2 == 0) {
|
|
if (this->itemAction == PLAYER_IA_BOTTLE_POE) {
|
|
s32 rand = Rand_S16Offset(-1, 3);
|
|
|
|
if (rand == 0) {
|
|
rand = 3;
|
|
}
|
|
|
|
if ((rand < 0) && (gSaveContext.health <= 0x10)) {
|
|
rand = 3;
|
|
}
|
|
|
|
if (rand < 0) {
|
|
Health_ChangeBy(play, -0x10);
|
|
} else {
|
|
gSaveContext.healthAccumulator = rand * 0x10;
|
|
}
|
|
} else {
|
|
s32 sp28 = D_808549FC[this->itemAction - PLAYER_IA_BOTTLE_POTION_RED];
|
|
|
|
if (CVarGetInteger("gRedPotionEffect", 0) && this->itemAction == PLAYER_IA_BOTTLE_POTION_RED) {
|
|
if (CVarGetInteger("gRedPercentRestore", 0)) {
|
|
gSaveContext.healthAccumulator =
|
|
(gSaveContext.healthCapacity * CVarGetInteger("gRedPotionHealth", 100) / 100 + 15) / 16 * 16;
|
|
} else {
|
|
gSaveContext.healthAccumulator = CVarGetInteger("gRedPotionHealth", 20) * 16;
|
|
}
|
|
} else if (CVarGetInteger("gBluePotionEffects", 0) &&
|
|
this->itemAction == PLAYER_IA_BOTTLE_POTION_BLUE) {
|
|
if (CVarGetInteger("gBlueHealthPercentRestore", 0)) {
|
|
gSaveContext.healthAccumulator =
|
|
(gSaveContext.healthCapacity * CVarGetInteger("gBluePotionHealth", 100) / 100 + 15) / 16 * 16;
|
|
} else {
|
|
gSaveContext.healthAccumulator = CVarGetInteger("gBluePotionHealth", 20) * 16;
|
|
}
|
|
|
|
if (CVarGetInteger("gBlueManaPercentRestore", 0)) {
|
|
if (gSaveContext.magicState != MAGIC_STATE_ADD) {
|
|
Magic_Fill(play);
|
|
}
|
|
|
|
Magic_RequestChange(play,
|
|
(gSaveContext.magicLevel * 48 * CVarGetInteger("gBluePotionMana", 100) / 100 + 15) /
|
|
16 * 16,
|
|
MAGIC_ADD);
|
|
} else {
|
|
if (gSaveContext.magicState != MAGIC_STATE_ADD) {
|
|
Magic_Fill(play);
|
|
}
|
|
|
|
Magic_RequestChange(play, CVarGetInteger("gBluePotionMana", 100), MAGIC_ADD);
|
|
;
|
|
}
|
|
} else if (CVarGetInteger("gGreenPotionEffect", 0) &&
|
|
this->itemAction == PLAYER_IA_BOTTLE_POTION_GREEN) {
|
|
if (CVarGetInteger("gGreenPercentRestore", 0)) {
|
|
if (gSaveContext.magicState != MAGIC_STATE_ADD) {
|
|
Magic_Fill(play);
|
|
}
|
|
|
|
Magic_RequestChange(play,
|
|
(gSaveContext.magicLevel * 48 * CVarGetInteger("gGreenPotionMana", 100) / 100 + 15) /
|
|
16 * 16,
|
|
MAGIC_ADD);
|
|
} else {
|
|
if (gSaveContext.magicState != MAGIC_STATE_ADD) {
|
|
Magic_Fill(play);
|
|
}
|
|
|
|
Magic_RequestChange(play, CVarGetInteger("gGreenPotionMana", 100), MAGIC_ADD);
|
|
;
|
|
}
|
|
} else if (CVarGetInteger("gMilkEffect", 0) && (this->itemAction == PLAYER_IA_BOTTLE_MILK_FULL ||
|
|
this->itemAction == PLAYER_IA_BOTTLE_MILK_HALF)) {
|
|
if (CVarGetInteger("gMilkPercentRestore", 0)) {
|
|
gSaveContext.healthAccumulator =
|
|
(gSaveContext.healthCapacity * CVarGetInteger("gMilkHealth", 100) / 100 + 15) / 16 * 16;
|
|
} else {
|
|
gSaveContext.healthAccumulator = CVarGetInteger("gMilkHealth", 5) * 16;
|
|
}
|
|
if (CVarGetInteger("gSeparateHalfMilkEffect", 0) &&
|
|
this->itemAction == PLAYER_IA_BOTTLE_MILK_HALF) {
|
|
if (CVarGetInteger("gHalfMilkPercentRestore", 0)) {
|
|
gSaveContext.healthAccumulator =
|
|
(gSaveContext.healthCapacity * CVarGetInteger("gHalfMilkHealth", 100) / 100 + 15) / 16 *
|
|
16;
|
|
} else {
|
|
gSaveContext.healthAccumulator = CVarGetInteger("gHalfMilkHealth", 5) * 16;
|
|
}
|
|
}
|
|
} else {
|
|
if (sp28 & 1) {
|
|
gSaveContext.healthAccumulator = 0x140;
|
|
}
|
|
|
|
if (sp28 & 2) {
|
|
Magic_Fill(play);
|
|
}
|
|
|
|
if (sp28 & 4) {
|
|
gSaveContext.healthAccumulator = 0x50;
|
|
}
|
|
}
|
|
}
|
|
|
|
Player_AnimPlayLoopAdjusted(play, this, &gPlayerAnim_link_bottle_drink_demo_wait);
|
|
this->av2.actionVar2 = 1;
|
|
return;
|
|
}
|
|
|
|
func_8083C0E8(this, play);
|
|
func_8005B1A4(Play_GetCamera(play, 0));
|
|
} else if (this->av2.actionVar2 == 1) {
|
|
if ((gSaveContext.healthAccumulator == 0) && (gSaveContext.magicState != MAGIC_STATE_FILL)) {
|
|
Player_AnimChangeOnceMorphAdjusted(play, this, &gPlayerAnim_link_bottle_drink_demo_end);
|
|
this->av2.actionVar2 = 2;
|
|
Player_UpdateBottleHeld(play, this, ITEM_BOTTLE, PLAYER_IA_BOTTLE);
|
|
}
|
|
func_80832698(this, NA_SE_VO_LI_DRINK - SFX_FLAG);
|
|
} else if ((this->av2.actionVar2 == 2) && LinkAnimation_OnFrame(&this->skelAnime, 29.0f)) {
|
|
func_80832698(this, NA_SE_VO_LI_BREATH_DRINK);
|
|
}
|
|
}
|
|
|
|
static BottleCatchInfo D_80854A04[] = {
|
|
{ ACTOR_EN_ELF, ITEM_FAIRY, 0x2A, 0x46 },
|
|
{ ACTOR_EN_FISH, ITEM_FISH, 0x1F, 0x47 },
|
|
{ ACTOR_EN_ICE_HONO, ITEM_BLUE_FIRE, 0x20, 0x5D },
|
|
{ ACTOR_EN_INSECT, ITEM_BUG, 0x21, 0x7A },
|
|
};
|
|
|
|
void Player_Action_8084ECA4(Player* this, PlayState* play) {
|
|
struct_80854554* sp24;
|
|
BottleCatchInfo* catchInfo;
|
|
s32 temp;
|
|
s32 i;
|
|
|
|
sp24 = &D_80854554[this->av2.actionVar2];
|
|
func_8083721C(this);
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (this->av1.actionVar1 != 0) {
|
|
if (this->av2.actionVar2 == 0) {
|
|
if (CVarGetInteger("gFastDrops", 0)) {
|
|
this->av1.actionVar1 = 0;
|
|
} else {
|
|
Message_StartTextbox(play, D_80854A04[this->av1.actionVar1 - 1].textId, &this->actor);
|
|
}
|
|
Audio_PlayFanfare(NA_BGM_ITEM_GET | 0x900);
|
|
this->av2.actionVar2 = 1;
|
|
} else if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) {
|
|
this->av1.actionVar1 = 0;
|
|
func_8005B1A4(Play_GetCamera(play, 0));
|
|
}
|
|
} else {
|
|
func_8083C0E8(this, play);
|
|
}
|
|
} else {
|
|
if (this->av1.actionVar1 == 0) {
|
|
temp = this->skelAnime.curFrame - sp24->unk_08;
|
|
|
|
if (temp >= 0) {
|
|
if (sp24->unk_09 >= temp) {
|
|
if (this->av2.actionVar2 != 0) {
|
|
if (temp == 0) {
|
|
Player_PlaySfx(this, NA_SE_IT_SCOOP_UP_WATER);
|
|
}
|
|
}
|
|
|
|
if (this->interactRangeActor != NULL) {
|
|
catchInfo = &D_80854A04[0];
|
|
for (i = 0; i < 4; i++, catchInfo++) {
|
|
if (this->interactRangeActor->id == catchInfo->actorId) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i < 4) {
|
|
this->av1.actionVar1 = i + 1;
|
|
this->av2.actionVar2 = 0;
|
|
this->interactRangeActor->parent = &this->actor;
|
|
Player_UpdateBottleHeld(play, this, catchInfo->itemId, ABS(catchInfo->itemAction));
|
|
if (!CVarGetInteger("gFastDrops", 0)) {
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE;
|
|
Player_AnimPlayOnceAdjusted(play, this, sp24->unk_04);
|
|
func_80835EA4(play, 4);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//! @bug If the animation is changed at any point above (such as by func_8083C0E8() or
|
|
//! Player_AnimPlayOnceAdjusted()), it will change the curFrame to 0. This causes this flag to be set for one frame,
|
|
//! at a time when it does not look like Player is swinging the bottle.
|
|
if (this->skelAnime.curFrame <= 7.0f) {
|
|
this->stateFlags1 |= PLAYER_STATE1_SWINGING_BOTTLE;
|
|
}
|
|
}
|
|
|
|
static Vec3f D_80854A1C = { 0.0f, 0.0f, 5.0f };
|
|
|
|
void Player_Action_8084EED8(Player* this, PlayState* play) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_8083C0E8(this, play);
|
|
func_8005B1A4(Play_GetCamera(play, 0));
|
|
return;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 37.0f)) {
|
|
Player_SpawnFairy(play, this, &this->leftHandPos, &D_80854A1C, FAIRY_REVIVE_BOTTLE);
|
|
Player_UpdateBottleHeld(play, this, ITEM_BOTTLE, PLAYER_IA_BOTTLE);
|
|
Player_PlaySfx(this, NA_SE_EV_BOTTLE_CAP_OPEN);
|
|
Player_PlaySfx(this, NA_SE_EV_FIATY_HEAL - SFX_FLAG);
|
|
} else if (LinkAnimation_OnFrame(&this->skelAnime, 47.0f)) {
|
|
if (CVarGetInteger("gFairyEffect", 0)) {
|
|
if (CVarGetInteger("gFairyPercentRestore", 0)) {
|
|
gSaveContext.healthAccumulator =
|
|
(gSaveContext.healthCapacity * CVarGetInteger("gFairyHealth", 100) / 100 + 15) / 16 * 16;
|
|
} else {
|
|
gSaveContext.healthAccumulator = CVarGetInteger("gFairyHealth", 8) * 16;
|
|
}
|
|
} else {
|
|
gSaveContext.healthAccumulator = 0x140;
|
|
}
|
|
}
|
|
}
|
|
|
|
static BottleDropInfo D_80854A28[] = {
|
|
{ ACTOR_EN_FISH, FISH_DROPPED },
|
|
{ ACTOR_EN_ICE_HONO, 0 },
|
|
{ ACTOR_EN_INSECT, 2 },
|
|
};
|
|
|
|
static AnimSfxEntry D_80854A34[] = {
|
|
{ NA_SE_VO_LI_AUTO_JUMP, ANIMSFX_DATA(ANIMSFX_TYPE_4, 38) },
|
|
{ NA_SE_EV_BOTTLE_CAP_OPEN, -ANIMSFX_DATA(ANIMSFX_TYPE_1, 40) },
|
|
};
|
|
|
|
void Player_Action_8084EFC0(Player* this, PlayState* play) {
|
|
func_8083721C(this);
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_8083C0E8(this, play);
|
|
func_8005B1A4(Play_GetCamera(play, 0));
|
|
return;
|
|
}
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 76.0f)) {
|
|
BottleDropInfo* dropInfo = &D_80854A28[this->itemAction - PLAYER_IA_BOTTLE_FISH];
|
|
|
|
Actor_Spawn(&play->actorCtx, play, dropInfo->actorId,
|
|
(Math_SinS(this->actor.shape.rot.y) * 5.0f) + this->leftHandPos.x, this->leftHandPos.y,
|
|
(Math_CosS(this->actor.shape.rot.y) * 5.0f) + this->leftHandPos.z, 0x4000, this->actor.shape.rot.y,
|
|
0, dropInfo->actorParams, true);
|
|
|
|
Player_UpdateBottleHeld(play, this, ITEM_BOTTLE, PLAYER_IA_BOTTLE);
|
|
return;
|
|
}
|
|
|
|
Player_ProcessAnimSfxList(this, D_80854A34);
|
|
}
|
|
|
|
static AnimSfxEntry D_80854A3C[] = {
|
|
{ NA_SE_PL_PUT_OUT_ITEM, -ANIMSFX_DATA(ANIMSFX_TYPE_1, 30) },
|
|
};
|
|
|
|
void Player_Action_8084F104(Player* this, PlayState* play) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (this->av2.actionVar2 < 0) {
|
|
func_8083C0E8(this, play);
|
|
} else if (this->exchangeItemId == EXCH_ITEM_NONE) {
|
|
Actor* targetActor = this->targetActor;
|
|
|
|
this->unk_862 = 0;
|
|
if (targetActor->textId != 0xFFFF) {
|
|
this->actor.flags |= ACTOR_FLAG_PLAYER_TALKED_TO;
|
|
}
|
|
|
|
Player_StartTalking(play, targetActor);
|
|
} else {
|
|
GetItemEntry giEntry = ItemTable_Retrieve(D_80854528[this->exchangeItemId - 1]);
|
|
|
|
if (this->itemAction >= PLAYER_IA_ZELDAS_LETTER) {
|
|
if (giEntry.gi >= 0) {
|
|
this->unk_862 = giEntry.gi;
|
|
} else {
|
|
this->unk_862 = -giEntry.gi;
|
|
}
|
|
}
|
|
|
|
if (this->av2.actionVar2 == 0) {
|
|
Message_StartTextbox(play, this->actor.textId, &this->actor);
|
|
|
|
if ((this->itemAction == PLAYER_IA_CHICKEN) || (this->itemAction == PLAYER_IA_POCKET_CUCCO)) {
|
|
Player_PlaySfx(this, NA_SE_EV_CHICKEN_CRY_M);
|
|
}
|
|
|
|
this->av2.actionVar2 = 1;
|
|
} else if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) {
|
|
this->actor.flags &= ~ACTOR_FLAG_PLAYER_TALKED_TO;
|
|
this->unk_862 = 0;
|
|
|
|
if (this->av1.actionVar1 == 1) {
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_bottle_read_end);
|
|
this->av2.actionVar2 = -1;
|
|
} else {
|
|
func_8083C0E8(this, play);
|
|
}
|
|
|
|
func_8005B1A4(Play_GetCamera(play, 0));
|
|
}
|
|
}
|
|
} else if (this->av2.actionVar2 >= 0) {
|
|
Player_ProcessAnimSfxList(this, D_80854A3C);
|
|
}
|
|
|
|
if ((this->av1.actionVar1 == 0) && (this->unk_664 != NULL)) {
|
|
this->yaw = this->actor.shape.rot.y = func_8083DB98(this, 0);
|
|
}
|
|
}
|
|
|
|
void func_8084F308(Player* this, PlayState* play) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET | PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimPlayLoop(play, this, &gPlayerAnim_link_normal_re_dead_attack_wait);
|
|
}
|
|
|
|
if (func_80832594(this, 0, 100)) {
|
|
func_80839F90(this, play);
|
|
this->stateFlags2 &= ~PLAYER_STATE2_GRABBED_BY_ENEMY;
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084F390(Player* this, PlayState* play) {
|
|
CollisionPoly* floorPoly;
|
|
f32 sp50;
|
|
f32 sp4C;
|
|
f32 sp48;
|
|
s16 sp46;
|
|
s16 sp44;
|
|
Vec3f sp38;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET | PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
func_8084269C(play, this);
|
|
func_800F4138(&this->actor.projectedPos, NA_SE_PL_SLIP_LEVEL - SFX_FLAG, this->actor.speedXZ);
|
|
|
|
if (Player_ActionChange_13(this, play) == 0) {
|
|
floorPoly = this->actor.floorPoly;
|
|
|
|
if (floorPoly == NULL) {
|
|
func_80837B9C(this, play);
|
|
return;
|
|
}
|
|
|
|
Player_GetSlopeDirection(floorPoly, &sp38, &sp46);
|
|
|
|
sp44 = sp46;
|
|
if (this->av1.actionVar1 != 0) {
|
|
sp44 = sp46 + 0x8000;
|
|
}
|
|
|
|
if (this->linearVelocity < 0) {
|
|
sp46 += 0x8000;
|
|
}
|
|
|
|
sp50 = (1.0f - sp38.y) * 40.0f;
|
|
sp50 = CLAMP(sp50, 0, 10.0f);
|
|
sp4C = (sp50 * sp50) * 0.015f;
|
|
sp48 = sp38.y * 0.01f;
|
|
|
|
if (SurfaceType_GetSlope(&play->colCtx, floorPoly, this->actor.floorBgId) != 1) {
|
|
sp50 = 0;
|
|
sp48 = sp38.y * 10.0f;
|
|
}
|
|
|
|
if (sp4C < 1.0f) {
|
|
sp4C = 1.0f;
|
|
}
|
|
|
|
if (Math_AsymStepToF(&this->linearVelocity, sp50, sp4C, sp48) && (sp50 == 0)) {
|
|
LinkAnimationHeader* anim;
|
|
if (this->av1.actionVar1 == 0) {
|
|
anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_down_slope_slip_end, this->modelAnimType);
|
|
} else {
|
|
anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_up_slope_slip_end, this->modelAnimType);
|
|
}
|
|
func_8083A098(this, anim, play);
|
|
}
|
|
|
|
Math_SmoothStepToS(&this->yaw, sp46, 10, 4000, 800);
|
|
Math_ScaledStepToS(&this->actor.shape.rot.y, sp44, 2000);
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084F608(Player* this, PlayState* play) {
|
|
if ((DECR(this->av2.actionVar2) == 0) && Player_StartCsAction(play, this)) {
|
|
func_80852280(play, this, NULL);
|
|
Player_SetupAction(play, this, Player_Action_CsAction, 0);
|
|
Player_Action_CsAction(this, play);
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084F698(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_8084F608, 0);
|
|
this->av2.actionVar2 = 40;
|
|
Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_KANKYO, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0x10, true);
|
|
}
|
|
|
|
void Player_Action_8084F710(Player* this, PlayState* play) {
|
|
s32 pad;
|
|
|
|
if ((this->av1.actionVar1 != 0) && (play->csCtx.frames < 0x131)) {
|
|
this->actor.gravity = 0.0f;
|
|
this->actor.velocity.y = 0.0f;
|
|
} else if (sYDistToFloor < 150.0f) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (this->av2.actionVar2 == 0) {
|
|
if (this->actor.bgCheckFlags & 1) {
|
|
this->skelAnime.endFrame = this->skelAnime.animLength - 1.0f;
|
|
func_808328A0(this);
|
|
this->av2.actionVar2 = 1;
|
|
}
|
|
} else {
|
|
if ((play->sceneNum == SCENE_KOKIRI_FOREST) && Player_StartCsAction(play, this)) {
|
|
return;
|
|
}
|
|
func_80853080(this, play);
|
|
}
|
|
}
|
|
Math_SmoothStepToF(&this->actor.velocity.y, 2.0f, 0.3f, 8.0f, 0.5f);
|
|
}
|
|
|
|
if ((play->sceneNum == SCENE_CHAMBER_OF_THE_SAGES) && Player_StartCsAction(play, this)) {
|
|
return;
|
|
}
|
|
|
|
if ((play->csCtx.state != CS_STATE_IDLE) && (play->csCtx.linkAction != NULL)) {
|
|
f32 sp28 = this->actor.world.pos.y;
|
|
func_808529D0(play, this, play->csCtx.linkAction);
|
|
this->actor.world.pos.y = sp28;
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084F88C(Player* this, PlayState* play) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if ((this->av2.actionVar2++ > 8) && (play->transitionTrigger == TRANS_TRIGGER_OFF)) {
|
|
|
|
if (this->av1.actionVar1 != 0) {
|
|
if (play->sceneNum == SCENE_ICE_CAVERN) {
|
|
Play_TriggerRespawn(play);
|
|
play->nextEntranceIndex = ENTR_ICE_CAVERN_0;
|
|
} else if (this->av1.actionVar1 < 0) {
|
|
Play_TriggerRespawn(play);
|
|
// In ER, handle DMT and other special void outs to respawn from last entrance from grotto
|
|
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
|
|
Grotto_ForceRegularVoidOut();
|
|
}
|
|
} else {
|
|
Play_TriggerVoidOut(play);
|
|
}
|
|
|
|
play->transitionType = TRANS_TYPE_FADE_BLACK_FAST;
|
|
func_80078884(NA_SE_OC_ABYSS);
|
|
} else {
|
|
play->transitionType = TRANS_TYPE_FADE_BLACK;
|
|
gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE;
|
|
gSaveContext.seqId = (u8)NA_BGM_DISABLED;
|
|
gSaveContext.natureAmbienceId = 0xFF;
|
|
}
|
|
|
|
play->transitionTrigger = TRANS_TRIGGER_START;
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084F9A0(Player* this, PlayState* play) {
|
|
Player_ActionChange_1(this, play);
|
|
}
|
|
|
|
void Player_Action_8084F9C0(Player* this, PlayState* play) {
|
|
this->actor.gravity = -1.0f;
|
|
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (this->actor.velocity.y < 0.0f) {
|
|
func_80837B9C(this, play);
|
|
} else if (this->actor.velocity.y < 6.0f) {
|
|
Math_StepToF(&this->linearVelocity, 3.0f, 0.5f);
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084FA54(Player* this, PlayState* play) {
|
|
this->unk_6AD = 2;
|
|
|
|
func_8083AD4C(play, this);
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
Player_UpdateUpperBody(this, play);
|
|
|
|
this->unk_6BE = func_8084ABD8(play, this, 1, 0) - this->actor.shape.rot.y;
|
|
this->unk_6AE |= 0x80;
|
|
|
|
if (play->shootingGalleryStatus < 0) {
|
|
play->shootingGalleryStatus++;
|
|
if (play->shootingGalleryStatus == 0) {
|
|
func_8083C148(this, play);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084FB10(Player* this, PlayState* play) {
|
|
if (this->av1.actionVar1 >= 0) {
|
|
if (this->av1.actionVar1 < 6) {
|
|
this->av1.actionVar1++;
|
|
}
|
|
|
|
if (func_80832594(this, 1, 100)) {
|
|
this->av1.actionVar1 = -1;
|
|
EffectSsIcePiece_SpawnBurst(play, &this->actor.world.pos, this->actor.scale.x);
|
|
Player_PlaySfx(this, NA_SE_PL_ICE_BROKEN);
|
|
} else {
|
|
this->stateFlags2 |= PLAYER_STATE2_FROZEN;
|
|
}
|
|
|
|
if ((play->gameplayFrames % 4) == 0) {
|
|
Player_InflictDamage(play, -1);
|
|
}
|
|
} else {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_80839F90(this, play);
|
|
func_80837AFC(this, -20);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_8084FBF4(Player* this, PlayState* play) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
func_808382BC(this);
|
|
|
|
if (((this->av2.actionVar2 % 25) != 0) || func_80837B18(play, this, -1)) {
|
|
if (DECR(this->av2.actionVar2) == 0) {
|
|
func_80839F90(this, play);
|
|
}
|
|
}
|
|
|
|
this->bodyShockTimer = 40;
|
|
func_8002F8F0(&this->actor, NA_SE_VO_LI_TAKEN_AWAY - SFX_FLAG + this->ageProperties->unk_92);
|
|
}
|
|
|
|
s32 func_8084FCAC(Player* this, PlayState* play) {
|
|
sControlInput = &play->state.input[0];
|
|
|
|
if (CVarGetInteger("gDebugEnabled", 0) &&
|
|
((CHECK_BTN_ALL(sControlInput->cur.button, BTN_A | BTN_L | BTN_R) &&
|
|
CHECK_BTN_ALL(sControlInput->press.button, BTN_B)) ||
|
|
(CHECK_BTN_ALL(sControlInput->cur.button, BTN_L) && CHECK_BTN_ALL(sControlInput->press.button, BTN_DRIGHT)))) {
|
|
|
|
D_808535D0 ^= 1;
|
|
|
|
if (D_808535D0) {
|
|
Camera_ChangeMode(Play_GetCamera(play, 0), CAM_MODE_BOWARROWZ);
|
|
}
|
|
}
|
|
|
|
if (D_808535D0) {
|
|
f32 speed;
|
|
|
|
if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_R)) {
|
|
speed = 100.0f;
|
|
} else {
|
|
speed = 20.0f;
|
|
}
|
|
|
|
func_8006375C(3, 2, "DEBUG MODE");
|
|
|
|
if (!CHECK_BTN_ALL(sControlInput->cur.button, BTN_L)) {
|
|
if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_B)) {
|
|
this->actor.world.pos.y += speed;
|
|
} else if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_A)) {
|
|
this->actor.world.pos.y -= speed;
|
|
}
|
|
|
|
if (CHECK_BTN_ANY(sControlInput->cur.button, BTN_DUP | BTN_DLEFT | BTN_DDOWN | BTN_DRIGHT)) {
|
|
s16 angle;
|
|
s16 temp;
|
|
|
|
angle = temp = Camera_GetInputDirYaw(GET_ACTIVE_CAM(play));
|
|
|
|
if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_DDOWN)) {
|
|
angle = temp + 0x8000;
|
|
} else if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_DLEFT)) {
|
|
angle = temp + (0x4000 * (CVarGetInteger("gMirroredWorld", 0) ? -1 : 1));
|
|
} else if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_DRIGHT)) {
|
|
angle = temp - (0x4000 * (CVarGetInteger("gMirroredWorld", 0) ? -1 : 1));
|
|
}
|
|
|
|
this->actor.world.pos.x += speed * Math_SinS(angle);
|
|
this->actor.world.pos.z += speed * Math_CosS(angle);
|
|
}
|
|
}
|
|
|
|
Player_ZeroSpeedXZ(this);
|
|
|
|
this->actor.gravity = 0.0f;
|
|
this->actor.velocity.z = 0.0f;
|
|
this->actor.velocity.y = 0.0f;
|
|
this->actor.velocity.x = 0.0f;
|
|
|
|
if (CHECK_BTN_ALL(sControlInput->cur.button, BTN_L) && CHECK_BTN_ALL(sControlInput->press.button, BTN_DLEFT)) {
|
|
Flags_SetTempClear(play, play->roomCtx.curRoom.num);
|
|
}
|
|
|
|
Math_Vec3f_Copy(&this->actor.home.pos, &this->actor.world.pos);
|
|
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void func_8084FF7C(Player* this) {
|
|
this->unk_858 += this->unk_85C;
|
|
this->unk_85C -= this->unk_858 * 5.0f;
|
|
this->unk_85C *= 0.3f;
|
|
|
|
if (ABS(this->unk_85C) < 0.00001f) {
|
|
this->unk_85C = 0.0f;
|
|
if (ABS(this->unk_858) < 0.00001f) {
|
|
this->unk_858 = 0.0f;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates the Bunny Hood's floppy ears' rotation and velocity.
|
|
*/
|
|
void Player_UpdateBunnyEars(Player* this) {
|
|
Vec3s force;
|
|
s16 angle;
|
|
|
|
// Damping: decay by 1/8 the previous value each frame
|
|
sBunnyEarKinematics.angVel.x -= sBunnyEarKinematics.angVel.x >> 3;
|
|
sBunnyEarKinematics.angVel.y -= sBunnyEarKinematics.angVel.y >> 3;
|
|
|
|
// Elastic restorative force
|
|
sBunnyEarKinematics.angVel.x += -sBunnyEarKinematics.rot.x >> 2;
|
|
sBunnyEarKinematics.angVel.y += -sBunnyEarKinematics.rot.y >> 2;
|
|
|
|
// Forcing from motion relative to shape frame
|
|
angle = this->actor.world.rot.y - this->actor.shape.rot.y;
|
|
force.x = (s32)(this->actor.speedXZ * -200.0f * Math_CosS(angle) * (Rand_CenteredFloat(2.0f) + 10.0f)) & 0xFFFF;
|
|
force.y = (s32)(this->actor.speedXZ * 100.0f * Math_SinS(angle) * (Rand_CenteredFloat(2.0f) + 10.0f)) & 0xFFFF;
|
|
|
|
sBunnyEarKinematics.angVel.x += force.x >> 2;
|
|
sBunnyEarKinematics.angVel.y += force.y >> 2;
|
|
|
|
// Clamp both angular velocities to [-6000, 6000]
|
|
if (sBunnyEarKinematics.angVel.x > 6000) {
|
|
sBunnyEarKinematics.angVel.x = 6000;
|
|
} else if (sBunnyEarKinematics.angVel.x < -6000) {
|
|
sBunnyEarKinematics.angVel.x = -6000;
|
|
}
|
|
if (sBunnyEarKinematics.angVel.y > 6000) {
|
|
sBunnyEarKinematics.angVel.y = 6000;
|
|
} else if (sBunnyEarKinematics.angVel.y < -6000) {
|
|
sBunnyEarKinematics.angVel.y = -6000;
|
|
}
|
|
|
|
// Add angular velocity to rotations
|
|
sBunnyEarKinematics.rot.x += sBunnyEarKinematics.angVel.x;
|
|
sBunnyEarKinematics.rot.y += sBunnyEarKinematics.angVel.y;
|
|
|
|
// swivel ears outwards if bending backwards
|
|
if (sBunnyEarKinematics.rot.x < 0) {
|
|
sBunnyEarKinematics.rot.z = sBunnyEarKinematics.rot.x >> 1;
|
|
} else {
|
|
sBunnyEarKinematics.rot.z = 0;
|
|
}
|
|
}
|
|
|
|
s32 Player_ActionChange_7(Player* this, PlayState* play) {
|
|
if (func_8083C6B8(play, this) == 0) {
|
|
if (func_8083BB20(this) != 0) {
|
|
s32 sp24 = func_80837818(this);
|
|
|
|
func_80837948(play, this, sp24);
|
|
|
|
if (sp24 >= PLAYER_MWA_SPIN_ATTACK_1H) {
|
|
this->stateFlags2 |= PLAYER_STATE2_SPIN_ATTACKING;
|
|
func_80837530(play, this, 0);
|
|
return 1;
|
|
}
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static Vec3f D_80854A40 = { 0.0f, 40.0f, 45.0f };
|
|
|
|
void Player_Action_808502D0(Player* this, PlayState* play) {
|
|
struct_80854190* sp44 = &D_80854190[this->meleeWeaponAnimation];
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
|
|
if (!func_80842DF4(play, this)) {
|
|
func_8084285C(this, 0.0f, sp44->unk_0C, sp44->unk_0D);
|
|
|
|
if ((this->stateFlags2 & PLAYER_STATE2_SWORD_LUNGE) && (this->heldItemAction != PLAYER_IA_HAMMER) &&
|
|
LinkAnimation_OnFrame(&this->skelAnime, 0.0f)) {
|
|
this->linearVelocity = 15.0f;
|
|
this->stateFlags2 &= ~PLAYER_STATE2_SWORD_LUNGE;
|
|
}
|
|
|
|
if (this->linearVelocity > 12.0f) {
|
|
func_8084269C(play, this);
|
|
}
|
|
|
|
Math_StepToF(&this->linearVelocity, 0.0f, 5.0f);
|
|
func_8083C50C(this);
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (!Player_ActionChange_7(this, play)) {
|
|
u8 sp43 = this->skelAnime.moveFlags;
|
|
LinkAnimationHeader* sp3C;
|
|
|
|
if (func_8008E9C4(this)) {
|
|
sp3C = sp44->unk_08;
|
|
} else {
|
|
sp3C = sp44->unk_04;
|
|
}
|
|
|
|
func_80832318(this);
|
|
this->skelAnime.moveFlags = 0;
|
|
|
|
if ((sp3C == &gPlayerAnim_link_fighter_Lpower_jump_kiru_end) &&
|
|
(this->modelAnimType != PLAYER_ANIMTYPE_3)) {
|
|
sp3C = &gPlayerAnim_link_fighter_power_jump_kiru_end;
|
|
}
|
|
|
|
func_8083A098(this, sp3C, play);
|
|
|
|
this->skelAnime.moveFlags = sp43;
|
|
this->stateFlags3 |= PLAYER_STATE3_FINISHED_ATTACKING;
|
|
}
|
|
} else if (this->heldItemAction == PLAYER_IA_HAMMER) {
|
|
if ((this->meleeWeaponAnimation == PLAYER_MWA_HAMMER_FORWARD) ||
|
|
(this->meleeWeaponAnimation == PLAYER_MWA_JUMPSLASH_FINISH)) {
|
|
static Vec3f zeroVec = { 0.0f, 0.0f, 0.0f };
|
|
Vec3f shockwavePos;
|
|
f32 sp2C;
|
|
|
|
shockwavePos.y = func_8083973C(play, this, &D_80854A40, &shockwavePos);
|
|
sp2C = this->actor.world.pos.y - shockwavePos.y;
|
|
|
|
Math_ScaledStepToS(&this->actor.focus.rot.x, Math_Atan2S(45.0f, sp2C), 800);
|
|
func_80836AB8(this, 1);
|
|
|
|
if ((((this->meleeWeaponAnimation == PLAYER_MWA_HAMMER_FORWARD) && LinkAnimation_OnFrame(&this->skelAnime, 7.0f)) ||
|
|
((this->meleeWeaponAnimation == PLAYER_MWA_JUMPSLASH_FINISH) && LinkAnimation_OnFrame(&this->skelAnime, 2.0f))) &&
|
|
(sp2C > -40.0f) && (sp2C < 40.0f)) {
|
|
func_80842A28(play, this);
|
|
EffectSsBlast_SpawnWhiteShockwave(play, &shockwavePos, &zeroVec, &zeroVec);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Player_Action_808505DC(Player* this, PlayState* play) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
func_8083721C(this);
|
|
|
|
if (this->skelAnime.curFrame >= 6.0f) {
|
|
func_80839FFC(this, play);
|
|
}
|
|
}
|
|
|
|
void Player_Action_8085063C(Player* this, PlayState* play) {
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
Player_UpdateUpperBody(this, play);
|
|
|
|
if (this->av2.actionVar2 == 0) {
|
|
Message_StartTextbox(play, 0x3B, &this->actor);
|
|
this->av2.actionVar2 = 1;
|
|
return;
|
|
}
|
|
|
|
if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) {
|
|
s32 respawnData = gSaveContext.respawn[RESPAWN_MODE_TOP].data;
|
|
|
|
if (play->msgCtx.choiceIndex == 0) { //Returns to FW
|
|
gSaveContext.respawnFlag = 3;
|
|
play->transitionTrigger = TRANS_TRIGGER_START;
|
|
play->nextEntranceIndex = gSaveContext.respawn[RESPAWN_MODE_TOP].entranceIndex;
|
|
play->transitionType = TRANS_TYPE_FADE_WHITE_FAST;
|
|
func_80088AF0(play);
|
|
return;
|
|
}
|
|
|
|
if (play->msgCtx.choiceIndex == 1) { //Unsets FW
|
|
gSaveContext.respawn[RESPAWN_MODE_TOP].data = -respawnData;
|
|
gSaveContext.fw.set = 0;
|
|
func_80078914(&gSaveContext.respawn[RESPAWN_MODE_TOP].pos, NA_SE_PL_MAGIC_WIND_VANISH);
|
|
}
|
|
|
|
func_80853080(this, play);
|
|
func_8005B1A4(Play_GetCamera(play, 0));
|
|
}
|
|
}
|
|
|
|
void Player_Action_8085076C(Player* this, PlayState* play) {
|
|
s32 respawnData = gSaveContext.respawn[RESPAWN_MODE_TOP].data;
|
|
|
|
if (this->av2.actionVar2 > 20) {
|
|
this->actor.draw = Player_Draw;
|
|
this->actor.world.pos.y += 60.0f;
|
|
func_80837B9C(this, play);
|
|
return;
|
|
}
|
|
|
|
if (this->av2.actionVar2++ == 20) {
|
|
gSaveContext.respawn[RESPAWN_MODE_TOP].data = respawnData + 1;
|
|
func_80078914(&gSaveContext.respawn[RESPAWN_MODE_TOP].pos, NA_SE_PL_MAGIC_WIND_WARP);
|
|
}
|
|
}
|
|
|
|
static LinkAnimationHeader* D_80854A58[] = {
|
|
&gPlayerAnim_link_magic_kaze1,
|
|
&gPlayerAnim_link_magic_honoo1,
|
|
&gPlayerAnim_link_magic_tamashii1,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_80854A64[] = {
|
|
&gPlayerAnim_link_magic_kaze2,
|
|
&gPlayerAnim_link_magic_honoo2,
|
|
&gPlayerAnim_link_magic_tamashii2,
|
|
};
|
|
|
|
static LinkAnimationHeader* D_80854A70[] = {
|
|
&gPlayerAnim_link_magic_kaze3,
|
|
&gPlayerAnim_link_magic_honoo3,
|
|
&gPlayerAnim_link_magic_tamashii3,
|
|
};
|
|
|
|
static u8 D_80854A7C[] = { 70, 10, 10 };
|
|
|
|
static AnimSfxEntry D_80854A80[] = {
|
|
{ NA_SE_PL_SKIP, ANIMSFX_DATA(ANIMSFX_TYPE_1, 20) },
|
|
{ NA_SE_VO_LI_SWORD_N, ANIMSFX_DATA(ANIMSFX_TYPE_4, 20) },
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_6, 26) },
|
|
};
|
|
|
|
static AnimSfxEntry D_80854A8C[][2] = {
|
|
{
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_8, 20) },
|
|
{ NA_SE_VO_LI_MAGIC_FROL, -ANIMSFX_DATA(ANIMSFX_TYPE_4, 30) },
|
|
},
|
|
{
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_8, 20) },
|
|
{ NA_SE_VO_LI_MAGIC_NALE, -ANIMSFX_DATA(ANIMSFX_TYPE_4, 44) },
|
|
},
|
|
{
|
|
{ NA_SE_VO_LI_MAGIC_ATTACK, ANIMSFX_DATA(ANIMSFX_TYPE_4, 20) },
|
|
{ NA_SE_IT_SWORD_SWING_HARD, -ANIMSFX_DATA(ANIMSFX_TYPE_1, 20) },
|
|
},
|
|
};
|
|
|
|
void Player_Action_808507F4(Player* this, PlayState* play) {
|
|
u8 isFastFarores = CVarGetInteger("gFastFarores", 0) && this->itemAction == PLAYER_IA_FARORES_WIND;
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (this->av1.actionVar1 < 0) {
|
|
if ((this->itemAction == PLAYER_IA_NAYRUS_LOVE) || isFastFarores || (gSaveContext.magicState == MAGIC_STATE_IDLE)) {
|
|
func_80839FFC(this, play);
|
|
func_8005B1A4(Play_GetCamera(play, 0));
|
|
}
|
|
} else {
|
|
if (this->av2.actionVar2 == 0) {
|
|
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, D_80854A58[this->av1.actionVar1], 0.83f * (isFastFarores ? 2 : 1));
|
|
|
|
if (func_80846A00(play, this, this->av1.actionVar1) != NULL) {
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE;
|
|
if ((this->av1.actionVar1 != 0) || (gSaveContext.respawn[RESPAWN_MODE_TOP].data <= 0)) {
|
|
gSaveContext.magicState = MAGIC_STATE_CONSUME_SETUP;
|
|
}
|
|
} else {
|
|
Magic_Reset(play);
|
|
}
|
|
} else {
|
|
LinkAnimation_PlayLoopSetSpeed(play, &this->skelAnime, D_80854A64[this->av1.actionVar1], 0.83f * (isFastFarores ? 2 : 1));
|
|
|
|
if (this->av1.actionVar1 == 0) {
|
|
this->av2.actionVar2 = -10;
|
|
}
|
|
}
|
|
|
|
this->av2.actionVar2++;
|
|
}
|
|
} else {
|
|
if (this->av2.actionVar2 < 0) {
|
|
this->av2.actionVar2++;
|
|
|
|
if (this->av2.actionVar2 == 0) {
|
|
gSaveContext.respawn[RESPAWN_MODE_TOP].data = 1;
|
|
Play_SetupRespawnPoint(play, RESPAWN_MODE_TOP, 0x6FF);
|
|
gSaveContext.fw.set = 1;
|
|
gSaveContext.fw.pos.x = gSaveContext.respawn[RESPAWN_MODE_DOWN].pos.x;
|
|
gSaveContext.fw.pos.y = gSaveContext.respawn[RESPAWN_MODE_DOWN].pos.y;
|
|
gSaveContext.fw.pos.z = gSaveContext.respawn[RESPAWN_MODE_DOWN].pos.z;
|
|
gSaveContext.fw.yaw = gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw;
|
|
gSaveContext.fw.playerParams = 0x6FF;
|
|
gSaveContext.fw.entranceIndex = gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex;
|
|
gSaveContext.fw.roomIndex = gSaveContext.respawn[RESPAWN_MODE_DOWN].roomIndex;
|
|
gSaveContext.fw.tempSwchFlags = gSaveContext.respawn[RESPAWN_MODE_DOWN].tempSwchFlags;
|
|
gSaveContext.fw.tempCollectFlags = gSaveContext.respawn[RESPAWN_MODE_DOWN].tempCollectFlags;
|
|
this->av2.actionVar2 = 2;
|
|
}
|
|
} else if (this->av1.actionVar1 >= 0) {
|
|
if (this->av2.actionVar2 == 0) {
|
|
Player_ProcessAnimSfxList(this, D_80854A80);
|
|
} else if (this->av2.actionVar2 == 1) {
|
|
Player_ProcessAnimSfxList(this, D_80854A8C[this->av1.actionVar1]);
|
|
if ((this->av1.actionVar1 == 2) && LinkAnimation_OnFrame(&this->skelAnime, 30.0f)) {
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE);
|
|
}
|
|
} else if ((isFastFarores ? 10 : D_80854A7C[this->av1.actionVar1]) < this->av2.actionVar2++) {
|
|
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, D_80854A70[this->av1.actionVar1], 0.83f * (isFastFarores ? 2 : 1));
|
|
this->yaw = this->actor.shape.rot.y;
|
|
this->av1.actionVar1 = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
func_8083721C(this);
|
|
}
|
|
|
|
void Player_Action_80850AEC(Player* this, PlayState* play) {
|
|
f32 temp;
|
|
|
|
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET;
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimPlayLoop(play, this, &gPlayerAnim_link_hook_fly_wait);
|
|
}
|
|
|
|
Math_Vec3f_Sum(&this->actor.world.pos, &this->actor.velocity, &this->actor.world.pos);
|
|
|
|
if (func_80834FBC(this)) {
|
|
Math_Vec3f_Copy(&this->actor.prevPos, &this->actor.world.pos);
|
|
Player_ProcessSceneCollision(play, this);
|
|
|
|
temp = this->actor.world.pos.y - this->actor.floorHeight;
|
|
if (temp > 20.0f) {
|
|
temp = 20.0f;
|
|
}
|
|
|
|
this->actor.world.rot.x = this->actor.shape.rot.x = 0;
|
|
this->actor.world.pos.y -= temp;
|
|
this->linearVelocity = 1.0f;
|
|
this->actor.velocity.y = 0.0f;
|
|
func_80837B9C(this, play);
|
|
this->stateFlags2 &= ~PLAYER_STATE2_UNDERWATER;
|
|
this->actor.bgCheckFlags |= 1;
|
|
this->stateFlags1 |= PLAYER_STATE1_HOOKSHOT_FALLING;
|
|
return;
|
|
}
|
|
|
|
if ((this->skelAnime.animation != &gPlayerAnim_link_hook_fly_start) || (4.0f <= this->skelAnime.curFrame)) {
|
|
this->actor.gravity = 0.0f;
|
|
Math_ScaledStepToS(&this->actor.shape.rot.x, this->actor.world.rot.x, 0x800);
|
|
Player_RequestRumble(this, 100, 2, 100, 0);
|
|
}
|
|
}
|
|
|
|
void Player_Action_80850C68(Player* this, PlayState* play) {
|
|
if ((this->av2.actionVar2 != 0) && ((this->unk_858 != 0.0f) || (this->unk_85C != 0.0f))) {
|
|
f32 updateScale = R_UPDATE_RATE * 0.5f;
|
|
|
|
this->skelAnime.curFrame += this->skelAnime.playSpeed * updateScale;
|
|
if (this->skelAnime.curFrame >= this->skelAnime.animLength) {
|
|
this->skelAnime.curFrame -= this->skelAnime.animLength;
|
|
}
|
|
|
|
LinkAnimation_BlendToJoint(
|
|
play, &this->skelAnime, &gPlayerAnim_link_fishing_wait, this->skelAnime.curFrame,
|
|
(this->unk_858 < 0.0f) ? &gPlayerAnim_link_fishing_reel_left : &gPlayerAnim_link_fishing_reel_right, 5.0f,
|
|
fabsf(this->unk_858), this->blendTable);
|
|
LinkAnimation_BlendToMorph(
|
|
play, &this->skelAnime, &gPlayerAnim_link_fishing_wait, this->skelAnime.curFrame,
|
|
(this->unk_85C < 0.0f) ? &gPlayerAnim_link_fishing_reel_up : &gPlayerAnim_link_fishing_reel_down, 5.0f,
|
|
fabsf(this->unk_85C), D_80858AD8);
|
|
LinkAnimation_InterpJointMorph(play, &this->skelAnime, 0.5f);
|
|
} else if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
this->unk_860 = 2;
|
|
Player_AnimPlayLoop(play, this, &gPlayerAnim_link_fishing_wait);
|
|
this->av2.actionVar2 = 1;
|
|
}
|
|
|
|
func_8083721C(this);
|
|
|
|
if (this->unk_860 == 0) {
|
|
func_80853080(this, play);
|
|
} else if (this->unk_860 == 3) {
|
|
Player_SetupAction(play, this, Player_Action_80850E84, 0);
|
|
Player_AnimChangeOnceMorph(play, this, &gPlayerAnim_link_fishing_fish_catch);
|
|
}
|
|
}
|
|
|
|
void Player_Action_80850E84(Player* this, PlayState* play) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime) && (this->unk_860 == 0)) {
|
|
func_8083A098(this, &gPlayerAnim_link_fishing_fish_catch_end, play);
|
|
}
|
|
}
|
|
|
|
static void (*D_80854AA4[])(PlayState*, Player*, void*) = {
|
|
NULL, func_80851008, func_80851030, func_80851094, func_808510B4, func_808510D4, func_808510F4,
|
|
func_80851114, func_80851134, func_80851154, func_80851174, func_808511D4, func_808511FC, func_80851294,
|
|
func_80851050, func_80851194, func_808511B4, func_80851248, func_808512E0,
|
|
};
|
|
|
|
static AnimSfxEntry D_80854AF0[] = {
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_5, 34) },
|
|
{ NA_SE_PL_CALM_HIT, ANIMSFX_DATA(ANIMSFX_TYPE_1, 45) },
|
|
{ NA_SE_PL_CALM_HIT, ANIMSFX_DATA(ANIMSFX_TYPE_1, 51) },
|
|
{ NA_SE_PL_CALM_HIT, -ANIMSFX_DATA(ANIMSFX_TYPE_1, 64) },
|
|
};
|
|
|
|
static AnimSfxEntry D_80854B00[] = {
|
|
{ NA_SE_VO_LI_SURPRISE, ANIMSFX_DATA(ANIMSFX_TYPE_4, 3) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 15) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 24) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 30) },
|
|
{ NA_SE_VO_LI_FALL_L, -ANIMSFX_DATA(ANIMSFX_TYPE_4, 31) },
|
|
};
|
|
|
|
static AnimSfxEntry D_80854B14[] = {
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_6, 10) },
|
|
};
|
|
|
|
static struct_80854B18 D_80854B18[] = {
|
|
{ 0, NULL },
|
|
{ -1, func_808515A4 },
|
|
{ 2, &gPlayerAnim_link_demo_goma_furimuki },
|
|
{ 0, NULL },
|
|
{ 0, NULL },
|
|
{ 3, &gPlayerAnim_link_demo_bikkuri },
|
|
{ 0, NULL },
|
|
{ 0, NULL },
|
|
{ -1, func_808515A4 },
|
|
{ 2, &gPlayerAnim_link_demo_furimuki },
|
|
{ -1, func_80851788 },
|
|
{ 3, &gPlayerAnim_link_demo_warp },
|
|
{ -1, func_808518DC },
|
|
{ 7, &gPlayerAnim_clink_demo_get1 },
|
|
{ 5, &gPlayerAnim_clink_demo_get2 },
|
|
{ 5, &gPlayerAnim_clink_demo_get3 },
|
|
{ 5, &gPlayerAnim_clink_demo_standup },
|
|
{ 7, &gPlayerAnim_clink_demo_standup_wait },
|
|
{ -1, func_808519EC },
|
|
{ 2, &gPlayerAnim_link_demo_baru_op1 },
|
|
{ 2, &gPlayerAnim_link_demo_baru_op3 },
|
|
{ 0, NULL },
|
|
{ -1, func_80851B90 },
|
|
{ 3, &gPlayerAnim_link_demo_jibunmiru },
|
|
{ 9, &gPlayerAnim_link_normal_back_downA },
|
|
{ 2, &gPlayerAnim_link_normal_back_down_wake },
|
|
{ -1, func_80851D2C },
|
|
{ 2, &gPlayerAnim_link_normal_okarina_end },
|
|
{ 3, &gPlayerAnim_link_demo_get_itemA },
|
|
{ -1, func_808515A4 },
|
|
{ 2, &gPlayerAnim_link_normal_normal2fighter_free },
|
|
{ 0, NULL },
|
|
{ 0, NULL },
|
|
{ 5, &gPlayerAnim_clink_demo_atozusari },
|
|
{ -1, func_80851368 },
|
|
{ -1, func_80851E64 },
|
|
{ 5, &gPlayerAnim_clink_demo_bashi },
|
|
{ 16, &gPlayerAnim_link_normal_hang_up_down },
|
|
{ -1, func_80851F84 },
|
|
{ -1, func_80851E90 },
|
|
{ 6, &gPlayerAnim_clink_op3_okiagari },
|
|
{ 6, &gPlayerAnim_clink_op3_tatiagari },
|
|
{ -1, func_80852080 },
|
|
{ 5, &gPlayerAnim_clink_demo_miokuri },
|
|
{ -1, func_808521F4 },
|
|
{ -1, func_8085225C },
|
|
{ -1, func_80852280 },
|
|
{ 5, &gPlayerAnim_clink_demo_nozoki },
|
|
{ 5, &gPlayerAnim_clink_demo_koutai },
|
|
{ -1, func_808515A4 },
|
|
{ 5, &gPlayerAnim_clink_demo_koutai_kennuki },
|
|
{ 5, &gPlayerAnim_link_demo_kakeyori },
|
|
{ 5, &gPlayerAnim_link_demo_kakeyori_mimawasi },
|
|
{ 5, &gPlayerAnim_link_demo_kakeyori_miokuri },
|
|
{ 3, &gPlayerAnim_link_demo_furimuki2 },
|
|
{ 3, &gPlayerAnim_link_demo_kaoage },
|
|
{ 4, &gPlayerAnim_link_demo_kaoage_wait },
|
|
{ 3, &gPlayerAnim_clink_demo_mimawasi },
|
|
{ 3, &gPlayerAnim_link_demo_nozokikomi },
|
|
{ 6, &gPlayerAnim_kolink_odoroki_demo },
|
|
{ 6, &gPlayerAnim_link_shagamu_demo },
|
|
{ 14, &gPlayerAnim_link_okiru_demo },
|
|
{ 3, &gPlayerAnim_link_okiru_demo },
|
|
{ 5, &gPlayerAnim_link_fighter_power_kiru_start },
|
|
{ 16, &gPlayerAnim_demo_link_nwait },
|
|
{ 15, &gPlayerAnim_demo_link_tewatashi },
|
|
{ 15, &gPlayerAnim_demo_link_orosuu },
|
|
{ 3, &gPlayerAnim_d_link_orooro },
|
|
{ 3, &gPlayerAnim_d_link_imanodare },
|
|
{ 3, &gPlayerAnim_link_hatto_demo },
|
|
{ 6, &gPlayerAnim_o_get_mae },
|
|
{ 6, &gPlayerAnim_o_get_ato },
|
|
{ 6, &gPlayerAnim_om_get_mae },
|
|
{ 6, &gPlayerAnim_nw_modoru },
|
|
{ 3, &gPlayerAnim_link_demo_gurad },
|
|
{ 3, &gPlayerAnim_link_demo_look_hand },
|
|
{ 4, &gPlayerAnim_link_demo_sita_wait },
|
|
{ 3, &gPlayerAnim_link_demo_ue },
|
|
{ 3, &gPlayerAnim_Link_muku },
|
|
{ 3, &gPlayerAnim_Link_miageru },
|
|
{ 6, &gPlayerAnim_Link_ha },
|
|
{ 3, &gPlayerAnim_L_1kyoro },
|
|
{ 3, &gPlayerAnim_L_2kyoro },
|
|
{ 3, &gPlayerAnim_L_sagaru },
|
|
{ 3, &gPlayerAnim_L_bouzen },
|
|
{ 3, &gPlayerAnim_L_kamaeru },
|
|
{ 3, &gPlayerAnim_L_hajikareru },
|
|
{ 3, &gPlayerAnim_L_ken_miru },
|
|
{ 3, &gPlayerAnim_L_mukinaoru },
|
|
{ -1, func_808524B0 },
|
|
{ 3, &gPlayerAnim_link_wait_itemD1_20f },
|
|
{ -1, func_80852544 },
|
|
{ -1, func_80852564 },
|
|
{ 3, &gPlayerAnim_link_normal_wait_typeB_20f },
|
|
{ -1, func_80852608 },
|
|
{ 3, &gPlayerAnim_link_demo_kousan },
|
|
{ 3, &gPlayerAnim_link_demo_return_to_past },
|
|
{ 3, &gPlayerAnim_link_last_hit_motion1 },
|
|
{ 3, &gPlayerAnim_link_last_hit_motion2 },
|
|
{ 3, &gPlayerAnim_link_demo_zeldamiru },
|
|
{ 3, &gPlayerAnim_link_demo_kenmiru1 },
|
|
{ 3, &gPlayerAnim_link_demo_kenmiru2 },
|
|
{ 3, &gPlayerAnim_link_demo_kenmiru2_modori },
|
|
};
|
|
|
|
static struct_80854B18 D_80854E50[] = {
|
|
{ 0, NULL },
|
|
{ -1, func_808514C0 },
|
|
{ -1, func_8085157C },
|
|
{ -1, func_80851998 },
|
|
{ -1, func_808519C0 },
|
|
{ 11, NULL },
|
|
{ -1, func_80852C50 },
|
|
{ -1, func_80852944 },
|
|
{ -1, func_80851688 },
|
|
{ -1, func_80851750 },
|
|
{ -1, func_80851828 },
|
|
{ -1, func_808521B8 },
|
|
{ -1, func_8085190C },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ 18, D_80854AF0 },
|
|
{ 11, NULL },
|
|
{ -1, func_80851A50 },
|
|
{ 12, &gPlayerAnim_link_demo_baru_op2 },
|
|
{ 11, NULL },
|
|
{ 0, NULL },
|
|
{ -1, func_80851BE8 },
|
|
{ 11, NULL },
|
|
{ -1, func_80851CA4 },
|
|
{ 11, NULL },
|
|
{ 17, &gPlayerAnim_link_normal_okarina_swing },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ -1, func_80851D80 },
|
|
{ -1, func_80851DEC },
|
|
{ -1, func_80851E28 },
|
|
{ 18, D_80854B00 },
|
|
{ -1, func_808513BC },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ -1, func_80851ECC },
|
|
{ -1, func_80851FB0 },
|
|
{ -1, func_80852048 },
|
|
{ -1, func_80852174 },
|
|
{ 13, &gPlayerAnim_clink_demo_miokuri_wait },
|
|
{ -1, func_80852234 },
|
|
{ 0, NULL },
|
|
{ 0, NULL },
|
|
{ 11, NULL },
|
|
{ -1, func_80852450 },
|
|
{ -1, func_80851688 },
|
|
{ -1, func_80852298 },
|
|
{ 13, &gPlayerAnim_link_demo_kakeyori_wait },
|
|
{ -1, func_80852480 },
|
|
{ 13, &gPlayerAnim_link_demo_kakeyori_miokuri_wait },
|
|
{ -1, func_80852328 },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ 12, &gPlayerAnim_clink_demo_mimawasi_wait },
|
|
{ -1, func_80852358 },
|
|
{ 11, NULL },
|
|
{ 18, D_80854B14 },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ -1, func_80852388 },
|
|
{ 17, &gPlayerAnim_demo_link_nwait },
|
|
{ 12, &gPlayerAnim_d_link_orowait },
|
|
{ 12, &gPlayerAnim_demo_link_nwait },
|
|
{ 11, NULL },
|
|
{ -1, func_808526EC },
|
|
{ 17, &gPlayerAnim_sude_nwait },
|
|
{ -1, func_808526EC },
|
|
{ 17, &gPlayerAnim_sude_nwait },
|
|
{ 12, &gPlayerAnim_link_demo_gurad_wait },
|
|
{ 12, &gPlayerAnim_link_demo_look_hand_wait },
|
|
{ 11, NULL },
|
|
{ 12, &gPlayerAnim_link_demo_ue_wait },
|
|
{ 12, &gPlayerAnim_Link_m_wait },
|
|
{ 13, &gPlayerAnim_Link_ue_wait },
|
|
{ 12, &gPlayerAnim_Link_otituku_w },
|
|
{ 12, &gPlayerAnim_L_kw },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ -1, func_80852648 },
|
|
{ 11, NULL },
|
|
{ 12, &gPlayerAnim_L_kennasi_w },
|
|
{ -1, func_808524D0 },
|
|
{ -1, func_80852514 },
|
|
{ -1, func_80852554 },
|
|
{ -1, func_808525C0 },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ 11, NULL },
|
|
{ -1, func_8085283C },
|
|
{ -1, func_808528C8 },
|
|
{ -1, func_808528C8 },
|
|
{ 12, &gPlayerAnim_link_demo_zeldamiru_wait },
|
|
{ 12, &gPlayerAnim_link_demo_kenmiru1_wait },
|
|
{ 12, &gPlayerAnim_link_demo_kenmiru2_wait },
|
|
{ 12, &gPlayerAnim_demo_link_nwait },
|
|
};
|
|
|
|
void Player_AnimChangeOnceMorphZeroRootYawSpeed(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
Player_ZeroRootLimbYaw(this);
|
|
Player_AnimChangeOnceMorph(play, this, anim);
|
|
Player_ZeroSpeedXZ(this);
|
|
}
|
|
|
|
void Player_AnimChangeOnceMorphAdjustedZeroRootYawSpeed(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
Player_ZeroRootLimbYaw(this);
|
|
LinkAnimation_Change(play, &this->skelAnime, anim, PLAYER_ANIM_ADJUSTED_SPEED, 0.0f, Animation_GetLastFrame(anim),
|
|
ANIMMODE_ONCE, -8.0f);
|
|
Player_ZeroSpeedXZ(this);
|
|
}
|
|
|
|
void Player_AnimChangeLoopMorphAdjustedZeroRootYawSpeed(PlayState* play, Player* this, LinkAnimationHeader* anim) {
|
|
Player_ZeroRootLimbYaw(this);
|
|
LinkAnimation_Change(play, &this->skelAnime, anim, PLAYER_ANIM_ADJUSTED_SPEED, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f);
|
|
Player_ZeroSpeedXZ(this);
|
|
}
|
|
|
|
void func_80851008(PlayState* play, Player* this, void* anim) {
|
|
Player_ZeroSpeedXZ(this);
|
|
}
|
|
|
|
void func_80851030(PlayState* play, Player* this, void* anim) {
|
|
Player_AnimChangeOnceMorphZeroRootYawSpeed(play, this, anim);
|
|
}
|
|
|
|
void func_80851050(PlayState* play, Player* this, void* anim) {
|
|
Player_ZeroRootLimbYaw(this);
|
|
Player_AnimChangeFreeze(play, this, anim);
|
|
Player_ZeroSpeedXZ(this);
|
|
}
|
|
|
|
void func_80851094(PlayState* play, Player* this, void* anim) {
|
|
Player_AnimChangeOnceMorphAdjustedZeroRootYawSpeed(play, this, anim);
|
|
}
|
|
|
|
void func_808510B4(PlayState* play, Player* this, void* anim) {
|
|
Player_AnimChangeLoopMorphAdjustedZeroRootYawSpeed(play, this, anim);
|
|
}
|
|
|
|
void func_808510D4(PlayState* play, Player* this, void* anim) {
|
|
Player_AnimReplaceNormalPlayOnceAdjusted(play, this, anim);
|
|
}
|
|
|
|
void func_808510F4(PlayState* play, Player* this, void* anim) {
|
|
Player_AnimReplacePlayOnce(play, this, anim, 0x9C);
|
|
}
|
|
|
|
void func_80851114(PlayState* play, Player* this, void* anim) {
|
|
Player_AnimReplaceNormalPlayLoopAdjusted(play, this, anim);
|
|
}
|
|
|
|
void func_80851134(PlayState* play, Player* this, void* anim) {
|
|
Player_AnimReplacePlayLoop(play, this, anim, 0x9C);
|
|
}
|
|
|
|
void func_80851154(PlayState* play, Player* this, void* anim) {
|
|
Player_AnimPlayOnce(play, this, anim);
|
|
}
|
|
|
|
void func_80851174(PlayState* play, Player* this, void* anim) {
|
|
Player_AnimPlayLoop(play, this, anim);
|
|
}
|
|
|
|
void func_80851194(PlayState* play, Player* this, void* anim) {
|
|
Player_AnimPlayOnceAdjusted(play, this, anim);
|
|
}
|
|
|
|
void func_808511B4(PlayState* play, Player* this, void* anim) {
|
|
Player_AnimPlayLoopAdjusted(play, this, anim);
|
|
}
|
|
|
|
void func_808511D4(PlayState* play, Player* this, void* anim) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
}
|
|
|
|
void func_808511FC(PlayState* play, Player* this, void* anim) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimChangeLoopMorphAdjustedZeroRootYawSpeed(play, this, anim);
|
|
this->av2.actionVar2 = 1;
|
|
}
|
|
}
|
|
|
|
void func_80851248(PlayState* play, Player* this, void* anim) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_80832DBC(this);
|
|
Player_AnimPlayLoopAdjusted(play, this, anim);
|
|
}
|
|
}
|
|
|
|
void func_80851294(PlayState* play, Player* this, void* anim) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimReplaceNormalPlayLoopAdjusted(play, this, anim);
|
|
this->av2.actionVar2 = 1;
|
|
}
|
|
}
|
|
|
|
void func_808512E0(PlayState* play, Player* this, void* arg2) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
Player_ProcessAnimSfxList(this, arg2);
|
|
}
|
|
|
|
void func_80851314(Player* this) {
|
|
if ((this->csActor == NULL) || (this->csActor->update == NULL)) {
|
|
this->csActor = NULL;
|
|
}
|
|
|
|
this->unk_664 = this->csActor;
|
|
|
|
if (this->unk_664 != NULL) {
|
|
this->actor.shape.rot.y = func_8083DB98(this, 0);
|
|
}
|
|
}
|
|
|
|
void func_80851368(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
this->stateFlags1 |= PLAYER_STATE1_IN_WATER;
|
|
this->stateFlags2 |= PLAYER_STATE2_UNDERWATER;
|
|
this->stateFlags1 &= ~(PLAYER_STATE1_JUMPING | PLAYER_STATE1_FREEFALL);
|
|
|
|
Player_AnimPlayLoop(play, this, &gPlayerAnim_link_swimer_swim);
|
|
}
|
|
|
|
void func_808513BC(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
this->actor.gravity = 0.0f;
|
|
|
|
if (this->av1.actionVar1 == 0) {
|
|
if (func_8083D12C(play, this, NULL)) {
|
|
this->av1.actionVar1 = 1;
|
|
} else {
|
|
func_8084B158(play, this, NULL, fabsf(this->actor.velocity.y));
|
|
Math_ScaledStepToS(&this->unk_6C2, -10000, 800);
|
|
func_8084AEEC(this, &this->actor.velocity.y, 4.0f, this->yaw);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
if (this->av1.actionVar1 == 1) {
|
|
Player_AnimChangeLoopSlowMorph(play, this, &gPlayerAnim_link_swimer_swim_wait);
|
|
} else {
|
|
Player_AnimPlayLoop(play, this, &gPlayerAnim_link_swimer_swim_wait);
|
|
}
|
|
}
|
|
|
|
func_8084B000(this);
|
|
func_8084AEEC(this, &this->linearVelocity, 0.0f, this->actor.shape.rot.y);
|
|
}
|
|
|
|
void func_808514C0(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
func_80851314(this);
|
|
|
|
if (func_808332B8(this)) {
|
|
func_808513BC(play, this, 0);
|
|
return;
|
|
}
|
|
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (func_8008F128(this) || (this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD)) {
|
|
Player_UpdateUpperBody(this, play);
|
|
return;
|
|
}
|
|
|
|
if ((this->interactRangeActor != NULL) && (this->interactRangeActor->textId == 0xFFFF)) {
|
|
Player_ActionChange_2(this, play);
|
|
}
|
|
}
|
|
|
|
void func_8085157C(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
}
|
|
|
|
void func_808515A4(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
LinkAnimationHeader* anim;
|
|
|
|
if (func_808332B8(this)) {
|
|
func_80851368(play, this, 0);
|
|
return;
|
|
}
|
|
|
|
anim = GET_PLAYER_ANIM(PLAYER_ANIMGROUP_nwait, this->modelAnimType);
|
|
|
|
if ((this->cueId == 6) || (this->cueId == 0x2E)) {
|
|
Player_AnimPlayOnce(play, this, anim);
|
|
} else {
|
|
Player_ZeroRootLimbYaw(this);
|
|
LinkAnimation_Change(play, &this->skelAnime, anim, (2.0f / 3.0f), 0.0f, Animation_GetLastFrame(anim),
|
|
ANIMMODE_LOOP, -4.0f);
|
|
}
|
|
|
|
Player_ZeroSpeedXZ(this);
|
|
}
|
|
|
|
void func_80851688(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
if (func_8084B3CC(play, this) == 0) {
|
|
if ((this->csAction == 0x31) && (play->csCtx.state == CS_STATE_IDLE)) {
|
|
func_8002DF54(play, NULL, 7);
|
|
return;
|
|
}
|
|
|
|
if (func_808332B8(this) != 0) {
|
|
func_808513BC(play, this, 0);
|
|
return;
|
|
}
|
|
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (func_8008F128(this) || (this->stateFlags1 & PLAYER_STATE1_ITEM_OVER_HEAD)) {
|
|
Player_UpdateUpperBody(this, play);
|
|
}
|
|
}
|
|
}
|
|
|
|
static AnimSfxEntry D_80855188[] = {
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 42) },
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_6, 48) },
|
|
};
|
|
|
|
void func_80851750(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
Player_ProcessAnimSfxList(this, D_80855188);
|
|
}
|
|
|
|
void func_80851788(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
this->stateFlags1 &= ~PLAYER_STATE1_THREW_BOOMERANG;
|
|
|
|
this->yaw = this->actor.shape.rot.y = this->actor.world.rot.y =
|
|
Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_450);
|
|
|
|
if (this->linearVelocity <= 0.0f) {
|
|
this->linearVelocity = 0.1f;
|
|
} else if (this->linearVelocity > 2.5f) {
|
|
this->linearVelocity = 2.5f;
|
|
}
|
|
}
|
|
|
|
void func_80851828(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
f32 sp1C = 2.5f;
|
|
|
|
func_80845BA0(play, this, &sp1C, 10);
|
|
|
|
if (play->sceneNum == SCENE_JABU_JABU_BOSS) {
|
|
if (this->av2.actionVar2 == 0) {
|
|
if (Message_GetState(&play->msgCtx) == TEXT_STATE_NONE) {
|
|
return;
|
|
}
|
|
} else {
|
|
if (Message_GetState(&play->msgCtx) != TEXT_STATE_NONE) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
this->av2.actionVar2++;
|
|
if (this->av2.actionVar2 > 20) {
|
|
this->csAction = 0xB;
|
|
}
|
|
}
|
|
|
|
void func_808518DC(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
func_8083CEAC(this, play);
|
|
}
|
|
|
|
void func_8085190C(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
func_80851314(this);
|
|
|
|
if (this->av2.actionVar2 != 0) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimPlayLoop(play, this, func_808334E4(this));
|
|
this->av2.actionVar2 = 0;
|
|
}
|
|
|
|
func_80833C3C(this);
|
|
} else {
|
|
func_808401B0(play, this);
|
|
}
|
|
}
|
|
|
|
void func_80851998(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
func_80845964(play, this, arg2, 0.0f, 0, 0);
|
|
}
|
|
|
|
void func_808519C0(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
func_80845964(play, this, arg2, 0.0f, 0, 1);
|
|
}
|
|
|
|
// unused
|
|
static LinkAnimationHeader* D_80855190[] = {
|
|
&gPlayerAnim_link_demo_back_to_past,
|
|
&gPlayerAnim_clink_demo_goto_future,
|
|
};
|
|
|
|
static Vec3f D_80855198 = { -1.0f, 70.0f, 20.0f };
|
|
|
|
void func_808519EC(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
Math_Vec3f_Copy(&this->actor.world.pos, &D_80855198);
|
|
this->actor.shape.rot.y = -0x8000;
|
|
Player_AnimPlayOnceAdjusted(play, this, this->ageProperties->unk_9C);
|
|
Player_AnimReplaceApplyFlags(play, this, 0x28F);
|
|
}
|
|
|
|
static struct_808551A4 D_808551A4[] = {
|
|
{ NA_SE_IT_SWORD_PUTAWAY_STN, 0 },
|
|
{ NA_SE_IT_SWORD_STICK_STN, NA_SE_VO_LI_SWORD_N },
|
|
};
|
|
|
|
static AnimSfxEntry D_808551AC[] = {
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_8, 29) },
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_8, 39) },
|
|
};
|
|
|
|
void func_80851A50(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
struct_808551A4* sp2C;
|
|
Gfx** dLists;
|
|
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if ((LINK_IS_ADULT && LinkAnimation_OnFrame(&this->skelAnime, 70.0f)) ||
|
|
(!LINK_IS_ADULT && LinkAnimation_OnFrame(&this->skelAnime, 87.0f))) {
|
|
sp2C = &D_808551A4[gSaveContext.linkAge];
|
|
this->interactRangeActor->parent = &this->actor;
|
|
|
|
if (!LINK_IS_ADULT) {
|
|
dLists = gPlayerLeftHandBgsDLs;
|
|
} else {
|
|
dLists = gPlayerLeftHandClosedDLs;
|
|
}
|
|
this->leftHandDLists = &dLists[gSaveContext.linkAge];
|
|
|
|
Player_PlaySfx(this, sp2C->unk_00);
|
|
if (!LINK_IS_ADULT) {
|
|
func_80832698(this, sp2C->unk_02);
|
|
}
|
|
} else if (LINK_IS_ADULT) {
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 66.0f)) {
|
|
func_80832698(this, NA_SE_VO_LI_SWORD_L);
|
|
}
|
|
} else {
|
|
Player_ProcessAnimSfxList(this, D_808551AC);
|
|
}
|
|
}
|
|
|
|
void func_80851B90(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_demo_warp, -(2.0f / 3.0f), 12.0f, 12.0f,
|
|
ANIMMODE_ONCE, 0.0f);
|
|
}
|
|
|
|
static AnimSfxEntry D_808551B4[] = {
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_5, 30) },
|
|
};
|
|
|
|
void func_80851BE8(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
this->av2.actionVar2++;
|
|
|
|
if (this->av2.actionVar2 >= 180) {
|
|
if (this->av2.actionVar2 == 180) {
|
|
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_okarina_warp_goal, (2.0f / 3.0f), 10.0f,
|
|
Animation_GetLastFrame(&gPlayerAnim_link_okarina_warp_goal), ANIMMODE_ONCE, -8.0f);
|
|
}
|
|
Player_ProcessAnimSfxList(this, D_808551B4);
|
|
}
|
|
}
|
|
|
|
void func_80851CA4(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime) && (this->av2.actionVar2 == 0) && (this->actor.bgCheckFlags & 1)) {
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_normal_back_downB);
|
|
this->av2.actionVar2 = 1;
|
|
}
|
|
|
|
if (this->av2.actionVar2 != 0) {
|
|
func_8083721C(this);
|
|
}
|
|
}
|
|
|
|
void func_80851D2C(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
Player_AnimChangeOnceMorphAdjustedZeroRootYawSpeed(play, this, &gPlayerAnim_link_normal_okarina_start);
|
|
func_8084B498(this);
|
|
Player_SetModels(this, Player_ActionToModelGroup(this, this->itemAction));
|
|
}
|
|
|
|
static AnimSfxEntry D_808551B8[] = {
|
|
{ NA_SE_IT_SWORD_PICKOUT, -ANIMSFX_DATA(ANIMSFX_TYPE_1, 12) },
|
|
};
|
|
|
|
void func_80851D80(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 6.0f)) {
|
|
func_80846720(play, this, 0);
|
|
} else {
|
|
Player_ProcessAnimSfxList(this, D_808551B8);
|
|
}
|
|
}
|
|
|
|
void func_80851DEC(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
Math_StepToS(&this->actor.shape.face, 0, 1);
|
|
}
|
|
|
|
void func_80851E28(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
Math_StepToS(&this->actor.shape.face, 2, 1);
|
|
}
|
|
|
|
void func_80851E64(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
Player_AnimReplacePlayOnceAdjusted(play, this, &gPlayerAnim_link_swimer_swim_get, 0x98);
|
|
}
|
|
|
|
void func_80851E90(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
Player_AnimReplacePlayOnce(play, this, &gPlayerAnim_clink_op3_negaeri, 0x9C);
|
|
func_80832698(this, NA_SE_VO_LI_GROAN);
|
|
}
|
|
|
|
void func_80851ECC(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimReplacePlayLoop(play, this, &gPlayerAnim_clink_op3_wait2, 0x9C);
|
|
}
|
|
}
|
|
|
|
void func_80851F14(PlayState* play, Player* this, LinkAnimationHeader* anim, AnimSfxEntry* arg3) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimPlayLoopAdjusted(play, this, anim);
|
|
this->av2.actionVar2 = 1;
|
|
} else if (this->av2.actionVar2 == 0) {
|
|
Player_ProcessAnimSfxList(this, arg3);
|
|
}
|
|
}
|
|
|
|
void func_80851F84(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
this->actor.shape.shadowDraw = NULL;
|
|
func_80851134(play, this, &gPlayerAnim_clink_op3_wait1);
|
|
}
|
|
|
|
static AnimSfxEntry D_808551BC[] = {
|
|
{ NA_SE_VO_LI_RELAX, ANIMSFX_DATA(ANIMSFX_TYPE_4, 35) },
|
|
{ NA_SE_PL_SLIPDOWN, ANIMSFX_DATA(ANIMSFX_TYPE_1, 236) },
|
|
{ NA_SE_PL_SLIPDOWN, -ANIMSFX_DATA(ANIMSFX_TYPE_1, 256) },
|
|
};
|
|
|
|
void func_80851FB0(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimReplacePlayLoop(play, this, &gPlayerAnim_clink_op3_wait3, 0x9C);
|
|
this->av2.actionVar2 = 1;
|
|
} else if (this->av2.actionVar2 == 0) {
|
|
Player_ProcessAnimSfxList(this, D_808551BC);
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 240.0f)) {
|
|
this->actor.shape.shadowDraw = ActorShadow_DrawFeet;
|
|
}
|
|
}
|
|
}
|
|
|
|
static AnimSfxEntry D_808551C8[] = {
|
|
{ NA_SE_PL_LAND_LADDER, ANIMSFX_DATA(ANIMSFX_TYPE_1, 67) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_9, 84) },
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_9, 90) },
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_9, 96) },
|
|
};
|
|
|
|
void func_80852048(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
Player_ProcessAnimSfxList(this, D_808551C8);
|
|
}
|
|
|
|
void func_80852080(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
Player_AnimReplacePlayOnceAdjusted(play, this, &gPlayerAnim_clink_demo_futtobi, 0x9D);
|
|
func_80832698(this, NA_SE_VO_LI_FALL_L);
|
|
}
|
|
|
|
void func_808520BC(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
f32 startX = arg2->startPos.x;
|
|
f32 startY = arg2->startPos.y;
|
|
f32 startZ = arg2->startPos.z;
|
|
f32 distX = (arg2->endPos.x - startX);
|
|
f32 distY = (arg2->endPos.y - startY);
|
|
f32 distZ = (arg2->endPos.z - startZ);
|
|
f32 sp4 = (f32)(play->csCtx.frames - arg2->startFrame) / (f32)(arg2->endFrame - arg2->startFrame);
|
|
|
|
this->actor.world.pos.x = distX * sp4 + startX;
|
|
this->actor.world.pos.y = distY * sp4 + startY;
|
|
this->actor.world.pos.z = distZ * sp4 + startZ;
|
|
}
|
|
|
|
static AnimSfxEntry D_808551D8[] = {
|
|
{ NA_SE_PL_BOUND, ANIMSFX_DATA(ANIMSFX_TYPE_2, 20) },
|
|
{ NA_SE_PL_BOUND, -ANIMSFX_DATA(ANIMSFX_TYPE_2, 30) },
|
|
};
|
|
|
|
void func_80852174(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
func_808520BC(play, this, arg2);
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
Player_ProcessAnimSfxList(this, D_808551D8);
|
|
}
|
|
|
|
void func_808521B8(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
if (arg2 != NULL) {
|
|
func_808520BC(play, this, arg2);
|
|
}
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
}
|
|
|
|
void func_808521F4(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
Player_AnimChangeOnceMorph(play, this, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_nwait, this->modelAnimType));
|
|
Player_ZeroSpeedXZ(this);
|
|
}
|
|
|
|
void func_80852234(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
}
|
|
|
|
void func_8085225C(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
Player_AnimReplaceApplyFlags(play, this, 0x98);
|
|
}
|
|
|
|
void func_80852280(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
this->actor.draw = Player_Draw;
|
|
}
|
|
|
|
void func_80852298(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimReplaceNormalPlayLoopAdjusted(play, this, &gPlayerAnim_clink_demo_koutai_wait);
|
|
this->av2.actionVar2 = 1;
|
|
} else if (this->av2.actionVar2 == 0) {
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 10.0f)) {
|
|
func_80846720(play, this, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
static AnimSfxEntry D_808551E0[] = {
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 10) },
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_6, 24) },
|
|
};
|
|
|
|
void func_80852328(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
func_80851F14(play, this, &gPlayerAnim_link_demo_furimuki2_wait, D_808551E0);
|
|
}
|
|
|
|
static AnimSfxEntry D_808551E8[] = {
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_8, 15) },
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_8, 35) },
|
|
};
|
|
|
|
void func_80852358(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
func_80851F14(play, this, &gPlayerAnim_link_demo_nozokikomi_wait, D_808551E8);
|
|
}
|
|
|
|
void func_80852388(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
Player_AnimPlayLoopAdjusted(play, this, &gPlayerAnim_demo_link_twait);
|
|
this->av2.actionVar2 = 1;
|
|
}
|
|
|
|
if ((this->av2.actionVar2 != 0) && (play->csCtx.frames >= 900)) {
|
|
this->rightHandType = PLAYER_MODELTYPE_LH_OPEN;
|
|
} else {
|
|
this->rightHandType = PLAYER_MODELTYPE_RH_FF;
|
|
}
|
|
}
|
|
|
|
void func_80852414(PlayState* play, Player* this, LinkAnimationHeader* anim, AnimSfxEntry* arg3) {
|
|
func_80851294(play, this, anim);
|
|
if (this->av2.actionVar2 == 0) {
|
|
Player_ProcessAnimSfxList(this, arg3);
|
|
}
|
|
}
|
|
|
|
static AnimSfxEntry D_808551F0[] = {
|
|
{ 0, ANIMSFX_DATA(ANIMSFX_TYPE_6, 15) },
|
|
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_6, 33) },
|
|
};
|
|
|
|
void func_80852450(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
func_80852414(play, this, &gPlayerAnim_clink_demo_koutai_wait, D_808551F0);
|
|
}
|
|
|
|
static AnimSfxEntry D_808551F8[] = {
|
|
{ NA_SE_PL_KNOCK, -ANIMSFX_DATA(ANIMSFX_TYPE_1, 78) },
|
|
};
|
|
|
|
void func_80852480(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
func_80852414(play, this, &gPlayerAnim_link_demo_kakeyori_wait, D_808551F8);
|
|
}
|
|
|
|
void func_808524B0(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
func_80837704(play, this);
|
|
}
|
|
|
|
void func_808524D0(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
sControlInput->press.button |= BTN_B;
|
|
|
|
Player_Action_80844E68(this, play);
|
|
}
|
|
|
|
void func_80852514(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
Player_Action_80844E68(this, play);
|
|
}
|
|
|
|
void func_80852544(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
}
|
|
|
|
void func_80852554(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
}
|
|
|
|
void func_80852564(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
this->stateFlags3 |= PLAYER_STATE3_MIDAIR;
|
|
this->linearVelocity = 2.0f;
|
|
this->actor.velocity.y = -1.0f;
|
|
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_normal_back_downA);
|
|
func_80832698(this, NA_SE_VO_LI_FALL_L);
|
|
}
|
|
|
|
static void (*D_808551FC[])(Player* this, PlayState* play) = {
|
|
Player_Action_8084377C,
|
|
Player_Action_80843954,
|
|
Player_Action_80843A38,
|
|
};
|
|
|
|
void func_808525C0(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
D_808551FC[this->av2.actionVar2](this, play);
|
|
}
|
|
|
|
void func_80852608(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
func_80846720(play, this, 0);
|
|
Player_AnimPlayOnceAdjusted(play, this, &gPlayerAnim_link_demo_return_to_past);
|
|
}
|
|
|
|
void func_80852648(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
LinkAnimation_Update(play, &this->skelAnime);
|
|
|
|
if (LinkAnimation_OnFrame(&this->skelAnime, 10.0f)) {
|
|
this->heldItemAction = this->itemAction = PLAYER_IA_NONE;
|
|
this->heldItemId = ITEM_NONE;
|
|
this->modelGroup = this->nextModelGroup = Player_ActionToModelGroup(this, PLAYER_IA_NONE);
|
|
this->leftHandDLists = gPlayerLeftHandOpenDLs;
|
|
|
|
// If MS sword is shuffled and not in the players inventory, then we need to unequip the current sword
|
|
// and set swordless flag to mimic Link having his weapon knocked out of his hand in the Ganon fight
|
|
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) {
|
|
Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_NONE);
|
|
gSaveContext.equips.buttonItems[0] = ITEM_NONE;
|
|
Flags_SetInfTable(INFTABLE_SWORDLESS);
|
|
return;
|
|
}
|
|
|
|
Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_MASTER);
|
|
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER;
|
|
Inventory_DeleteEquipment(play, EQUIP_TYPE_SWORD);
|
|
}
|
|
}
|
|
|
|
static LinkAnimationHeader* D_80855208[] = {
|
|
&gPlayerAnim_L_okarina_get,
|
|
&gPlayerAnim_om_get,
|
|
};
|
|
|
|
static Vec3s D_80855210[2][2] = {
|
|
{ { -200, 700, 100 }, { 800, 600, 800 } },
|
|
{ { -200, 500, 0 }, { 600, 400, 600 } },
|
|
};
|
|
|
|
void func_808526EC(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
static Vec3f zeroVec = { 0.0f, 0.0f, 0.0f };
|
|
static Color_RGBA8 primColor = { 255, 255, 255, 0 };
|
|
static Color_RGBA8 envColor = { 0, 128, 128, 0 };
|
|
s32 age = gSaveContext.linkAge;
|
|
Vec3f sparklePos;
|
|
Vec3f sp34;
|
|
Vec3s* ptr;
|
|
|
|
func_80851294(play, this, D_80855208[age]);
|
|
|
|
if (this->rightHandType != PLAYER_MODELTYPE_RH_FF) {
|
|
this->rightHandType = PLAYER_MODELTYPE_RH_FF;
|
|
return;
|
|
}
|
|
|
|
ptr = D_80855210[gSaveContext.linkAge];
|
|
|
|
sp34.x = ptr[0].x + Rand_CenteredFloat(ptr[1].x);
|
|
sp34.y = ptr[0].y + Rand_CenteredFloat(ptr[1].y);
|
|
sp34.z = ptr[0].z + Rand_CenteredFloat(ptr[1].z);
|
|
|
|
SkinMatrix_Vec3fMtxFMultXYZ(&this->shieldMf, &sp34, &sparklePos);
|
|
|
|
EffectSsKiraKira_SpawnDispersed(play, &sparklePos, &zeroVec, &zeroVec, &primColor, &envColor, 600, -10);
|
|
}
|
|
|
|
void func_8085283C(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_80852944(play, this, arg2);
|
|
} else if (this->av2.actionVar2 == 0) {
|
|
Item_Give(play, ITEM_SWORD_MASTER);
|
|
func_80846720(play, this, 0);
|
|
} else {
|
|
func_8084E988(this);
|
|
}
|
|
}
|
|
|
|
void func_808528C8(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
|
func_8084285C(this, 0.0f, 99.0f, this->skelAnime.endFrame - 8.0f);
|
|
}
|
|
|
|
if (this->heldItemAction != PLAYER_IA_SWORD_MASTER) {
|
|
func_80846720(play, this, 1);
|
|
}
|
|
}
|
|
|
|
void func_80852944(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
if (func_808332B8(this)) {
|
|
func_80838F18(play, this);
|
|
func_80832340(play, this);
|
|
} else {
|
|
func_8083C148(this, play);
|
|
if (!Player_ActionChange_4(this, play)) {
|
|
Player_ActionChange_2(this, play);
|
|
}
|
|
}
|
|
|
|
this->csAction = 0;
|
|
this->unk_6AD = 0;
|
|
}
|
|
|
|
void func_808529D0(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
this->actor.world.pos.x = arg2->startPos.x;
|
|
this->actor.world.pos.y = arg2->startPos.y;
|
|
if ((play->sceneNum == SCENE_KOKIRI_FOREST) && !LINK_IS_ADULT) {
|
|
this->actor.world.pos.y -= 1.0f;
|
|
}
|
|
this->actor.world.pos.z = arg2->startPos.z;
|
|
this->yaw = this->actor.shape.rot.y = arg2->rot.y;
|
|
}
|
|
|
|
void func_80852A54(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
f32 dx = arg2->startPos.x - (s32)this->actor.world.pos.x;
|
|
f32 dy = arg2->startPos.y - (s32)this->actor.world.pos.y;
|
|
f32 dz = arg2->startPos.z - (s32)this->actor.world.pos.z;
|
|
f32 dist = sqrtf(SQ(dx) + SQ(dy) + SQ(dz));
|
|
s16 yawDiff = arg2->rot.y - this->actor.shape.rot.y;
|
|
|
|
if ((this->linearVelocity == 0.0f) && ((dist > 50.0f) || (ABS(yawDiff) > 0x4000))) {
|
|
func_808529D0(play, this, arg2);
|
|
}
|
|
|
|
this->skelAnime.moveFlags = 0;
|
|
Player_ZeroRootLimbYaw(this);
|
|
}
|
|
|
|
void func_80852B4C(PlayState* play, Player* this, CsCmdActorAction* arg2, struct_80854B18* arg3) {
|
|
if (arg3->type > 0) {
|
|
D_80854AA4[arg3->type](play, this, arg3->ptr);
|
|
} else if (arg3->type < 0) {
|
|
arg3->func(play, this, arg2);
|
|
}
|
|
|
|
if ((D_80858AA0 & 4) && !(this->skelAnime.moveFlags & 4)) {
|
|
this->skelAnime.morphTable[0].y /= this->ageProperties->unk_08;
|
|
D_80858AA0 = 0;
|
|
}
|
|
}
|
|
|
|
void func_80852C0C(PlayState* play, Player* this, s32 csAction) {
|
|
if ((csAction != 1) && (csAction != 8) && (csAction != 0x31) && (csAction != 7)) {
|
|
Player_DetachHeldActor(play, this);
|
|
}
|
|
}
|
|
|
|
void func_80852C50(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
|
CsCmdActorAction* linkCsAction = play->csCtx.linkAction;
|
|
s32 pad;
|
|
s32 sp24;
|
|
|
|
if (play->csCtx.state == CS_STATE_UNSKIPPABLE_INIT) {
|
|
func_8002DF54(play, NULL, 7);
|
|
this->cueId = 0;
|
|
Player_ZeroSpeedXZ(this);
|
|
return;
|
|
}
|
|
|
|
if (linkCsAction == NULL) {
|
|
this->actor.flags &= ~ACTOR_FLAG_ACTIVE;
|
|
return;
|
|
}
|
|
|
|
if (this->cueId != linkCsAction->action) {
|
|
sp24 = D_808547C4[linkCsAction->action];
|
|
if (sp24 >= 0) {
|
|
if ((sp24 == 3) || (sp24 == 4)) {
|
|
func_80852A54(play, this, linkCsAction);
|
|
} else {
|
|
func_808529D0(play, this, linkCsAction);
|
|
}
|
|
}
|
|
|
|
D_80858AA0 = this->skelAnime.moveFlags;
|
|
|
|
func_80832DBC(this);
|
|
osSyncPrintf("TOOL MODE=%d\n", sp24);
|
|
func_80852C0C(play, this, ABS(sp24));
|
|
func_80852B4C(play, this, linkCsAction, &D_80854B18[ABS(sp24)]);
|
|
|
|
this->av2.actionVar2 = 0;
|
|
this->av1.actionVar1 = 0;
|
|
this->cueId = linkCsAction->action;
|
|
}
|
|
|
|
sp24 = D_808547C4[this->cueId];
|
|
func_80852B4C(play, this, linkCsAction, &D_80854E50[ABS(sp24)]);
|
|
|
|
if (CVarGetInteger("gFixEyesOpenWhileSleeping", 0) && (play->csCtx.linkAction->action == 28 || play->csCtx.linkAction->action == 29)) {
|
|
this->skelAnime.jointTable[22].x = 8;
|
|
}
|
|
}
|
|
|
|
void Player_Action_CsAction(Player* this, PlayState* play) {
|
|
if (this->csAction != this->prevCsAction) {
|
|
D_80858AA0 = this->skelAnime.moveFlags;
|
|
|
|
func_80832DBC(this);
|
|
this->prevCsAction = this->csAction;
|
|
osSyncPrintf("DEMO MODE=%d\n", this->csAction);
|
|
func_80852C0C(play, this, this->csAction);
|
|
func_80852B4C(play, this, NULL, &D_80854B18[this->csAction]);
|
|
}
|
|
|
|
func_80852B4C(play, this, NULL, &D_80854E50[this->csAction]);
|
|
}
|
|
|
|
int Player_IsDroppingFish(PlayState* play) {
|
|
Player* this = GET_PLAYER(play);
|
|
|
|
return (Player_Action_8084EFC0 == this->actionFunc) && (this->itemAction == PLAYER_IA_BOTTLE_FISH);
|
|
}
|
|
|
|
s32 Player_StartFishing(PlayState* play) {
|
|
Player* this = GET_PLAYER(play);
|
|
|
|
func_80832564(play, this);
|
|
Player_UseItem(play, this, ITEM_FISHING_POLE);
|
|
return 1;
|
|
}
|
|
|
|
s32 func_80852F38(PlayState* play, Player* this) {
|
|
if (!Player_InBlockingCsMode(play, this) && (this->invincibilityTimer >= 0) && !func_8008F128(this) &&
|
|
!(this->stateFlags3 & PLAYER_STATE3_HOOKSHOT_TRAVELLING)) {
|
|
func_80832564(play, this);
|
|
Player_SetupAction(play, this, func_8084F308, 0);
|
|
Player_AnimPlayOnce(play, this, &gPlayerAnim_link_normal_re_dead_attack);
|
|
this->stateFlags2 |= PLAYER_STATE2_GRABBED_BY_ENEMY;
|
|
func_80832224(this);
|
|
func_80832698(this, NA_SE_VO_LI_HELD);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Tries to starts a cutscene action specified by `csAction`.
|
|
* A cutscene action will only start if player is not already in another form of cutscene.
|
|
*
|
|
* No actors will be halted over the duration of the cutscene action.
|
|
*
|
|
* @return true if successful starting a `csAction`, false if not
|
|
*/
|
|
s32 Player_TryCsAction(PlayState* play, Actor* actor, s32 csAction) {
|
|
Player* this = GET_PLAYER(play);
|
|
|
|
if (!Player_InBlockingCsMode(play, this)) {
|
|
func_80832564(play, this);
|
|
Player_SetupAction(play, this, Player_Action_CsAction, 0);
|
|
this->csAction = csAction;
|
|
this->csActor = actor;
|
|
func_80832224(this);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void func_80853080(Player* this, PlayState* play) {
|
|
Player_SetupAction(play, this, Player_Action_80840BC8, 1);
|
|
Player_AnimChangeOnceMorph(play, this, func_80833338(this));
|
|
this->yaw = this->actor.shape.rot.y;
|
|
}
|
|
|
|
s32 Player_InflictDamage(PlayState* play, s32 damage) {
|
|
return Player_InflictDamageModified(play, damage, true);
|
|
}
|
|
|
|
s32 Player_InflictDamageModified(PlayState* play, s32 damage, u8 modified) {
|
|
Player* this = GET_PLAYER(play);
|
|
|
|
if (!Player_InBlockingCsMode(play, this) && !func_80837B18_modified(play, this, damage, modified)) {
|
|
this->stateFlags2 &= ~PLAYER_STATE2_GRABBED_BY_ENEMY;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Start talking with the given actor
|
|
void Player_StartTalking(PlayState* play, Actor* actor) {
|
|
Player* this = GET_PLAYER(play);
|
|
s32 pad;
|
|
|
|
if ((this->targetActor != NULL) || (actor == this->naviActor) ||
|
|
CHECK_FLAG_ALL(actor->flags, ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_NAVI_HAS_INFO)) {
|
|
actor->flags |= ACTOR_FLAG_PLAYER_TALKED_TO;
|
|
}
|
|
|
|
this->targetActor = actor;
|
|
this->exchangeItemId = EXCH_ITEM_NONE;
|
|
|
|
if (actor->textId == 0xFFFF) {
|
|
func_8002DF54(play, actor, 1);
|
|
actor->flags |= ACTOR_FLAG_PLAYER_TALKED_TO;
|
|
func_80832528(play, this);
|
|
} else {
|
|
if (this->actor.flags & ACTOR_FLAG_PLAYER_TALKED_TO) {
|
|
this->actor.textId = 0;
|
|
} else {
|
|
this->actor.flags |= ACTOR_FLAG_PLAYER_TALKED_TO;
|
|
this->actor.textId = actor->textId;
|
|
}
|
|
|
|
if (this->stateFlags1 & PLAYER_STATE1_ON_HORSE) {
|
|
s32 sp24 = this->av2.actionVar2;
|
|
|
|
func_80832528(play, this);
|
|
func_8083A2F8(play, this);
|
|
|
|
this->av2.actionVar2 = sp24;
|
|
} else {
|
|
if (func_808332B8(this)) {
|
|
func_80836898(play, this, func_8083A2F8);
|
|
Player_AnimChangeLoopSlowMorph(play, this, &gPlayerAnim_link_swimer_swim_wait);
|
|
} else if ((actor->category != ACTORCAT_NPC) || (this->heldItemAction == PLAYER_IA_FISHING_POLE)) {
|
|
func_8083A2F8(play, this);
|
|
|
|
if (!func_8008E9C4(this)) {
|
|
if ((actor != this->naviActor) && (actor->xzDistToPlayer < 40.0f)) {
|
|
Player_AnimPlayOnceAdjusted(play, this, &gPlayerAnim_link_normal_backspace);
|
|
} else {
|
|
Player_AnimPlayLoop(play, this, func_80833338(this));
|
|
}
|
|
}
|
|
} else {
|
|
func_80836898(play, this, func_8083A2F8);
|
|
Player_AnimPlayOnceAdjusted(play, this,
|
|
(actor->xzDistToPlayer < 40.0f) ? &gPlayerAnim_link_normal_backspace
|
|
: &gPlayerAnim_link_normal_talk_free);
|
|
}
|
|
|
|
if (this->skelAnime.animation == &gPlayerAnim_link_normal_backspace) {
|
|
Player_AnimReplaceApplyFlags(play, this, 0x19);
|
|
}
|
|
|
|
func_80832224(this);
|
|
}
|
|
|
|
this->stateFlags1 |= PLAYER_STATE1_TEXT_ON_SCREEN | PLAYER_STATE1_IN_CUTSCENE;
|
|
}
|
|
|
|
if ((this->naviActor == this->targetActor) && ((this->targetActor->textId & 0xFF00) != 0x200)) {
|
|
this->naviActor->flags |= ACTOR_FLAG_PLAYER_TALKED_TO;
|
|
func_80835EA4(play, 0xB);
|
|
}
|
|
}
|