Files
tmc/src/object/linkAnimation.c
T
2023-12-30 22:09:30 +01:00

123 lines
4.6 KiB
C

/**
* @file linkAnimation.c
* @ingroup Objects
*
* @brief Link Animation object. This is used during "item get" sequences and
* replaces the player entity for the duration.
*/
#include "functions.h"
#include "message.h"
#include "object.h"
#include "object/linkAnimation.h"
typedef enum {
ITEMGET_INIT,
ITEMGET_UPDATE,
ITEMGET_WAIT,
} ItemGetState;
void LinkAnimation_Init(LinkAnimationEntity*);
void LinkAnimation_Default(LinkAnimationEntity*);
void LinkAnimation_ItemGet(LinkAnimationEntity*);
void LinkAnimation(LinkAnimationEntity* this) {
static void (*const LinkAnimation_Actions[])(LinkAnimationEntity*) = {
LinkAnimation_Init, LinkAnimation_Default, LinkAnimation_Default, LinkAnimation_Default,
LinkAnimation_Default, LinkAnimation_Default, LinkAnimation_Default, LinkAnimation_Default,
LinkAnimation_ItemGet, LinkAnimation_Default, LinkAnimation_Default, LinkAnimation_Default,
LinkAnimation_Default, LinkAnimation_Default, LinkAnimation_Default, LinkAnimation_Default,
LinkAnimation_Default, LinkAnimation_Default, LinkAnimation_Default, LinkAnimation_Default,
LinkAnimation_Default, LinkAnimation_Default, LinkAnimation_Default, LinkAnimation_Default,
LinkAnimation_Default, LinkAnimation_Default, LinkAnimation_Default, LinkAnimation_Default,
LinkAnimation_Default, LinkAnimation_Default, LinkAnimation_Default, LinkAnimation_Default,
};
LinkAnimation_Actions[super->action](this);
}
void LinkAnimation_Init(LinkAnimationEntity* this) {
super->action = PLAYER_ITEMGET;
LinkAnimation_ItemGet(this);
}
void LinkAnimation_Default(LinkAnimationEntity* this) {
ResetPlayerEventPriority();
gPauseMenuOptions.disabled = 0;
DeleteThisEntity();
}
void LinkAnimation_ItemGet(LinkAnimationEntity* this) {
u32 one;
u32 sprite;
Entity* held_obj;
u8* ptr;
// hide player entity
gPlayerEntity.base.flags &= ~ENT_COLLIDE;
gPlayerEntity.base.spriteSettings.draw = 0;
super->palette.b.b0 = gPlayerEntity.base.palette.b.b0;
switch (super->subAction) {
case ITEMGET_INIT:
one = 1;
super->subAction = one;
super->spriteSettings.draw = one;
super->collisionLayer = gPlayerEntity.base.collisionLayer;
super->spritePriority.b0 = gPlayerEntity.base.spritePriority.b0;
super->spriteRendering.b3 = gPlayerEntity.base.spriteRendering.b3;
super->spriteOrientation.flipY = gPlayerEntity.base.spriteOrientation.flipY;
super->spriteSettings.flipX = 0;
super->animationState = 4;
SetEntityPriority(super, PRIO_PLAYER_EVENT);
if (gPlayerState.flags & PL_NO_CAP) {
if (IsMinishItem(super->type)) {
sprite = ANIM_GET_ITEM_SMALL_NOCAP;
} else {
sprite = ANIM_GET_ITEM_BIG_NOCAP;
}
} else {
if (IsMinishItem(super->type)) {
sprite = ANIM_GET_ITEM_SMALL;
} else {
sprite = ANIM_GET_ITEM_BIG;
}
}
super->spriteIndex = (sprite >> 8);
InitAnimationForceUpdate(super, sprite & 0xff);
break;
case ITEMGET_UPDATE:
UpdateAnimationSingleFrame(super);
if (super->frame != 0) {
super->subAction++;
}
break;
case ITEMGET_WAIT:
UpdateAnimationSingleFrame(super);
if ((gMessage.state & MESSAGE_ACTIVE) != 0) {
return;
}
if (super->frame & ANIM_DONE) {
super->action = PLAYER_NORMAL;
// restore player state
gPlayerEntity.base.flags = this->storeFlags;
gPlayerEntity.base.spriteSettings.draw = this->storeDrawFlags;
gPlayerEntity.base.iframes = this->storeIFrames;
gPlayerState.field_0x7 = this->storeField7;
gPlayerState.keepFacing = this->storeKeepFacing;
gPlayerState.field_0xa = this->storeFieldA;
gPlayerState.field_0x27[0] = this->storeField27;
gPlayerState.mobility = this->storeMobility;
gPlayerState.flags = this->storeStateFlags;
gPlayerState.field_0x8a = this->store8A;
}
break;
}
held_obj = super->parent;
if (held_obj != NULL) {
PositionEntityOnTop(super, held_obj);
ptr = GetSpriteSubEntryOffsetDataPointer((u16)super->spriteIndex, super->frameIndex);
held_obj->spriteOffsetX = ptr[0];
held_obj->spriteOffsetY = ptr[1];
}
}