mirror of https://github.com/zeldaret/tmc.git
473 lines
14 KiB
C
473 lines
14 KiB
C
#include "functions.h"
|
|
#include "npc.h"
|
|
#include "item.h"
|
|
|
|
extern void sub_0806A8C8(Entity*);
|
|
|
|
extern void script_Rem;
|
|
|
|
extern void sub_0807F950(Entity* this, ScriptExecutionContext* context);
|
|
|
|
void sub_0806A9B0(Entity*, ScriptExecutionContext*);
|
|
void sub_0806A914(Entity* this);
|
|
|
|
void sub_0806a370(Entity* this);
|
|
void sub_0806A5E8(Entity* this);
|
|
void sub_0806A630(Entity* this);
|
|
void sub_0806A674(Entity* this);
|
|
void sub_0806A830(Entity* this);
|
|
void sub_0806A890(Entity* this);
|
|
|
|
void sub_0806A3D8(Entity* this);
|
|
void sub_0806A410(Entity* this);
|
|
void sub_0806A458(Entity* this);
|
|
void sub_0806A4CC(Entity* this);
|
|
void sub_0806A550(Entity* this);
|
|
void nullsub_503(Entity* this);
|
|
void sub_0806A5C0(Entity* this);
|
|
|
|
void Rem(Entity* this) {
|
|
static void (*const typeFuncs[])(Entity*) = {
|
|
sub_0806a370, sub_0806A5E8, sub_0806A630, sub_0806A674, sub_0806A830, sub_0806A890,
|
|
};
|
|
typeFuncs[this->type](this);
|
|
}
|
|
|
|
void sub_0806a370(Entity* this) {
|
|
static void (*const actionFuncs[])(Entity*) = {
|
|
sub_0806A3D8, sub_0806A410, sub_0806A458, sub_0806A4CC, sub_0806A550, nullsub_503, sub_0806A5C0,
|
|
};
|
|
|
|
actionFuncs[this->action](this);
|
|
ExecuteScriptForEntity(this, NULL);
|
|
HandleEntity0x82Actions(this);
|
|
UpdateAnimationSingleFrame(this);
|
|
sub_0806ED78(this);
|
|
if (this->animIndex == 0xf) {
|
|
if (this->frame == 1) {
|
|
this->frame = 0;
|
|
SoundReq(SFX_218);
|
|
}
|
|
if (this->frame == 2) {
|
|
this->frame = 0;
|
|
SoundReq(SFX_219);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_0806A3D8(Entity* this) {
|
|
this->action = 1;
|
|
this->timer = 180;
|
|
SetDefaultPriority(this, PRIO_MESSAGE);
|
|
sub_0806A8C8(this);
|
|
*(ScriptExecutionContext**)&this->cutsceneBeh = StartCutscene(this, &script_Rem);
|
|
sub_0807DD94(this, NULL);
|
|
}
|
|
|
|
void sub_0806A410(Entity* this) {
|
|
switch (this->subAction) {
|
|
case 0:
|
|
if (--this->timer == 0) {
|
|
this->subAction++;
|
|
InitializeAnimation(this, 8);
|
|
}
|
|
break;
|
|
case 1:
|
|
if (((this->frame & ANIM_DONE) != 0)) {
|
|
sub_0806A9B0(this, *(ScriptExecutionContext**)&this->cutsceneBeh);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sub_0806A458(Entity* this) {
|
|
switch (this->subAction) {
|
|
case 0:
|
|
if (--this->timer == 0) {
|
|
this->subAction += 1;
|
|
}
|
|
break;
|
|
case 1:
|
|
if ((this->frame & ANIM_DONE) != 0) {
|
|
this->subAction = 2;
|
|
InitializeAnimation(this, 10);
|
|
ClearLocalFlag(0x62);
|
|
}
|
|
break;
|
|
case 2:
|
|
if (((this->frame & ANIM_DONE) != 0)) {
|
|
this->action = 1;
|
|
this->subAction = 0;
|
|
this->timer = 60;
|
|
InitializeAnimation(this, 2);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sub_0806A4CC(Entity* this) {
|
|
switch (this->subAction) {
|
|
case 0:
|
|
if ((this->frame & ANIM_DONE) != 0) {
|
|
if ((u8)(this->animIndex - 8) < 2) {
|
|
this->subAction = 1;
|
|
this->field_0x6a.HWORD = 1;
|
|
InitializeAnimation(this, 10);
|
|
} else {
|
|
this->subAction = 2;
|
|
this->field_0x6a.HWORD = 0;
|
|
InitializeAnimation(this, GetAnimationState(this));
|
|
}
|
|
break;
|
|
case 1:
|
|
if ((this->frame & ANIM_DONE) != 0) {
|
|
this->subAction = 2;
|
|
InitializeAnimation(this, GetAnimationState(this));
|
|
}
|
|
break;
|
|
default:
|
|
this->timer = 180;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_0806A550(Entity* this) {
|
|
if (this->subAction == 0) {
|
|
this->subAction = 1;
|
|
InitializeAnimation(this, 0xc);
|
|
} else {
|
|
if (this->frame == 1) {
|
|
this->frame = 0;
|
|
InitScreenShake(8, 2);
|
|
gActiveScriptInfo.syncFlags |= 0x100;
|
|
SoundReq(SFX_CHEST_OPEN);
|
|
}
|
|
if ((this->frame & ANIM_DONE) != 0) {
|
|
this->action = 5;
|
|
this->subAction = 0;
|
|
InitializeAnimation(this, 0xd);
|
|
sub_0806A914(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
void nullsub_503(Entity* this) {
|
|
}
|
|
|
|
void sub_0806A5C0(Entity* this) {
|
|
GetNextFrame(this);
|
|
if ((this->frame & ANIM_DONE) != 0) {
|
|
InitializeAnimation(this, (Random() & 3) + 4);
|
|
}
|
|
}
|
|
|
|
void sub_0806A5E8(Entity* this) {
|
|
if (this->action == 0) {
|
|
this->action = 1;
|
|
InitializeAnimation(this, 0x10);
|
|
this->timer = (Random() & 0x3f) + 60;
|
|
}
|
|
this->timer -= 1;
|
|
if (this->timer == 0) {
|
|
this->timer = (Random() & 0x3f) + 120;
|
|
SoundReq(SFX_REM_SLEEP);
|
|
}
|
|
GetNextFrame(this);
|
|
}
|
|
|
|
void sub_0806A630(Entity* this) {
|
|
if (this->action == 0) {
|
|
this->action = 1;
|
|
InitializeAnimation(this, 0x12);
|
|
}
|
|
if ((gActiveScriptInfo.syncFlags & 0x100) != 0) {
|
|
GetNextFrame(this);
|
|
}
|
|
if (this->frame == 1) {
|
|
this->frame = 0;
|
|
SoundReq(SFX_SECRET);
|
|
}
|
|
}
|
|
|
|
void sub_0806A674(Entity* this) {
|
|
static const u8 gUnk_08112294[] = { 0, -1, 0, 1, 0, -1, 0, 1 };
|
|
u32 rand;
|
|
u8 auStack16[8];
|
|
|
|
memcpy(auStack16, &gUnk_08112294, 8);
|
|
switch (this->action) {
|
|
case 0:
|
|
this->action = 1;
|
|
this->spritePriority.b0 = 6;
|
|
InitializeAnimation(this, 0x13);
|
|
break;
|
|
case 1:
|
|
if ((gActiveScriptInfo.syncFlags & 0x100) != 0) {
|
|
this->action = 2;
|
|
this->spriteOffsetY = 0;
|
|
this->spriteOffsetX = 0;
|
|
} else {
|
|
if (this->parent->animIndex == 9) {
|
|
this->spritePriority.b0 = 3;
|
|
|
|
if (this->timer == 0) {
|
|
rand = Random();
|
|
this->timer = rand & 7;
|
|
this->field_0x68.HALF.LO = auStack16[rand >> 8 & 7];
|
|
} else if ((gRoomTransition.frameCount & 3U) == 0) {
|
|
this->timer--;
|
|
if ((s8)this->spriteOffsetX < 1) {
|
|
this->field_0x68.HALF.LO = 1;
|
|
}
|
|
|
|
if (0xf < (s8)this->spriteOffsetX) {
|
|
this->field_0x68.HALF.LO = -1;
|
|
}
|
|
this->spriteOffsetX += this->field_0x68.HALF.LO;
|
|
}
|
|
|
|
if (this->subtimer == 0) {
|
|
rand = Random();
|
|
this->subtimer = rand & 7;
|
|
this->field_0x68.HALF.HI = auStack16[rand >> 8 & 7];
|
|
} else if (((u32)gRoomTransition.frameCount >> 4 & 3) == 0) {
|
|
this->subtimer--;
|
|
if (-1 < this->spriteOffsetY) {
|
|
this->field_0x68.HALF.HI = -1;
|
|
}
|
|
|
|
if (this->spriteOffsetY <= -8) {
|
|
this->field_0x68.HALF.HI = 1;
|
|
}
|
|
this->spriteOffsetY += this->field_0x68.HALF.HI;
|
|
}
|
|
} else {
|
|
this->spritePriority.b0 = 6;
|
|
if ((s8)this->spriteOffsetX != 0) {
|
|
if (0 < (s8)this->spriteOffsetX) {
|
|
this->spriteOffsetX--;
|
|
}
|
|
|
|
if ((s8)this->spriteOffsetX < 0) {
|
|
this->spriteOffsetX++;
|
|
}
|
|
}
|
|
|
|
if (this->spriteOffsetY != 0) {
|
|
if (0 < this->spriteOffsetY) {
|
|
this->spriteOffsetY--;
|
|
}
|
|
|
|
if (this->spriteOffsetY < 0) {
|
|
this->spriteOffsetY++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
case 2:
|
|
GetNextFrame(this);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sub_0806A830(Entity* this) {
|
|
Entity* npc;
|
|
|
|
if (this->action == 0) {
|
|
this->action = 1;
|
|
InitializeAnimation(this, 0x14);
|
|
SetDefaultPriority(this, PRIO_MESSAGE);
|
|
}
|
|
if ((gActiveScriptInfo.syncFlags & 0x200) != 0) {
|
|
DeleteThisEntity();
|
|
}
|
|
GetNextFrame(this);
|
|
if (this->frame == 1) {
|
|
this->frame = 0;
|
|
npc = CreateNPC(REM, 5, 0);
|
|
if (npc != NULL) {
|
|
PositionEntityOnTop(this, npc);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_0806A890(Entity* this) {
|
|
if (this->action == 0) {
|
|
this->action = 1;
|
|
InitializeAnimation(this, 0x15);
|
|
SetDefaultPriority(this, PRIO_MESSAGE);
|
|
}
|
|
GetNextFrame(this);
|
|
if ((this->frame & ANIM_DONE) != 0) {
|
|
DeleteThisEntity();
|
|
}
|
|
}
|
|
|
|
void sub_0806A8C8(Entity* this) {
|
|
Entity* entity;
|
|
if ((CheckLocalFlag(SHOP02_KUTSU_00) == 0) && (entity = CreateNPC(REM, 2, 0), entity != NULL)) {
|
|
CopyPosition(this, entity);
|
|
entity->parent = this;
|
|
}
|
|
entity = CreateNPC(REM, 3, 0);
|
|
if (entity != NULL) {
|
|
CopyPosition(this, entity);
|
|
entity->y.HALF.HI += 2;
|
|
entity->parent = this;
|
|
}
|
|
}
|
|
|
|
void sub_0806A914(Entity* this) {
|
|
Entity* npc = CreateNPC(REM, 1, 0);
|
|
if (npc != NULL) {
|
|
CopyPosition(this, npc);
|
|
SortEntityAbove(this, npc);
|
|
}
|
|
}
|
|
|
|
void sub_0806A93C(Entity* this) {
|
|
static const u8 gUnk_0811229C[] = { 0, 6, 10, 16 };
|
|
sub_08078778(this);
|
|
sub_08078850(this, 0, 0, &gUnk_0811229C);
|
|
}
|
|
|
|
void sub_0806A958(Entity* this) {
|
|
if (this->action != 5) {
|
|
gActiveScriptInfo.commandSize = 0;
|
|
}
|
|
}
|
|
|
|
void sub_0806A96C(Entity* this, ScriptExecutionContext* context) {
|
|
context->condition = 0;
|
|
if (this->interactType != 0) {
|
|
if (this->action != 3) {
|
|
this->action = 3;
|
|
this->subAction = 0;
|
|
} else {
|
|
if (this->subAction > 1) {
|
|
this->interactType = 0;
|
|
context->condition = 1;
|
|
gActiveScriptInfo.flags |= 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_0806A9B0(Entity* this, ScriptExecutionContext* context) {
|
|
static const u8 gUnk_081122A0[] = { 60, 100, 200, 60, 100, 200, 80, 80 };
|
|
this->action = 2;
|
|
this->subAction = 0;
|
|
this->timer = gUnk_081122A0[Random() & 7];
|
|
this->field_0x80.HWORD = 9;
|
|
InitializeAnimation(this, 9);
|
|
SetLocalFlag(NPC37_REM_SLEEP);
|
|
}
|
|
|
|
void sub_0806A9E8(Entity* this) {
|
|
Entity* npc = CreateNPC(REM, 4, 0);
|
|
if (npc != NULL) {
|
|
CopyPosition(this, npc);
|
|
SortEntityBelow(this, npc);
|
|
}
|
|
}
|
|
|
|
void sub_0806AA10(Entity* this) {
|
|
sub_0806A914(this);
|
|
}
|
|
|
|
void sub_0806AA18(Entity* this) {
|
|
u32 index;
|
|
if (this->field_0x6a.HWORD != 0) {
|
|
index = TEXT_INDEX(TEXT_REM, 0x8);
|
|
} else if ((gRoomTransition.frameCount & 1) == 0) {
|
|
index = TEXT_INDEX(TEXT_REM, 0x7);
|
|
} else {
|
|
index = TEXT_INDEX(TEXT_REM, 0xd);
|
|
}
|
|
MessageNoOverlap(index, this);
|
|
}
|
|
|
|
void sub_0806AA50(Entity* this, ScriptExecutionContext* context) {
|
|
static const u16 gUnk_081122A8[] = { TEXT_INDEX(TEXT_REM, 0x1c), TEXT_INDEX(TEXT_REM, 0x1d),
|
|
TEXT_INDEX(TEXT_REM, 0x1e), 0 };
|
|
static const u16 gUnk_081122B0[] = { TEXT_INDEX(TEXT_REM, 0x1f), TEXT_INDEX(TEXT_REM, 0x20),
|
|
TEXT_INDEX(TEXT_REM, 0x21), 0 };
|
|
static const u16 gUnk_081122B8[] = { TEXT_INDEX(TEXT_REM, 0x10), TEXT_INDEX(TEXT_REM, 0x11),
|
|
TEXT_INDEX(TEXT_REM, 0x12), 0 };
|
|
s32 messageIndex;
|
|
Entity* pEnt;
|
|
|
|
switch (context->unk_18) {
|
|
case 0:
|
|
context->condition = 0;
|
|
if (CheckLocalFlag(0x8f) == 0) {
|
|
messageIndex = gUnk_081122A8[gRoomVars.animFlags];
|
|
} else if (GetInventoryValue(ITEM_PEGASUS_BOOTS) == 0) {
|
|
messageIndex = gUnk_081122B0[gRoomVars.animFlags];
|
|
} else {
|
|
messageIndex = gUnk_081122B8[gRoomVars.animFlags];
|
|
}
|
|
|
|
if (++gRoomVars.animFlags > 2) {
|
|
gRoomVars.animFlags = 0;
|
|
}
|
|
MessageNoOverlap(messageIndex, this);
|
|
switch (context->intVariable) {
|
|
case 0:
|
|
gRoomVars.entities[0] = this;
|
|
PrependEntityToList(this, NPC);
|
|
this->zVelocity = Q_16_16(1.5);
|
|
break;
|
|
case 1:
|
|
pEnt = FindNextDuplicateID(gRoomVars.entities[0], NPC);
|
|
gRoomVars.entities[1] = pEnt;
|
|
pEnt->zVelocity = Q_16_16(1.5);
|
|
break;
|
|
case 2:
|
|
pEnt = FindNextDuplicateID(gRoomVars.entities[1], NPC);
|
|
gRoomVars.entities[2] = pEnt;
|
|
pEnt->zVelocity = Q_16_16(1.5);
|
|
break;
|
|
}
|
|
if (messageIndex == TEXT_INDEX(TEXT_REM, 0x1e)) {
|
|
SetLocalFlag(0x8f);
|
|
context->condition = 1;
|
|
}
|
|
context->unk_18 = 1;
|
|
break;
|
|
case 1:
|
|
pEnt = gRoomVars.entities[context->intVariable];
|
|
if (pEnt->z.HALF.HI < 0) {
|
|
break;
|
|
}
|
|
pEnt->zVelocity = Q_16_16(1.5);
|
|
context->unk_18 = 2;
|
|
break;
|
|
case 2:
|
|
if (this->z.HALF.HI >= 0) {
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
|
|
gActiveScriptInfo.commandSize = 0;
|
|
}
|
|
|
|
void sub_0806AB74(Entity* this) {
|
|
gRoomVars.field_0x3 = 1;
|
|
if ((s32)(this->y.HALF.HI - (u32)gRoomControls.origin_y) < 0xa8) {
|
|
this->y.HALF.HI = gRoomControls.origin_y + 0xa8;
|
|
}
|
|
}
|
|
|
|
void sub_0806AB9C(Entity* this, ScriptExecutionContext* context) {
|
|
Entity* entity = FindEntity(NPC, REM, NPC, 1, 0);
|
|
if (entity != NULL) {
|
|
DeleteEntity(entity);
|
|
}
|
|
sub_0807F950(this, context);
|
|
}
|