mirror of
https://github.com/zeldaret/tmc
synced 2026-07-08 14:36:41 -04:00
304 lines
10 KiB
C
304 lines
10 KiB
C
#include "functions.h"
|
|
#include "item.h"
|
|
#include "playeritem.h"
|
|
#include "sound.h"
|
|
|
|
u32 sub_08077F64(ItemBehavior* arg0, u32 index);
|
|
u32 sub_080789A8(void);
|
|
void sub_080762C4(ItemBehavior*, Entity*, u8, u32);
|
|
void sub_08076088(ItemBehavior*, Entity*, u32);
|
|
void ItemPickupCheck(ItemBehavior*, u32);
|
|
void sub_080762D8(ItemBehavior*, u32);
|
|
void sub_08076488(ItemBehavior*, u32);
|
|
void sub_08076518(ItemBehavior*, u32);
|
|
void sub_080765E0(ItemBehavior*, u32);
|
|
void sub_0807660C(ItemBehavior*, u32);
|
|
|
|
extern s32 DoItemTileInteraction(Entity*, u32, ItemBehavior*);
|
|
|
|
extern const u16 gUnk_0811BE38[];
|
|
extern const u16 gUnk_0811BE40[];
|
|
|
|
void sub_08076088(ItemBehavior* this, Entity* param_2, u32 param_3) {
|
|
if (param_2 != NULL) {
|
|
if ((param_2->carryFlags & 1) != 0) {
|
|
return;
|
|
}
|
|
param_2->action = 2;
|
|
param_2->subAction = param_2->carryFlags & 1;
|
|
}
|
|
|
|
this->field_0x18 = param_2;
|
|
if ((gPlayerState.flags & PL_NO_CAP)) {
|
|
SetItemAnim(this, ANIM_PICKUP_NOCAP);
|
|
} else {
|
|
SetItemAnim(this, ANIM_PICKUP);
|
|
}
|
|
gPlayerState.heldObject = 3;
|
|
gPlayerState.framestate = 4;
|
|
this->stateID = 2;
|
|
this->animPriority = 0xf;
|
|
if ((gPlayerEntity.unk_79 & 0x80)) {
|
|
gPlayerEntity.unk_79 = 0;
|
|
COLLISION_ON(&gPlayerEntity.base);
|
|
gPlayerState.heldObject = 4;
|
|
gPlayerState.keepFacing = ~(8 >> param_3) & gPlayerState.keepFacing;
|
|
gPlayerState.field_0xa = ~(8 >> param_3) & gPlayerState.field_0xa;
|
|
this->stateID = 3;
|
|
this->animPriority = 0;
|
|
} else {
|
|
gPlayerState.field_0xa |= (8 >> param_3);
|
|
gPlayerState.keepFacing |= (8 >> param_3);
|
|
}
|
|
|
|
param_2 = CreatePlayerItemWithParent(this, PLAYER_ITEM_HELD_OBJECT);
|
|
if (param_2 == NULL) {
|
|
PlayerCancelHoldItem(this, param_3);
|
|
} else {
|
|
PlayerEntity* playerEnt = &gPlayerEntity;
|
|
playerEnt->carriedEntity = param_2;
|
|
playerEnt->base.subtimer = 0;
|
|
param_2->child = this->field_0x18;
|
|
param_2->carryFlags = playerEnt->base.carryFlags;
|
|
param_2->parent = (Entity*)this;
|
|
this->field_0x18 = param_2;
|
|
param_2->type2 = this->field_0x2[1];
|
|
param_2->timer = this->timer;
|
|
param_2->subtimer = this->subtimer;
|
|
if ((this->field_0x18->carryFlags & 0xf0) == 0x10) {
|
|
this->timer = 8;
|
|
} else {
|
|
this->timer = 0;
|
|
}
|
|
SoundReq(SFX_PLY_LIFT);
|
|
}
|
|
}
|
|
|
|
void ItemTryPickupObject(ItemBehavior* this, u32 index) {
|
|
static void (*const stateFuncs[])(ItemBehavior*, u32) = {
|
|
ItemPickupCheck, sub_080762D8, sub_08076488, sub_08076518, sub_080765E0, sub_0807660C,
|
|
};
|
|
stateFuncs[this->stateID](this, index);
|
|
}
|
|
|
|
void ItemPickupCheck(ItemBehavior* this, u32 index) {
|
|
Entity* carried;
|
|
|
|
if (gPlayerState.attack_status == 0 &&
|
|
(gPlayerState.jump_status == 0 || (gPlayerState.flags & (PL_BUSY | PL_FALLING | PL_IN_MINECART)) != 0) &&
|
|
(gPlayerState.grab_status = gPlayerEntity.base.animationState | 0x80, gPlayerEntity.base.iframes <= 8)) {
|
|
|
|
switch (sub_080789A8()) {
|
|
case 2:
|
|
if (((gCarriedEntity.unk_8)->carryFlags & 0xf) == 0) {
|
|
sub_08076088(this, gCarriedEntity.unk_8, index);
|
|
return;
|
|
}
|
|
carried = gCarriedEntity.unk_8;
|
|
this->field_0x18 = carried;
|
|
carried->action = 2;
|
|
carried->subAction = 5;
|
|
gPlayerState.framestate = PL_STATE_THROW;
|
|
sub_080762C4(this, carried, 2, index);
|
|
gUnk_0200AF00.rActionGrabbing = R_ACTION_GRAB;
|
|
SoundReq(SFX_102);
|
|
break;
|
|
case 1:
|
|
sub_080762C4(this, 0, 1, index);
|
|
SoundReq(SFX_102);
|
|
break;
|
|
case 0:
|
|
this->stateID = 5;
|
|
this->timer = 0x0f;
|
|
this->animPriority = 6;
|
|
gPlayerState.field_0xa = (8 >> index) | gPlayerState.field_0xa;
|
|
gPlayerState.keepFacing = (8 >> index) | gPlayerState.keepFacing;
|
|
if (!(gPlayerState.flags & PL_NO_CAP)) {
|
|
SetItemAnim(this, ANIM_GRAB);
|
|
} else {
|
|
SetItemAnim(this, ANIM_GRAB_NOCAP);
|
|
}
|
|
SoundReq(SFX_GRAB);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else {
|
|
PlayerCancelHoldItem(this, index);
|
|
}
|
|
}
|
|
|
|
void sub_080762C4(ItemBehavior* this, Entity* arg1, u8 arg2, u32 arg3) {
|
|
this->field_0x18 = arg1;
|
|
gPlayerState.heldObject = arg2;
|
|
sub_08077D38(this, arg3);
|
|
}
|
|
|
|
void sub_080762D8(ItemBehavior* this, u32 index) {
|
|
u32 animIndex;
|
|
|
|
gPlayerState.heldObject &= 0xcf;
|
|
if (!PlayerTryDropObject(this, index)) {
|
|
return;
|
|
}
|
|
|
|
if (gPlayerEntity.base.iframes < 9 && gPlayerEntity.base.knockbackDuration == 0) {
|
|
if (this->field_0x18 != NULL) {
|
|
if (this->field_0x18->action == 2 && this->field_0x18->subAction == 5) {
|
|
if (!(gPlayerState.playerInput.heldInput & INPUT_ACTION)) { // Pressing R
|
|
this->field_0x18->subAction = 6;
|
|
PlayerCancelHoldItem(this, index);
|
|
return;
|
|
}
|
|
} else {
|
|
PlayerCancelHoldItem(this, index);
|
|
return;
|
|
}
|
|
}
|
|
|
|
gPlayerState.framestate = PL_STATE_THROW;
|
|
gUnk_0200AF00.rActionGrabbing = 8;
|
|
} else {
|
|
if (this->field_0x18 != NULL) {
|
|
this->field_0x18->subAction = 6;
|
|
}
|
|
PlayerCancelHoldItem(this, index);
|
|
return;
|
|
}
|
|
|
|
if (!gPlayerState.jump_status) {
|
|
|
|
if (gPlayerState.heldObject == 1 && DoItemTileInteraction(&gPlayerEntity.base, 6, this) != 0) {
|
|
sub_08076088(this, NULL, index);
|
|
return;
|
|
} else if (gUnk_0811BE38[gPlayerEntity.base.animationState >> 1] & gPlayerState.playerInput.heldInput) {
|
|
UpdateItemAnim(this);
|
|
|
|
if (!(gPlayerState.flags & PL_NO_CAP)) {
|
|
animIndex = ANIM_PULL;
|
|
} else {
|
|
animIndex = ANIM_PULL_START_NOCAP;
|
|
}
|
|
|
|
if (animIndex != this->animIndex) {
|
|
SetItemAnim(this, animIndex);
|
|
}
|
|
|
|
gPlayerState.heldObject |= 0x10;
|
|
gPlayerState.framestate = PL_STATE_PULL;
|
|
|
|
if (gPlayerState.heldObject == 1) {
|
|
return;
|
|
}
|
|
|
|
sub_08076088(this, this->field_0x18, index);
|
|
} else {
|
|
if (gPlayerState.playerInput.heldInput & gUnk_0811BE40[gPlayerEntity.base.animationState >> 1]) {
|
|
if (gPlayerEntity.base.subtimer < 6) {
|
|
gPlayerEntity.base.subtimer++;
|
|
return;
|
|
}
|
|
|
|
gPlayerState.field_0x35 = this->playerAnimationState;
|
|
gPlayerState.pushedObject |= 0x80;
|
|
gPlayerState.heldObject |= 0x20;
|
|
gPlayerState.framestate = PL_STATE_PUSH;
|
|
|
|
if (!(gPlayerState.flags & PL_NO_CAP)) {
|
|
animIndex = ANIM_PUSH;
|
|
} else {
|
|
animIndex = ANIM_PUSH_NOCAP;
|
|
}
|
|
|
|
if (animIndex == this->animIndex) {
|
|
UpdateItemAnim(this);
|
|
} else {
|
|
SetItemAnim(this, animIndex);
|
|
}
|
|
} else {
|
|
gPlayerEntity.base.subtimer = 0;
|
|
|
|
if (!(gPlayerState.flags & PL_NO_CAP)) {
|
|
SetItemAnim(this, ANIM_PULL);
|
|
} else {
|
|
SetItemAnim(this, ANIM_PULL_START_NOCAP);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
PlayerCancelHoldItem(this, index);
|
|
}
|
|
}
|
|
|
|
void sub_08076488(ItemBehavior* this, u32 index) {
|
|
u32 bVar1;
|
|
s32 iVar2;
|
|
|
|
if (this->timer == 0) {
|
|
if (PlayerTryDropObject(this, index) != 0) {
|
|
if ((((this->field_0x18->carryFlags) & 0xf0) == 0x10) && ((gRoomTransition.frameCount & 1U) != 0)) {
|
|
return;
|
|
}
|
|
UpdateItemAnim(this);
|
|
if ((this->playerFrame & 0x80) != 0) {
|
|
gPlayerEntity.base.flags |= ENT_COLLIDE;
|
|
gPlayerState.heldObject = 4;
|
|
bVar1 = ~(8 >> index);
|
|
gPlayerState.keepFacing = bVar1 & gPlayerState.keepFacing;
|
|
gPlayerState.field_0xa = bVar1 & gPlayerState.field_0xa;
|
|
this->stateID++;
|
|
this->animPriority = 0;
|
|
}
|
|
}
|
|
} else {
|
|
this->timer--;
|
|
}
|
|
gPlayerState.framestate = PL_STATE_HOLD;
|
|
}
|
|
|
|
void sub_08076518(ItemBehavior* this, u32 index) {
|
|
if (PlayerTryDropObject(this, index)) {
|
|
gPlayerState.framestate = PL_STATE_HOLD;
|
|
if ((gPlayerState.jump_status & 0x80) == 0 && gPlayerState.field_0x1f[0] == 0) {
|
|
if (gPlayerEntity.base.knockbackDuration != 0) {
|
|
PlayerCancelHoldItem(this, index);
|
|
} else {
|
|
if ((gPlayerState.playerInput.newInput & (INPUT_LIFT_THROW | INPUT_CANCEL | INPUT_INTERACT)) != 0) {
|
|
sub_0806F948(&gPlayerEntity.base);
|
|
gPlayerState.heldObject = 5;
|
|
this->field_0x18->subAction = 2;
|
|
this->field_0x18->direction = (gPlayerEntity.base.animationState & 0xe) << 2;
|
|
this->field_0x18 = NULL;
|
|
this->stateID++;
|
|
this->animPriority = 0x0f;
|
|
if (gPlayerState.flags & PL_NO_CAP) {
|
|
SetItemAnim(this, ANIM_THROW_NOCAP);
|
|
} else {
|
|
SetItemAnim(this, ANIM_THROW);
|
|
}
|
|
gPlayerState.field_0xa |= 8 >> index;
|
|
gPlayerState.keepFacing |= 8 >> index;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_080765E0(ItemBehavior* this, u32 index) {
|
|
if (PlayerTryDropObject(this, index) != 0) {
|
|
if ((this->playerFrame & 0x80) != 0) {
|
|
PlayerCancelHoldItem(this, index);
|
|
} else {
|
|
UpdateItemAnim(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_0807660C(ItemBehavior* this, u32 index) {
|
|
UpdateItemAnim(this);
|
|
if ((this->timer-- == 0) || (gPlayerState.grab_status == 0)) {
|
|
gPlayerState.grab_status = 0;
|
|
DeleteItemBehavior(this, index);
|
|
}
|
|
}
|