mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-08-13 17:03:47 -04:00
d45968270a
* prefix randomizer methods with Randomizer_ * make filename a local var * remove unused file, update malon to use new names * move randomizertypes to randomizer directory * rename to Randomizer_GetSettingValue Co-authored-by: briaguya <briaguya@alice>
2106 lines
77 KiB
C
2106 lines
77 KiB
C
#include "z_en_go2.h"
|
|
#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
|
|
#include "objects/gameplay_keep/gameplay_keep.h"
|
|
#include "objects/object_oF1d_map/object_oF1d_map.h"
|
|
|
|
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3 | ACTOR_FLAG_4 | ACTOR_FLAG_5)
|
|
|
|
/*
|
|
FLAGS
|
|
|
|
gSaveContext.eventChkInf[2] & 0x8 - DC entrance boulder blown up as child
|
|
|
|
InfTable
|
|
|
|
gSaveContext.infTable[11] & 0x10
|
|
gSaveContext.infTable[14] & 0x1 - Talked to DMT Goron at DC entrance (Before DC is opened as child)
|
|
gSaveContext.infTable[14] & 0x8 - Talked to GC Goron in bottom level stairwell
|
|
gSaveContext.infTable[14] & 0x40 - Talked to GC Goron at LW entrance (Before LW shortcut is opened)
|
|
gSaveContext.infTable[14] & 0x800 - Talked to DMT Goron at Bomb Flower with goron bracelet
|
|
gSaveContext.infTable[15] & 0x1 - Talked to Goron at GC Entrance (Before goron ruby is obtained)
|
|
gSaveContext.infTable[15] & 0x10 - Talked to Goron at GC Island (Before goron ruby is obtained)
|
|
gSaveContext.infTable[15] & 0x100 - (not on cloud modding) Talked to GC Goron outside Darunias door (after opening door,
|
|
before getting goron bracelet) gSaveContext.infTable[16] & 0x200 - Obtained Fire Tunic from Goron Link
|
|
gSaveContext.infTable[16] & 0x400 - (not on cloud modding)
|
|
gSaveContext.infTable[16] & 0x800 - Spoke to Goron Link About Volvagia
|
|
gSaveContext.infTable[16] & 0x1000 - Stopped Goron Link's Rolling
|
|
gSaveContext.infTable[16] & 0x2000 - EnGo Exclusive
|
|
gSaveContext.infTable[16] & 0x4000 - Spoke to Goron Link
|
|
gSaveContext.infTable[16] & 0x8000 - (not on cloud modding)
|
|
|
|
gSaveContext.infTable[17] & 0x4000 - Bomb bag upgrade obtained from rolling Goron
|
|
|
|
EnGo
|
|
pathIndex: this->actor.params & 0xF
|
|
Goron: this->actor.params & 0xF0
|
|
|
|
EnGo2
|
|
(this->actor.params & 0x3E0) >> 5
|
|
(this->actor.params & 0xFC00) >> 0xA - Gorons in Fire Temple
|
|
this->actor.params & 0x1F
|
|
|
|
Gorons only move when this->unk_194.unk_00 == 0
|
|
*/
|
|
|
|
void EnGo2_Init(Actor* thisx, GlobalContext* globalCtx);
|
|
void EnGo2_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|
void EnGo2_Update(Actor* thisx, GlobalContext* globalCtx);
|
|
void EnGo2_Draw(Actor* thisx, GlobalContext* globalCtx);
|
|
|
|
void EnGo2_StopRolling(EnGo2* this, GlobalContext* globalCtx);
|
|
void EnGo2_CurledUp(EnGo2* this, GlobalContext* globalCtx);
|
|
|
|
void func_80A46B40(EnGo2* this, GlobalContext* globalCtx);
|
|
void EnGo2_GoronDmtBombFlowerAnimation(EnGo2* this, GlobalContext* globalCtx);
|
|
void EnGo2_GoronRollingBigContinueRolling(EnGo2* this, GlobalContext* globalCtx);
|
|
void EnGo2_ContinueRolling(EnGo2* this, GlobalContext* globalCtx);
|
|
void EnGo2_SlowRolling(EnGo2* this, GlobalContext* globalCtx);
|
|
void EnGo2_GroundRolling(EnGo2* this, GlobalContext* globalCtx);
|
|
|
|
void EnGo2_ReverseRolling(EnGo2* this, GlobalContext* globalCtx);
|
|
void EnGo2_SetupGetItem(EnGo2* this, GlobalContext* globalCtx);
|
|
void EnGo2_SetGetItem(EnGo2* this, GlobalContext* globalCtx);
|
|
void EnGo2_BiggoronEyedrops(EnGo2* this, GlobalContext* globalCtx);
|
|
void EnGo2_GoronLinkStopRolling(EnGo2* this, GlobalContext* globalCtx);
|
|
void EnGo2_GoronFireGenericAction(EnGo2* this, GlobalContext* globalCtx);
|
|
|
|
static void* sDustTex[] = { gDust8Tex, gDust7Tex, gDust6Tex, gDust5Tex, gDust4Tex, gDust3Tex, gDust2Tex, gDust1Tex };
|
|
|
|
static Vec3f sPos = { 0.0f, 0.0f, 0.0f };
|
|
static Vec3f sVelocity = { 0.0f, 0.0f, 0.0f };
|
|
static Vec3f sAccel = { 0.0f, 0.3f, 0.0f };
|
|
|
|
static ColliderCylinderInit sCylinderInit = {
|
|
{
|
|
COLTYPE_NONE,
|
|
AT_NONE,
|
|
AC_ON | AC_TYPE_PLAYER,
|
|
OC1_ON | OC1_TYPE_ALL,
|
|
OC2_TYPE_2,
|
|
COLSHAPE_CYLINDER,
|
|
},
|
|
{
|
|
ELEMTYPE_UNK0,
|
|
{ 0x00000000, 0x00, 0x00 },
|
|
{ 0x00000008, 0x00, 0x00 },
|
|
TOUCH_NONE,
|
|
BUMP_NONE,
|
|
OCELEM_ON,
|
|
},
|
|
{ 40, 65, 0, { 0, 0, 0 } },
|
|
};
|
|
|
|
static CollisionCheckInfoInit2 sColChkInfoInit = {
|
|
0, 0, 0, 0, MASS_IMMOVABLE,
|
|
};
|
|
|
|
const ActorInit En_Go2_InitVars = {
|
|
ACTOR_EN_GO2,
|
|
ACTORCAT_NPC,
|
|
FLAGS,
|
|
OBJECT_OF1D_MAP,
|
|
sizeof(EnGo2),
|
|
(ActorFunc)EnGo2_Init,
|
|
(ActorFunc)EnGo2_Destroy,
|
|
(ActorFunc)EnGo2_Update,
|
|
(ActorFunc)EnGo2_Draw,
|
|
NULL,
|
|
};
|
|
|
|
static EnGo2DataStruct1 D_80A4816C[14] = {
|
|
{ 0, 0, 0, 68, 148 }, { 0, 0, 0, 24, 52 }, { 0, 320, 380, 400, 120 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 46, 90 },
|
|
{ 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 },
|
|
{ 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 }, { 0, 0, 0, 30, 68 },
|
|
};
|
|
|
|
static EnGo2DataStruct2 D_80A481F8[14] = {
|
|
{ 30.0f, 0.026f, 6, 60.0f }, { 24.0f, 0.008f, 6, 30.0f }, { 28.0f, 0.16f, 5, 380.0f }, { 28.0f, 0.01f, 7, 40.0f },
|
|
{ 30.0f, 0.015f, 6, 30.0f }, { 28.0f, 0.01f, 6, 30.0f }, { 28.0f, 0.01f, 6, 30.0f }, { 28.0f, 0.01f, 6, 30.0f },
|
|
{ 28.0f, 0.01f, 6, 30.0f }, { 28.0f, 0.01f, 6, 30.0f }, { 28.0f, 0.01f, 6, 30.0f }, { 28.0f, 0.01f, 6, 30.0f },
|
|
{ 28.0f, 0.01f, 6, 30.0f }, { 28.0f, 0.01f, 6, 30.0f },
|
|
};
|
|
|
|
static f32 D_80A482D8[14][2] = {
|
|
{ 80.0f, 80.0f }, { -10.0f, -10.0f }, { 800.0f, 800.0f }, { 0.0f, 0.0f }, { 20.0f, 40.0f },
|
|
{ 20.0f, 20.0f }, { 20.0f, 20.0f }, { 20.0f, 20.0f }, { 20.0f, 20.0f }, { 20.0f, 20.0f },
|
|
{ 20.0f, 20.0f }, { 20.0f, 20.0f }, { 20.0f, 20.0f }, { 20.0f, 20.0f },
|
|
};
|
|
|
|
typedef enum {
|
|
/* 0 */ ENGO2_ANIM_0,
|
|
/* 1 */ ENGO2_ANIM_1,
|
|
/* 2 */ ENGO2_ANIM_2,
|
|
/* 3 */ ENGO2_ANIM_3,
|
|
/* 4 */ ENGO2_ANIM_4,
|
|
/* 5 */ ENGO2_ANIM_5,
|
|
/* 6 */ ENGO2_ANIM_6,
|
|
/* 7 */ ENGO2_ANIM_7,
|
|
/* 8 */ ENGO2_ANIM_8,
|
|
/* 9 */ ENGO2_ANIM_9,
|
|
/* 10 */ ENGO2_ANIM_10,
|
|
/* 11 */ ENGO2_ANIM_11,
|
|
/* 12 */ ENGO2_ANIM_12
|
|
} EnGo2Animation;
|
|
|
|
static AnimationInfo sAnimationInfo[] = {
|
|
{ &gGoronAnim_004930, 0.0f, 0.0f, -1.0f, 0x00, 0.0f }, { &gGoronAnim_004930, 0.0f, 0.0f, -1.0f, 0x00, -8.0f },
|
|
{ &gGoronAnim_0029A8, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, { &gGoronAnim_010590, 1.0f, 0.0f, -1.0f, 0x00, -8.0f },
|
|
{ &gGoronAnim_003768, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, { &gGoronAnim_0038E4, 1.0f, 0.0f, -1.0f, 0x02, -8.0f },
|
|
{ &gGoronAnim_002D80, 1.0f, 0.0f, -1.0f, 0x02, -8.0f }, { &gGoronAnim_00161C, 1.0f, 0.0f, -1.0f, 0x00, -8.0f },
|
|
{ &gGoronAnim_001A00, 1.0f, 0.0f, -1.0f, 0x00, -8.0f }, { &gGoronAnim_0021D0, 1.0f, 0.0f, -1.0f, 0x00, -8.0f },
|
|
{ &gGoronAnim_004930, 0.0f, 0.0f, -1.0f, 0x01, -8.0f }, { &gGoronAnim_000750, 1.0f, 0.0f, -1.0f, 0x00, -8.0f },
|
|
{ &gGoronAnim_000D5C, 1.0f, 0.0f, -1.0f, 0x00, -8.0f },
|
|
};
|
|
|
|
static EnGo2DustEffectData sDustEffectData[2][4] = {
|
|
{
|
|
{ 12, 0.2f, 0.2f, 1, 18.0f, 0.0f },
|
|
{ 12, 0.1f, 0.2f, 12, 26.0f, 0.0f },
|
|
{ 12, 0.1f, 0.3f, 4, 10.0f, 0.0f },
|
|
{ 12, 0.2f, 0.2f, 1, 18.0f, 0.0f },
|
|
},
|
|
{
|
|
{ 12, 0.5f, 0.4f, 3, 42.0f, 0.0f },
|
|
{ 12, 0.5f, 0.4f, 3, 42.0f, 0.0f },
|
|
{ 12, 0.5f, 0.4f, 3, 42.0f, 0.0f },
|
|
{ 12, 0.5f, 0.4f, 3, 42.0f, 0.0f },
|
|
},
|
|
};
|
|
|
|
static Vec3f sZeroVec = { 0.0f, 0.0f, 0.0f };
|
|
|
|
void EnGo2_AddDust(EnGo2* this, Vec3f* pos, Vec3f* velocity, Vec3f* accel, u8 initialTimer, f32 scale, f32 scaleStep) {
|
|
EnGoEffect* dustEffect = this->dustEffects;
|
|
s16 i;
|
|
s16 timer;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(this->dustEffects); i++, dustEffect++) {
|
|
if (dustEffect->type != 1) {
|
|
dustEffect->scale = scale;
|
|
dustEffect->scaleStep = scaleStep;
|
|
timer = initialTimer;
|
|
dustEffect->timer = timer;
|
|
dustEffect->type = 1;
|
|
dustEffect->initialTimer = initialTimer;
|
|
dustEffect->pos = *pos;
|
|
dustEffect->accel = *accel;
|
|
dustEffect->velocity = *velocity;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnGo2_UpdateDust(EnGo2* this) {
|
|
EnGoEffect* dustEffect = this->dustEffects;
|
|
f32 randomNumber;
|
|
s16 i;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(this->dustEffects); i++, dustEffect++) {
|
|
if (dustEffect->type) {
|
|
dustEffect->timer--;
|
|
if (dustEffect->timer == 0) {
|
|
dustEffect->type = 0;
|
|
}
|
|
dustEffect->accel.x = (Rand_ZeroOne() * 0.4f) - 0.2f;
|
|
randomNumber = Rand_ZeroOne() * 0.4f;
|
|
dustEffect->accel.z = randomNumber - 0.2f;
|
|
dustEffect->pos.x += dustEffect->velocity.x;
|
|
dustEffect->pos.y += dustEffect->velocity.y;
|
|
dustEffect->pos.z += dustEffect->velocity.z;
|
|
dustEffect->velocity.x += dustEffect->accel.x;
|
|
dustEffect->velocity.y += dustEffect->accel.y;
|
|
dustEffect->velocity.z += randomNumber - 0.2f;
|
|
dustEffect->scale += dustEffect->scaleStep;
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnGo2_DrawDust(EnGo2* this, GlobalContext* globalCtx) {
|
|
EnGoEffect* dustEffect = this->dustEffects;
|
|
s16 alpha;
|
|
s16 firstDone;
|
|
s16 index;
|
|
s16 i;
|
|
|
|
OPEN_DISPS(globalCtx->state.gfxCtx);
|
|
|
|
firstDone = false;
|
|
func_80093D84(globalCtx->state.gfxCtx);
|
|
|
|
for (i = 0; i < ARRAY_COUNT(this->dustEffects); i++, dustEffect++) {
|
|
if (dustEffect->type) {
|
|
if (!firstDone) {
|
|
POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0);
|
|
gSPDisplayList(POLY_XLU_DISP++, gGoronDL_00FD40);
|
|
gDPSetEnvColor(POLY_XLU_DISP++, 100, 60, 20, 0);
|
|
firstDone = true;
|
|
}
|
|
|
|
alpha = dustEffect->timer * (255.0f / dustEffect->initialTimer);
|
|
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 170, 130, 90, alpha);
|
|
gDPPipeSync(POLY_XLU_DISP++);
|
|
Matrix_Translate(dustEffect->pos.x, dustEffect->pos.y, dustEffect->pos.z, MTXMODE_NEW);
|
|
Matrix_ReplaceRotation(&globalCtx->billboardMtxF);
|
|
Matrix_Scale(dustEffect->scale, dustEffect->scale, 1.0f, MTXMODE_APPLY);
|
|
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
|
|
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
index = dustEffect->timer * (8.0f / dustEffect->initialTimer);
|
|
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sDustTex[index]));
|
|
gSPDisplayList(POLY_XLU_DISP++, gGoronDL_00FD50);
|
|
}
|
|
}
|
|
|
|
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
|
}
|
|
|
|
s32 EnGo2_SpawnDust(EnGo2* this, u8 initialTimer, f32 scale, f32 scaleStep, s32 numDustEffects, f32 radius,
|
|
f32 yAccel) {
|
|
Vec3f pos = sPos;
|
|
Vec3f velocity = sVelocity;
|
|
Vec3f accel = sAccel;
|
|
s32 i;
|
|
s16 angle;
|
|
|
|
pos = this->actor.world.pos; // overwrites sPos data
|
|
pos.y = this->actor.floorHeight;
|
|
angle = (Rand_ZeroOne() - 0.5f) * 0x10000;
|
|
i = numDustEffects;
|
|
while (i >= 0) {
|
|
accel.y += Rand_ZeroOne() * yAccel;
|
|
pos.x = (Math_SinS(angle) * radius) + this->actor.world.pos.x;
|
|
pos.z = (Math_CosS(angle) * radius) + this->actor.world.pos.z;
|
|
EnGo2_AddDust(this, &pos, &velocity, &accel, initialTimer, scale, scaleStep);
|
|
angle += (s16)(0x10000 / numDustEffects);
|
|
i--;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void EnGo2_GetItem(EnGo2* this, GlobalContext* globalCtx, s32 getItemId) {
|
|
this->getItemId = getItemId;
|
|
func_8002F434(&this->actor, globalCtx, getItemId, this->actor.xzDistToPlayer + 1.0f,
|
|
fabsf(this->actor.yDistToPlayer) + 1.0f);
|
|
}
|
|
|
|
s32 EnGo2_GetDialogState(EnGo2* this, GlobalContext* globalCtx) {
|
|
s16 dialogState = Message_GetState(&globalCtx->msgCtx);
|
|
|
|
if ((this->dialogState == TEXT_STATE_AWAITING_NEXT) || (this->dialogState == TEXT_STATE_EVENT) ||
|
|
(this->dialogState == TEXT_STATE_CLOSING) || (this->dialogState == TEXT_STATE_DONE_HAS_NEXT)) {
|
|
if (dialogState != this->dialogState) {
|
|
this->unk_20C++;
|
|
}
|
|
}
|
|
|
|
this->dialogState = dialogState;
|
|
return dialogState;
|
|
}
|
|
|
|
u16 EnGo2_GoronFireGenericGetTextId(EnGo2* this) {
|
|
switch ((this->actor.params & 0xFC00) >> 0xA) {
|
|
case 3:
|
|
return 0x3069;
|
|
case 5:
|
|
return 0x306A;
|
|
case 4:
|
|
return 0x306B;
|
|
case 2:
|
|
return 0x306C;
|
|
case 10:
|
|
return 0x306D;
|
|
case 8:
|
|
return 0x306E;
|
|
case 11:
|
|
return 0x306F;
|
|
case 1:
|
|
return 0x3070;
|
|
default:
|
|
return 0x3052;
|
|
}
|
|
}
|
|
|
|
u16 EnGo2_GetTextIdGoronCityRollingBig(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (gSaveContext.infTable[17] & 0x4000) {
|
|
return 0x3013;
|
|
} else if ((CUR_CAPACITY(UPG_BOMB_BAG) >= 20 || gSaveContext.n64ddFlag) && this->waypoint > 7 && this->waypoint < 12) {
|
|
return 0x3012;
|
|
} else {
|
|
return 0x3011;
|
|
}
|
|
}
|
|
|
|
s16 EnGo2_GetStateGoronCityRollingBig(GlobalContext* globalCtx, EnGo2* this) {
|
|
s32 bombBagUpgrade;
|
|
|
|
switch (Message_GetState(&globalCtx->msgCtx)) {
|
|
case TEXT_STATE_CLOSING:
|
|
return 2;
|
|
case TEXT_STATE_EVENT:
|
|
if (Message_ShouldAdvance(globalCtx)) {
|
|
if (this->actor.textId == 0x3012) {
|
|
this->actionFunc = EnGo2_SetupGetItem;
|
|
if(!gSaveContext.n64ddFlag) {
|
|
bombBagUpgrade = CUR_CAPACITY(UPG_BOMB_BAG) == 30 ? GI_BOMB_BAG_40 : GI_BOMB_BAG_30;
|
|
} else {
|
|
bombBagUpgrade = Randomizer_GetItemIdFromKnownCheck(RC_GC_ROLLING_GORON_AS_CHILD, GI_BOMB_BAG_40);
|
|
}
|
|
EnGo2_GetItem(this, globalCtx, bombBagUpgrade);
|
|
Message_CloseTextbox(globalCtx);
|
|
gSaveContext.infTable[17] |= 0x4000;
|
|
return 2;
|
|
} else {
|
|
return 2;
|
|
}
|
|
}
|
|
default:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
u16 EnGo2_GetTextIdGoronDmtBombFlower(GlobalContext* globalCtx, EnGo2* this) {
|
|
return CHECK_QUEST_ITEM(QUEST_GORON_RUBY) ? 0x3027 : 0x300A;
|
|
}
|
|
|
|
// DMT Goron by Bomb Flower Choice
|
|
s16 EnGo2_GetStateGoronDmtBombFlower(GlobalContext* globalCtx, EnGo2* this) {
|
|
switch (Message_GetState(&globalCtx->msgCtx)) {
|
|
case TEXT_STATE_CLOSING:
|
|
if ((this->actor.textId == 0x300B) && (gSaveContext.infTable[14] & 0x800) == 0) {
|
|
gSaveContext.infTable[14] |= 0x800;
|
|
return 2;
|
|
} else {
|
|
return 0;
|
|
}
|
|
case TEXT_STATE_CHOICE:
|
|
if (Message_ShouldAdvance(globalCtx)) {
|
|
// Ask question to DMT Goron by bomb flower
|
|
if (this->actor.textId == 0x300A) {
|
|
if (globalCtx->msgCtx.choiceIndex == 0) {
|
|
this->actor.textId = CUR_UPG_VALUE(UPG_STRENGTH) != 0 ? 0x300B : 0x300C;
|
|
} else {
|
|
this->actor.textId = 0x300D;
|
|
}
|
|
Message_ContinueTextbox(globalCtx, this->actor.textId);
|
|
}
|
|
return 1;
|
|
}
|
|
default:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
u16 EnGo2_GetTextIdGoronDmtRollingSmall(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) {
|
|
return 0x3027;
|
|
} else {
|
|
return (gSaveContext.eventChkInf[2] & 0x8) ? 0x3026 : 0x3009;
|
|
}
|
|
}
|
|
|
|
s16 EnGo2_GetStateGoronDmtRollingSmall(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CLOSING) {
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
u16 EnGo2_GetTextIdGoronDmtDcEntrance(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (((!gSaveContext.n64ddFlag && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) ||
|
|
(gSaveContext.n64ddFlag && gSaveContext.dungeonsDone[4])) && LINK_IS_ADULT) {
|
|
return 0x3043;
|
|
} else if ((!gSaveContext.n64ddFlag && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) ||
|
|
(gSaveContext.n64ddFlag && gSaveContext.dungeonsDone[0])) {
|
|
return 0x3027;
|
|
} else {
|
|
return gSaveContext.eventChkInf[2] & 0x8 ? 0x3021 : gSaveContext.infTable[14] & 0x1 ? 0x302A : 0x3008;
|
|
}
|
|
}
|
|
|
|
s16 EnGo2_GetStateGoronDmtDcEntrance(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CLOSING) {
|
|
if (this->actor.textId == 0x3008) {
|
|
gSaveContext.infTable[14] |= 0x1;
|
|
}
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
u16 EnGo2_GetTextIdGoronCityEntrance(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (((!gSaveContext.n64ddFlag && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) ||
|
|
(gSaveContext.n64ddFlag && gSaveContext.dungeonsDone[4])) && LINK_IS_ADULT) {
|
|
return 0x3043;
|
|
} else if ((!gSaveContext.n64ddFlag && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) ||
|
|
(gSaveContext.n64ddFlag && gSaveContext.dungeonsDone[0])) {
|
|
return 0x3027;
|
|
} else {
|
|
return gSaveContext.infTable[15] & 0x1 ? 0x3015 : 0x3014;
|
|
}
|
|
}
|
|
|
|
s16 EnGo2_GetStateGoronCityEntrance(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CLOSING) {
|
|
if (this->actor.textId == 0x3014) {
|
|
gSaveContext.infTable[15] |= 0x1;
|
|
}
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
u16 EnGo2_GetTextIdGoronCityIsland(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (((!gSaveContext.n64ddFlag && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) ||
|
|
(gSaveContext.n64ddFlag && gSaveContext.dungeonsDone[4])) && LINK_IS_ADULT) {
|
|
return 0x3043;
|
|
} else if ((!gSaveContext.n64ddFlag && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) ||
|
|
(gSaveContext.n64ddFlag && gSaveContext.dungeonsDone[0])) {
|
|
return 0x3027;
|
|
} else {
|
|
return gSaveContext.infTable[15] & 0x10 ? 0x3017 : 0x3016;
|
|
}
|
|
}
|
|
|
|
s16 EnGo2_GetStateGoronCityIsland(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CLOSING) {
|
|
if (this->actor.textId == 0x3016) {
|
|
gSaveContext.infTable[15] |= 0x10;
|
|
}
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
u16 EnGo2_GetTextIdGoronCityLowestFloor(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (((!gSaveContext.n64ddFlag && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) ||
|
|
(gSaveContext.n64ddFlag && gSaveContext.dungeonsDone[4])) && LINK_IS_ADULT) {
|
|
return 0x3043;
|
|
} else if ((!gSaveContext.n64ddFlag && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) ||
|
|
(gSaveContext.n64ddFlag && gSaveContext.dungeonsDone[0])) {
|
|
return 0x3027;
|
|
} else {
|
|
return CUR_UPG_VALUE(UPG_STRENGTH) != 0 ? 0x302C
|
|
: !Flags_GetSwitch(globalCtx, 0x1B) ? 0x3017
|
|
: gSaveContext.infTable[15] & 0x100 ? 0x3019
|
|
: 0x3018;
|
|
}
|
|
}
|
|
|
|
s16 EnGo2_GetStateGoronCityLowestFloor(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CLOSING) {
|
|
if (this->actor.textId == 0x3018) {
|
|
gSaveContext.infTable[15] |= 0x100;
|
|
}
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
u16 EnGo2_GetTextIdGoronCityLink(GlobalContext* globalCtx, EnGo2* this) {
|
|
if(gSaveContext.n64ddFlag) {
|
|
return 0x3036;
|
|
}
|
|
|
|
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) {
|
|
return gSaveContext.infTable[16] & 0x8000 ? 0x3042 : 0x3041;
|
|
} else if (CHECK_OWNED_EQUIP(EQUIP_TUNIC, 1)) {
|
|
return gSaveContext.infTable[16] & 0x4000 ? 0x3038 : 0x3037;
|
|
} else if (gSaveContext.infTable[16] & 0x1000) {
|
|
this->unk_20C = 0;
|
|
this->dialogState = TEXT_STATE_NONE;
|
|
return gSaveContext.infTable[16] & 0x400 ? 0x3033 : 0x3032;
|
|
} else {
|
|
return 0x3030;
|
|
}
|
|
}
|
|
|
|
s16 EnGo2_GetStateGoronCityLink(GlobalContext* globalCtx, EnGo2* this) {
|
|
switch (EnGo2_GetDialogState(this, globalCtx)) {
|
|
case TEXT_STATE_CLOSING:
|
|
if(!gSaveContext.n64ddFlag) {
|
|
switch (this->actor.textId) {
|
|
case 0x3036:
|
|
EnGo2_GetItem(this, globalCtx, GI_TUNIC_GORON);
|
|
this->actionFunc = EnGo2_SetupGetItem;
|
|
return 2;
|
|
case 0x3037:
|
|
gSaveContext.infTable[16] |= 0x4000;
|
|
default:
|
|
return 0;
|
|
}
|
|
} else {
|
|
if (Flags_GetTreasure(globalCtx, 0x1F)) {
|
|
return 0;
|
|
}
|
|
|
|
gSaveContext.infTable[16] |= 0x200;
|
|
EnGo2_GetItem(this, globalCtx, Randomizer_GetItemIdFromKnownCheck(RC_GC_ROLLING_GORON_AS_ADULT, GI_TUNIC_GORON));
|
|
this->actionFunc = EnGo2_SetupGetItem;
|
|
Flags_SetTreasure(globalCtx, 0x1F);
|
|
return 2;
|
|
}
|
|
|
|
case TEXT_STATE_CHOICE:
|
|
if (Message_ShouldAdvance(globalCtx)) {
|
|
if (this->actor.textId == 0x3034) {
|
|
if (globalCtx->msgCtx.choiceIndex == 0) {
|
|
this->actor.textId = gSaveContext.infTable[16] & 0x800 ? 0x3033 : 0x3035;
|
|
if (this->actor.textId == 0x3035) {
|
|
Audio_StopSfxById(NA_SE_EN_GOLON_CRY);
|
|
}
|
|
} else {
|
|
this->actor.textId = gSaveContext.infTable[16] & 0x800 ? 0x3036 : 0x3033;
|
|
if (this->actor.textId == 0x3036) {
|
|
Audio_StopSfxById(NA_SE_EN_GOLON_CRY);
|
|
}
|
|
}
|
|
Message_ContinueTextbox(globalCtx, this->actor.textId);
|
|
this->unk_20C = 0;
|
|
}
|
|
} else {
|
|
break;
|
|
}
|
|
return 1;
|
|
case TEXT_STATE_EVENT:
|
|
if (Message_ShouldAdvance(globalCtx)) {
|
|
switch (this->actor.textId) {
|
|
case 0x3035:
|
|
gSaveContext.infTable[16] |= 0x800;
|
|
case 0x3032:
|
|
case 0x3033:
|
|
this->actor.textId = 0x3034;
|
|
Message_ContinueTextbox(globalCtx, this->actor.textId);
|
|
return 1;
|
|
default:
|
|
return 2;
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
u16 EnGo2_GetTextIdGoronDmtBiggoron(GlobalContext* globalCtx, EnGo2* this) {
|
|
Player* player = GET_PLAYER(globalCtx);
|
|
|
|
if (gSaveContext.bgsFlag) {
|
|
player->exchangeItemId = EXCH_ITEM_CLAIM_CHECK;
|
|
return 0x305E;
|
|
} else if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_CLAIM_CHECK) {
|
|
player->exchangeItemId = EXCH_ITEM_CLAIM_CHECK;
|
|
return 0x305E;
|
|
} else if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_PRESCRIPTION) {
|
|
player->exchangeItemId = EXCH_ITEM_EYEDROPS;
|
|
return 0x3058;
|
|
} else {
|
|
player->exchangeItemId = EXCH_ITEM_SWORD_BROKEN;
|
|
return 0x3053;
|
|
}
|
|
}
|
|
|
|
s16 EnGo2_GetStateGoronDmtBiggoron(GlobalContext* globalCtx, EnGo2* this) {
|
|
s32 unusedPad;
|
|
u8 dialogState = this->dialogState;
|
|
|
|
switch (EnGo2_GetDialogState(this, globalCtx)) {
|
|
case TEXT_STATE_DONE:
|
|
if (this->actor.textId == 0x305E) {
|
|
if((!gSaveContext.n64ddFlag && gSaveContext.bgsFlag) || (gSaveContext.n64ddFlag && Flags_GetTreasure(globalCtx, 0x1F))) {
|
|
return 0;
|
|
}
|
|
|
|
if(gSaveContext.n64ddFlag) {
|
|
if (INV_CONTENT(ITEM_CLAIM_CHECK) != ITEM_CLAIM_CHECK) {
|
|
return 0;
|
|
}
|
|
|
|
EnGo2_GetItem(this, globalCtx, Randomizer_GetItemIdFromKnownCheck(RC_DMT_TRADE_CLAIM_CHECK, GI_SWORD_BGS));
|
|
Flags_SetTreasure(globalCtx, 0x1F);
|
|
} else {
|
|
EnGo2_GetItem(this, globalCtx, GI_SWORD_BGS);
|
|
}
|
|
this->actionFunc = EnGo2_SetupGetItem;
|
|
return 2;
|
|
} else {
|
|
return 0;
|
|
}
|
|
case TEXT_STATE_DONE_FADING:
|
|
switch (this->actor.textId) {
|
|
case 0x305E:
|
|
if (func_8002F368(globalCtx) != EXCH_ITEM_CLAIM_CHECK) {
|
|
break;
|
|
}
|
|
case 0x3059:
|
|
if (dialogState == TEXT_STATE_NONE) {
|
|
func_800F4524(&D_801333D4, NA_SE_EN_GOLON_WAKE_UP, 60);
|
|
}
|
|
case 0x3054:
|
|
if (dialogState == TEXT_STATE_NONE) {
|
|
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
|
&D_801333E8);
|
|
}
|
|
}
|
|
return 1;
|
|
case TEXT_STATE_CHOICE:
|
|
if (Message_ShouldAdvance(globalCtx)) {
|
|
if ((this->actor.textId == 0x3054) || (this->actor.textId == 0x3055)) {
|
|
if (globalCtx->msgCtx.choiceIndex == 0) {
|
|
EnGo2_GetItem(this, globalCtx, GI_PRESCRIPTION);
|
|
this->actionFunc = EnGo2_SetupGetItem;
|
|
return 2;
|
|
}
|
|
this->actor.textId = 0x3056;
|
|
Message_ContinueTextbox(globalCtx, this->actor.textId);
|
|
}
|
|
return 1;
|
|
}
|
|
break;
|
|
case TEXT_STATE_EVENT:
|
|
if (Message_ShouldAdvance(globalCtx)) {
|
|
if (this->actor.textId == 0x3059) {
|
|
globalCtx->msgCtx.msgMode = MSGMODE_PAUSED;
|
|
this->actionFunc = EnGo2_BiggoronEyedrops;
|
|
}
|
|
return 2;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
u16 EnGo2_GetTextIdGoronFireGeneric(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (Flags_GetSwitch(globalCtx, (this->actor.params & 0xFC00) >> 0xA)) {
|
|
return 0x3071;
|
|
} else {
|
|
return 0x3051;
|
|
}
|
|
}
|
|
|
|
s16 EnGo2_GetStateGoronFireGeneric(GlobalContext* globalCtx, EnGo2* this) {
|
|
switch (Message_GetState(&globalCtx->msgCtx)) {
|
|
case TEXT_STATE_CLOSING:
|
|
return 0;
|
|
case TEXT_STATE_EVENT:
|
|
if (Message_ShouldAdvance(globalCtx)) {
|
|
if (this->actor.textId == 0x3071) {
|
|
this->actor.textId = EnGo2_GoronFireGenericGetTextId(this);
|
|
Message_ContinueTextbox(globalCtx, this->actor.textId);
|
|
}
|
|
return 1;
|
|
}
|
|
default:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
u16 EnGo2_GetTextIdGoronCityStairwell(GlobalContext* globalCtx, EnGo2* this) {
|
|
return !LINK_IS_ADULT ? gSaveContext.infTable[14] & 0x8 ? 0x3022 : 0x300E : 0x3043;
|
|
}
|
|
|
|
s16 EnGo2_GetStateGoronCityStairwell(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CLOSING) {
|
|
if (this->actor.textId == 0x300E) {
|
|
gSaveContext.infTable[14] |= 0x8;
|
|
}
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// Goron in child market bazaar after obtaining Goron Ruby
|
|
u16 EnGo2_GetTextIdGoronMarketBazaar(GlobalContext* globalCtx, EnGo2* this) {
|
|
return 0x7122;
|
|
}
|
|
|
|
s16 EnGo2_GetStateGoronMarketBazaar(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CLOSING) {
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
u16 EnGo2_GetTextIdGoronCityLostWoods(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (!LINK_IS_ADULT) {
|
|
if (Flags_GetSwitch(globalCtx, 0x1C)) {
|
|
return 0x302F;
|
|
} else {
|
|
return gSaveContext.infTable[14] & 0x40 ? 0x3025 : 0x3024;
|
|
}
|
|
} else {
|
|
return 0x3043;
|
|
}
|
|
}
|
|
|
|
s16 EnGo2_GetStateGoronCityLostWoods(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CLOSING) {
|
|
if (this->actor.textId == 0x3024) {
|
|
gSaveContext.infTable[14] |= 0x40;
|
|
}
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// Goron at base of DMT summit
|
|
u16 EnGo2_GetTextIdGoronDmtFairyHint(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (!LINK_IS_ADULT) {
|
|
return CHECK_QUEST_ITEM(QUEST_GORON_RUBY) ? 0x3065 : 0x3064;
|
|
} else {
|
|
return 0x3043;
|
|
}
|
|
}
|
|
|
|
s16 EnGo2_GetStateGoronDmtFairyHint(GlobalContext* globalCtx, EnGo2* this) {
|
|
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CLOSING) {
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
u16 EnGo2_GetTextId(GlobalContext* globalCtx, Actor* thisx) {
|
|
EnGo2* this = (EnGo2*)thisx;
|
|
u16 faceReaction = Text_GetFaceReaction(globalCtx, 0x20);
|
|
|
|
if (faceReaction) {
|
|
return faceReaction;
|
|
} else {
|
|
switch (this->actor.params & 0x1F) {
|
|
case GORON_CITY_ROLLING_BIG:
|
|
return EnGo2_GetTextIdGoronCityRollingBig(globalCtx, this);
|
|
case GORON_CITY_LINK:
|
|
return EnGo2_GetTextIdGoronCityLink(globalCtx, this);
|
|
case GORON_DMT_BIGGORON:
|
|
return EnGo2_GetTextIdGoronDmtBiggoron(globalCtx, this);
|
|
case GORON_FIRE_GENERIC:
|
|
return EnGo2_GetTextIdGoronFireGeneric(globalCtx, this);
|
|
case GORON_DMT_BOMB_FLOWER:
|
|
return EnGo2_GetTextIdGoronDmtBombFlower(globalCtx, this);
|
|
case GORON_DMT_ROLLING_SMALL:
|
|
return EnGo2_GetTextIdGoronDmtRollingSmall(globalCtx, this);
|
|
case GORON_DMT_DC_ENTRANCE:
|
|
return EnGo2_GetTextIdGoronDmtDcEntrance(globalCtx, this);
|
|
case GORON_CITY_ENTRANCE:
|
|
return EnGo2_GetTextIdGoronCityEntrance(globalCtx, this);
|
|
case GORON_CITY_ISLAND:
|
|
return EnGo2_GetTextIdGoronCityIsland(globalCtx, this);
|
|
case GORON_CITY_LOWEST_FLOOR:
|
|
return EnGo2_GetTextIdGoronCityLowestFloor(globalCtx, this);
|
|
case GORON_CITY_STAIRWELL:
|
|
return EnGo2_GetTextIdGoronCityStairwell(globalCtx, this);
|
|
case GORON_CITY_LOST_WOODS:
|
|
return EnGo2_GetTextIdGoronCityLostWoods(globalCtx, this);
|
|
case GORON_DMT_FAIRY_HINT:
|
|
return EnGo2_GetTextIdGoronDmtFairyHint(globalCtx, this);
|
|
case GORON_MARKET_BAZAAR:
|
|
return EnGo2_GetTextIdGoronMarketBazaar(globalCtx, this);
|
|
}
|
|
}
|
|
}
|
|
|
|
s16 EnGo2_GetState(GlobalContext* globalCtx, Actor* thisx) {
|
|
EnGo2* this = (EnGo2*)thisx;
|
|
switch (this->actor.params & 0x1F) {
|
|
case GORON_CITY_ROLLING_BIG:
|
|
return EnGo2_GetStateGoronCityRollingBig(globalCtx, this);
|
|
case GORON_CITY_LINK:
|
|
return EnGo2_GetStateGoronCityLink(globalCtx, this);
|
|
case GORON_DMT_BIGGORON:
|
|
return EnGo2_GetStateGoronDmtBiggoron(globalCtx, this);
|
|
case GORON_FIRE_GENERIC:
|
|
return EnGo2_GetStateGoronFireGeneric(globalCtx, this);
|
|
case GORON_DMT_BOMB_FLOWER:
|
|
return EnGo2_GetStateGoronDmtBombFlower(globalCtx, this);
|
|
case GORON_DMT_ROLLING_SMALL:
|
|
return EnGo2_GetStateGoronDmtRollingSmall(globalCtx, this);
|
|
case GORON_DMT_DC_ENTRANCE:
|
|
return EnGo2_GetStateGoronDmtDcEntrance(globalCtx, this);
|
|
case GORON_CITY_ENTRANCE:
|
|
return EnGo2_GetStateGoronCityEntrance(globalCtx, this);
|
|
case GORON_CITY_ISLAND:
|
|
return EnGo2_GetStateGoronCityIsland(globalCtx, this);
|
|
case GORON_CITY_LOWEST_FLOOR:
|
|
return EnGo2_GetStateGoronCityLowestFloor(globalCtx, this);
|
|
case GORON_CITY_STAIRWELL:
|
|
return EnGo2_GetStateGoronCityStairwell(globalCtx, this);
|
|
case GORON_CITY_LOST_WOODS:
|
|
return EnGo2_GetStateGoronCityLostWoods(globalCtx, this);
|
|
case GORON_DMT_FAIRY_HINT:
|
|
return EnGo2_GetStateGoronDmtFairyHint(globalCtx, this);
|
|
case GORON_MARKET_BAZAAR:
|
|
return EnGo2_GetStateGoronMarketBazaar(globalCtx, this);
|
|
}
|
|
}
|
|
|
|
s32 func_80A44790(EnGo2* this, GlobalContext* globalCtx) {
|
|
if ((this->actor.params & 0x1F) != GORON_DMT_BIGGORON && (this->actor.params & 0x1F) != GORON_CITY_ROLLING_BIG) {
|
|
return func_800343CC(globalCtx, &this->actor, &this->unk_194.unk_00, this->unk_218, EnGo2_GetTextId,
|
|
EnGo2_GetState);
|
|
} else if (((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) && ((this->collider.base.ocFlags2 & 1) == 0)) {
|
|
return false;
|
|
} else {
|
|
if (Actor_ProcessTalkRequest(&this->actor, globalCtx)) {
|
|
this->unk_194.unk_00 = 1;
|
|
return true;
|
|
} else if (this->unk_194.unk_00 != 0) {
|
|
this->unk_194.unk_00 = EnGo2_GetState(globalCtx, &this->actor);
|
|
return false;
|
|
} else if (func_8002F2CC(&this->actor, globalCtx, this->unk_218)) {
|
|
this->actor.textId = EnGo2_GetTextId(globalCtx, &this->actor);
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void EnGo2_SetColliderDim(EnGo2* this) {
|
|
u8 index = this->actor.params & 0x1F;
|
|
|
|
this->collider.dim.radius = D_80A4816C[index].radius;
|
|
this->collider.dim.height = D_80A4816C[index].height;
|
|
}
|
|
|
|
void EnGo2_SetShape(EnGo2* this) {
|
|
u8 index = this->actor.params & 0x1F;
|
|
|
|
this->actor.shape.shadowScale = D_80A481F8[index].shape_unk_10;
|
|
Actor_SetScale(&this->actor, D_80A481F8[index].scale);
|
|
this->actor.targetMode = D_80A481F8[index].actor_unk_1F;
|
|
this->unk_218 = D_80A481F8[index].unk_218;
|
|
this->unk_218 += this->collider.dim.radius;
|
|
}
|
|
|
|
void EnGo2_CheckCollision(EnGo2* this, GlobalContext* globalCtx) {
|
|
Vec3s pos;
|
|
f32 xzDist;
|
|
|
|
pos.x = this->actor.world.pos.x;
|
|
pos.y = this->actor.world.pos.y;
|
|
pos.z = this->actor.world.pos.z;
|
|
xzDist = D_80A4816C[this->actor.params & 0x1F].xzDist;
|
|
pos.x += (s16)(xzDist * Math_SinS(this->actor.shape.rot.y));
|
|
pos.z += (s16)(xzDist * Math_CosS(this->actor.shape.rot.y));
|
|
pos.y += D_80A4816C[this->actor.params & 0x1F].yDist;
|
|
this->collider.dim.pos = pos;
|
|
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
|
|
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
|
|
}
|
|
|
|
void EnGo2_SwapInitialFrameAnimFrameCount(EnGo2* this) {
|
|
f32 initialFrame;
|
|
|
|
initialFrame = this->skelAnime.startFrame;
|
|
this->skelAnime.startFrame = this->skelAnime.endFrame;
|
|
this->skelAnime.endFrame = initialFrame;
|
|
}
|
|
|
|
s32 func_80A44AB0(EnGo2* this, GlobalContext* globalCtx) {
|
|
Player* player = GET_PLAYER(globalCtx);
|
|
f32 arg2;
|
|
|
|
if ((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) {
|
|
return false;
|
|
} else {
|
|
if ((this->actionFunc != EnGo2_SlowRolling) && (this->actionFunc != EnGo2_ReverseRolling) &&
|
|
(this->actionFunc != EnGo2_ContinueRolling)) {
|
|
return false;
|
|
} else {
|
|
if (this->collider.base.acFlags & 2) {
|
|
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
|
this->actor.flags &= ~ACTOR_FLAG_24;
|
|
this->collider.base.acFlags &= ~0x2;
|
|
EnGo2_StopRolling(this, globalCtx);
|
|
return true;
|
|
}
|
|
if (player->invincibilityTimer <= 0) {
|
|
this->collider.base.ocFlags1 |= 8;
|
|
} else {
|
|
return false;
|
|
}
|
|
if (this->collider.base.ocFlags2 & 1) {
|
|
this->collider.base.ocFlags2 &= ~1;
|
|
|
|
arg2 = this->actionFunc == EnGo2_ContinueRolling ? 1.5f : this->actor.speedXZ * 1.5f;
|
|
|
|
globalCtx->damagePlayer(globalCtx, -4);
|
|
func_8002F71C(globalCtx, &this->actor, arg2, this->actor.yawTowardsPlayer, 6.0f);
|
|
Audio_PlayActorSound2(&player->actor, NA_SE_PL_BODY_HIT);
|
|
this->collider.base.ocFlags1 &= ~0x8;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
s32 EnGo2_UpdateWaypoint(EnGo2* this, GlobalContext* globalCtx) {
|
|
s32 change;
|
|
|
|
if (this->path == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
change = (u8)(this->path->count - 1);
|
|
if (this->reverse) {
|
|
this->waypoint--;
|
|
if (this->waypoint < 0) {
|
|
this->waypoint = change - 1;
|
|
}
|
|
} else {
|
|
this->waypoint++;
|
|
if (this->waypoint >= change) {
|
|
this->waypoint = 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 EnGo2_Orient(EnGo2* this, GlobalContext* globalCtx) {
|
|
s16 targetYaw;
|
|
f32 waypointDistSq = Path_OrientAndGetDistSq(&this->actor, this->path, this->waypoint, &targetYaw);
|
|
|
|
Math_SmoothStepToS(&this->actor.world.rot.y, targetYaw, 6, 4000, 1);
|
|
if (waypointDistSq > 0.0f && waypointDistSq < SQ(30.0f)) {
|
|
return EnGo2_UpdateWaypoint(this, globalCtx);
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
s32 func_80A44D84(EnGo2* this) {
|
|
s16 targetYaw;
|
|
|
|
Path_OrientAndGetDistSq(&this->actor, this->path, this->waypoint, &targetYaw);
|
|
this->actor.world.rot.y = targetYaw;
|
|
return 1;
|
|
}
|
|
|
|
s32 EnGo2_IsWakingUp(EnGo2* this) {
|
|
s16 yawDiff;
|
|
f32 xyzDist = (this->actor.params & 0x1F) == GORON_DMT_BIGGORON ? 800.0f : 200.0f;
|
|
f32 yDist = (this->actor.params & 0x1F) == GORON_DMT_BIGGORON ? 400.0f : 60.0f;
|
|
s16 yawDiffAbs;
|
|
|
|
if ((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) {
|
|
if ((this->collider.base.ocFlags2 & 1) == 0) {
|
|
this->actor.flags &= ~ACTOR_FLAG_0;
|
|
return false;
|
|
} else {
|
|
this->actor.flags |= ACTOR_FLAG_0;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
xyzDist = SQ(xyzDist);
|
|
yawDiff = (f32)this->actor.yawTowardsPlayer - (f32)this->actor.shape.rot.y;
|
|
yawDiffAbs = ABS(yawDiff);
|
|
if (this->actor.xyzDistToPlayerSq <= xyzDist && fabsf(this->actor.yDistToPlayer) < yDist && yawDiffAbs < 0x2AA8) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
s32 EnGo2_IsRollingOnGround(EnGo2* this, s16 arg1, f32 arg2, s16 arg3) {
|
|
if ((this->actor.bgCheckFlags & 1) == 0 || this->actor.velocity.y > 0.0f) {
|
|
return false;
|
|
}
|
|
|
|
if (DECR(this->unk_590)) {
|
|
if (!arg3) {
|
|
return true;
|
|
} else {
|
|
this->actor.world.pos.y =
|
|
(this->unk_590 & 1) ? this->actor.world.pos.y + 1.5f : this->actor.world.pos.y - 1.5f;
|
|
Audio_PlayActorSound2(&this->actor, NA_SE_EV_BIGBALL_ROLL - SFX_FLAG);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (this->unk_59C >= 2) {
|
|
Audio_PlayActorSound2(&this->actor, (this->actor.params & 0x1F) == GORON_CITY_ROLLING_BIG
|
|
? NA_SE_EN_GOLON_LAND_BIG
|
|
: NA_SE_EN_DODO_M_GND);
|
|
}
|
|
|
|
this->unk_59C--;
|
|
if (this->unk_59C <= 0) {
|
|
if (this->unk_59C == 0) {
|
|
this->unk_590 = Rand_S16Offset(60, 30);
|
|
this->unk_59C = 0;
|
|
this->actor.velocity.y = 0.0f;
|
|
return true;
|
|
} else {
|
|
this->unk_59C = arg1;
|
|
}
|
|
}
|
|
|
|
this->actor.velocity.y = ((f32)this->unk_59C / (f32)arg1) * arg2;
|
|
return true;
|
|
}
|
|
|
|
void EnGo2_BiggoronSetTextId(EnGo2* this, GlobalContext* globalCtx, Player* player) {
|
|
u16 textId;
|
|
|
|
if ((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) {
|
|
if (gSaveContext.bgsFlag) {
|
|
if (func_8002F368(globalCtx) == EXCH_ITEM_CLAIM_CHECK) {
|
|
this->actor.textId = 0x3003;
|
|
} else {
|
|
this->actor.textId = 0x305E;
|
|
}
|
|
player->actor.textId = this->actor.textId;
|
|
|
|
} else if (!gSaveContext.bgsFlag && (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_CLAIM_CHECK)) {
|
|
if (func_8002F368(globalCtx) == EXCH_ITEM_CLAIM_CHECK) {
|
|
if (Environment_GetBgsDayCount() >= CVar_GetS32("gForgeTime", 3)) {
|
|
textId = 0x305E;
|
|
} else {
|
|
textId = 0x305D;
|
|
}
|
|
this->actor.textId = textId;
|
|
} else {
|
|
if (Environment_GetBgsDayCount() >= CVar_GetS32("gForgeTime", 3)) {
|
|
textId = 0x3002;
|
|
} else {
|
|
textId = 0x305D;
|
|
}
|
|
this->actor.textId = textId;
|
|
}
|
|
player->actor.textId = this->actor.textId;
|
|
|
|
} else if ((INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_PRESCRIPTION) &&
|
|
(INV_CONTENT(ITEM_TRADE_ADULT) <= ITEM_CLAIM_CHECK)) {
|
|
if (func_8002F368(globalCtx) == EXCH_ITEM_EYEDROPS) {
|
|
this->actor.textId = 0x3059;
|
|
} else {
|
|
this->actor.textId = 0x3058;
|
|
}
|
|
if (this->actor.textId == 0x3059) {
|
|
gSaveContext.timer2State = 0;
|
|
}
|
|
player->actor.textId = this->actor.textId;
|
|
|
|
} else if (INV_CONTENT(ITEM_TRADE_ADULT) <= ITEM_SWORD_BROKEN) {
|
|
if (func_8002F368(globalCtx) == EXCH_ITEM_SWORD_BROKEN) {
|
|
if (gSaveContext.infTable[11] & 0x10) {
|
|
textId = 0x3055;
|
|
} else {
|
|
textId = 0x3054;
|
|
}
|
|
this->actor.textId = textId;
|
|
} else {
|
|
this->actor.textId = 0x3053;
|
|
}
|
|
player->actor.textId = this->actor.textId;
|
|
} else {
|
|
this->actor.textId = 0x3053;
|
|
player->actor.textId = this->actor.textId;
|
|
}
|
|
}
|
|
}
|
|
|
|
void func_80A45288(EnGo2* this, GlobalContext* globalCtx) {
|
|
Player* player = GET_PLAYER(globalCtx);
|
|
s32 linkAge;
|
|
|
|
if (this->actionFunc != EnGo2_GoronFireGenericAction) {
|
|
this->unk_194.unk_18 = player->actor.world.pos;
|
|
linkAge = gSaveContext.linkAge;
|
|
this->unk_194.unk_14 = D_80A482D8[this->actor.params & 0x1F][linkAge];
|
|
func_80034A14(&this->actor, &this->unk_194, 4, this->unk_26E);
|
|
}
|
|
if ((this->actionFunc != EnGo2_SetGetItem) && (this->isAwake == true)) {
|
|
if (func_80A44790(this, globalCtx)) {
|
|
EnGo2_BiggoronSetTextId(this, globalCtx, player);
|
|
}
|
|
}
|
|
}
|
|
|
|
void func_80A45360(EnGo2* this, f32* alpha) {
|
|
f32 alphaTarget =
|
|
(this->skelAnime.animation == &gGoronAnim_004930) && (this->skelAnime.curFrame <= 32.0f) ? 0.0f : 255.0f;
|
|
|
|
Math_ApproachF(alpha, alphaTarget, 0.4f, 100.0f);
|
|
this->actor.shape.shadowAlpha = (u8)(u32)*alpha;
|
|
}
|
|
|
|
void EnGo2_RollForward(EnGo2* this) {
|
|
f32 speedXZ = this->actor.speedXZ;
|
|
|
|
if (this->unk_194.unk_00 != 0) {
|
|
this->actor.speedXZ = 0.0f;
|
|
}
|
|
|
|
if (this->actionFunc != EnGo2_ContinueRolling) {
|
|
Actor_MoveForward(&this->actor);
|
|
}
|
|
|
|
this->actor.speedXZ = speedXZ;
|
|
}
|
|
|
|
void func_80A454CC(EnGo2* this) {
|
|
switch (this->actor.params & 0x1F) {
|
|
case GORON_CITY_ROLLING_BIG:
|
|
case GORON_DMT_DC_ENTRANCE:
|
|
case GORON_CITY_ENTRANCE:
|
|
case GORON_CITY_STAIRWELL:
|
|
case GORON_DMT_FAIRY_HINT:
|
|
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_9);
|
|
break;
|
|
case GORON_DMT_BIGGORON:
|
|
if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_SWORD_BROKEN && INV_CONTENT(ITEM_TRADE_ADULT) <= ITEM_EYEDROPS) {
|
|
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_4);
|
|
break;
|
|
}
|
|
default:
|
|
this->skelAnime.playSpeed = 0.0f;
|
|
break;
|
|
}
|
|
}
|
|
|
|
f32 EnGo2_GetTargetXZSpeed(EnGo2* this) {
|
|
f32 yDist = (this->actor.params & 0x1F) == GORON_DMT_BIGGORON ? 400.0f : 60.0f;
|
|
s32 index = this->actor.params & 0x1F;
|
|
|
|
if (index == GORON_CITY_LINK && (fabsf(this->actor.yDistToPlayer) < yDist) &&
|
|
(this->actor.xzDistToPlayer < 400.0f)) {
|
|
return 9.0f;
|
|
} else {
|
|
return index == GORON_CITY_ROLLING_BIG ? 3.6000001f : 6.0f;
|
|
}
|
|
}
|
|
|
|
s32 EnGo2_IsCameraModified(EnGo2* this, GlobalContext* globalCtx) {
|
|
Camera* camera = globalCtx->cameraPtrs[MAIN_CAM];
|
|
|
|
if ((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) {
|
|
if (EnGo2_IsWakingUp(this)) {
|
|
Camera_ChangeSetting(camera, CAM_SET_DIRECTED_YAW);
|
|
func_8005AD1C(camera, 4);
|
|
} else if (!EnGo2_IsWakingUp(this) && (camera->setting == CAM_SET_DIRECTED_YAW)) {
|
|
Camera_ChangeSetting(camera, CAM_SET_DUNGEON1);
|
|
func_8005ACFC(camera, 4);
|
|
}
|
|
}
|
|
|
|
if ((this->actor.params & 0x1F) == GORON_FIRE_GENERIC || (this->actor.params & 0x1F) == GORON_CITY_ROLLING_BIG ||
|
|
(this->actor.params & 0x1F) == GORON_CITY_STAIRWELL || (this->actor.params & 0x1F) == GORON_DMT_BIGGORON ||
|
|
(this->actor.params & 0x1F) == GORON_MARKET_BAZAAR) {
|
|
return true;
|
|
} else if (!CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_OWNED_EQUIP(EQUIP_TUNIC, 1)) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void EnGo2_DefaultWakingUp(EnGo2* this) {
|
|
if (EnGo2_IsWakingUp(this)) {
|
|
this->unk_26E = 2;
|
|
} else {
|
|
this->unk_26E = 1;
|
|
}
|
|
|
|
if (this->unk_194.unk_00 != 0) {
|
|
this->unk_26E = 4;
|
|
}
|
|
|
|
this->isAwake = true;
|
|
}
|
|
|
|
void EnGo2_WakingUp(EnGo2* this) {
|
|
f32 xyzDist = (this->actor.params & 0x1F) == GORON_DMT_BIGGORON ? 800.0f : 200.0f;
|
|
s32 isTrue = true;
|
|
|
|
xyzDist = SQ(xyzDist);
|
|
this->unk_26E = 1;
|
|
if ((this->actor.xyzDistToPlayerSq <= xyzDist) || (this->unk_194.unk_00 != 0)) {
|
|
this->unk_26E = 4;
|
|
}
|
|
|
|
this->isAwake = isTrue;
|
|
}
|
|
|
|
void EnGo2_BiggoronWakingUp(EnGo2* this) {
|
|
if (EnGo2_IsWakingUp(this) || this->unk_194.unk_00 != 0) {
|
|
this->unk_26E = 2;
|
|
this->isAwake = true;
|
|
} else {
|
|
this->unk_26E = 1;
|
|
this->isAwake = false;
|
|
}
|
|
}
|
|
|
|
void EnGo2_SelectGoronWakingUp(EnGo2* this) {
|
|
switch (this->actor.params & 0x1F) {
|
|
case GORON_DMT_BOMB_FLOWER:
|
|
this->isAwake = true;
|
|
this->unk_26E = EnGo2_IsWakingUp(this) ? 2 : 1;
|
|
break;
|
|
case GORON_FIRE_GENERIC:
|
|
EnGo2_WakingUp(this);
|
|
break;
|
|
case GORON_DMT_BIGGORON:
|
|
EnGo2_BiggoronWakingUp(this);
|
|
break;
|
|
case GORON_CITY_LINK:
|
|
if (!CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_OWNED_EQUIP(EQUIP_TUNIC, 1)) {
|
|
EnGo2_WakingUp(this);
|
|
break;
|
|
}
|
|
default:
|
|
EnGo2_DefaultWakingUp(this);
|
|
}
|
|
}
|
|
|
|
void EnGo2_EyeMouthTexState(EnGo2* this) {
|
|
switch (this->eyeMouthTexState) {
|
|
case 1:
|
|
this->blinkTimer = 0;
|
|
this->eyeTexIndex = 0;
|
|
this->mouthTexIndex = 0;
|
|
break;
|
|
case 2:
|
|
this->blinkTimer = 0;
|
|
this->eyeTexIndex = 1;
|
|
this->mouthTexIndex = 0;
|
|
break;
|
|
// case 3 only when biggoron is given eyedrops. Biggoron smiles. (only use of second mouth texture)
|
|
case 3:
|
|
this->blinkTimer = 0;
|
|
this->eyeTexIndex = 0;
|
|
this->mouthTexIndex = 1;
|
|
break;
|
|
default:
|
|
if (DECR(this->blinkTimer) == 0) {
|
|
this->eyeTexIndex++;
|
|
if (this->eyeTexIndex >= 4) {
|
|
this->blinkTimer = Rand_S16Offset(30, 30);
|
|
this->eyeTexIndex = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnGo2_SitDownAnimation(EnGo2* this) {
|
|
if ((this->skelAnime.playSpeed != 0.0f) && (this->skelAnime.animation == &gGoronAnim_004930)) {
|
|
if (this->skelAnime.playSpeed > 0.0f && this->skelAnime.curFrame == 14.0f) {
|
|
if ((this->actor.params & 0x1F) != GORON_DMT_BIGGORON) {
|
|
Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_SIT_DOWN);
|
|
} else {
|
|
func_800F4524(&D_801333D4, NA_SE_EN_GOLON_SIT_DOWN, 60);
|
|
}
|
|
}
|
|
if (this->skelAnime.playSpeed < 0.0f) {
|
|
if (this->skelAnime.curFrame == 1.0f) {
|
|
Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_M_GND);
|
|
}
|
|
if (this->skelAnime.curFrame == 40.0f) {
|
|
Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_SIT_DOWN);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnGo2_GetDustData(EnGo2* this, s32 index2) {
|
|
s32 index1 = (this->actor.params & 0x1F) == GORON_CITY_ROLLING_BIG ? 1 : 0;
|
|
EnGo2DustEffectData* dustEffectData = &sDustEffectData[index1][index2];
|
|
|
|
EnGo2_SpawnDust(this, dustEffectData->initialTimer, dustEffectData->scale, dustEffectData->scaleStep,
|
|
dustEffectData->numDustEffects, dustEffectData->radius, dustEffectData->yAccel);
|
|
}
|
|
|
|
void EnGo2_RollingAnimation(EnGo2* this, GlobalContext* globalCtx) {
|
|
if ((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) {
|
|
this->actor.flags &= ~ACTOR_FLAG_0;
|
|
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_10);
|
|
this->skelAnime.playSpeed = -0.5f;
|
|
} else {
|
|
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_1);
|
|
this->skelAnime.playSpeed = -1.0f;
|
|
}
|
|
EnGo2_SwapInitialFrameAnimFrameCount(this);
|
|
this->unk_26E = 1;
|
|
this->unk_211 = false;
|
|
this->isAwake = false;
|
|
this->actionFunc = EnGo2_CurledUp;
|
|
}
|
|
|
|
void EnGo2_WakeUp(EnGo2* this, GlobalContext* globalCtx) {
|
|
if (this->skelAnime.playSpeed == 0.0f) {
|
|
if ((this->actor.params & 0x1F) != GORON_DMT_BIGGORON) {
|
|
Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_WAKE_UP);
|
|
} else {
|
|
func_800F4524(&D_801333D4, NA_SE_EN_GOLON_WAKE_UP, 60);
|
|
}
|
|
}
|
|
if ((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) {
|
|
OnePointCutscene_Init(globalCtx, 4200, -99, &this->actor, MAIN_CAM);
|
|
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_10);
|
|
this->skelAnime.playSpeed = 0.5f;
|
|
} else {
|
|
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_1);
|
|
this->skelAnime.playSpeed = 1.0f;
|
|
}
|
|
this->actionFunc = func_80A46B40;
|
|
}
|
|
|
|
void EnGo2_GetItemAnimation(EnGo2* this, GlobalContext* globalCtx) {
|
|
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_1);
|
|
this->unk_211 = true;
|
|
this->actionFunc = func_80A46B40;
|
|
this->skelAnime.playSpeed = 0.0f;
|
|
this->actor.speedXZ = 0.0f;
|
|
this->skelAnime.curFrame = this->skelAnime.endFrame;
|
|
}
|
|
|
|
void EnGo2_SetupRolling(EnGo2* this, GlobalContext* globalCtx) {
|
|
if ((this->actor.params & 0x1F) == GORON_CITY_ROLLING_BIG || (this->actor.params & 0x1F) == GORON_CITY_LINK) {
|
|
this->collider.info.bumperFlags = 1;
|
|
this->actor.speedXZ = gSaveContext.infTable[17] & 0x4000 ? 6.0f : 3.6000001f;
|
|
} else {
|
|
this->actor.speedXZ = 6.0f;
|
|
}
|
|
this->actor.flags |= ACTOR_FLAG_24;
|
|
this->animTimer = 10;
|
|
this->actor.shape.yOffset = 1800.0f;
|
|
this->actor.speedXZ += this->actor.speedXZ; // Speeding up
|
|
this->actionFunc = EnGo2_ContinueRolling;
|
|
}
|
|
|
|
void EnGo2_StopRolling(EnGo2* this, GlobalContext* globalCtx) {
|
|
EnBom* bomb;
|
|
|
|
if (((this->actor.params & 0x1F) != GORON_CITY_ROLLING_BIG) && ((this->actor.params & 0x1F) != GORON_CITY_LINK)) {
|
|
if ((this->actor.params & 0x1F) == GORON_DMT_ROLLING_SMALL) {
|
|
bomb = (EnBom*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOM, this->actor.world.pos.x,
|
|
this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0);
|
|
if (bomb != NULL) {
|
|
bomb->timer = 0;
|
|
}
|
|
}
|
|
} else {
|
|
this->collider.info.bumperFlags = 0;
|
|
}
|
|
|
|
this->actor.shape.rot = this->actor.world.rot;
|
|
this->unk_59C = 0;
|
|
this->unk_590 = 0;
|
|
this->actionFunc = EnGo2_GroundRolling;
|
|
this->actor.shape.yOffset = 0.0f;
|
|
this->actor.speedXZ = 0.0f;
|
|
}
|
|
|
|
s32 EnGo2_IsFreeingGoronInFire(EnGo2* this, GlobalContext* globalCtx) {
|
|
if ((this->actor.params & 0x1F) != GORON_FIRE_GENERIC) {
|
|
return false;
|
|
}
|
|
|
|
// shaking curled up
|
|
this->actor.world.pos.x += (globalCtx->state.frames & 1) ? 1.0f : -1.0f;
|
|
if (Flags_GetSwitch(globalCtx, (this->actor.params & 0xFC00) >> 0xA)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
s32 EnGo2_IsGoronDmtBombFlower(EnGo2* this) {
|
|
if ((this->actor.params & 0x1F) != GORON_DMT_BOMB_FLOWER || this->unk_194.unk_00 != 2) {
|
|
return false;
|
|
}
|
|
|
|
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_3);
|
|
this->unk_194.unk_00 = 0;
|
|
this->isAwake = false;
|
|
this->unk_26E = 1;
|
|
this->actionFunc = EnGo2_GoronDmtBombFlowerAnimation;
|
|
return true;
|
|
}
|
|
|
|
s32 EnGo2_IsGoronRollingBig(EnGo2* this, GlobalContext* globalCtx) {
|
|
if ((this->actor.params & 0x1F) != GORON_CITY_ROLLING_BIG || (this->unk_194.unk_00 != 2)) {
|
|
return false;
|
|
}
|
|
this->unk_194.unk_00 = 0;
|
|
EnGo2_RollingAnimation(this, globalCtx);
|
|
this->actionFunc = EnGo2_GoronRollingBigContinueRolling;
|
|
return true;
|
|
}
|
|
|
|
s32 EnGo2_IsGoronFireGeneric(EnGo2* this) {
|
|
if ((this->actor.params & 0x1F) != GORON_FIRE_GENERIC || this->unk_194.unk_00 == 0) {
|
|
return false;
|
|
}
|
|
this->actionFunc = EnGo2_GoronFireGenericAction;
|
|
return true;
|
|
}
|
|
|
|
s32 EnGo2_IsGoronLinkReversing(EnGo2* this) {
|
|
if ((this->actor.params & 0x1F) != GORON_CITY_LINK || (this->waypoint >= this->unk_216) ||
|
|
!EnGo2_IsWakingUp(this)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
s32 EnGo2_IsRolling(EnGo2* this) {
|
|
if (this->unk_194.unk_00 == 0 || this->actor.speedXZ < 1.0f) {
|
|
return false;
|
|
}
|
|
if (EnGo2_IsRollingOnGround(this, 2, 20.0 / 3.0f, 0)) {
|
|
if ((this->unk_590 >= 9) && (this->unk_59C == 0)) {
|
|
this->unk_590 = 8;
|
|
}
|
|
EnGo2_GetDustData(this, 0);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void EnGo2_GoronLinkAnimation(EnGo2* this, GlobalContext* globalCtx) {
|
|
s32 animation = ARRAY_COUNT(sAnimationInfo);
|
|
|
|
if ((this->actor.params & 0x1F) == GORON_CITY_LINK) {
|
|
if ((this->actor.textId == 0x3035 && this->unk_20C == 0) ||
|
|
(this->actor.textId == 0x3036 && this->unk_20C == 0)) {
|
|
if (this->skelAnime.animation != &gGoronAnim_000D5C) {
|
|
animation = ENGO2_ANIM_12;
|
|
this->eyeMouthTexState = 0;
|
|
}
|
|
}
|
|
|
|
if ((this->actor.textId == 0x3032 && this->unk_20C == 12) || (this->actor.textId == 0x3033) ||
|
|
(this->actor.textId == 0x3035 && this->unk_20C == 6)) {
|
|
if (this->skelAnime.animation != &gGoronAnim_000750) {
|
|
animation = ENGO2_ANIM_11;
|
|
this->eyeMouthTexState = 1;
|
|
}
|
|
}
|
|
|
|
if (this->skelAnime.animation == &gGoronAnim_000750) {
|
|
if (this->skelAnime.curFrame == 20.0f) {
|
|
Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_CRY);
|
|
}
|
|
}
|
|
|
|
if (animation != ARRAY_COUNT(sAnimationInfo)) {
|
|
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, animation);
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnGo2_GoronFireCamera(EnGo2* this, GlobalContext* globalCtx) {
|
|
s16 yaw;
|
|
|
|
this->camId = Gameplay_CreateSubCamera(globalCtx);
|
|
Gameplay_ChangeCameraStatus(globalCtx, MAIN_CAM, CAM_STAT_WAIT);
|
|
Gameplay_ChangeCameraStatus(globalCtx, this->camId, CAM_STAT_ACTIVE);
|
|
Path_CopyLastPoint(this->path, &this->at);
|
|
yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->at) + 0xE38;
|
|
this->eye.x = Math_SinS(yaw) * 100.0f + this->actor.world.pos.x;
|
|
this->eye.z = Math_CosS(yaw) * 100.0f + this->actor.world.pos.z;
|
|
this->eye.y = this->actor.world.pos.y + 20.0f;
|
|
this->at.x = this->actor.world.pos.x;
|
|
this->at.y = this->actor.world.pos.y + 40.0f;
|
|
this->at.z = this->actor.world.pos.z;
|
|
Gameplay_CameraSetAtEye(globalCtx, this->camId, &this->at, &this->eye);
|
|
}
|
|
|
|
void EnGo2_GoronFireClearCamera(EnGo2* this, GlobalContext* globalCtx) {
|
|
Gameplay_ChangeCameraStatus(globalCtx, MAIN_CAM, CAM_STAT_ACTIVE);
|
|
Gameplay_ClearCamera(globalCtx, this->camId);
|
|
}
|
|
|
|
void EnGo2_BiggoronAnimation(EnGo2* this) {
|
|
if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_SWORD_BROKEN && INV_CONTENT(ITEM_TRADE_ADULT) <= ITEM_EYEDROPS &&
|
|
(this->actor.params & 0x1F) == GORON_DMT_BIGGORON && this->unk_194.unk_00 == 0) {
|
|
if (DECR(this->animTimer) == 0) {
|
|
this->animTimer = Rand_S16Offset(30, 30);
|
|
func_800F4524(&D_801333D4, NA_SE_EN_GOLON_EYE_BIG, 60);
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnGo2_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|
EnGo2* this = (EnGo2*)thisx;
|
|
s32 pad;
|
|
|
|
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 28.0f);
|
|
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGoronSkel, NULL, this->jointTable, this->morphTable, 18);
|
|
Collider_InitCylinder(globalCtx, &this->collider);
|
|
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
|
|
CollisionCheck_SetInfo2(&this->actor.colChkInfo, NULL, &sColChkInfoInit);
|
|
|
|
// Not GORON_CITY_ROLLING_BIG, GORON_CITY_LINK, GORON_DMT_BIGGORON
|
|
switch (this->actor.params & 0x1F) {
|
|
case GORON_FIRE_GENERIC:
|
|
case GORON_DMT_BOMB_FLOWER:
|
|
case GORON_DMT_ROLLING_SMALL:
|
|
case GORON_DMT_DC_ENTRANCE:
|
|
case GORON_CITY_ENTRANCE:
|
|
case GORON_CITY_ISLAND:
|
|
case GORON_CITY_LOWEST_FLOOR:
|
|
case GORON_CITY_STAIRWELL:
|
|
case GORON_CITY_LOST_WOODS:
|
|
case GORON_DMT_FAIRY_HINT:
|
|
case GORON_MARKET_BAZAAR:
|
|
this->actor.flags &= ~ACTOR_FLAG_4;
|
|
this->actor.flags &= ~ACTOR_FLAG_5;
|
|
}
|
|
|
|
EnGo2_SetColliderDim(this);
|
|
EnGo2_SetShape(this);
|
|
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_0);
|
|
this->actor.gravity = -1.0f;
|
|
this->alpha = this->actor.shape.shadowAlpha = 0;
|
|
this->reverse = 0;
|
|
this->isAwake = false;
|
|
this->unk_211 = false;
|
|
this->goronState = 0;
|
|
this->waypoint = 0;
|
|
this->unk_216 = this->actor.shape.rot.z;
|
|
this->unk_26E = 1;
|
|
this->path = Path_GetByIndex(globalCtx, (this->actor.params & 0x3E0) >> 5, 0x1F);
|
|
switch (this->actor.params & 0x1F) {
|
|
case GORON_CITY_ENTRANCE:
|
|
case GORON_CITY_ISLAND:
|
|
case GORON_CITY_LOWEST_FLOOR:
|
|
case GORON_CITY_STAIRWELL:
|
|
case GORON_CITY_LOST_WOODS:
|
|
if (((!gSaveContext.n64ddFlag && !CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) ||
|
|
(gSaveContext.n64ddFlag && !gSaveContext.dungeonsDone[4])) && LINK_IS_ADULT) {
|
|
Actor_Kill(&this->actor);
|
|
}
|
|
this->actionFunc = EnGo2_CurledUp;
|
|
break;
|
|
case GORON_MARKET_BAZAAR:
|
|
if ((LINK_IS_ADULT) || !CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) {
|
|
Actor_Kill(&this->actor);
|
|
}
|
|
EnGo2_GetItemAnimation(this, globalCtx);
|
|
break;
|
|
case GORON_CITY_LINK:
|
|
if ((gSaveContext.infTable[16] & 0x200)) {
|
|
Path_CopyLastPoint(this->path, &this->actor.world.pos);
|
|
this->actor.home.pos = this->actor.world.pos;
|
|
if (!CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_OWNED_EQUIP(EQUIP_TUNIC, 1)) {
|
|
EnGo2_GetItemAnimation(this, globalCtx);
|
|
} else {
|
|
this->actionFunc = EnGo2_CurledUp;
|
|
}
|
|
} else {
|
|
gSaveContext.infTable[16] &= ~0x1000;
|
|
this->collider.dim.height = (D_80A4816C[this->actor.params & 0x1F].height * 0.6f);
|
|
EnGo2_SetupRolling(this, globalCtx);
|
|
this->isAwake = true;
|
|
}
|
|
break;
|
|
case GORON_CITY_ROLLING_BIG:
|
|
case GORON_DMT_ROLLING_SMALL:
|
|
this->collider.dim.height = (D_80A4816C[this->actor.params & 0x1F].height * 0.6f);
|
|
EnGo2_SetupRolling(this, globalCtx);
|
|
break;
|
|
case GORON_FIRE_GENERIC:
|
|
if (Flags_GetSwitch(globalCtx, (this->actor.params & 0xFC00) >> 0xA)) {
|
|
Actor_Kill(&this->actor);
|
|
} else {
|
|
this->isAwake = true;
|
|
this->actionFunc = EnGo2_CurledUp;
|
|
}
|
|
break;
|
|
case GORON_DMT_BIGGORON:
|
|
this->actor.shape.shadowDraw = NULL;
|
|
this->actor.flags &= ~ACTOR_FLAG_0;
|
|
if ((INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_SWORD_BROKEN) &&
|
|
(INV_CONTENT(ITEM_TRADE_ADULT) <= ITEM_EYEDROPS)) {
|
|
this->eyeMouthTexState = 1;
|
|
}
|
|
this->collider.base.acFlags = 0;
|
|
this->collider.base.ocFlags1 = 0xD; // OC_PLAYER | OC_NO_PUSH | OC_ON
|
|
this->actionFunc = EnGo2_CurledUp;
|
|
break;
|
|
case GORON_DMT_BOMB_FLOWER:
|
|
if (gSaveContext.infTable[14] & 0x800) {
|
|
Path_CopyLastPoint(this->path, &this->actor.world.pos);
|
|
this->actor.home.pos = this->actor.world.pos;
|
|
}
|
|
case GORON_DMT_DC_ENTRANCE:
|
|
case GORON_DMT_FAIRY_HINT:
|
|
default:
|
|
this->actionFunc = EnGo2_CurledUp;
|
|
}
|
|
}
|
|
|
|
void EnGo2_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
|
}
|
|
|
|
void EnGo2_CurledUp(EnGo2* this, GlobalContext* globalCtx) {
|
|
u8 index = this->actor.params & 0x1F;
|
|
s16 height;
|
|
s32 quake;
|
|
|
|
if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
|
|
if ((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) {
|
|
quake = Quake_Add(GET_ACTIVE_CAM(globalCtx), 3);
|
|
Quake_SetSpeed(quake, -0x3CB0);
|
|
Quake_SetQuakeValues(quake, 8, 0, 0, 0);
|
|
Quake_SetCountdown(quake, 16);
|
|
} else {
|
|
EnGo2_GetDustData(this, 1);
|
|
}
|
|
this->skelAnime.playSpeed = 0.0f;
|
|
}
|
|
|
|
if ((s32)this->skelAnime.curFrame == 0) {
|
|
this->collider.dim.height = (D_80A4816C[index].height * 0.6f);
|
|
} else {
|
|
height = D_80A4816C[index].height;
|
|
this->collider.dim.height =
|
|
((D_80A4816C[index].height * 0.4f * (this->skelAnime.curFrame / this->skelAnime.startFrame)) +
|
|
(height * 0.6f));
|
|
}
|
|
if (EnGo2_IsFreeingGoronInFire(this, globalCtx)) {
|
|
this->isAwake = false;
|
|
EnGo2_WakeUp(this, globalCtx);
|
|
}
|
|
if (((this->actor.params & 0x1F) != GORON_FIRE_GENERIC) && EnGo2_IsWakingUp(this)) {
|
|
EnGo2_WakeUp(this, globalCtx);
|
|
}
|
|
}
|
|
|
|
void func_80A46B40(EnGo2* this, GlobalContext* globalCtx) {
|
|
u8 index = (this->actor.params & 0x1F);
|
|
f32 height;
|
|
|
|
if (this->unk_211 == true) {
|
|
EnGo2_BiggoronAnimation(this);
|
|
EnGo2_GoronLinkAnimation(this, globalCtx);
|
|
EnGo2_SelectGoronWakingUp(this);
|
|
|
|
if (!EnGo2_IsGoronRollingBig(this, globalCtx) && !EnGo2_IsGoronFireGeneric(this)) {
|
|
if (EnGo2_IsGoronDmtBombFlower(this)) {
|
|
return;
|
|
}
|
|
} else {
|
|
return;
|
|
}
|
|
} else {
|
|
if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
|
|
if ((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) {
|
|
this->actor.flags |= ACTOR_FLAG_0;
|
|
}
|
|
func_80A454CC(this);
|
|
this->unk_211 = true;
|
|
this->collider.dim.height = D_80A4816C[index].height;
|
|
} else {
|
|
height = D_80A4816C[index].height;
|
|
this->collider.dim.height =
|
|
(s16)((height * 0.4f * (this->skelAnime.curFrame / this->skelAnime.endFrame)) + (height * 0.6f));
|
|
}
|
|
}
|
|
if ((!EnGo2_IsCameraModified(this, globalCtx)) && (!EnGo2_IsWakingUp(this))) {
|
|
EnGo2_RollingAnimation(this, globalCtx);
|
|
}
|
|
}
|
|
|
|
void EnGo2_GoronDmtBombFlowerAnimation(EnGo2* this, GlobalContext* globalCtx) {
|
|
f32 float1 = this->skelAnime.endFrame;
|
|
f32 float2 = this->skelAnime.curFrame * ((f32)0x8000 / float1);
|
|
|
|
this->actor.speedXZ = Math_SinS(float2);
|
|
if ((EnGo2_Orient(this, globalCtx)) && (this->waypoint == 0)) {
|
|
EnGo2_GetItemAnimation(this, globalCtx);
|
|
}
|
|
}
|
|
|
|
void EnGo2_GoronRollingBigContinueRolling(EnGo2* this, GlobalContext* globalCtx) {
|
|
if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
|
|
EnGo2_GetDustData(this, 1);
|
|
this->skelAnime.playSpeed = 0.0f;
|
|
EnGo2_SetupRolling(this, globalCtx);
|
|
}
|
|
}
|
|
|
|
void EnGo2_ContinueRolling(EnGo2* this, GlobalContext* globalCtx) {
|
|
f32 float1 = 1000.0f;
|
|
|
|
if (((this->actor.params & 0x1F) != GORON_DMT_ROLLING_SMALL || !(this->actor.xyzDistToPlayerSq > SQ(float1))) &&
|
|
DECR(this->animTimer) == 0) {
|
|
this->actionFunc = EnGo2_SlowRolling;
|
|
this->actor.speedXZ *= 0.5f; // slowdown
|
|
}
|
|
EnGo2_GetDustData(this, 2);
|
|
}
|
|
|
|
void EnGo2_SlowRolling(EnGo2* this, GlobalContext* globalCtx) {
|
|
s32 orientation;
|
|
s32 index;
|
|
|
|
if (!EnGo2_IsRolling(this)) {
|
|
if (EnGo2_IsRollingOnGround(this, 4, 8.0f, 1) == true) {
|
|
if (EnGo2_IsGoronLinkReversing(this)) {
|
|
this->actionFunc = EnGo2_ReverseRolling;
|
|
return;
|
|
}
|
|
EnGo2_GetDustData(this, 3);
|
|
}
|
|
orientation = EnGo2_Orient(this, globalCtx);
|
|
index = this->actor.params & 0x1F;
|
|
if (index != GORON_CITY_LINK) {
|
|
if ((index == GORON_DMT_ROLLING_SMALL) && (orientation == 1) && (this->waypoint == 0)) {
|
|
EnGo2_StopRolling(this, globalCtx);
|
|
return;
|
|
}
|
|
} else if ((orientation == 2) && (this->waypoint == 1)) {
|
|
EnGo2_StopRolling(this, globalCtx);
|
|
return;
|
|
}
|
|
Math_ApproachF(&this->actor.speedXZ, EnGo2_GetTargetXZSpeed(this), 0.4f, 0.6f);
|
|
this->actor.shape.rot = this->actor.world.rot;
|
|
}
|
|
}
|
|
|
|
void EnGo2_GroundRolling(EnGo2* this, GlobalContext* globalCtx) {
|
|
if (EnGo2_IsRollingOnGround(this, 4, 8.0f, 0)) {
|
|
EnGo2_GetDustData(this, 0);
|
|
if (this->unk_59C == 0) {
|
|
switch (this->actor.params & 0x1F) {
|
|
case GORON_CITY_LINK:
|
|
this->goronState = 0;
|
|
this->actionFunc = EnGo2_GoronLinkStopRolling;
|
|
break;
|
|
case GORON_CITY_ROLLING_BIG:
|
|
EnGo2_WakeUp(this, globalCtx);
|
|
break;
|
|
default:
|
|
this->actionFunc = EnGo2_CurledUp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnGo2_ReverseRolling(EnGo2* this, GlobalContext* globalCtx) {
|
|
if (!EnGo2_IsRolling(this)) {
|
|
Math_ApproachF(&this->actor.speedXZ, 0.0f, 0.6f, 0.8f);
|
|
if (this->actor.speedXZ >= 1.0f) {
|
|
EnGo2_GetDustData(this, 3);
|
|
}
|
|
if ((s32)this->actor.speedXZ == 0) {
|
|
this->actor.world.rot.y ^= 0x8000;
|
|
this->actor.shape.rot.y = this->actor.world.rot.y;
|
|
this->reverse ^= 1;
|
|
EnGo2_UpdateWaypoint(this, globalCtx);
|
|
EnGo2_SetupRolling(this, globalCtx);
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnGo2_SetupGetItem(EnGo2* this, GlobalContext* globalCtx) {
|
|
if (Actor_HasParent(&this->actor, globalCtx)) {
|
|
this->actor.parent = NULL;
|
|
this->actionFunc = EnGo2_SetGetItem;
|
|
} else {
|
|
func_8002F434(&this->actor, globalCtx, this->getItemId, this->actor.xzDistToPlayer + 1.0f,
|
|
fabsf(this->actor.yDistToPlayer) + 1.0f);
|
|
}
|
|
}
|
|
|
|
void EnGo2_SetGetItem(EnGo2* this, GlobalContext* globalCtx) {
|
|
if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(globalCtx)) {
|
|
this->unk_194.unk_00 = 0;
|
|
switch (this->getItemId) {
|
|
case GI_CLAIM_CHECK:
|
|
Environment_ClearBgsDayCount();
|
|
EnGo2_GetItemAnimation(this, globalCtx);
|
|
return;
|
|
case GI_TUNIC_GORON:
|
|
if (!gSaveContext.n64ddFlag) {
|
|
gSaveContext.infTable[16] |= 0x200;
|
|
}
|
|
EnGo2_GetItemAnimation(this, globalCtx);
|
|
return;
|
|
case GI_SWORD_BGS:
|
|
gSaveContext.bgsFlag = true;
|
|
break;
|
|
case GI_BOMB_BAG_30:
|
|
case GI_BOMB_BAG_40:
|
|
EnGo2_RollingAnimation(this, globalCtx);
|
|
this->actionFunc = EnGo2_GoronRollingBigContinueRolling;
|
|
return;
|
|
}
|
|
this->actionFunc = func_80A46B40;
|
|
}
|
|
}
|
|
|
|
void EnGo2_BiggoronEyedrops(EnGo2* this, GlobalContext* globalCtx) {
|
|
switch (this->goronState) {
|
|
case 0:
|
|
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_5);
|
|
this->actor.flags &= ~ACTOR_FLAG_0;
|
|
this->actor.shape.rot.y += 0x5B0;
|
|
this->unk_26E = 1;
|
|
this->animTimer = this->skelAnime.endFrame + 60.0f + 60.0f; // eyeDrops animation timer
|
|
this->eyeMouthTexState = 2;
|
|
this->unk_20C = 0;
|
|
this->goronState++;
|
|
func_800F483C(0x28, 5);
|
|
OnePointCutscene_Init(globalCtx, 4190, -99, &this->actor, MAIN_CAM);
|
|
break;
|
|
case 1:
|
|
if (DECR(this->animTimer)) {
|
|
if (this->animTimer == 60 || this->animTimer == 120) {
|
|
func_8005B1A4(GET_ACTIVE_CAM(globalCtx));
|
|
func_800F4524(&D_801333D4, NA_SE_EV_GORON_WATER_DROP, 60);
|
|
}
|
|
} else {
|
|
func_800F4524(&D_801333D4, NA_SE_EN_GOLON_GOOD_BIG, 60);
|
|
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_6);
|
|
Message_ContinueTextbox(globalCtx, 0x305A);
|
|
this->eyeMouthTexState = 3;
|
|
this->goronState++;
|
|
func_800F483C(0x7F, 5);
|
|
}
|
|
break;
|
|
case 2:
|
|
if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
|
|
this->eyeMouthTexState = 0;
|
|
}
|
|
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CLOSING) {
|
|
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_1);
|
|
this->actor.flags |= ACTOR_FLAG_0;
|
|
this->unk_26E = 2;
|
|
this->skelAnime.playSpeed = 0.0f;
|
|
this->skelAnime.curFrame = this->skelAnime.endFrame;
|
|
EnGo2_GetItem(this, globalCtx, GI_CLAIM_CHECK);
|
|
this->actionFunc = EnGo2_SetupGetItem;
|
|
this->goronState = 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void EnGo2_GoronLinkStopRolling(EnGo2* this, GlobalContext* globalCtx) {
|
|
Player* player = GET_PLAYER(globalCtx);
|
|
|
|
switch (this->goronState) {
|
|
case 0:
|
|
if (Message_GetState(&globalCtx->msgCtx) != TEXT_STATE_NONE) {
|
|
return;
|
|
} else {
|
|
Message_StartTextbox(globalCtx, 0x3031, NULL);
|
|
player->actor.freezeTimer = 10;
|
|
this->goronState++;
|
|
}
|
|
case 1:
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
if (Message_GetState(&globalCtx->msgCtx) != TEXT_STATE_CLOSING) {
|
|
player->actor.freezeTimer = 10;
|
|
} else {
|
|
gSaveContext.infTable[16] |= 0x1000;
|
|
this->unk_26E = 1;
|
|
this->unk_211 = false;
|
|
this->isAwake = false;
|
|
this->actionFunc = EnGo2_CurledUp;
|
|
}
|
|
}
|
|
|
|
void EnGo2_GoronFireGenericAction(EnGo2* this, GlobalContext* globalCtx) {
|
|
Player* player = GET_PLAYER(globalCtx);
|
|
Vec3s D_80A4854C = { 0x00, 0x00, 0x00 };
|
|
|
|
switch (this->goronState) {
|
|
case 0: // Wake up
|
|
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CLOSING) {
|
|
EnGo2_GoronFireCamera(this, globalCtx);
|
|
globalCtx->msgCtx.msgMode = MSGMODE_PAUSED;
|
|
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_2);
|
|
this->waypoint = 1;
|
|
this->skelAnime.playSpeed = 2.0f;
|
|
func_80A44D84(this);
|
|
this->actor.shape.rot = this->actor.world.rot;
|
|
this->animTimer = 60;
|
|
this->actor.gravity = 0.0f;
|
|
this->actor.speedXZ = 2.0f;
|
|
this->unk_194.unk_08 = D_80A4854C;
|
|
this->unk_194.unk_0E = D_80A4854C;
|
|
this->goronState++;
|
|
this->goronState++;
|
|
player->actor.world.rot.y = this->actor.world.rot.y;
|
|
player->actor.shape.rot.y = this->actor.world.rot.y;
|
|
player->actor.world.pos.x =
|
|
(f32)((Math_SinS(this->actor.world.rot.y) * -30.0f) + this->actor.world.pos.x);
|
|
player->actor.world.pos.z =
|
|
(f32)((Math_CosS(this->actor.world.rot.y) * -30.0f) + this->actor.world.pos.z);
|
|
func_8002DF54(globalCtx, &this->actor, 8);
|
|
Audio_PlayFanfare(NA_BGM_APPEAR);
|
|
}
|
|
break;
|
|
case 2: // Walking away
|
|
if (DECR(this->animTimer)) {
|
|
if (!(this->animTimer % 8)) {
|
|
Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_WALK);
|
|
}
|
|
Actor_MoveForward(&this->actor);
|
|
} else {
|
|
this->animTimer = 0;
|
|
this->actor.speedXZ = 0.0f;
|
|
if ((((this->actor.params & 0xFC00) >> 0xA) != 1) && (((this->actor.params & 0xFC00) >> 0xA) != 2) &&
|
|
(((this->actor.params & 0xFC00) >> 0xA) != 4) && (((this->actor.params & 0xFC00) >> 0xA) != 5) &&
|
|
(((this->actor.params & 0xFC00) >> 0xA) != 9) && (((this->actor.params & 0xFC00) >> 0xA) != 11)) {
|
|
this->goronState++;
|
|
}
|
|
this->goronState++;
|
|
}
|
|
break;
|
|
case 3: // Walking away
|
|
this->animTimer++;
|
|
if (!(this->animTimer % 8) && (this->animTimer < 10)) {
|
|
Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_WALK);
|
|
}
|
|
if (this->animTimer == 10) {
|
|
Audio_PlayActorSound2(&this->actor, NA_SE_EV_IRON_DOOR_OPEN);
|
|
}
|
|
if (this->animTimer > 44) {
|
|
SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_IRON_DOOR_CLOSE);
|
|
} else {
|
|
break;
|
|
}
|
|
case 4: // Finalize walking away
|
|
Message_CloseTextbox(globalCtx);
|
|
EnGo2_GoronFireClearCamera(this, globalCtx);
|
|
func_8002DF54(globalCtx, &this->actor, 7);
|
|
Actor_Kill(&this->actor);
|
|
break;
|
|
case 1:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void EnGo2_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|
EnGo2* this = (EnGo2*)thisx;
|
|
|
|
func_80A45360(this, &this->alpha);
|
|
EnGo2_SitDownAnimation(this);
|
|
SkelAnime_Update(&this->skelAnime);
|
|
EnGo2_RollForward(this);
|
|
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, (f32)this->collider.dim.height * 0.5f,
|
|
(f32)this->collider.dim.radius * 0.6f, 0.0f, 5);
|
|
if (this->unk_194.unk_00 == 0) {
|
|
func_80A44AB0(this, globalCtx);
|
|
}
|
|
this->actionFunc(this, globalCtx);
|
|
if (this->unk_211 == true) {
|
|
func_80034F54(globalCtx, this->unk_226, this->unk_24A, 18);
|
|
}
|
|
func_80A45288(this, globalCtx);
|
|
EnGo2_EyeMouthTexState(this);
|
|
EnGo2_CheckCollision(this, globalCtx);
|
|
}
|
|
|
|
s32 EnGo2_DrawCurledUp(EnGo2* this, GlobalContext* globalCtx) {
|
|
Vec3f D_80A48554 = { 0.0f, 0.0f, 0.0f };
|
|
|
|
OPEN_DISPS(globalCtx->state.gfxCtx);
|
|
func_80093D18(globalCtx->state.gfxCtx);
|
|
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
|
|
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
gSPDisplayList(POLY_OPA_DISP++, gGoronDL_00BD80);
|
|
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
|
Matrix_MultVec3f(&D_80A48554, &this->actor.focus.pos);
|
|
|
|
return 1;
|
|
}
|
|
|
|
s32 EnGo2_DrawRolling(EnGo2* this, GlobalContext* globalCtx) {
|
|
s32 pad;
|
|
Vec3f D_80A48560 = { 0.0f, 0.0f, 0.0f };
|
|
f32 speedXZ;
|
|
|
|
OPEN_DISPS(globalCtx->state.gfxCtx);
|
|
func_80093D18(globalCtx->state.gfxCtx);
|
|
speedXZ = this->actionFunc == EnGo2_ReverseRolling ? 0.0f : this->actor.speedXZ;
|
|
Matrix_RotateZYX((globalCtx->state.frames * ((s16)speedXZ * 1400)), 0, this->actor.shape.rot.z, MTXMODE_APPLY);
|
|
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
|
|
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
gSPDisplayList(POLY_OPA_DISP++, gGoronDL_00C140);
|
|
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
|
Matrix_MultVec3f(&D_80A48560, &this->actor.focus.pos);
|
|
return 1;
|
|
}
|
|
|
|
s32 EnGo2_OverrideLimbDraw(GlobalContext* globalCtx, s32 limb, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) {
|
|
EnGo2* this = (EnGo2*)thisx;
|
|
Vec3s vec1;
|
|
f32 float1;
|
|
|
|
if (limb == 17) {
|
|
Matrix_Translate(2800.0f, 0.0f, 0.0f, MTXMODE_APPLY);
|
|
vec1 = this->unk_194.unk_08;
|
|
float1 = (vec1.y / (f32)0x8000) * M_PI;
|
|
Matrix_RotateX(float1, MTXMODE_APPLY);
|
|
float1 = (vec1.x / (f32)0x8000) * M_PI;
|
|
Matrix_RotateZ(float1, MTXMODE_APPLY);
|
|
Matrix_Translate(-2800.0f, 0.0f, 0.0f, MTXMODE_APPLY);
|
|
}
|
|
if (limb == 10) {
|
|
vec1 = this->unk_194.unk_0E;
|
|
float1 = (vec1.y / (f32)0x8000) * M_PI;
|
|
Matrix_RotateY(float1, MTXMODE_APPLY);
|
|
float1 = (vec1.x / (f32)0x8000) * M_PI;
|
|
Matrix_RotateX(float1, MTXMODE_APPLY);
|
|
}
|
|
if ((limb == 10) || (limb == 11) || (limb == 14)) {
|
|
float1 = Math_SinS(this->unk_226[limb]);
|
|
rot->y += float1 * 200.0f;
|
|
float1 = Math_CosS(this->unk_24A[limb]);
|
|
rot->z += float1 * 200.0f;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void EnGo2_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
|
|
EnGo2* this = (EnGo2*)thisx;
|
|
Vec3f D_80A4856C = { 600.0f, 0.0f, 0.0f };
|
|
|
|
if (limbIndex == 17) {
|
|
Matrix_MultVec3f(&D_80A4856C, &this->actor.focus.pos);
|
|
}
|
|
}
|
|
|
|
void EnGo2_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|
EnGo2* this = (EnGo2*)thisx;
|
|
void* eyeTextures[] = { gGoronCsEyeClosed2Tex, gGoronCsEyeOpenTex, gGoronCsEyeHalfTex, gGoronCsEyeClosedTex };
|
|
void* mouthTextures[] = { gGoronCsMouthNeutralTex, gGoronCsMouthSmileTex };
|
|
|
|
EnGo2_UpdateDust(this);
|
|
Matrix_Push();
|
|
EnGo2_DrawDust(this, globalCtx);
|
|
Matrix_Pop();
|
|
|
|
if ((this->actionFunc == EnGo2_CurledUp) && (this->skelAnime.playSpeed == 0.0f) &&
|
|
(this->skelAnime.curFrame == 0.0f)) {
|
|
EnGo2_DrawCurledUp(this, globalCtx);
|
|
} else if (this->actionFunc == EnGo2_SlowRolling || this->actionFunc == EnGo2_ReverseRolling ||
|
|
this->actionFunc == EnGo2_ContinueRolling) {
|
|
EnGo2_DrawRolling(this, globalCtx);
|
|
} else {
|
|
OPEN_DISPS(globalCtx->state.gfxCtx);
|
|
func_80093D18(globalCtx->state.gfxCtx);
|
|
|
|
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(eyeTextures[this->eyeTexIndex]));
|
|
gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(mouthTextures[this->mouthTexIndex]));
|
|
|
|
SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable,
|
|
this->skelAnime.dListCount, EnGo2_OverrideLimbDraw, EnGo2_PostLimbDraw, this);
|
|
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
|
}
|
|
}
|