mirror of https://github.com/zeldaret/tmc.git
366 lines
11 KiB
C
366 lines
11 KiB
C
/**
|
|
* @file frozenOctorok.c
|
|
* @ingroup Objects
|
|
*
|
|
* @brief Frozen Octorok object
|
|
*/
|
|
#define NENT_DEPRECATED
|
|
#include "enemy/octorokBoss.h"
|
|
#include "functions.h"
|
|
#include "global.h"
|
|
#include "message.h"
|
|
#include "object.h"
|
|
|
|
typedef struct {
|
|
/*0x00*/ Entity base;
|
|
/*0x68*/ u8 unk_68[0xc];
|
|
/*0x74*/ u16 unk_74;
|
|
/*0x76*/ u16 unk_76;
|
|
/*0x78*/ u8 unk_78;
|
|
/*0x79*/ u8 unk_79;
|
|
/*0x7a*/ u8 unk_7a;
|
|
/*0x7b*/ u8 unk_7b;
|
|
/*0x7c*/ u8 unk_7c[2];
|
|
/*0x7e*/ u16 unk_7e;
|
|
/*0x7f*/ u8 unk_7f[4];
|
|
/*0x84*/ OctorokBossHeap* heap;
|
|
} FrozenOctorokEntity;
|
|
|
|
void FrozenOctorok_Init(FrozenOctorokEntity*);
|
|
void FrozenOctorok_Action1(FrozenOctorokEntity*);
|
|
void FrozenOctorok_Action1SubAction0(FrozenOctorokEntity*);
|
|
void FrozenOctorok_Action1SubAction1(FrozenOctorokEntity*);
|
|
void FrozenOctorok_Action1SubAction2(FrozenOctorokEntity*);
|
|
void FrozenOctorok_Action1SubAction3(FrozenOctorokEntity*);
|
|
void FrozenOctorok_Action1SubAction4(FrozenOctorokEntity*);
|
|
void FrozenOctorok_Action1SubAction5(FrozenOctorokEntity*);
|
|
void FrozenOctorok_Action1SubAction6(FrozenOctorokEntity*);
|
|
void FrozenOctorok_Action1SubAction7(FrozenOctorokEntity*);
|
|
void FrozenOctorok_ChangeObjPaletteOfChildren(FrozenOctorokEntity*, u32);
|
|
void sub_0809CBE4(FrozenOctorokEntity*);
|
|
void sub_0809CB70(FrozenOctorokEntity*, s32, s32);
|
|
|
|
void FrozenOctorok(FrozenOctorokEntity* this) {
|
|
static void (*const FrozenOctorok_Actions[])(FrozenOctorokEntity*) = {
|
|
FrozenOctorok_Init,
|
|
FrozenOctorok_Action1,
|
|
};
|
|
FrozenOctorok_Actions[super->action](this);
|
|
super->spriteRendering.b3 = 3;
|
|
}
|
|
|
|
const u8 gUnk_08123DDC[] = {
|
|
9, 4, 0, 0, 1, 5, 0, 0, 1, 4, 0, 0, 1, 3, 0, 0, 1, 2, 0, 0, 2, 1, 0, 0, 10, 4, 0, 0,
|
|
};
|
|
|
|
NONMATCH("asm/non_matching/frozenOctorok/FrozenOctorok_Init.inc", void FrozenOctorok_Init(FrozenOctorokEntity* this)) {
|
|
OctorokBossHeap* heap;
|
|
Entity*** pppEVar2;
|
|
FrozenOctorokEntity* pEVar3;
|
|
FrozenOctorokEntity* obj1;
|
|
FrozenOctorokEntity* obj2;
|
|
u32 uVar3;
|
|
u32 type;
|
|
|
|
super->action = 1;
|
|
switch (super->type) {
|
|
case 0:
|
|
SetDefaultPriority(super, 6);
|
|
this->unk_7e = 0;
|
|
case 6:
|
|
super->timer = 1;
|
|
super->direction = 0x10;
|
|
this->unk_79 = 0xf0;
|
|
super->x.HALF.HI = gRoomControls.origin_x + 0x108;
|
|
super->y.HALF.HI = gRoomControls.origin_y + 0x168;
|
|
super->spriteRendering.b0 = 3;
|
|
this->unk_76 = 0xa0;
|
|
this->unk_74 = 0xa0;
|
|
this->unk_7b = -0x80;
|
|
if (super->type == 0) {
|
|
super->spriteOffsetX = 0x29;
|
|
super->spriteOffsetY = -0x20;
|
|
heap = (OctorokBossHeap*)zMalloc(sizeof(OctorokBossHeap));
|
|
this->heap = heap;
|
|
if (heap == NULL) {
|
|
DeleteThisEntity();
|
|
return;
|
|
}
|
|
super->myHeap = heap;
|
|
this->heap->tailCount = 5;
|
|
|
|
for (uVar3 = 0; uVar3 < 4; uVar3++) {
|
|
super->child = CreateObjectWithParent(super, FROZEN_OCTOROK, uVar3 + 1, 0);
|
|
if (super->child != NULL) {
|
|
((FrozenOctorokEntity*)super->child)->heap = this->heap;
|
|
this->heap->legObjects[uVar3] = (OctorokBossEntity*)super->child;
|
|
}
|
|
}
|
|
obj1 = (FrozenOctorokEntity*)CreateObjectWithParent(super, FROZEN_OCTOROK, 5, 0);
|
|
super->child = (Entity*)obj1;
|
|
if (obj1 != NULL) {
|
|
obj1->heap = this->heap;
|
|
}
|
|
obj2 = (FrozenOctorokEntity*)CreateObjectWithParent(super, FROZEN_OCTOROK, 6, 0);
|
|
super->parent = (Entity*)obj2;
|
|
if (obj2 != NULL) {
|
|
obj2->heap = this->heap;
|
|
}
|
|
} else {
|
|
super->spriteOffsetX = 0xd7;
|
|
super->spriteOffsetY = -0x20;
|
|
}
|
|
break;
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
super->timer = 0x10;
|
|
this->unk_79 = 0;
|
|
if ((super->type & 2) == 0) {
|
|
super->subtimer = 2;
|
|
} else {
|
|
super->subtimer = 0xfe;
|
|
}
|
|
this->unk_74 = 0x100;
|
|
if ((super->type & 1) == 0) {
|
|
this->unk_76 = 0xff00;
|
|
} else {
|
|
this->unk_76 = 0x100;
|
|
}
|
|
break;
|
|
case 5:
|
|
this->unk_76 = 0x100;
|
|
this->unk_74 = 0x100;
|
|
this->unk_79 = 0x1c;
|
|
this->heap->mouthObject = (OctorokBossEntity*)this;
|
|
break;
|
|
case 7:
|
|
return;
|
|
}
|
|
InitializeAnimation(super, gUnk_08123DDC[super->type * 4]);
|
|
FrozenOctorok_Action1(this);
|
|
}
|
|
END_NONMATCH
|
|
|
|
void (*const FrozenOctorok_Action1SubActions[])(FrozenOctorokEntity*) = {
|
|
FrozenOctorok_Action1SubAction0, FrozenOctorok_Action1SubAction1, FrozenOctorok_Action1SubAction2,
|
|
FrozenOctorok_Action1SubAction3, FrozenOctorok_Action1SubAction4, FrozenOctorok_Action1SubAction5,
|
|
FrozenOctorok_Action1SubAction6, FrozenOctorok_Action1SubAction7,
|
|
};
|
|
|
|
const u8 gUnk_08123E18[] = {
|
|
40,
|
|
80,
|
|
176,
|
|
216,
|
|
};
|
|
const u8 gUnk_08123E1C[] = {
|
|
128,
|
|
0,
|
|
0,
|
|
128,
|
|
};
|
|
|
|
ASM_FUNC("asm/non_matching/frozenOctorok/FrozenOctorok_Action1.inc",
|
|
void FrozenOctorok_Action1(FrozenOctorokEntity* this))
|
|
|
|
void FrozenOctorok_Action1SubAction0(FrozenOctorokEntity* this) {
|
|
Entity* child;
|
|
if (super->subtimer != 0) {
|
|
if (this->unk_7e == 0) {
|
|
child = super->child;
|
|
if (child->z.HALF.HI > -0x10) {
|
|
child->z.WORD -= Q_16_16(0.25);
|
|
} else {
|
|
child->z.WORD -= Q_16_16(0.0625);
|
|
(super->child)->zVelocity = Q_16_16(0.1875);
|
|
this->unk_7e = 0x200;
|
|
}
|
|
}
|
|
if (this->unk_79-- == 0) {
|
|
MessageFromTarget(TEXT_INDEX(TEXT_EZLO, 0x43));
|
|
super->subAction = 1;
|
|
this->unk_79 = 8;
|
|
}
|
|
}
|
|
}
|
|
|
|
void FrozenOctorok_Action1SubAction1(FrozenOctorokEntity* this) {
|
|
Entity* obj;
|
|
if ((gMessage.doTextBox & 0x7f) == 0) {
|
|
if (this->unk_79-- == 0) {
|
|
obj = CreateObjectWithParent(super, FROZEN_OCTOROK, 7, 0);
|
|
if (obj != NULL) {
|
|
obj->y.HALF.HI -= 0x50;
|
|
gRoomControls.camera_target = obj;
|
|
}
|
|
if (super->subtimer < 3) {
|
|
super->subAction = 2;
|
|
this->unk_79 = 0x1e;
|
|
SoundReq(SFX_THUD_HEAVY);
|
|
} else {
|
|
super->subAction = 3;
|
|
this->unk_79 = 0x78;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void FrozenOctorok_Action1SubAction2(FrozenOctorokEntity* this) {
|
|
if (this->unk_79-- == 0) {
|
|
super->subAction = 1;
|
|
this->unk_79 = 0x1e;
|
|
super->subtimer++;
|
|
return;
|
|
}
|
|
switch (this->unk_79 & 3) {
|
|
case 0:
|
|
case 2:
|
|
super->x.HALF.HI = (super->x.HALF.HI & 0xfff0) + 8;
|
|
break;
|
|
case 1:
|
|
super->x.HALF.HI = (super->x.HALF.HI & 0xfff8) + 4;
|
|
break;
|
|
case 3:
|
|
super->x.HALF.HI = (super->x.HALF.HI & 0xfff8) - 4;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void FrozenOctorok_Action1SubAction3(FrozenOctorokEntity* this) {
|
|
if (this->unk_79-- != 0) {
|
|
CreateObjectWithParent(super, OCTOROK_BOSS_OBJECT, 6, 0);
|
|
} else {
|
|
super->subAction = 4;
|
|
this->unk_79 = 0x3c;
|
|
LoadFixedGFX(super, 0x115);
|
|
LoadFixedGFX(super->parent, 0x115);
|
|
ChangeObjPalette(super, 0xef);
|
|
ChangeObjPalette(super->parent, 0xef);
|
|
FrozenOctorok_ChangeObjPaletteOfChildren(this, 0xef);
|
|
SoundReq(SFX_WIND2);
|
|
}
|
|
}
|
|
|
|
void FrozenOctorok_Action1SubAction4(FrozenOctorokEntity* this) {
|
|
u8 bVar1;
|
|
s16 sVar2;
|
|
u8* pbVar3;
|
|
u8* puVar4;
|
|
|
|
if (this->unk_79-- == 0) {
|
|
super->subAction = 5;
|
|
this->unk_79 = 0xb4;
|
|
super->type2 = 3;
|
|
} else {
|
|
if ((gRoomTransition.frameCount & 8) != 0) {
|
|
this->heap->mouthObject->unk_76 -= 4;
|
|
} else {
|
|
this->heap->mouthObject->unk_76 += 4;
|
|
}
|
|
}
|
|
}
|
|
|
|
void FrozenOctorok_Action1SubAction5(FrozenOctorokEntity* this) {
|
|
Entity* child;
|
|
|
|
if ((gRoomTransition.frameCount & 2) != 0) {
|
|
this->heap->mouthObject->unk_76 -= 8;
|
|
} else {
|
|
this->heap->mouthObject->unk_76 += 8;
|
|
}
|
|
if ((gRoomTransition.frameCount & 3) == 0) {
|
|
CreateObjectWithParent(super, OCTOROK_BOSS_OBJECT, 2, 0);
|
|
}
|
|
if (this->unk_79 == 0) {
|
|
(super->child)->spriteOffsetX = 0;
|
|
LinearMoveAngle(super->child, 0x200, -this->unk_7b);
|
|
if (sub_0806FC80(super, super->child, 0x48) != 0) {
|
|
super->subAction = 6;
|
|
super->speed = 0xc0;
|
|
super->type2 = 0;
|
|
super->subtimer = 0;
|
|
child = super->child;
|
|
child->spriteSettings.draw = 0;
|
|
this->heap->mouthObject->unk_76 = 0x100;
|
|
this->heap->unk_0 = 1;
|
|
SoundReq(SFX_ED);
|
|
}
|
|
} else {
|
|
this->unk_79--;
|
|
switch ((u32)(gRoomTransition.frameCount & 3)) {
|
|
case 0:
|
|
case 2:
|
|
super->child->spriteOffsetX = 0;
|
|
break;
|
|
case 1:
|
|
super->child->spriteOffsetX = 0xfc;
|
|
break;
|
|
case 3:
|
|
super->child->spriteOffsetX = 4;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void FrozenOctorok_Action1SubAction6(FrozenOctorokEntity* this) {
|
|
LinearMoveUpdate(super);
|
|
if ((gRoomControls.origin_y + 0x1c8) < super->y.HALF.HI) {
|
|
gRoomControls.unk5 = 4;
|
|
gRoomControls.camera_target = &gPlayerEntity;
|
|
SetLocalFlag(0x9b);
|
|
DeleteEntity(super->parent);
|
|
DeleteEntity(&this->heap->mouthObject->base);
|
|
DeleteEntity(&this->heap->legObjects[0]->base);
|
|
DeleteEntity(&this->heap->legObjects[1]->base);
|
|
DeleteEntity(&this->heap->legObjects[2]->base);
|
|
DeleteEntity(&this->heap->legObjects[3]->base);
|
|
super->subAction = 7;
|
|
}
|
|
if ((gRoomTransition.frameCount & 0xf) == 0) {
|
|
SoundReq(SFX_TOGGLE_DIVING);
|
|
}
|
|
}
|
|
|
|
void FrozenOctorok_Action1SubAction7(FrozenOctorokEntity* this) {
|
|
if ((gRoomControls.scroll_flags & 4) == 0) {
|
|
CreateEzloHint(TEXT_INDEX(TEXT_EZLO, 0x44), 0);
|
|
DeleteThisEntity();
|
|
}
|
|
}
|
|
|
|
void sub_0809CB70(FrozenOctorokEntity* this, s32 angle, s32 radius) {
|
|
s32 tmp;
|
|
tmp = FixedMul(gSineTable[angle], radius);
|
|
tmp = FixedDiv(tmp, 0x100);
|
|
super->x.WORD = (super->parent)->x.WORD + ((tmp << 0x10) >> 8);
|
|
tmp = FixedMul(gSineTable[angle + 0x40], radius);
|
|
tmp = FixedDiv(tmp, 0x100);
|
|
super->y.WORD = super->parent->y.WORD - ((tmp << 0x10) >> 8);
|
|
super->z.WORD = super->parent->z.WORD;
|
|
}
|
|
|
|
NONMATCH("asm/non_matching/frozenOctorok/sub_0809CBE4.inc", void sub_0809CBE4(FrozenOctorokEntity* this)) {
|
|
this->unk_79 += super->subtimer;
|
|
if ((s8)super->subtimer < 0) {
|
|
if (super->timer < -this->unk_79) {
|
|
super->subtimer = -super->subtimer;
|
|
SoundReq(SFX_19E);
|
|
}
|
|
} else if ((s8)this->unk_79 > super->timer) {
|
|
super->subtimer = -super->subtimer;
|
|
SoundReq(SFX_19E);
|
|
}
|
|
}
|
|
END_NONMATCH
|
|
|
|
void FrozenOctorok_ChangeObjPaletteOfChildren(FrozenOctorokEntity* this, u32 palette) {
|
|
u32 index;
|
|
|
|
ChangeObjPalette(&this->heap->mouthObject->base, palette);
|
|
for (index = 0; index < 4; index++) {
|
|
ChangeObjPalette(&this->heap->legObjects[index]->base, palette);
|
|
}
|
|
}
|