tmc/src/object/pullableMushroom.c

412 lines
13 KiB
C

/**
* @file pullableMushroom.c
* @ingroup Objects
*
* @brief Pullable Mushroom object
*/
#define NENT_DEPRECATED
#include "global.h"
#include "object.h"
#include "functions.h"
#include "game.h"
#include "hitbox.h"
typedef struct {
/*0x00*/ Entity base;
/*0x68*/ u8 unk_68[0x8];
/*0x70*/ u32 unk_70;
/*0x74*/ u32 unk_74;
/*0x78*/ u32 unk_78;
/*0x7c*/ u32 unk_7c;
} PullableMushroomEntity;
extern const u8 gUnk_08126EE4[];
void PullableMushroom_Init(PullableMushroomEntity*);
void PullableMushroom_Action1(PullableMushroomEntity*);
void PullableMushroom_Action2(PullableMushroomEntity*);
void PullableMushroom_Action3(PullableMushroomEntity*);
void PullableMushroom_Action1_Type0(PullableMushroomEntity*);
void PullableMushroom_Action1_Type1(PullableMushroomEntity*);
void sub_0808ABC4(PullableMushroomEntity*);
void sub_0808ACEC(PullableMushroomEntity*);
void sub_0808ADA0(PullableMushroomEntity*);
void sub_0808ADF0(PullableMushroomEntity*);
void sub_0808AEB0(PullableMushroomEntity*);
void sub_0808AFD4(PullableMushroomEntity*);
void sub_0808B05C(PullableMushroomEntity*);
void sub_0808B0BC(PullableMushroomEntity*);
void sub_0808B168(PullableMushroomEntity*, u32);
u32 sub_0808B1F0(PullableMushroomEntity*, Entity*);
bool32 sub_0808B21C(PullableMushroomEntity*, u32);
void PullableMushroom(PullableMushroomEntity* this) {
static void (*const PullableMushroom_Actions[])(PullableMushroomEntity*) = {
PullableMushroom_Init,
PullableMushroom_Action1,
PullableMushroom_Action2,
PullableMushroom_Action3,
};
PullableMushroom_Actions[super->action](this);
super->bitfield = 0;
}
void PullableMushroom_Init(PullableMushroomEntity* this) {
super->action = 1;
if (AreaIsDungeon() == 0) {
ChangeObjPalette(super, 0);
}
switch (super->type) {
case 0:
super->spritePriority.b0 = 4;
super->hitbox = (Hitbox*)&gUnk_080FD224;
super->field_0x16 = 1;
SetTile(0x4022, COORD_TO_TILE(super), super->collisionLayer);
super->health = 1;
super->field_0x3c = 7;
super->hitType = 0x6e;
super->flags2 = 0x0e;
super->field_0x1c = 1;
super->flags |= 0x80;
super->spriteOffsetY = 4;
break;
case 1:
super->spritePriority.b0 = 4;
if (super->type2 != 0) {
super->hitbox = (Hitbox*)&gUnk_080FD224;
super->flags |= 0x80;
super->health = 1;
super->field_0x3c = 7;
super->hitType = 0x6e;
super->flags2 = 4;
super->field_0x1c = 1;
super->action = 3;
}
InitializeAnimation(super, super->animationState + 9);
break;
case 2:
super->spritePriority.b0 = 5;
super->spriteRendering.b0 = 3;
if ((super->animationState & 1)) {
this->unk_74 = 0x200;
this->unk_78 = 0x100;
} else {
this->unk_78 = 0x200;
this->unk_74 = 0x100;
}
break;
}
PullableMushroom_Action1(this);
}
void PullableMushroom_Action1(PullableMushroomEntity* this) {
static void (*const funcs[])(PullableMushroomEntity*) = {
PullableMushroom_Action1_Type0,
PullableMushroom_Action1_Type1,
sub_0808ABC4,
};
funcs[super->type](this);
}
void PullableMushroom_Action1_Type0(PullableMushroomEntity* this) {
static void (*const funcs[])(PullableMushroomEntity*) = {
sub_0808ACEC,
sub_0808ADA0,
sub_0808ADF0,
};
funcs[super->subAction](this);
}
void PullableMushroom_Action1_Type1(PullableMushroomEntity* this) {
if (*(u16*)&super->parent->action == 0x201) {
super->parent->child = NULL;
DeleteThisEntity();
} else if (super->parent->action == 2) {
sub_0808B168(this, 0);
}
}
const u16 gUnk_081211CC[] = { 32768, 64000, 0, 64517, 0, 0, 32768, 64763 };
ASM_FUNC("asm/non_matching/pullableMushroom/sub_0808ABC4.inc", void sub_0808ABC4(PullableMushroomEntity* this))
void sub_0808ACEC(PullableMushroomEntity* this) {
if (super->animIndex != 0) {
InitializeAnimation(super, 0);
}
switch (super->bitfield & 0x7f) {
case 0x4:
case 0x5:
case 0x6:
case 0x8:
case 0x9:
case 0xa:
case 0xb:
case 0xc:
case 0xd:
case 0x10:
case 0x11:
case 0x12:
case 0x14:
case 0x16:
COLLISION_OFF(super);
super->animationState = sub_0806F5A4(super->knockbackDirection);
super->subAction = 2;
super->actionDelay = 2;
break;
case 0x13:
super->action = 3;
super->subAction = 0;
break;
default:
super->field_0xf = 0;
super->actionDelay = 0;
RegisterCarryEntity(super);
break;
}
}
void sub_0808ADA0(PullableMushroomEntity* this) {
if ((sub_0808B1F0(this, super->child) < 8) || (super->child == NULL)) {
super->subAction += 1;
super->actionDelay = 2;
super->flags |= ENT_COLLIDE;
super->animationState ^= 2;
super->spritePriority.b0 = 4;
} else {
super->child->speed = 0x400;
LinearMoveUpdate(super->child);
}
}
void sub_0808ADF0(PullableMushroomEntity* this) {
if (super->animationState + 0xd == super->animIndex) {
if ((super->frame & ANIM_DONE) != 0) {
super->subAction = 0;
super->flags |= ENT_COLLIDE;
} else {
GetNextFrame(super);
}
} else {
if (super->animationState + 1 != super->animIndex) {
InitializeAnimation(super, super->animationState + 1);
if (super->animationState == 3) {
super->spriteSettings.flipX = 0;
} else {
super->spriteSettings.flipX = 1;
}
SoundReq(SFX_12E);
} else {
GetNextFrame(super);
if (((super->frame & ANIM_DONE) != 0) && (--super->actionDelay == 0xff)) {
InitializeAnimation(super, super->animationState + 0xd);
}
}
}
}
void PullableMushroom_Action2(PullableMushroomEntity* this) {
static void (*const funcs[])(PullableMushroomEntity*) = {
sub_0808AEB0,
sub_0808AFD4,
};
if (gPlayerState.heldObject == 0) {
super->subAction = 6;
}
funcs[super->subAction - 5](this);
}
void sub_0808AEB0(PullableMushroomEntity* this) {
static const u16 gUnk_081211E4[] = { 1024, 256, 2048, 512 };
u32 uVar1;
if (super->actionDelay != 0) {
uVar1 = sub_0808B1F0(this, super->child);
if ((gPlayerState.field_0x90 & gUnk_081211E4[super->animationState]) != 0) {
GetNextFrame(super);
if (uVar1 < 0x40) {
sub_080044AE(&gPlayerEntity, 0x40, super->direction);
if (--this->unk_7c == 0xffffffff) {
this->unk_7c = 4;
SoundReq(SFX_12F);
}
}
super->field_0xf = 1;
} else {
if (((super->field_0xf != 0) && (gPlayerEntity.action == 1)) && (gPlayerState.swim_state == 0)) {
gPlayerState.queued_action = 0x1b;
gPlayerState.field_0x38 = uVar1;
gPlayerState.field_0x39 = super->direction ^ 0x10;
gPlayerState.field_0x3a = sub_0808B1F0(this, &gPlayerEntity);
super->subAction++;
}
}
} else {
super->actionDelay = 1;
this->unk_7c = 1;
super->animationState = AnimationStateFlip90(gPlayerEntity.animationState >> 1);
super->direction = (super->animationState << 3);
super->flags &= 0x7f;
super->spriteSettings.flipX = gPlayerEntity.spriteSettings.flipX;
InitializeAnimation(super, super->animationState + 5);
if (sub_0808B21C(this, 0)) {
sub_0808B168((PullableMushroomEntity*)super->child, 0);
}
if ((super->animationState & 1) != 0) {
gPlayerEntity.y.HALF.HI = super->y.HALF.HI;
} else {
gPlayerEntity.x.HALF.HI = super->x.HALF.HI;
}
}
}
void sub_0808AFD4(PullableMushroomEntity* this) {
super->action = 1;
super->subAction = 1;
(super->child)->direction = DirectionTurnAround(super->direction);
SoundReq(SFX_130);
}
void PullableMushroom_Action3(PullableMushroomEntity* this) {
static void (*const funcs[])(PullableMushroomEntity*) = {
sub_0808B05C,
sub_0808B0BC,
};
funcs[super->subAction](this);
if ((((gPlayerState.field_0x1c & 0xf) != 1) || ((super->bitfield & 0x7f) != 0x13)) && (super->type == 1)) {
(super->parent)->action = 1;
(super->parent)->subAction = 1;
super->direction = DirectionTurnAround(super->parent->direction);
super->parent->flags &= ~ENT_COLLIDE;
super->flags &= ~ENT_COLLIDE;
super->action = 1;
SoundReq(SFX_130);
}
}
void sub_0808B05C(PullableMushroomEntity* this) {
if (super->type == 0) {
super->animationState = AnimationStateFlip90(gPlayerEntity.animationState >> 1);
super->direction = super->animationState << 3;
super->spriteSettings.flipX = gPlayerEntity.spriteSettings.flipX;
super->flags &= 0x7f;
InitializeAnimation(super, super->animationState + 5);
if (sub_0808B21C(this, 1)) {
sub_0808B168((PullableMushroomEntity*)super->child, 1);
}
}
super->subAction++;
}
void sub_0808B0BC(PullableMushroomEntity* this) {
u32 uVar2;
const s8* ptr;
GenericEntity ent;
uVar2 = sub_0808B1F0(this, super->parent);
switch (super->type) {
case 0:
GetNextFrame(super);
break;
case 1:
ptr = &gUnk_08126EE4[gPlayerEntity.animationState & 0xe];
ent.base.x.HALF.HI = ptr[0] + gPlayerEntity.x.HALF.HI;
ent.base.y.HALF.HI = ptr[1] + gPlayerEntity.y.HALF.HI;
if (sub_0800419C(&ent.base, super, 7, 7)) {
if ((gPlayerEntity.action != 1) || (gPlayerState.swim_state != 0))
return;
gPlayerState.queued_action = 0x1b;
gPlayerState.field_0x38 = uVar2;
gPlayerState.field_0x39 = super->direction ^ 0x10;
gPlayerState.field_0x3a = sub_0808B1F0((PullableMushroomEntity*)super->parent, &gPlayerEntity);
} else {
super->speed = 0x40;
if (uVar2 < 0x40) {
LinearMoveUpdate(super);
}
}
break;
}
}
void sub_0808B168(PullableMushroomEntity* this, u32 param_2) {
static const s8 gUnk_081211F4[] = {
0, 8, -8, -4, 0, -8, 8, -4,
};
static const s8 gUnk_081211FC[] = {
0, 3, -8, -4, 0, -12, 8, -4,
};
s32 iVar2;
const s8* pcVar3;
u32 uVar4;
const s8* pcVar5;
Entity* pEVar5;
Entity* pEVar6;
if (param_2 != 0) {
iVar2 = AnimationStateFlip90(super->animationState) * 2;
pcVar5 = (gUnk_081211F4 + iVar2);
pcVar3 = pcVar5 + 1;
pEVar5 = super->parent;
pEVar6 = pEVar5;
} else {
if ((super->animationState & 1) != 0) {
pEVar6 = &gPlayerEntity;
pEVar5 = super->parent;
pcVar5 = (gUnk_081211FC + super->animationState * 2);
pcVar3 = (gUnk_081211F4 + 1 + AnimationStateFlip90(super->animationState) * 2);
} else {
pEVar6 = super->parent;
pEVar5 = &gPlayerEntity;
pcVar5 = (gUnk_081211F4 + AnimationStateFlip90(super->animationState) * 2);
pcVar3 = (gUnk_081211FC + 1 + super->animationState * 2);
}
}
super->x.HALF.HI = *pcVar5 + pEVar6->x.HALF.HI;
super->y.HALF.HI = *pcVar3 + pEVar5->y.HALF.HI;
}
u32 sub_0808B1F0(PullableMushroomEntity* this, Entity* other) {
s32 sVar1;
s32 sVar2;
u32 uVar3;
if ((super->animationState & 1) != 0) {
sVar1 = super->x.HALF.HI;
sVar2 = other->x.HALF.HI;
} else {
sVar1 = super->y.HALF.HI;
sVar2 = other->y.HALF.HI;
}
uVar3 = (s32)sVar1 - (s32)sVar2;
if ((s32)uVar3 < 0) {
uVar3 = -uVar3;
}
return uVar3;
}
bool32 sub_0808B21C(PullableMushroomEntity* this, u32 param_2) {
Entity* obj;
super->spritePriority.b0 = 6;
obj = CreateObjectWithParent(super, PULLABLE_MUSHROOM, 1, 0);
super->child = obj;
if (obj != NULL) {
obj->animationState = super->animationState;
(super->child)->direction = super->direction;
super->child->spriteSettings.flipX = super->spriteSettings.flipX;
(super->child)->parent = super;
(super->child)->type2 = (u8)param_2;
}
obj = CreateObjectWithParent(super, PULLABLE_MUSHROOM, 2, 0);
super->parent = obj;
if (obj != NULL) {
obj->animationState = super->animationState;
(super->parent)->child = super->child;
return TRUE;
}
return FALSE;
}