Shipwright/soh/src/overlays/actors/ovl_Demo_Gj/z_demo_gj.c

1460 lines
44 KiB
C

/*
* File: z_demo_gj.c
* Overlay: Demo_Gj
* Description: Ganon battle rubble.
*/
#include "z_demo_gj.h"
#include "objects/object_gj/object_gj.h"
#include "objects/object_geff/object_geff.h"
#include "vt.h"
#define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED)
void DemoGj_Init(Actor* thisx, PlayState* play);
void DemoGj_Destroy(Actor* thisx, PlayState* play);
void DemoGj_Update(Actor* thisx, PlayState* play);
void DemoGj_Draw(Actor* thisx, PlayState* play);
static ColliderCylinderInitType1 sCylinderInit1 = {
{
COLTYPE_HIT0,
AT_NONE,
AC_ON | AC_TYPE_PLAYER,
OC1_NONE,
COLSHAPE_CYLINDER,
},
{
ELEMTYPE_UNK0,
{ 0x00000000, 0x00, 0x00 },
{ 0x00000008, 0x00, 0x00 },
TOUCH_NONE,
BUMP_ON,
OCELEM_NONE,
},
{ 30, 100, 0, { 0, 0, 0 } },
};
static ColliderCylinderInitType1 sCylinderInit2 = {
{
COLTYPE_HIT0,
AT_NONE,
AC_ON | AC_TYPE_PLAYER,
OC1_NONE,
COLSHAPE_CYLINDER,
},
{
ELEMTYPE_UNK0,
{ 0x00000000, 0x00, 0x00 },
{ 0x00000008, 0x00, 0x00 },
TOUCH_NONE,
BUMP_ON,
OCELEM_NONE,
},
{ 25, 110, 0, { 0, 0, 0 } },
};
static ColliderCylinderInitType1 sCylinderInit3 = {
{
COLTYPE_HIT0,
AT_NONE,
AC_ON | AC_TYPE_PLAYER,
OC1_NONE,
COLSHAPE_CYLINDER,
},
{
ELEMTYPE_UNK0,
{ 0x00000000, 0x00, 0x00 },
{ 0x00000008, 0x00, 0x00 },
TOUCH_NONE,
BUMP_ON,
OCELEM_NONE,
},
{ 25, 200, 0, { 0, 0, 0 } },
};
typedef void (*DemoGjUpdateFunc)(DemoGj*, PlayState*);
typedef void (*DemoGjDrawFunc)(DemoGj*, PlayState*);
// bits 11-15
s32 DemoGj_GetCollectibleType(DemoGj* this) {
s32 params = this->dyna.actor.params >> 0xB;
return params & 0x1F;
}
// bits 8-10
s32 DemoGj_GetCollectibleAmount(DemoGj* this) {
s32 params = this->dyna.actor.params >> 0x8;
return params & 7;
}
// bits 0-7
s32 DemoGj_GetType(DemoGj* this) {
s32 params = this->dyna.actor.params;
return params & 0xFF;
}
void DemoGj_InitCylinder(DemoGj* this, PlayState* play, ColliderCylinder* cylinder,
ColliderCylinderInitType1* cylinderInit) {
Collider_InitCylinder(play, cylinder);
Collider_SetCylinderType1(play, cylinder, &this->dyna.actor, cylinderInit);
}
s32 DemoGj_HitByExplosion(DemoGj* this, PlayState* play, ColliderCylinder* cylinder) {
if (Actor_GetCollidedExplosive(play, &cylinder->base) != NULL) {
return true;
}
return false;
}
void DemoGj_DestroyCylinder(DemoGj* this, PlayState* play) {
switch (DemoGj_GetType(this)) {
case DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_1:
Collider_DestroyCylinder(play, &this->cylinders[0]);
Collider_DestroyCylinder(play, &this->cylinders[1]);
Collider_DestroyCylinder(play, &this->cylinders[2]);
break;
case DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_2:
Collider_DestroyCylinder(play, &this->cylinders[0]);
Collider_DestroyCylinder(play, &this->cylinders[1]);
Collider_DestroyCylinder(play, &this->cylinders[2]);
break;
case DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_TALL:
Collider_DestroyCylinder(play, &this->cylinders[0]);
break;
}
}
void DemoGj_Destroy(Actor* thisx, PlayState* play) {
DemoGj* this = (DemoGj*)thisx;
DemoGj_DestroyCylinder(this, play);
DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
}
void DemoGj_PlayExplosionSfx(DemoGj* this, PlayState* play) {
SoundSource_PlaySfxAtFixedWorldPos(play, &this->dyna.actor.world.pos, 50, NA_SE_EV_GRAVE_EXPLOSION);
}
void DemoGj_SpawnSmoke(PlayState* play, Vec3f* pos, f32 arg2) {
static Vec3f velocity = { 0.0f, 6.0f, 0.0f };
static Vec3f accel = { 0.0f, 0.0f, 0.0f };
static Color_RGBA8 primColor = { 0, 0, 0, 0 };
static Color_RGBA8 envColor = { 0, 0, 0, 0 };
f32 temp = arg2 * 0.2f;
func_800283D4(play, pos, &velocity, &accel, &primColor, &envColor, temp * Rand_ZeroOne() + arg2, 15, 90);
}
void DemoGj_DropCollectible(DemoGj* this, PlayState* play) {
Vec3f* pos = &this->dyna.actor.world.pos;
s16 collectible = DemoGj_GetCollectibleType(this);
s32 amount = DemoGj_GetCollectibleAmount(this);
s32 i;
for (i = 0; i < amount; i++) {
Item_DropCollectible(play, pos, collectible);
}
}
void DemoGj_Explode(DemoGj* this, PlayState* play, Vec3f* initialPos, Vec3f* direction) {
Vec3f explosionPos;
Vec3f velocity;
s32 phi_s0;
f32 aux;
s16 theta = 0;
s32 i;
for (i = 0; i < 6; i++) {
explosionPos.x = Math_SinS(theta) * 16.0f;
explosionPos.y = (Rand_ZeroOne() * 5.0f) + 2.0f;
explosionPos.z = Math_CosS(theta) * 16.0f;
velocity.x = (explosionPos.x * 0.6f) + (12.0f * direction->x);
velocity.y = (Rand_ZeroOne() * 36.0f) + 6.0f;
velocity.z = (explosionPos.z * 0.6f) + (12.0f * direction->z);
explosionPos.x += initialPos->x;
explosionPos.y += initialPos->y;
explosionPos.z += initialPos->z;
aux = Rand_ZeroOne();
if (aux < 0.1f) {
phi_s0 = 0x61;
} else if (aux < 0.7f) {
phi_s0 = 0x41;
} else {
phi_s0 = 0x21;
}
// SoH [Port] Changed from &gGanonsCastleRubbleAroundArenaDL[28] to gGanonRubbleDL as it seems this was an error in the original rom/decomp
// Other calls to EffectSsKakera_Spawn with OBJECT_GEFF use gGanonRubbleDL, so this change is to match that
EffectSsKakera_Spawn(play, &explosionPos, &velocity, initialPos, -200, phi_s0, 10, 10, 0,
Rand_ZeroOne() * 20.0f + 20.0f, 20, 300, (s32)(Rand_ZeroOne() * 30.0f) + 30, -1,
OBJECT_GEFF, gGanonRubbleDL);
theta += 0x2AAA;
}
DemoGj_PlayExplosionSfx(this, play);
}
s32 DemoGj_IsSceneInvalid(void) {
if (gSaveContext.sceneSetupIndex < 4) {
return false;
}
return true;
}
s32 DemoGj_FindGanon(DemoGj* this, PlayState* play) {
Actor* actor;
if (this->ganon == NULL) {
actor = play->actorCtx.actorLists[ACTORCAT_BOSS].head;
while (actor != NULL) {
if (actor->id == ACTOR_BOSS_GANON2) {
this->ganon = (BossGanon2*)actor;
// "Demo_Gj_Search_Boss_Ganon %d: Discover Ganon !!!!"
osSyncPrintf("Demo_Gj_Search_Boss_Ganon %d:ガノン発見!!!!\n", this->dyna.actor.params);
return true;
}
actor = actor->next;
}
// "Demo_Gj_Search_Boss_Ganon %d: I couldn't find Ganon"
osSyncPrintf("Demo_Gj_Search_Boss_Ganon %d:ガノン発見出来ず\n", this->dyna.actor.params);
return false;
}
//! @bug: Missing return value when `this->ganon` is already set.
}
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP),
};
void DemoGj_InitCommon(DemoGj* this, PlayState* play, CollisionHeader* header) {
s32 pad[3];
CollisionHeader* newHeader;
if (header != NULL) {
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
DynaPolyActor_Init(&this->dyna, DPM_UNK);
newHeader = NULL;
CollisionHeader_GetVirtual(header, &newHeader);
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, newHeader);
}
}
// TODO: find a better name
s32 DemoGj_InitSetIndexes(DemoGj* this, PlayState* play, s32 updateMode, s32 drawConfig,
CollisionHeader* header) {
if (!DemoGj_IsSceneInvalid()) {
this->updateMode = updateMode;
this->drawConfig = drawConfig;
DemoGj_InitCommon(this, play, header);
return true;
}
Actor_Kill(&this->dyna.actor);
return false;
}
void DemoGj_DrawCommon(DemoGj* this, PlayState* play, Gfx* displayList) {
if (kREG(0) == 0) {
GraphicsContext* gfxCtx = play->state.gfxCtx;
OPEN_DISPS(gfxCtx);
Gfx_SetupDL_25Opa(gfxCtx);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(gfxCtx),
G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, displayList);
gSPPopMatrix(POLY_OPA_DISP++, G_MTX_MODELVIEW);
CLOSE_DISPS(gfxCtx);
}
}
void DemoGj_DrawRotated(DemoGj* this, PlayState* play, Gfx* displayList) {
s32 pad;
GraphicsContext* gfxCtx;
s16 x = this->rotationVec.x;
s16 y = this->rotationVec.y;
s16 z = this->rotationVec.z;
s32 pad2;
Mtx* matrix;
gfxCtx = play->state.gfxCtx;
matrix = Graph_Alloc(gfxCtx, sizeof(Mtx));
OPEN_DISPS(gfxCtx);
Matrix_Push();
Matrix_RotateZYX(x, y, z, MTXMODE_APPLY);
MATRIX_TOMTX(matrix);
Matrix_Pop();
Gfx_SetupDL_25Opa(gfxCtx);
gSPMatrix(POLY_OPA_DISP++, matrix, G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, displayList);
gSPPopMatrix(POLY_OPA_DISP++, G_MTX_MODELVIEW);
CLOSE_DISPS(gfxCtx);
}
void DemoGj_SetupRotation(DemoGj* this, PlayState* play) {
f32 yPosition = this->dyna.actor.world.pos.y;
f32* yVelocity = &this->dyna.actor.velocity.y;
f32* speedXZ = &this->dyna.actor.speedXZ;
Vec3s* unk_172 = &this->unk_172;
f32 verticalTranslation;
Vec3f vec;
f32 verticalFactor;
f32 xzPlaneFactor;
switch (DemoGj_GetType(this)) {
case DEMOGJ_TYPE_RUBBLE_PILE_1:
verticalTranslation = kREG(23);
vec.x = kREG(24) * 0.01f + 1.0f;
vec.y = kREG(25) * 0.01f + 1.0f;
vec.z = kREG(26) * 0.01f + 1.0f;
verticalFactor = kREG(27) * 0.01f + -1.0f;
xzPlaneFactor = kREG(28) * 0.01f + 1.0f;
break;
case DEMOGJ_TYPE_RUBBLE_PILE_2:
verticalTranslation = kREG(36);
vec.x = kREG(37) * 0.01f + 1.0f;
vec.y = kREG(38) * 0.01f + 1.0f;
vec.z = kREG(39) * 0.01f + 1.0f;
verticalFactor = kREG(40) * 0.01f + -1.0f;
xzPlaneFactor = kREG(41) * 0.01f + 1.0f;
break;
case DEMOGJ_TYPE_RUBBLE_PILE_3:
verticalTranslation = kREG(49);
vec.x = kREG(50) * 0.01f + 1.0f;
vec.y = kREG(51) * 0.01f + 1.0f;
vec.z = kREG(52) * 0.01f + 1.0f;
verticalFactor = kREG(53) * 0.01f + -1.0f;
xzPlaneFactor = kREG(54) * 0.01f + 1.0f;
break;
case DEMOGJ_TYPE_RUBBLE_PILE_4:
verticalTranslation = kREG(62);
vec.x = kREG(63) * 0.01f + 1.0f;
vec.y = kREG(64) * 0.01f + 1.0f;
vec.z = kREG(65) * 0.01f + 1.0f;
verticalFactor = kREG(66) * 0.01f + -1.0f;
xzPlaneFactor = kREG(67) * 0.01f + 1.0f;
break;
case DEMOGJ_TYPE_RUBBLE_PILE_5:
verticalTranslation = kREG(75);
vec.x = kREG(76) * 0.01f + 1.0f;
vec.y = kREG(77) * 0.01f + 1.0f;
vec.z = kREG(78) * 0.01f + 1.0f;
verticalFactor = kREG(79) * 0.01f + -1.0f;
xzPlaneFactor = kREG(80) * 0.01f + 1.0f;
break;
case DEMOGJ_TYPE_RUBBLE_PILE_6:
verticalTranslation = kREG(88);
vec.x = kREG(89) * 0.01f + 1.0f;
vec.y = kREG(90) * 0.01f + 1.0f;
vec.z = kREG(91) * 0.01f + 1.0f;
verticalFactor = kREG(92) * 0.01f + -1.0f;
xzPlaneFactor = kREG(93) * 0.01f + 1.0f;
break;
case DEMOGJ_TYPE_RUBBLE_PILE_7:
verticalTranslation = kREG(10) + -190.0f;
vec.x = kREG(9) * 0.01f + 1.0f;
vec.y = kREG(8) * 0.01f + 1.0f;
vec.z = kREG(7) * 0.01f + 1.0f;
verticalFactor = kREG(6) * 0.01f + -1.0f;
xzPlaneFactor = kREG(5) * 0.01f + 1.0f;
break;
default:
// "Demo_Gj_common_Reflect : This arg_data is not supported = %d"
osSyncPrintf(VT_FGCOL(RED) "Demo_Gj_common_Reflect : そんなarg_dataには対応していない = %d\n" VT_RST,
this->dyna.actor.params);
return;
}
yPosition += verticalTranslation;
if (yPosition <= 1086.0f && (*yVelocity < 0.0f)) {
if (!this->isRotated) {
*yVelocity *= verticalFactor;
*speedXZ *= xzPlaneFactor;
unk_172->x *= vec.x;
unk_172->y *= vec.y;
unk_172->z *= vec.z;
if (*yVelocity <= -this->dyna.actor.gravity) {
*yVelocity = 0.0f;
*speedXZ = 0.0f;
unk_172->x = 0;
unk_172->y = 0;
unk_172->z = 0;
}
this->isRotated = true;
}
}
}
/*
* Returns true if `ganon->unk_314` is equals to `arg1`.
* `ganon->unk_314` can have the following values:
* 0: Before the battle has started.
* 1: When is set: Ganondorf starts rising from the rubble.
* What is happening: Ganondorf is moving vertically and has vertical velocity.
* Proposed name: BOSSGANON2_MODE_GANONDORF_RISING
* 2: When is set: Ganondorf has stopped rising in air.
* What is happening: The camera is in front of him, focusing the clouds and going down to focus him.
* Proposed name: BOSSGANON2_MODE_GANONDORF_FLOATING
* 3: When is set: The camera has stopped moving and is focusing him.
* What is happening: Ganondorf raises his hand, shows the triforce and transforms into Ganon. The battle starts.
* This value is set during the whole real fight against Ganon. Without and with Master Sword.
* Proposed name: BOSSGANON2_MODE_GANON_FIGHTING
* 4: When is set: Link has hit Ganon's tail for last time with Master Sword.
* What is happening: Ganon falls to the floor, Zelda uses her magic and tells Link to kill him.
* Proposed name: BOSSGANON2_MODE_GANON_DEFEATED
*
* Those values should probably be defined as macros or enums in `ovl_Boss_Ganon2/z_boss_ganon2.h`.
* Proposed name for the function: `s32 DemoGj_CheckGanonMode(DemoGj* this, u8 mode)`
*/
s32 func_809797E4(DemoGj* this, u8 arg1) {
BossGanon2* ganon = this->ganon;
if ((ganon != NULL) && (ganon->unk_314 == arg1)) {
return true;
}
return false;
}
s32 DemoGj_IsGanondorfRisingFromRubble(DemoGj* this, PlayState* play) {
return func_809797E4(this, 1);
}
// Ganondorf has stopped rising into the air and is just floating. Just before he transforms.
s32 DemoGj_IsGanondorfFloatingInAir(DemoGj* this, PlayState* play) {
return func_809797E4(this, 2);
}
void DemoGj_SetupMovement(DemoGj* this, PlayState* play) {
Actor* actor = &this->dyna.actor;
Player* player;
Vec3f* pos = &actor->world.pos;
Vec3s* unk_172;
f32 xDistance;
f32 zDistance;
if (this->ganon != NULL) {
xDistance = actor->world.pos.x - this->ganon->actor.world.pos.x;
zDistance = actor->world.pos.z - this->ganon->actor.world.pos.z;
unk_172 = &this->unk_172;
switch (DemoGj_GetType(this)) {
case DEMOGJ_TYPE_RUBBLE_PILE_1:
actor->speedXZ = kREG(16) + 10.0f;
actor->velocity.y = kREG(17) + 40.0f;
unk_172->x = kREG(18);
unk_172->y = kREG(19) + 0x3E8;
unk_172->z = kREG(20) + 0xBB8;
actor->minVelocityY = kREG(21) * 0.01f + -29.0f;
actor->gravity = kREG(22) * 0.01f + -5.0f;
break;
case DEMOGJ_TYPE_RUBBLE_PILE_2:
actor->speedXZ = kREG(29) + 10.0f;
actor->velocity.y = kREG(30) + 40.0f;
unk_172->x = kREG(31);
unk_172->y = kREG(32) + 0x3E8;
unk_172->z = kREG(33) + 0xBB8;
actor->minVelocityY = kREG(34) * 0.01f + -29.0f;
actor->gravity = kREG(35) * 0.01f + -5.0f;
break;
case DEMOGJ_TYPE_RUBBLE_PILE_3:
actor->speedXZ = kREG(42) + 10.0f;
actor->velocity.y = kREG(43) + 40.0f;
unk_172->x = kREG(44);
unk_172->y = kREG(45) + 0x3E8;
unk_172->z = kREG(46) + 0xBB8;
actor->minVelocityY = kREG(47) * 0.01f + -29.0f;
actor->gravity = kREG(48) * 0.01f + -5.0f;
break;
case DEMOGJ_TYPE_RUBBLE_PILE_4:
actor->speedXZ = kREG(55) + 10.0f;
actor->velocity.y = kREG(56) + 40.0f;
unk_172->x = kREG(57);
unk_172->y = kREG(58) + 0x3E8;
unk_172->z = kREG(59) + 0xBB8;
actor->minVelocityY = kREG(60) * 0.01f + -29.0f;
actor->gravity = kREG(61) * 0.01f + -5.0f;
break;
case DEMOGJ_TYPE_RUBBLE_PILE_5:
actor->speedXZ = kREG(68) + 10.0f;
actor->velocity.y = kREG(69) + 40.0f;
unk_172->x = kREG(70);
unk_172->y = kREG(71) + 0x3E8;
unk_172->z = kREG(72) + 0xBB8;
actor->minVelocityY = kREG(73) * 0.01f + -29.0f;
actor->gravity = kREG(74) * 0.01f + -5.0f;
break;
case DEMOGJ_TYPE_RUBBLE_PILE_6:
actor->speedXZ = kREG(81) + 10.0f;
actor->velocity.y = kREG(82) + 40.0f;
unk_172->x = kREG(83);
unk_172->y = kREG(84) + 0x3E8;
unk_172->z = kREG(85) + 0xBB8;
actor->minVelocityY = kREG(86) * 0.01f + -29.0f;
actor->gravity = kREG(87) * 0.01f + -5.0f;
break;
case DEMOGJ_TYPE_RUBBLE_PILE_7:
actor->speedXZ = kREG(94) + 10.0f;
actor->velocity.y = kREG(95) + 70.0f;
unk_172->x = kREG(15);
unk_172->y = kREG(14) + 0x3E8;
unk_172->z = kREG(13) + 0xBB8;
actor->minVelocityY = kREG(12) * 0.01f + -29.0f;
actor->gravity = kREG(11) * 0.01f + -5.0f;
break;
default:
// "Demo_Gj_Setup_Move_common : This arg_data is not supported = %d"
osSyncPrintf(VT_FGCOL(RED) "Demo_Gj_Setup_Move_common : そんなarg_dataには対応していない = %d\n" VT_RST,
actor->params);
break;
}
if (xDistance == 0.0f && zDistance == 0.0f) {
player = GET_PLAYER(play);
xDistance = player->actor.world.pos.x - pos->x;
zDistance = player->actor.world.pos.z - pos->z;
if (xDistance != 0.0f || zDistance != 0.0f) {
actor->world.rot.y = (Math_FAtan2F(xDistance, zDistance) * (0x8000 / M_PI));
}
} else {
actor->world.rot.y = (Math_FAtan2F(xDistance, zDistance) * (0x8000 / M_PI));
}
}
}
void DemoGj_CheckIfTransformedIntoGanon(DemoGj* this) {
if (func_809797E4(this, 3)) {
this->isTransformedIntoGanon = true;
}
}
void DemoGj_InitRubblePile1(DemoGj* this, PlayState* play) {
DemoGj_InitSetIndexes(this, play, 1, 2, &gGanonsCastleRubble2Col);
}
void func_8097A000(DemoGj* this, PlayState* play) {
Actor_MoveForward(&this->dyna.actor);
this->rotationVec.x += (s16)(kREG(18));
this->rotationVec.y += (s16)(kREG(19) + 1000);
this->rotationVec.z += (s16)(kREG(20) + 3000);
DemoGj_SetupRotation(this, play);
}
void DemoGj_SpawnSmokePreBattle1(DemoGj* this, PlayState* play) {
static Vec3f pos = { -371.0f, 1188.0f, -303.0f };
u32 gameplayFrames;
if (!this->isTransformedIntoGanon) {
gameplayFrames = play->gameplayFrames % 3;
if (gameplayFrames == 0) {
if (!play->gameplayFrames) {}
DemoGj_SpawnSmoke(play, &pos, 300.0f);
}
DemoGj_CheckIfTransformedIntoGanon(this);
}
}
void func_8097A0E4(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfRisingFromRubble(this, play)) {
DemoGj_SetupMovement(this, play);
this->updateMode = 8;
this->drawConfig = 9;
}
}
void func_8097A130(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfFloatingInAir(this, play)) {
Actor_Kill(&this->dyna.actor);
}
}
// func_8097A160
void DemoGj_Update01(DemoGj* this, PlayState* play) {
DemoGj_FindGanon(this, play);
func_8097A0E4(this, play);
}
// func_8097A190
void DemoGj_Update08(DemoGj* this, PlayState* play) {
func_8097A000(this, play);
func_8097A130(this, play);
}
void DemoGj_DrawRubble2(DemoGj* this, PlayState* play) {
DemoGj_DrawCommon(this, play, gGanonsCastleRubble2DL);
}
void DemoGj_DrawRotatedRubble2(DemoGj* this, PlayState* play) {
DemoGj_DrawRotated(this, play, gGanonsCastleRubble2DL);
}
void DemoGj_InitRubblePile2(DemoGj* this, PlayState* play) {
DemoGj_InitSetIndexes(this, play, 2, 3, &gGanonsCastleRubble3Col);
}
void func_8097A238(DemoGj* this, PlayState* play) {
Actor_MoveForward(&this->dyna.actor);
this->rotationVec.x += (s16)(kREG(31));
this->rotationVec.y += (s16)(kREG(32) + 1000);
this->rotationVec.z += (s16)(kREG(33) + 3000);
DemoGj_SetupRotation(this, play);
}
void DemoGj_SpawnSmokePreBattle2(DemoGj* this, PlayState* play) {
static Vec3f pos = { -119.0f, 1056.0f, -147.0f };
u32 gameplayFrames;
if (!this->isTransformedIntoGanon) {
gameplayFrames = play->gameplayFrames % 3;
if (gameplayFrames == 1) {
if (!play->gameplayFrames) {}
DemoGj_SpawnSmoke(play, &pos, 300.0f);
}
DemoGj_CheckIfTransformedIntoGanon(this);
}
}
void func_8097A320(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfRisingFromRubble(this, play)) {
DemoGj_SetupMovement(this, play);
this->updateMode = 9;
this->drawConfig = 10;
}
}
void func_8097A36C(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfFloatingInAir(this, play)) {
Actor_Kill(&this->dyna.actor);
}
}
// func_8097A39C
void DemoGj_Update02(DemoGj* this, PlayState* play) {
DemoGj_FindGanon(this, play);
func_8097A320(this, play);
}
// func_8097A3CC
void DemoGj_Update09(DemoGj* this, PlayState* play) {
func_8097A238(this, play);
func_8097A36C(this, play);
}
void DemoGj_DrawRubble3(DemoGj* this, PlayState* play) {
DemoGj_DrawCommon(this, play, gGanonsCastleRubble3DL);
}
void DemoGj_DrawRotatedRubble3(DemoGj* this, PlayState* play) {
DemoGj_DrawRotated(this, play, gGanonsCastleRubble3DL);
}
void DemoGj_InitRubblePile3(DemoGj* this, PlayState* play) {
DemoGj_InitSetIndexes(this, play, 3, 4, &gGanonsCastleRubble4Col);
}
void func_8097A474(DemoGj* this, PlayState* play) {
Actor_MoveForward(&this->dyna.actor);
this->rotationVec.x += (s16)(kREG(44));
this->rotationVec.y += (s16)(kREG(45) + 1000);
this->rotationVec.z += (s16)(kREG(46) + 3000);
DemoGj_SetupRotation(this, play);
}
void func_8097A4F0(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfRisingFromRubble(this, play)) {
DemoGj_SetupMovement(this, play);
this->updateMode = 10;
this->drawConfig = 11;
}
}
void func_8097A53C(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfFloatingInAir(this, play)) {
Actor_Kill(&this->dyna.actor);
}
}
// func_8097A56C
void DemoGj_Update03(DemoGj* this, PlayState* play) {
DemoGj_FindGanon(this, play);
func_8097A4F0(this, play);
}
// func_8097A59C
void DemoGj_Update10(DemoGj* this, PlayState* play) {
func_8097A474(this, play);
func_8097A53C(this, play);
}
void DemoGj_DrawRubble4(DemoGj* this, PlayState* play) {
DemoGj_DrawCommon(this, play, gGanonsCastleRubble4DL);
}
void DemoGj_DrawRotatedRubble4(DemoGj* this, PlayState* play) {
DemoGj_DrawRotated(this, play, gGanonsCastleRubble4DL);
}
void DemoGj_InitRubblePile4(DemoGj* this, PlayState* play) {
DemoGj_InitSetIndexes(this, play, 4, 5, &gGanonsCastleRubble5Col);
}
void func_8097A644(DemoGj* this, PlayState* play) {
Actor_MoveForward(&this->dyna.actor);
this->rotationVec.x += (s16)(kREG(57));
this->rotationVec.y += (s16)(kREG(58) + 1000);
this->rotationVec.z += (s16)(kREG(59) + 3000);
DemoGj_SetupRotation(this, play);
}
void func_8097A6C0(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfRisingFromRubble(this, play)) {
DemoGj_SetupMovement(this, play);
this->updateMode = 11;
this->drawConfig = 12;
}
}
void func_8097A70C(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfFloatingInAir(this, play)) {
Actor_Kill(&this->dyna.actor);
}
}
// func_8097A73C
void DemoGj_Update04(DemoGj* this, PlayState* play) {
DemoGj_FindGanon(this, play);
func_8097A6C0(this, play);
}
// func_8097A76C
void DemoGj_Update11(DemoGj* this, PlayState* play) {
func_8097A644(this, play);
func_8097A70C(this, play);
}
void DemoGj_DrawRubble5(DemoGj* this, PlayState* play) {
DemoGj_DrawCommon(this, play, gGanonsCastleRubble5DL);
}
void DemoGj_DrawRotatedRubble5(DemoGj* this, PlayState* play) {
DemoGj_DrawRotated(this, play, gGanonsCastleRubble5DL);
}
void DemoGj_InitRubblePile5(DemoGj* this, PlayState* play) {
DemoGj_InitSetIndexes(this, play, 5, 6, &gGanonsCastleRubble6Col);
}
void func_8097A814(DemoGj* this, PlayState* play) {
Actor_MoveForward(&this->dyna.actor);
this->rotationVec.x += (s16)(kREG(70));
this->rotationVec.y += (s16)(kREG(71) + 1000);
this->rotationVec.z += (s16)(kREG(72) + 3000);
DemoGj_SetupRotation(this, play);
}
void func_8097A890(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfRisingFromRubble(this, play)) {
DemoGj_SetupMovement(this, play);
this->updateMode = 12;
this->drawConfig = 13;
}
}
void func_8097A8DC(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfFloatingInAir(this, play)) {
Actor_Kill(&this->dyna.actor);
}
}
// func_8097A90C
void DemoGj_Update05(DemoGj* this, PlayState* play) {
DemoGj_FindGanon(this, play);
func_8097A890(this, play);
}
// func_8097A93C
void DemoGj_Update12(DemoGj* this, PlayState* play) {
func_8097A814(this, play);
func_8097A8DC(this, play);
}
void DemoGj_DrawRubble6(DemoGj* this, PlayState* play) {
DemoGj_DrawCommon(this, play, gGanonsCastleRubble6DL);
}
void DemoGj_DrawRotatedRubble6(DemoGj* this, PlayState* play) {
DemoGj_DrawRotated(this, play, gGanonsCastleRubble6DL);
}
void DemoGj_InitRubblePile6(DemoGj* this, PlayState* play) {
DemoGj_InitSetIndexes(this, play, 6, 7, &gGanonsCastleRubble7Col);
}
void func_8097A9E4(DemoGj* this, PlayState* play) {
Actor_MoveForward(&this->dyna.actor);
this->rotationVec.x += (s16)(kREG(83));
this->rotationVec.y += (s16)(kREG(84) + 1000);
this->rotationVec.z += (s16)(kREG(85) + 3000);
DemoGj_SetupRotation(this, play);
}
void func_8097AA60(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfRisingFromRubble(this, play)) {
DemoGj_SetupMovement(this, play);
this->updateMode = 13;
this->drawConfig = 14;
}
}
void func_8097AAAC(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfFloatingInAir(this, play)) {
Actor_Kill(&this->dyna.actor);
}
}
// func_8097AADC
void DemoGj_Update06(DemoGj* this, PlayState* play) {
DemoGj_FindGanon(this, play);
func_8097AA60(this, play);
}
// func_8097AB0C
void DemoGj_Update13(DemoGj* this, PlayState* play) {
func_8097A9E4(this, play);
func_8097AAAC(this, play);
}
void DemoGj_DrawRubble7(DemoGj* this, PlayState* play) {
DemoGj_DrawCommon(this, play, gGanonsCastleRubble7DL);
}
void DemoGj_DrawRotatedRubble7(DemoGj* this, PlayState* play) {
DemoGj_DrawRotated(this, play, gGanonsCastleRubble7DL);
}
void DemoGj_InitRubblePile7(DemoGj* this, PlayState* play) {
DemoGj_InitSetIndexes(this, play, 7, 8, &gGanonsCastleRubbleTallCol);
}
void func_8097ABB4(DemoGj* this, PlayState* play) {
Actor_MoveForward(&this->dyna.actor);
this->rotationVec.x += (s16)(kREG(15));
this->rotationVec.y += (s16)(kREG(14) + 1000);
this->rotationVec.z += (s16)(kREG(13) + 3000);
DemoGj_SetupRotation(this, play);
}
void DemoGj_SpawnSmokePreBattle3(DemoGj* this, PlayState* play) {
static Vec3f pos = { -6.0f, 1053.0f, -473.0f };
u32 gameplayFrames;
if (!this->isTransformedIntoGanon) {
gameplayFrames = play->gameplayFrames % 3;
if (gameplayFrames == 2) {
if (!play->gameplayFrames) {}
DemoGj_SpawnSmoke(play, &pos, 300.0f);
}
DemoGj_CheckIfTransformedIntoGanon(this);
}
}
void func_8097AC9C(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfRisingFromRubble(this, play)) {
DemoGj_SetupMovement(this, play);
this->updateMode = 14;
this->drawConfig = 15;
}
}
void func_8097ACE8(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfFloatingInAir(this, play)) {
Actor_Kill(&this->dyna.actor);
}
}
// func_8097AD18
void DemoGj_Update07(DemoGj* this, PlayState* play) {
DemoGj_FindGanon(this, play);
func_8097AC9C(this, play);
}
// func_8097AD48
void DemoGj_Update14(DemoGj* this, PlayState* play) {
func_8097ABB4(this, play);
func_8097ACE8(this, play);
}
void DemoGj_DrawRubbleTall(DemoGj* this, PlayState* play) {
DemoGj_DrawCommon(this, play, gGanonsCastleRubbleTallDL);
}
void DemoGj_DrawRotatedRubbleTall(DemoGj* this, PlayState* play) {
DemoGj_DrawRotated(this, play, gGanonsCastleRubbleTallDL);
}
void DemoGj_InitRubbleAroundArena(DemoGj* this, PlayState* play) {
DemoGj_InitSetIndexes(this, play, 0, 1, &gGanonsCastleRubbleAroundArenaCol);
}
// func_8097ADF0
void DemoGj_UpdateRubbleAroundArena(DemoGj* this, PlayState* play) {
DemoGj_FindGanon(this, play);
DemoGj_SpawnSmokePreBattle1(this, play);
DemoGj_SpawnSmokePreBattle2(this, play);
DemoGj_SpawnSmokePreBattle3(this, play);
}
void DemoGj_DrawRubbleAroundArena(DemoGj* this, PlayState* play) {
DemoGj_DrawCommon(this, play, gGanonsCastleRubbleAroundArenaDL);
}
// Inits the three cylinders with `sCylinderInit1`
void DemoGj_InitDestructableRubble1(DemoGj* this, PlayState* play) {
DemoGj_InitSetIndexes(this, play, 15, 0, NULL);
DemoGj_InitCylinder(this, play, &this->cylinders[0], &sCylinderInit1);
DemoGj_InitCylinder(this, play, &this->cylinders[1], &sCylinderInit1);
DemoGj_InitCylinder(this, play, &this->cylinders[2], &sCylinderInit1);
}
void DemoGj_DoNothing1(DemoGj* this, PlayState* play) {
}
/*
* Moves the ColliderCylinder's relative to the actor's position.
* Used by DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_1
*/
void func_8097AEE8(DemoGj* this, PlayState* play) {
ColliderCylinder* cylinder0 = &this->cylinders[0];
ColliderCylinder* cylinder1 = &this->cylinders[1];
ColliderCylinder* cylinder2 = &this->cylinders[2];
Vec3f* actorPos = &this->dyna.actor.world.pos;
s32 pad;
s16 theta = this->dyna.actor.world.rot.y;
f32 cos_theta = Math_CosS(theta);
f32 sin_theta = Math_SinS(theta);
cylinder0->dim.pos.z = actorPos->z + (20.0f * cos_theta) - (-20.0f * sin_theta);
cylinder0->dim.pos.x = actorPos->x + (20.0f * sin_theta) + (-20.0f * cos_theta);
cylinder0->dim.pos.y = actorPos->y;
cylinder1->dim.pos.z = actorPos->z + (-20.0f * cos_theta) - (20.0f * sin_theta);
cylinder1->dim.pos.x = actorPos->x + (-20.0f * sin_theta) + (20.0f * cos_theta);
cylinder1->dim.pos.y = actorPos->y;
cylinder2->dim.pos.z = actorPos->z + (-60.0f * cos_theta) - (60.0f * sin_theta);
cylinder2->dim.pos.x = actorPos->x + (-60.0f * sin_theta) + (60.0f * cos_theta);
cylinder2->dim.pos.y = actorPos->y;
}
void DemoGj_SetCylindersAsAC(DemoGj* this, PlayState* play) {
s32 pad[2];
Collider* cylinder0 = &this->cylinders[0].base;
Collider* cylinder1 = &this->cylinders[1].base;
Collider* cylinder2 = &this->cylinders[2].base;
s32 pad2[3];
CollisionCheck_SetAC(play, &play->colChkCtx, cylinder0);
CollisionCheck_SetAC(play, &play->colChkCtx, cylinder1);
CollisionCheck_SetAC(play, &play->colChkCtx, cylinder2);
}
void DemoGj_DirectedExplosion(DemoGj* this, PlayState* play, Vec3f* direction) {
Vec3f pos;
pos.x = this->dyna.actor.world.pos.x;
pos.y = this->dyna.actor.world.pos.y;
pos.z = this->dyna.actor.world.pos.z;
DemoGj_Explode(this, play, &pos, direction);
}
void func_8097B128(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfFloatingInAir(this, play)) {
Vec3f* scale = &this->dyna.actor.scale;
DemoGj_InitCommon(this, play, &gGanonsCastleRubble2Col);
this->updateMode = 18;
this->drawConfig = 16;
scale->x *= 0.8f;
scale->y *= 0.8f;
scale->z *= 0.8f;
}
}
s32 DemoGj_HasCylinderAnyExploded(DemoGj* this, PlayState* play) {
if (DemoGj_HitByExplosion(this, play, &this->cylinders[0])) {
return true;
}
if (DemoGj_HitByExplosion(this, play, &this->cylinders[1])) {
return true;
}
if (DemoGj_HitByExplosion(this, play, &this->cylinders[2])) {
return true;
}
return false;
}
/*
* Checks if should kill the actor and drop collectibles
* Kills the actor if ganon->unk_314==4 (Ganon killed), this rubble was hit by an explosion or killFlag==true
* Used by DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_1
*/
void func_8097B22C(DemoGj* this, PlayState* play) {
Actor* thisx = &this->dyna.actor;
if (func_809797E4(this, 4)) {
Actor_Kill(thisx);
} else if (DemoGj_HasCylinderAnyExploded(this, play)) {
Vec3f vec1 = { 0.0f, 0.0f, 0.0f };
DemoGj_DropCollectible(this, play);
DemoGj_DirectedExplosion(this, play, &vec1);
Actor_Kill(thisx);
} else if (this->killFlag) {
Vec3f vec2 = this->unk_26C;
vec2.y = 0.0f;
DemoGj_DropCollectible(this, play);
DemoGj_DirectedExplosion(this, play, &vec2);
Actor_Kill(thisx);
}
func_8097AEE8(this, play);
DemoGj_SetCylindersAsAC(this, play);
}
// func_8097B340
void DemoGj_Update15(DemoGj* this, PlayState* play) {
DemoGj_FindGanon(this, play);
func_8097B128(this, play);
}
// func_8097B370
void DemoGj_Update18(DemoGj* this, PlayState* play) {
func_8097B22C(this, play);
DemoGj_DoNothing1(this, play);
}
void DemoGj_DrawDestructableRubble1(DemoGj* this, PlayState* play) {
DemoGj_DrawCommon(this, play, gGanonsCastleRubble2DL);
}
// Inits the three cylinders with `sCylinderInit2`
void DemoGj_InitDestructableRubble2(DemoGj* this, PlayState* play) {
DemoGj_InitSetIndexes(this, play, 16, 0, NULL);
DemoGj_InitCylinder(this, play, &this->cylinders[0], &sCylinderInit2);
DemoGj_InitCylinder(this, play, &this->cylinders[1], &sCylinderInit2);
DemoGj_InitCylinder(this, play, &this->cylinders[2], &sCylinderInit2);
}
void DemoGj_DoNothing2(DemoGj* this, PlayState* play) {
}
// Moves the ColliderCylinder's relative to the actor's position.
void func_8097B450(DemoGj* this, PlayState* play) {
ColliderCylinder* cylinder0 = &this->cylinders[0];
ColliderCylinder* cylinder1 = &this->cylinders[1];
ColliderCylinder* cylinder2 = &this->cylinders[2];
Vec3f* actorPos = &this->dyna.actor.world.pos;
s32 pad;
s16 theta = this->dyna.actor.world.rot.y;
f32 cos_theta = Math_CosS(theta);
f32 sin_theta = Math_SinS(theta);
cylinder0->dim.pos.z = actorPos->z - (35.0f * sin_theta);
cylinder0->dim.pos.x = actorPos->x + (35.0f * cos_theta);
cylinder0->dim.pos.y = actorPos->y;
cylinder1->dim.pos.z = actorPos->z - (-10.0f * sin_theta);
cylinder1->dim.pos.x = actorPos->x + (-10.0f * cos_theta);
cylinder1->dim.pos.y = actorPos->y;
cylinder2->dim.pos.z = actorPos->z - (-55.0f * sin_theta);
cylinder2->dim.pos.x = actorPos->x + (-55.0f * cos_theta);
cylinder2->dim.pos.y = actorPos->y;
}
void DemoGj_SetCylindersAsAC2(DemoGj* this, PlayState* play) {
s32 pad[2];
Collider* cylinder0 = &this->cylinders[0].base;
Collider* cylinder1 = &this->cylinders[1].base;
Collider* cylinder2 = &this->cylinders[2].base;
s32 pad2[3];
CollisionCheck_SetAC(play, &play->colChkCtx, cylinder0);
CollisionCheck_SetAC(play, &play->colChkCtx, cylinder1);
CollisionCheck_SetAC(play, &play->colChkCtx, cylinder2);
}
// Does the same as `DemoGj_HasCylinderAnyExploded`
s32 DemoGj_HasCylinderAnyExploded2(DemoGj* this, PlayState* play) {
if (DemoGj_HitByExplosion(this, play, &this->cylinders[0])) {
return true;
}
if (DemoGj_HitByExplosion(this, play, &this->cylinders[1])) {
return true;
}
if (DemoGj_HitByExplosion(this, play, &this->cylinders[2])) {
return true;
}
return false;
}
void DemoGj_DirectedExplosion2(DemoGj* this, PlayState* play, Vec3f* direction) {
Vec3f pos;
pos.x = this->dyna.actor.world.pos.x;
pos.y = this->dyna.actor.world.pos.y;
pos.z = this->dyna.actor.world.pos.z;
DemoGj_Explode(this, play, &pos, direction);
}
void func_8097B6C4(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfFloatingInAir(this, play)) {
Vec3f* scale = &this->dyna.actor.scale;
DemoGj_InitCommon(this, play, &gGanonsCastleRubble3Col);
this->updateMode = 19;
this->drawConfig = 17;
scale->x *= 0.8f;
scale->y *= 0.8f;
scale->z *= 0.8f;
}
}
/*
* Checks if should kill the actor and drop collectibles
* Kills the actor if ganon->unk_314==4 (Ganon killed), this rubble was hit by an explosion or killFlag==true
* Used by DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_2
*/
void func_8097B750(DemoGj* this, PlayState* play) {
Actor* thisx = &this->dyna.actor;
if (func_809797E4(this, 4)) {
Actor_Kill(thisx);
} else if (DemoGj_HasCylinderAnyExploded2(this, play)) {
Vec3f vec1 = { 0.0f, 0.0f, 0.0f };
DemoGj_DropCollectible(this, play);
DemoGj_DirectedExplosion2(this, play, &vec1);
Actor_Kill(thisx);
} else if (this->killFlag) {
Vec3f vec2 = this->unk_26C;
vec2.y = 0.0f;
DemoGj_DropCollectible(this, play);
DemoGj_DirectedExplosion2(this, play, &vec2);
Actor_Kill(thisx);
}
func_8097B450(this, play);
DemoGj_SetCylindersAsAC2(this, play);
}
// func_8097B864
void DemoGj_Update16(DemoGj* this, PlayState* play) {
DemoGj_FindGanon(this, play);
func_8097B6C4(this, play);
}
// func_8097B894
void DemoGj_Update19(DemoGj* this, PlayState* play) {
func_8097B750(this, play);
DemoGj_DoNothing2(this, play);
}
void DemoGj_DemoGj_InitDestructableRubble2(DemoGj* this, PlayState* play) {
DemoGj_DrawCommon(this, play, gGanonsCastleRubble3DL);
}
// Inits the first cylinder (only that one) with `sCylinderInit3`
void DemoGj_InitDestructableRubbleTall(DemoGj* this, PlayState* play) {
DemoGj_InitSetIndexes(this, play, 17, 0, NULL);
DemoGj_InitCylinder(this, play, &this->cylinders[0], &sCylinderInit3);
}
void DemoGj_DoNothing3(DemoGj* this, PlayState* play) {
}
void DemoGj_DirectedDoubleExplosion(DemoGj* this, PlayState* play, Vec3f* direction) {
Vec3f pos;
pos.x = this->dyna.actor.world.pos.x;
pos.y = this->dyna.actor.world.pos.y;
pos.z = this->dyna.actor.world.pos.z;
DemoGj_Explode(this, play, &pos, direction);
pos.x = this->dyna.actor.world.pos.x;
pos.y = this->dyna.actor.world.pos.y + 100.0f;
pos.z = this->dyna.actor.world.pos.z;
DemoGj_Explode(this, play, &pos, direction);
}
void func_8097B9BC(DemoGj* this, PlayState* play) {
if (DemoGj_IsGanondorfFloatingInAir(this, play)) {
Vec3f* scale = &this->dyna.actor.scale;
DemoGj_InitCommon(this, play, &gGanonsCastleRubbleTallCol);
this->updateMode = 20;
this->drawConfig = 18;
scale->x *= 0.8f;
scale->y *= 0.8f;
scale->z *= 0.8f;
}
}
/*
* Checks if should kill the actor and drop collectibles
* Kills the actor if ganon->unk_314==4 (Ganon killed), this rubble was hit by an explosion or killFlag==true
* Used by DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_TALL
*/
void func_8097BA48(DemoGj* this, PlayState* play) {
Actor* thisx = &this->dyna.actor;
ColliderCylinder* cylinder = &this->cylinders[0];
s32 pad[2];
if (func_809797E4(this, 4)) {
Actor_Kill(thisx);
} else if (DemoGj_HitByExplosion(this, play, cylinder)) {
Vec3f vec1 = { 0.0f, 0.0f, 0.0f };
DemoGj_DropCollectible(this, play);
DemoGj_DirectedDoubleExplosion(this, play, &vec1);
Actor_Kill(thisx);
} else if (this->killFlag) {
Vec3f vec2 = this->unk_26C;
vec2.y = 0.0f;
DemoGj_DropCollectible(this, play);
DemoGj_DirectedDoubleExplosion(this, play, &vec2);
Actor_Kill(thisx);
}
Collider_UpdateCylinder(thisx, cylinder);
CollisionCheck_SetAC(play, &play->colChkCtx, &cylinder->base);
}
// func_8097BB78
void DemoGj_Update17(DemoGj* this, PlayState* play) {
DemoGj_FindGanon(this, play);
func_8097B9BC(this, play);
}
// func_8097BBA8
void DemoGj_Update20(DemoGj* this, PlayState* play) {
func_8097BA48(this, play);
DemoGj_DoNothing3(this, play);
}
void DemoGj_DemoGj_InitDestructableRubbleTall(DemoGj* this, PlayState* play) {
DemoGj_DrawCommon(this, play, gGanonsCastleRubbleTallDL);
}
static DemoGjUpdateFunc sUpdateFuncs[] = {
DemoGj_UpdateRubbleAroundArena,
DemoGj_Update01,
DemoGj_Update02,
DemoGj_Update03,
DemoGj_Update04,
DemoGj_Update05,
DemoGj_Update06,
DemoGj_Update07,
DemoGj_Update08,
DemoGj_Update09,
DemoGj_Update10,
DemoGj_Update11,
DemoGj_Update12,
DemoGj_Update13,
DemoGj_Update14,
DemoGj_Update15,
DemoGj_Update16,
DemoGj_Update17,
DemoGj_Update18,
DemoGj_Update19,
DemoGj_Update20,
};
void DemoGj_Update(Actor* thisx, PlayState* play) {
DemoGj* this = (DemoGj*)thisx;
if (this->updateMode < 0 || this->updateMode >= ARRAY_COUNT(sUpdateFuncs) ||
sUpdateFuncs[this->updateMode] == NULL) {
// "The main mode is abnormal!!!!!!!!!!!!!!!!!!!!!!!!!"
osSyncPrintf(VT_FGCOL(RED) "メインモードがおかしい!!!!!!!!!!!!!!!!!!!!!!!!!\n" VT_RST);
return;
}
sUpdateFuncs[this->updateMode](this, play);
}
void DemoGj_Init(Actor* thisx, PlayState* play) {
DemoGj* this = (DemoGj*)thisx;
switch (DemoGj_GetType(this)) {
case DEMOGJ_TYPE_AROUNDARENA:
DemoGj_InitRubbleAroundArena(this, play);
break;
case DEMOGJ_TYPE_RUBBLE_PILE_1:
DemoGj_InitRubblePile1(this, play);
break;
case DEMOGJ_TYPE_RUBBLE_PILE_2:
DemoGj_InitRubblePile2(this, play);
break;
case DEMOGJ_TYPE_RUBBLE_PILE_3:
DemoGj_InitRubblePile3(this, play);
break;
case DEMOGJ_TYPE_RUBBLE_PILE_4:
DemoGj_InitRubblePile4(this, play);
break;
case DEMOGJ_TYPE_RUBBLE_PILE_5:
DemoGj_InitRubblePile5(this, play);
break;
case DEMOGJ_TYPE_RUBBLE_PILE_6:
DemoGj_InitRubblePile6(this, play);
break;
case DEMOGJ_TYPE_RUBBLE_PILE_7:
DemoGj_InitRubblePile7(this, play);
break;
case DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_1:
DemoGj_InitDestructableRubble1(this, play);
break;
case DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_2:
DemoGj_InitDestructableRubble2(this, play);
break;
case DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_TALL:
DemoGj_InitDestructableRubbleTall(this, play);
break;
default:
// "Demo_Gj_Actor_ct There is no such argument!!!!!!!!!!!!!!!!!!!!!!"
osSyncPrintf(VT_FGCOL(RED) "Demo_Gj_Actor_ct そんな引数は無い!!!!!!!!!!!!!!!!!!!!!!\n" VT_RST, play,
this);
Actor_Kill(&this->dyna.actor);
}
}
void DemoGj_DrawNothing(DemoGj* this, PlayState* play) {
}
static DemoGjDrawFunc sDrawFuncs[] = {
DemoGj_DrawNothing,
DemoGj_DrawRubbleAroundArena,
DemoGj_DrawRubble2,
DemoGj_DrawRubble3,
DemoGj_DrawRubble4,
DemoGj_DrawRubble5,
DemoGj_DrawRubble6,
DemoGj_DrawRubble7,
DemoGj_DrawRubbleTall,
DemoGj_DrawRotatedRubble2,
DemoGj_DrawRotatedRubble3,
DemoGj_DrawRotatedRubble4,
DemoGj_DrawRotatedRubble5,
DemoGj_DrawRotatedRubble6,
DemoGj_DrawRotatedRubble7,
DemoGj_DrawRotatedRubbleTall,
DemoGj_DrawDestructableRubble1,
DemoGj_DemoGj_InitDestructableRubble2,
DemoGj_DemoGj_InitDestructableRubbleTall,
};
void DemoGj_Draw(Actor* thisx, PlayState* play) {
DemoGj* this = (DemoGj*)thisx;
if (this->drawConfig < 0 || this->drawConfig >= ARRAY_COUNT(sDrawFuncs) || sDrawFuncs[this->drawConfig] == NULL) {
// "The drawing mode is abnormal!!!!!!!!!!!!!!!!!!!!!!!!!"
osSyncPrintf(VT_FGCOL(RED) "描画モードがおかしい!!!!!!!!!!!!!!!!!!!!!!!!!\n" VT_RST);
return;
}
sDrawFuncs[this->drawConfig](this, play);
}
const ActorInit Demo_Gj_InitVars = {
ACTOR_DEMO_GJ,
ACTORCAT_PROP,
FLAGS,
OBJECT_GJ,
sizeof(DemoGj),
(ActorFunc)DemoGj_Init,
(ActorFunc)DemoGj_Destroy,
(ActorFunc)DemoGj_Update,
(ActorFunc)DemoGj_Draw,
NULL,
};