1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-07-17 13:24:45 +00:00

Phantom Ganon (ovl_Boss_Ganondrof) and related actors (#442)

* Darkmeiro decompilation

Bg_Gnd_Darkmeiro decompiled, matched, and documented.

* give this a shot

* fix conflict

* one more try

* It's Phantom Ganon time

* Fhg_Fire matched

* small touch up

* more documentation

* starting naming fire

* renaming

* cleanup

* hooray for new names

* merge

* first pass

* camera status

* bgcheck

* object 1

* object 2

* .s

* .s

* fig's comments

* implementing zel's suggestions and a few other things

* the work begins

* work continues

* docs, shifts, cleanup

* cleanup

* texture names

* addressing the rest of the notes

Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
This commit is contained in:
petrie911 2021-03-29 14:35:46 -05:00 committed by GitHub
parent 86f16cf662
commit 28cfd82a4f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 2969 additions and 9752 deletions

File diff suppressed because it is too large Load diff

View file

@ -6,11 +6,99 @@
struct BossGanondrof;
typedef void (*BossGanondrofActionFunc)(struct BossGanondrof*, GlobalContext*);
#define GND_REAL_BOSS 1
#define GND_FAKE_BOSS 10
#define GND_BOSSROOM_CENTER_X 14.0f
#define GND_BOSSROOM_CENTER_Y -33.0f
#define GND_BOSSROOM_CENTER_Z -3315.0f
typedef enum {
/* 0 */ GND_FLY_PAINTING,
/* 1 */ GND_FLY_NEUTRAL,
/* 2 */ GND_FLY_VOLLEY,
/* 3 */ GND_FLY_RETURN,
/* 4 */ GND_FLY_CHARGE
} BossGanondrofFlyMode;
typedef enum {
/* 0 */ GND_EYESTATE_NONE,
/* 1 */ GND_EYESTATE_FADE,
/* 2 */ GND_EYESTATE_BRIGHTEN
} BossGanondrofEyeState;
typedef enum {
/* 0 */ GND_VARIANCE_TIMER,
/* 1 */ GND_US_1,
/* 2 */ GND_US_2,
/* 3 */ GND_US_3,
/* 4 */ GND_UNKTIMER_1,
/* 5 */ GND_UNKTIMER_2,
/* 6 */ GND_INVINC_TIMER,
/* 7 */ GND_ACTION_STATE,
/* 8 */ GND_THROW_FRAME,
/* 9 */ GND_THROW_COUNT,
/* 10 */ GND_MASK_OFF,
/* 11 */ GND_EYE_STATE,
/* 12 */ GND_PARTICLE_ANGLE,
/* 13 */ GND_BODY_DECAY_INDEX,
/* 14 */ GND_BODY_DECAY_FLAG,
/* 15 */ GND_LIMB_DECAY_INDEX,
/* 16 */ GND_DEATH_ENV_TIMER,
/* 17 */ GND_DEATH_SFX_TIMER,
/* 20 */ GND_SHORT_COUNT = 20
} BossGanondrofS16Var;
typedef enum {
/* 0 */ GND_FLOAT_SPEED,
/* 1 */ GND_END_FRAME,
/* 2 */ GND_EYE_BRIGHTNESS,
/* 3 */ GND_CAMERA_ZOOM,
/* 4 */ GND_CAMERA_ANGLE,
/* 5 */ GND_EYE_ALPHA,
/* 13 */ GND_FLOAT_COUNT = 13
} BossGanondrofF32Var;
typedef struct BossGanondrof {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0xCC];
/* 0x0218 */ Vec3f bodyPartsPos[24];
/* 0x03C8 */ char unk_3C8[0x1B0];
/* 0x014C */ SkelAnime skelAnime;
/* 0x0190 */ BossGanondrofActionFunc actionFunc;
/* 0x0194 */ s16 work[GND_SHORT_COUNT];
/* 0x01BC */ s16 timers[5];
/* 0x01C6 */ u8 killActor;
/* 0x01C7 */ u8 returnCount;
/* 0x01C8 */ u8 shockTimer;
/* 0x01C9 */ u8 flyMode;
/* 0x01CA */ u8 returnSuccess;
/* 0x01CC */ f32 fwork[GND_FLOAT_COUNT];
/* 0x0200 */ Vec3f spearTip;
/* 0x020C */ Vec3f targetPos;
/* 0x0218 */ Vec3f bodyPartsPos[27]; // only 25 used
/* 0x035C */ s16 deathCamera;
/* 0x035E */ s16 deathState;
/* 0x0360 */ Vec3f cameraEye;
/* 0x036C */ Vec3f cameraAt;
/* 0x0378 */ Vec3f cameraEyeVel;
/* 0x0384 */ Vec3f cameraAtVel;
/* 0x0390 */ Vec3f cameraNextEye;
/* 0x039C */ Vec3f cameraEyeMaxVel;
/* 0x03A8 */ Vec3f cameraNextAt;
/* 0x03B4 */ Vec3f cameraAtMaxVel;
/* 0x03C0 */ f32 cameraSpeedMod;
/* 0x03C4 */ f32 cameraAccel;
/* 0x03C8 */ f32 legRotY;
/* 0x03CC */ f32 legRotZ;
/* 0x03D0 */ f32 legSplitY;
/* 0x03D4 */ f32 armRotY;
/* 0x03D8 */ f32 armRotZ;
/* 0x03DC */ f32 rideRotZ[30]; // possibly only 25 used
/* 0x0454 */ f32 rideRotY[30]; // possibly only 25 used
/* 0x04CC */ LightNode* lightNode;
/* 0x04D0 */ LightInfo lightInfo;
/* 0x04E0 */ ColliderCylinder colliderBody;
/* 0x052C */ ColliderCylinder colliderSpear;
} BossGanondrof; // size = 0x0578
extern const ActorInit Boss_Ganondrof_InitVars;

View file

@ -7,6 +7,7 @@
#include "z_door_shutter.h"
#include "objects/object_demo_kekkai/object_demo_kekkai.h"
#include "overlays/actors/ovl_Boss_Goma/z_boss_goma.h"
#include "objects/object_gnd/object_gnd.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_hidan_objects/object_hidan_objects.h"
@ -87,7 +88,7 @@ static ShutterInfo D_80998134[] = {
{ 0x06006910, gDungeonDoorDL, 130, 12, 20, 15 },
{ 0x060000C0, 0x060001F0, 240, 14, 70, 15 },
{ 0x06000590, 0x06006460, 0, 110, 50, 15 },
{ 0x06012AB0, NULL, 130, 12, 50, 15 },
{ gPhantomGanonBarsDL, NULL, 130, 12, 50, 15 },
{ 0x0601EC20, NULL, 130, 12, 50, 15 },
{ 0x06000100, 0x060001F0, 240, 14, 50, 15 },
{ 0x060010C0, NULL, 130, 12, 50, 15 },
@ -156,7 +157,6 @@ static UNK_PTR D_809982D4[] = {
};
extern CollisionHeader D_0601EDD0; // gohma block collision header
extern CollisionHeader D_06012FD0; // phantom ganon bars collision header
void DoorShutter_SetupAction(DoorShutter* this, DoorShutterActionFunc actionFunc) {
this->actionFunc = actionFunc;
@ -283,7 +283,8 @@ void DoorShutter_SetupType(DoorShutter* this, GlobalContext* globalCtx) {
Actor_SetObjectDependency(globalCtx, &this->dyna.actor);
this->unk_16C = D_809980F0[this->unk_16B].index1;
CollisionHeader_GetVirtual((this->doorType == SHUTTER_GOHMA_BLOCK) ? &D_0601EDD0 : &D_06012FD0, &colHeader);
CollisionHeader_GetVirtual((this->doorType == SHUTTER_GOHMA_BLOCK) ? &D_0601EDD0 : &gPhantomGanonBarsCol,
&colHeader);
this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
if (this->doorType == SHUTTER_GOHMA_BLOCK) {
this->dyna.actor.velocity.y = 0.0f;

View file

@ -5,6 +5,9 @@
*/
#include "z_en_fhg_fire.h"
#include "objects/object_fhg/object_fhg.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h"
#include "overlays/actors/ovl_En_fHG/z_en_fhg.h"
#include "overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.h"
@ -12,28 +15,36 @@
#define THIS ((EnFhgFire*)thisx)
typedef enum {
/* 0 */ STRIKE_INIT,
/* 10 */ STRIKE_BURST = 10,
/* 11 */ STRIKE_TRAILS
} StrikeMode;
typedef enum {
/* 0 */ TRAIL_INIT,
/* 1 */ TRAIL_APPEAR,
/* 2 */ TRAIL_DISSIPATE
} TrailMode;
typedef enum {
/* 0 */ BALL_FIZZLE,
/* 1 */ BALL_BURST,
/* 2 */ BALL_IMPACT
} BallKillMode;
void EnFhgFire_Init(Actor* thisx, GlobalContext* globalCtx);
void EnFhgFire_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnFhgFire_Update(Actor* thisx, GlobalContext* globalCtx);
void EnFhgFire_Draw(Actor* thisx, GlobalContext* globalCtx);
void func_80A0F6F8(EnFhgFire* this, GlobalContext* globalCtx);
void func_80A0FA90(EnFhgFire* this, GlobalContext* globalCtx);
void func_80A0FC48(EnFhgFire* this, GlobalContext* globalCtx);
void func_80A0FD8C(EnFhgFire* this, GlobalContext* globalCtx);
void func_80A10008(EnFhgFire* this, GlobalContext* globalCtx);
void func_80A10220(EnFhgFire* this, GlobalContext* globalCtx);
void func_80A10F18(EnFhgFire* this, GlobalContext* globalCtx);
extern ColliderCylinderInit D_80A11790;
extern Vec3f D_80A117BC;
extern Vec3f D_80A117C8;
extern Vec3f D_80A117D4;
extern Gfx D_0600FAA0[];
extern Gfx D_0600FCF8[];
extern Gfx D_060105E0[];
extern Gfx D_06012160[];
void EnFhgFire_LightningStrike(EnFhgFire* this, GlobalContext* globalCtx);
void EnFhgFire_LightningTrail(EnFhgFire* this, GlobalContext* globalCtx);
void EnFhgFire_LightningShock(EnFhgFire* this, GlobalContext* globalCtx);
void EnFhgFire_LightningBurst(EnFhgFire* this, GlobalContext* globalCtx);
void EnFhgFire_SpearLight(EnFhgFire* this, GlobalContext* globalCtx);
void EnFhgFire_EnergyBall(EnFhgFire* this, GlobalContext* globalCtx);
void EnFhgFire_PhantomWarp(EnFhgFire* this, GlobalContext* globalCtx);
const ActorInit En_Fhg_Fire_InitVars = {
0,
@ -47,224 +58,224 @@ const ActorInit En_Fhg_Fire_InitVars = {
(ActorFunc)EnFhgFire_Draw,
};
void EnFhgFire_SetupAction(EnFhgFire* this, EnFhgFireActionFunc actionFunc) {
this->actionFunc = actionFunc;
static ColliderCylinderInit sCylinderInit = {
{
COLTYPE_NONE,
AT_ON | AT_TYPE_ENEMY,
AC_ON | AC_TYPE_PLAYER,
OC1_ON | OC1_TYPE_ALL,
OC2_TYPE_1,
COLSHAPE_CYLINDER,
},
{
ELEMTYPE_UNK6,
{ 0x00100700, 0x03, 0x20 },
{ 0x0D900700, 0x00, 0x00 },
TOUCH_ON,
BUMP_ON,
OCELEM_ON,
},
{ 20, 30, 10, { 0, 0, 0 } },
};
void EnFhgFire_SetUpdate(EnFhgFire* this, EnFhgFireUpdateFunc updateFunc) {
this->updateFunc = updateFunc;
}
void EnFhgFire_Init(Actor* thisx, GlobalContext* globalCtx) {
f32 tempf0;
s32 pad;
EnFhgFire* this = THIS;
Player* player = PLAYER;
f32 tempf1;
f32 tempf2;
f32 tempf3;
ActorShape_Init(&thisx->shape, 0.0f, NULL, 0.0f);
if ((thisx->params == 0x23) || (thisx->params == 0x24) || (thisx->params == 0x32)) {
ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f);
if ((this->actor.params == FHGFIRE_LIGHTNING_SHOCK) || (this->actor.params == FHGFIRE_LIGHTNING_BURST) ||
(this->actor.params == FHGFIRE_ENERGY_BALL)) {
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, thisx, &D_80A11790);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
}
this->unk_160 = 200.0f;
Actor_SetScale(thisx, 0.0f);
this->fwork[FHGFIRE_ALPHA] = 200.0f;
Actor_SetScale(&this->actor, 0.0f);
if (thisx->params == 0x01) {
EnFhgFire_SetupAction(this, func_80A0F6F8);
Audio_PlayActorSound2(thisx, NA_SE_EN_FANTOM_THUNDER);
} else if (thisx->params >= 0x64) {
EnFhgFire_SetupAction(this, func_80A0FA90);
thisx->shape.rot = thisx->world.rot;
if (this->actor.params == FHGFIRE_LIGHTNING_STRIKE) {
EnFhgFire_SetUpdate(this, EnFhgFire_LightningStrike);
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_THUNDER);
} else if (this->actor.params >= FHGFIRE_LIGHTNING_TRAIL) {
EnFhgFire_SetUpdate(this, EnFhgFire_LightningTrail);
this->actor.shape.rot = this->actor.world.rot;
}
if (this->actor.params == FHGFIRE_LIGHTNING_SHOCK) {
this->actor.draw = NULL;
EnFhgFire_SetUpdate(this, EnFhgFire_LightningShock);
this->actor.speedXZ = 30.0f;
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_SPARK);
} else if (this->actor.params == FHGFIRE_LIGHTNING_BURST) {
EnFhgFire_SetUpdate(this, EnFhgFire_LightningBurst);
this->fwork[FHGFIRE_ALPHA] = 255.0f;
this->work[FHGFIRE_TIMER] = 32;
this->work[FHGFIRE_FX_TIMER] = 50;
this->lensFlareTimer = 10;
if (thisx->params == 0x23) {
thisx->draw = NULL;
EnFhgFire_SetupAction(this, func_80A0FC48);
thisx->speedXZ = 30.0f;
Audio_PlayActorSound2(thisx, NA_SE_EN_FANTOM_SPARK);
return;
}
if (thisx->params == 0x24) {
EnFhgFire_SetupAction(this, func_80A0FD8C);
this->unk_160 = 255.0f;
this->unk_150.x = 0x20;
this->unk_150.y = 0x32;
this->unk_1FE = 0x0A;
tempf2 = thisx->world.rot.x;
this->unk_18C = tempf2 / 100.0f;
tempf1 = tempf2 * 0.13f;
this->collider.dim.radius = tempf1;
this->collider.dim.height = tempf1;
this->fwork[FHGFIRE_BURST_SCALE] = this->actor.world.rot.x / 100.0f;
this->collider.dim.radius = this->actor.world.rot.x * 0.13f;
this->collider.dim.height = this->actor.world.rot.x * 0.13f;
this->collider.dim.yShift = 0;
return;
}
if (thisx->params == 0x26) {
} else if (this->actor.params == FHGFIRE_SPEAR_LIGHT) {
// "light spear"
osSyncPrintf("yari hikari ct 1\n");
EnFhgFire_SetupAction(this, func_80A10008);
EnFhgFire_SetUpdate(this, EnFhgFire_SpearLight);
osSyncPrintf("yari hikari ct 2\n");
this->unk_150.x = thisx->world.rot.x;
this->fireMode = thisx->world.rot.y;
return;
}
this->work[FHGFIRE_TIMER] = this->actor.world.rot.x;
this->work[FHGFIRE_FIRE_MODE] = this->actor.world.rot.y;
} else if ((this->actor.params == FHGFIRE_WARP_EMERGE) || (this->actor.params == FHGFIRE_WARP_RETREAT) ||
(this->actor.params == FHGFIRE_WARP_DEATH)) {
Actor_SetScale(&this->actor, 7.0f);
EnFhgFire_SetUpdate(this, EnFhgFire_PhantomWarp);
if (this->actor.params == FHGFIRE_WARP_DEATH) {
this->work[FHGFIRE_TIMER] = 440;
this->actor.scale.z = 1.0f;
} else {
this->work[FHGFIRE_TIMER] = 76;
Audio_PlayActorSound2(&this->actor, NA_SE_EV_FANTOM_WARP_S);
Audio_PlayActorSound2(&this->actor, NA_SE_EV_FANTOM_WARP_S2);
}
} else if (this->actor.params == FHGFIRE_ENERGY_BALL) {
f32 dxL;
f32 dyL;
f32 dzL;
f32 dxzL;
switch (thisx->params) {
case 0x27:
case 0x28:
case 0x29:
Actor_SetScale(thisx, 7.0f);
EnFhgFire_SetupAction(this, func_80A10F18);
if (thisx->params == 0x29) {
this->unk_150.x = 0x01B8;
thisx->scale.z = 1.0f;
} else {
this->unk_150.x = 0x4C;
Audio_PlayActorSound2(thisx, NA_SE_EV_FANTOM_WARP_S);
Audio_PlayActorSound2(thisx, NA_SE_EV_FANTOM_WARP_S2);
}
return;
}
this->actor.speedXZ = (this->actor.world.rot.x == 0) ? 8.0f : 3.0f;
EnFhgFire_SetUpdate(this, EnFhgFire_EnergyBall);
if (thisx->params == 0x32) {
thisx->speedXZ = (thisx->world.rot.x == 0) ? 8.0f : 3.0f;
EnFhgFire_SetupAction(this, func_80A10220);
this->work[FHGFIRE_TIMER] = 70;
this->work[FHGFIRE_FX_TIMER] = 2;
this->unk_150.x = 0x46;
this->unk_150.y = 0x02;
tempf1 = player->actor.world.pos.x - thisx->world.pos.x;
tempf2 = player->actor.world.pos.y + 30.0f - thisx->world.pos.y;
tempf3 = player->actor.world.pos.z - thisx->world.pos.z;
thisx->world.rot.y = Math_FAtan2F(tempf1, tempf3) * 10430.378f; // 65536/(2*M_PI)
tempf0 = sqrtf(SQ(tempf1) + SQ(tempf3));
thisx->world.rot.x = Math_FAtan2F(tempf2, tempf0) * 10430.378f; // 65536/(2*M_PI)
dxL = player->actor.world.pos.x - this->actor.world.pos.x;
dyL = player->actor.world.pos.y + 30.0f - this->actor.world.pos.y;
dzL = player->actor.world.pos.z - this->actor.world.pos.z;
this->actor.world.rot.y = Math_FAtan2F(dxL, dzL) * (0x8000 / M_PI);
dxzL = sqrtf(SQ(dxL) + SQ(dzL));
this->actor.world.rot.x = Math_FAtan2F(dyL, dxzL) * (0x8000 / M_PI);
this->collider.dim.radius = 40;
this->collider.dim.height = 50;
this->collider.dim.yShift = -25;
this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo);
Lights_PointNoGlowSetInfo(&this->lightInfo, thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.z, 255,
255, 255, 0xFF);
Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.world.pos.x, this->actor.world.pos.y,
this->actor.world.pos.z, 255, 255, 255, 255);
}
}
void EnFhgFire_Destroy(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnFhgFire* this = THIS;
if ((thisx->params == 0x23) || (thisx->params == 0x24) || (thisx->params == 0x32)) {
if ((this->actor.params == FHGFIRE_LIGHTNING_SHOCK) || (this->actor.params == FHGFIRE_LIGHTNING_BURST) ||
(this->actor.params == FHGFIRE_ENERGY_BALL)) {
Collider_DestroyCylinder(globalCtx, &this->collider);
}
if (thisx->params == 0x32) {
if (this->actor.params == FHGFIRE_ENERGY_BALL) {
LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode);
}
}
void func_80A0F6F8(EnFhgFire* this, GlobalContext* globalCtx) {
Camera* camera;
s32 pad;
Vec3f ballVelocity;
Vec3f ballAccel;
void EnFhgFire_LightningStrike(EnFhgFire* this, GlobalContext* globalCtx) {
Camera* camera = Gameplay_GetCamera(globalCtx, 0);
s16 i;
s16 randY;
s16* tmp;
tmp = &this->unk_156;
camera = Gameplay_GetCamera(globalCtx, 0);
switch (this->fireMode) {
case 0x00:
this->fireMode = 0x0A;
this->unk_150.x = 0x07;
switch (this->work[FHGFIRE_FIRE_MODE]) {
case STRIKE_INIT:
this->work[FHGFIRE_FIRE_MODE] = STRIKE_BURST;
this->work[FHGFIRE_TIMER] = 7;
break;
case STRIKE_BURST:
this->actor.shape.rot.y =
Camera_GetInputDirYaw(camera) + 0x8000 * (this->work[FHGFIRE_VARIANCE_TIMER] & 0xFF);
Math_ApproachF(&this->fwork[FHGFIRE_SCALE], 1.0f, 1.0f, 0.2f);
case 0x0A:
this->actor.shape.rot.y = Camera_GetInputDirYaw(camera) + ((*tmp & 0xFF) << 0x0F);
Math_ApproachF(&this->scale, 1.0f, 1.0f, 0.2f);
if (this->unk_150.x == 0) {
this->fireMode = 0x0B;
if (this->work[FHGFIRE_TIMER] == 0) {
this->work[FHGFIRE_FIRE_MODE] = STRIKE_TRAILS;
this->actor.shape.rot.z += 0x8000;
this->unk_150.x = 0x25;
this->work[FHGFIRE_TIMER] = 37;
this->actor.world.pos.y -= 200.0f;
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FHG_FIRE,
this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 500, 0, 0,
0x24);
FHGFIRE_LIGHTNING_BURST);
{
Vec3f sp7C;
Vec3f sp70 = { 0.0f, -1.0f, 0.0f };
ballAccel = D_80A117BC;
for (i = 0; i < 35; i++) {
ballVelocity.x = Rand_CenteredFloat(30.f);
ballVelocity.y = Rand_ZeroFloat(5.0f) + 3.0f;
ballVelocity.z = Rand_CenteredFloat(30.f);
ballAccel.y = -0.2f;
EffectSsFhgFlash_SpawnLightBall(globalCtx, &this->actor.world.pos, &ballVelocity, &ballAccel,
(s16)(Rand_ZeroOne() * 100.0f) + 240, FHGFLASH_LIGHTBALL_GREEN);
for (i = 0; i < 35; i++) {
sp7C.x = Rand_CenteredFloat(30.f);
sp7C.y = Rand_ZeroFloat(5.0f) + 3.0f;
sp7C.z = Rand_CenteredFloat(30.f);
sp70.y = -0.2f;
EffectSsFhgFlash_SpawnLightBall(globalCtx, &this->actor.world.pos, &sp7C, &sp70,
(s16)(Rand_ZeroOne() * 100.0f) + 240, FHGFLASH_LIGHTBALL_GREEN);
}
}
func_80033E88(&this->actor, globalCtx, 4, 10);
}
break;
case STRIKE_TRAILS:
this->actor.shape.rot.y =
Camera_GetInputDirYaw(camera) + (this->work[FHGFIRE_VARIANCE_TIMER] & 0xFF) * 0x8000;
case 0x0B:
this->actor.shape.rot.y = Camera_GetInputDirYaw(camera) + ((*tmp & 0xFF) << 0x0F);
Math_ApproachF(&this->scale, 0.0f, 1.0f, 0.2f);
if (this->unk_150.x == 0x1E) {
randY = (Rand_ZeroOne() < 0.5f) ? 0x1000 : 0;
Math_ApproachF(&this->fwork[FHGFIRE_SCALE], 0.0f, 1.0f, 0.2f);
if (this->work[FHGFIRE_TIMER] == 30) {
s16 randY = (Rand_ZeroOne() < 0.5f) ? 0x1000 : 0;
for (i = 0; i < 8; i++) {
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FHG_FIRE,
this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0,
(i * 8192) + randY, 0x4000, i + 0x64);
(i * 0x2000) + randY, 0x4000, FHGFIRE_LIGHTNING_TRAIL + i);
}
for (i = 0; i < 8; i++) {
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FHG_FIRE,
this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0,
(i * 8192) + randY, 0, 0x23);
(i * 0x2000) + randY, 0, FHGFIRE_LIGHTNING_SHOCK);
}
}
if (this->unk_150.x == 0) {
if (this->work[FHGFIRE_TIMER] == 0) {
Actor_Kill(&this->actor);
}
}
Actor_SetScale(&this->actor, this->scale);
Actor_SetScale(&this->actor, this->fwork[FHGFIRE_SCALE]);
}
void func_80A0FA90(EnFhgFire* this, GlobalContext* globalCtx) {
void EnFhgFire_LightningTrail(EnFhgFire* this, GlobalContext* globalCtx) {
osSyncPrintf("FF MOVE 1\n");
this->actor.shape.rot.x += (s16)(Rand_ZeroOne() * 4000.0f) + 0x4000;
switch (this->fireMode) {
case 0:
this->fireMode = 1;
this->unk_150.x = (s16)(Rand_ZeroOne() * 7.0f) + 0x07;
case 1:
Math_ApproachF(&this->scale, 1.7f, 1.0f, 0.34f);
switch (this->work[FHGFIRE_FIRE_MODE]) {
case TRAIL_INIT:
this->work[FHGFIRE_FIRE_MODE] = TRAIL_APPEAR;
this->work[FHGFIRE_TIMER] = (s16)(Rand_ZeroOne() * 7.0f) + 7;
case TRAIL_APPEAR:
Math_ApproachF(&this->fwork[FHGFIRE_SCALE], 1.7f, 1.0f, 0.34f);
if (this->unk_150.x == 0) {
this->fireMode = 0x02;
this->unk_150.x = 0x0A;
this->actor.world.pos.z += Math_SinS(this->actor.shape.rot.y) * -200.0f * this->scale;
this->actor.world.pos.x += Math_CosS(this->actor.shape.rot.y) * 200.0f * this->scale;
if (this->work[FHGFIRE_TIMER] == 0) {
this->work[FHGFIRE_FIRE_MODE] = TRAIL_DISSIPATE;
this->work[FHGFIRE_TIMER] = 10;
this->actor.world.pos.z += Math_SinS(this->actor.shape.rot.y) * -200.0f * this->fwork[FHGFIRE_SCALE];
this->actor.world.pos.x += Math_CosS(this->actor.shape.rot.y) * 200.0f * this->fwork[FHGFIRE_SCALE];
this->actor.shape.rot.y += 0x8000;
}
break;
case 2:
Math_ApproachZeroF(&this->scale, 1.0f, 0.34f);
if (this->unk_150.x == 0) {
case TRAIL_DISSIPATE:
Math_ApproachZeroF(&this->fwork[FHGFIRE_SCALE], 1.0f, 0.34f);
if (this->work[FHGFIRE_TIMER] == 0) {
Actor_Kill(&this->actor);
}
break;
}
Actor_SetScale(&this->actor, this->scale);
Actor_SetScale(&this->actor, this->fwork[FHGFIRE_SCALE]);
if (this->actor.scale.x > 1.0f) {
this->actor.scale.x = 1.0f;
}
@ -272,7 +283,7 @@ void func_80A0FA90(EnFhgFire* this, GlobalContext* globalCtx) {
osSyncPrintf("FF MOVE 2\n");
}
void func_80A0FC48(EnFhgFire* this, GlobalContext* globalCtx) {
void EnFhgFire_LightningShock(EnFhgFire* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
Vec3f pos;
@ -299,27 +310,27 @@ void func_80A0FC48(EnFhgFire* this, GlobalContext* globalCtx) {
}
}
void func_80A0FD8C(EnFhgFire* this, GlobalContext* globalCtx) {
void EnFhgFire_LightningBurst(EnFhgFire* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
s32 pad;
globalCtx->envCtx.unk_E1 = 0x01;
this->actor.shape.rot.y += 0x1000;
if (this->unk_150.y == 0x31) {
if (this->work[FHGFIRE_FX_TIMER] == 49) {
globalCtx->envCtx.unk_BF = 1;
globalCtx->envCtx.unk_D6 = 0xFF;
}
if (this->unk_150.y == 0x1F) {
if (this->work[FHGFIRE_FX_TIMER] == 31) {
globalCtx->envCtx.unk_BF = 0x00;
globalCtx->envCtx.unk_D6 = 0x14;
}
if (this->unk_150.y >= 0x30) {
if (this->work[FHGFIRE_FX_TIMER] >= 48) {
globalCtx->envCtx.unk_E2[2] = 0xFF;
globalCtx->envCtx.unk_E2[1] = 0xFF;
globalCtx->envCtx.unk_E2[0] = 0xFF;
if (((this->unk_150.x & 0xFF) % 2) != 0) {
if (((this->work[FHGFIRE_TIMER] & 0xFF) % 2) != 0) {
globalCtx->envCtx.unk_E2[3] = 0x46;
} else {
globalCtx->envCtx.unk_E2[3] = 0x00;
@ -328,65 +339,64 @@ void func_80A0FD8C(EnFhgFire* this, GlobalContext* globalCtx) {
globalCtx->envCtx.unk_E2[3] = 0x00;
}
if (this->unk_150.x < 0x15) {
Math_ApproachZeroF(&this->unk_160, 1.0f, 45.0f);
Math_ApproachZeroF(&this->scale, 1.0f, 0.5f);
if (this->work[FHGFIRE_TIMER] <= 20) {
Math_ApproachZeroF(&this->fwork[FHGFIRE_ALPHA], 1.0f, 45.0f);
Math_ApproachZeroF(&this->fwork[FHGFIRE_SCALE], 1.0f, 0.5f);
} else {
Math_ApproachF(&this->scale, this->unk_18C, 0.5f, 3.0f);
Math_ApproachF(&this->fwork[FHGFIRE_SCALE], this->fwork[FHGFIRE_BURST_SCALE], 0.5f, 3.0f);
}
Actor_SetScale(&this->actor, this->scale);
if (3.0f < this->unk_18C) {
Actor_SetScale(&this->actor, this->fwork[FHGFIRE_SCALE]);
if (this->fwork[FHGFIRE_BURST_SCALE] > 3.0f) {
Collider_UpdateCylinder(&this->actor, &this->collider);
if (player->invincibilityTimer == 0) {
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
}
if (this->unk_150.x == 0) {
if (this->work[FHGFIRE_TIMER] == 0) {
Actor_Kill(&this->actor);
globalCtx->envCtx.unk_E1 = 0;
}
if (this->unk_1FE != 0) {
this->unk_1FE--;
this->unk_1FC = 1;
Math_ApproachF(&this->unk_200, 40.0f, 0.3f, 10.0f);
if (this->lensFlareTimer != 0) {
this->lensFlareTimer--;
this->lensFlareOn = true;
Math_ApproachF(&this->lensFlareScale, 40.0f, 0.3f, 10.0f);
} else {
Math_ApproachZeroF(&this->unk_200, 1.0f, 5.0f);
if (this->unk_200 == 0.0f) {
this->unk_1FC = 0;
Math_ApproachZeroF(&this->lensFlareScale, 1.0f, 5.0f);
if (this->lensFlareScale == 0.0f) {
this->lensFlareOn = false;
}
}
// Related to scene draw config 30, only used in BossGanon_Update and
// loaded in z_kankyo
D_8015FCF0 = this->unk_1FC;
D_8015FCF0 = this->lensFlareOn;
D_8015FCF8 = this->actor.world.pos;
D_8015FD06 = this->unk_200;
D_8015FD06 = this->lensFlareScale;
D_8015FD08 = 10.0f;
D_8015FD0C = 0;
}
void func_80A10008(EnFhgFire* this, GlobalContext* globalCtx) {
EnfHG* horse;
void EnFhgFire_SpearLight(EnFhgFire* this, GlobalContext* globalCtx) {
BossGanondrof* bossGnd;
s16 i;
osSyncPrintf("yari hikari 1\n");
horse = (EnfHG*)this->actor.parent;
if ((this->unk_156 % 2) != 0) {
bossGnd = (BossGanondrof*)this->actor.parent;
if ((this->work[FHGFIRE_VARIANCE_TIMER] % 2) != 0) {
Actor_SetScale(&this->actor, 6.0f);
} else {
Actor_SetScale(&this->actor, 5.25f);
}
this->actor.world.pos = horse->unk_200;
this->actor.shape.rot.z += (s16)(Rand_ZeroOne() * 20000.0f) + 0x4000;
this->actor.world.pos = bossGnd->spearTip;
this->actor.shape.rot.z += (s16)(Rand_ZeroOne() * 0x4E20) + 0x4000;
osSyncPrintf("yari hikari 2\n");
if (this->fireMode == 0) {
if (this->work[FHGFIRE_FIRE_MODE] == FHGFIRE_LIGHT_GREEN) {
Vec3f ballPos;
Vec3f ballVelocity = D_80A117C8;
Vec3f ballAccel = D_80A117D4;
Vec3f ballVel = { 0.0f, 0.0f, 0.0f };
Vec3f ballAccel = { 0.0f, 0.0f, 0.0f };
osSyncPrintf("FLASH !!\n");
@ -396,124 +406,354 @@ void func_80A10008(EnFhgFire* this, GlobalContext* globalCtx) {
ballPos.z = Rand_CenteredFloat(20.0f) + this->actor.world.pos.z;
ballAccel.y = -0.08f;
EffectSsFhgFlash_SpawnLightBall(globalCtx, &ballPos, &ballVelocity, &ballAccel,
EffectSsFhgFlash_SpawnLightBall(globalCtx, &ballPos, &ballVel, &ballAccel,
(s16)(Rand_ZeroOne() * 80.0f) + 150, FHGFLASH_LIGHTBALL_GREEN);
}
}
if (this->unk_150.x == 0) {
if (this->work[FHGFIRE_TIMER] == 0) {
Actor_Kill(&this->actor);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fhg_Fire/func_80A10220.s")
void EnFhgFire_EnergyBall(EnFhgFire* this, GlobalContext* globalCtx) {
f32 dxL;
f32 dyL;
f32 dzL;
f32 dxzL;
f32 dxPG;
f32 dyPG;
f32 dzPG;
u8 killMode = BALL_FIZZLE;
u8 canBottleReflect1;
Player* player = PLAYER;
void func_80A10F18(EnFhgFire* this, GlobalContext* globalCtx) {
if (this->work[FHGFIRE_KILL_TIMER] != 0) {
this->work[FHGFIRE_KILL_TIMER]--;
if (this->work[FHGFIRE_KILL_TIMER] == 0) {
Actor_Kill(&this->actor);
return;
}
} else {
s32 canBottleReflect2;
BossGanondrof* bossGnd = (BossGanondrof*)this->actor.parent;
dxPG = bossGnd->targetPos.x - this->actor.world.pos.x;
dyPG = bossGnd->targetPos.y - this->actor.world.pos.y;
dzPG = bossGnd->targetPos.z - this->actor.world.pos.z;
dxL = player->actor.world.pos.x - this->actor.world.pos.x;
dyL = player->actor.world.pos.y + 40.0f - this->actor.world.pos.y;
dzL = player->actor.world.pos.z - this->actor.world.pos.z;
func_8002D908(&this->actor);
func_8002D7EC(&this->actor);
if (this->work[FHGFIRE_VARIANCE_TIMER] & 1) {
Actor_SetScale(&this->actor, 6.0f);
} else {
Actor_SetScale(&this->actor, 5.25f);
}
this->actor.shape.rot.z += (s16)(Rand_ZeroOne() * 0x4E20) + 0x4000;
{
u8 lightBallColor1 = FHGFLASH_LIGHTBALL_GREEN;
s16 i1;
Vec3f spD4;
Vec3f spC8 = { 0.0f, 0.0f, 0.0f };
Vec3f spBC = { 0.0f, 0.0f, 0.0f };
if (this->work[FHGFIRE_FIRE_MODE] >= FHGFIRE_LIGHT_BLUE) {
lightBallColor1 = FHGFLASH_LIGHTBALL_LIGHTBLUE;
}
for (i1 = 0; i1 < 3; i1++) {
spD4.x = Rand_CenteredFloat(20.0f) + this->actor.world.pos.x;
spD4.y = Rand_CenteredFloat(20.0f) + this->actor.world.pos.y;
spD4.z = Rand_CenteredFloat(20.0f) + this->actor.world.pos.z;
spBC.y = -0.08f;
EffectSsFhgFlash_SpawnLightBall(globalCtx, &spD4, &spC8, &spBC, (s16)(Rand_ZeroOne() * 80.0f) + 150,
lightBallColor1);
}
}
switch (this->work[FHGFIRE_FIRE_MODE]) {
case FHGFIRE_LIGHT_GREEN:
canBottleReflect1 =
((player->stateFlags1 & 2) &&
(ABS((s16)(player->actor.shape.rot.y - (s16)(bossGnd->actor.yawTowardsPlayer + 0x8000))) <
0x2000) &&
(sqrtf(SQ(dxL) + SQ(dyL) + SQ(dzL)) <= 25.0f))
? true
: false;
if ((this->collider.base.acFlags & AC_HIT) || canBottleReflect1) {
ColliderInfo* hurtbox = this->collider.info.acHitInfo;
s16 i2;
Vec3f spA8;
Vec3f sp9C = { 0.0f, -0.5f, 0.0f };
s16 angleModX;
s16 angleModY;
for (i2 = 0; i2 < 30; i2++) {
spA8.x = Rand_CenteredFloat(20.0f);
spA8.y = Rand_CenteredFloat(20.0f);
spA8.z = Rand_CenteredFloat(20.0f);
EffectSsFhgFlash_SpawnLightBall(globalCtx, &this->actor.world.pos, &spA8, &sp9C,
(s16)(Rand_ZeroOne() * 25.0f) + 50, FHGFLASH_LIGHTBALL_GREEN);
}
canBottleReflect2 = canBottleReflect1;
if (!canBottleReflect2 && (hurtbox->toucher.dmgFlags & 0x00100000)) {
killMode = BALL_IMPACT;
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_MG, &player->actor.projectedPos, 4, &D_801333E0,
&D_801333E0, &D_801333E8);
func_800AA000(this->actor.xyzDistToPlayerSq, 0xFF, 0x14, 0x96);
} else {
if (bossGnd->flyMode == GND_FLY_NEUTRAL) {
angleModX = Rand_CenteredFloat(0x2000);
angleModY = Rand_CenteredFloat(0x2000);
this->actor.speedXZ = 15.0f;
} else {
angleModX = 0;
angleModY = 0;
this->work[FHGFIRE_RETURN_COUNT]++;
if ((this->work[FHGFIRE_RETURN_COUNT] > 3) && (Rand_ZeroOne() < 0.5f)) {
this->work[FHGFIRE_RETURN_COUNT] = 100;
}
if (!canBottleReflect2 && (player->swordAnimation >= 24)) {
this->actor.speedXZ = 20.0f;
this->work[FHGFIRE_RETURN_COUNT] = 4;
} else {
this->actor.speedXZ += 1.0f;
}
}
this->actor.world.rot.y = (s16)(Math_FAtan2F(dxPG, dzPG) * (0x8000 / M_PI)) + angleModY;
this->actor.world.rot.x =
(s16)(Math_FAtan2F(dyPG, sqrtf((dxPG * dxPG) + (dzPG * dzPG))) * (0x8000 / M_PI)) +
angleModX;
this->work[FHGFIRE_FIRE_MODE] = FHGFIRE_LIGHT_BLUE;
this->work[FHGFIRE_FX_TIMER] = 2;
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_REFLECT_MG, &player->actor.projectedPos, 4, &D_801333E0,
&D_801333E0, &D_801333E8);
func_800AA000(this->actor.xyzDistToPlayerSq, 0xB4, 0x14, 0x64);
}
} else if (sqrtf(SQ(dxL) + SQ(dyL) + SQ(dzL)) <= 25.0f) {
killMode = BALL_BURST;
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_HIT_THUNDER);
if ((bossGnd->flyMode >= GND_FLY_VOLLEY) && (this->work[FHGFIRE_RETURN_COUNT] >= 2)) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_LAUGH);
}
func_8002F698(globalCtx, &this->actor, 3.0f, this->actor.world.rot.y, 0.0f, 3, 0x10);
}
break;
case FHGFIRE_LIGHT_BLUE:
if ((bossGnd->flyMode == GND_FLY_RETURN) && (this->work[FHGFIRE_RETURN_COUNT] < 100)) {
this->actor.world.rot.y = Math_FAtan2F(dxPG, dzPG) * (0x8000 / M_PI);
if ((sqrtf(SQ(dxPG) + SQ(dzPG)) < (150.0f + (this->actor.speedXZ * 8.0f)))) {
this->work[FHGFIRE_FIRE_MODE] = FHGFIRE_LIGHT_REFLECT;
bossGnd->returnSuccess = true;
this->work[FHGFIRE_TIMER] = 8;
}
} else {
if (this->work[FHGFIRE_RETURN_COUNT] >= 100) {
if ((sqrtf(SQ(dxPG) + SQ(dyPG) + SQ(dzPG)) < 100.0f)) {
bossGnd->returnSuccess = true;
}
this->actor.world.rot.y = Math_FAtan2F(dxPG, dzPG) * (0x8000 / M_PI);
this->actor.world.rot.x = Math_FAtan2F(dyPG, sqrtf(SQ(dxPG) + SQ(dzPG))) * (0x8000 / M_PI);
}
if ((fabsf(dxPG) < 30.0f) && (fabsf(dzPG) < 30.0f) && (fabsf(dyPG) < 45.0f)) {
killMode = BALL_IMPACT;
bossGnd->returnCount = this->work[FHGFIRE_RETURN_COUNT] + 1;
Audio_PlaySoundGeneral(NA_SE_EN_FANTOM_HIT_THUNDER, &bossGnd->actor.projectedPos, 4,
&D_801333E0, &D_801333E0, &D_801333E8);
Audio_PlaySoundGeneral(NA_SE_EN_FANTOM_DAMAGE, &bossGnd->actor.projectedPos, 4, &D_801333E0,
&D_801333E0, &D_801333E8);
}
}
break;
case FHGFIRE_LIGHT_REFLECT:
if (this->work[FHGFIRE_TIMER] == 0) {
s16 i3;
Vec3f sp88;
Vec3f sp7C = { 0.0f, -0.5f, 0.0f };
for (i3 = 0; i3 < 30; i3++) {
sp88.x = Rand_CenteredFloat(20.0f);
sp88.y = Rand_CenteredFloat(20.0f);
sp88.z = Rand_CenteredFloat(20.0f);
EffectSsFhgFlash_SpawnLightBall(globalCtx, &this->actor.world.pos, &sp88, &sp7C,
(s16)(Rand_ZeroOne() * 40.0f) + 80, FHGFLASH_LIGHTBALL_GREEN);
}
this->actor.world.rot.y = Math_FAtan2F(dxL, dzL) * (0x8000 / M_PI);
dxzL = sqrtf(SQ(dxL) + SQ(dzL));
this->actor.world.rot.x = Math_FAtan2F(dyL, dxzL) * (0x8000 / M_PI);
this->work[FHGFIRE_FIRE_MODE] = FHGFIRE_LIGHT_GREEN;
Audio_PlayActorSound2(&this->actor, NA_SE_IT_SWORD_REFLECT_MG);
this->actor.speedXZ += 2.0f;
}
break;
}
osSyncPrintf("F_FIRE_MODE %d\n", this->work[FHGFIRE_FIRE_MODE]);
osSyncPrintf("fly_mode %d\n", bossGnd->flyMode);
if (this->work[FHGFIRE_FX_TIMER] == 0) {
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 50.0f, 100.0f, 7);
if ((this->actor.bgCheckFlags & 0x19) || killMode) {
u8 lightBallColor2 = FHGFLASH_LIGHTBALL_GREEN;
s16 i4;
Vec3f sp6C;
Vec3f sp60 = { 0.0f, -1.0f, 0.0f };
if (this->work[FHGFIRE_FIRE_MODE] > FHGFIRE_LIGHT_GREEN) {
lightBallColor2 = FHGFLASH_LIGHTBALL_LIGHTBLUE;
}
for (i4 = 0; i4 < 30; i4++) {
sp6C.x = Rand_CenteredFloat(20.0f);
sp6C.y = Rand_CenteredFloat(20.0f);
sp6C.z = Rand_CenteredFloat(20.0f);
sp60.y = -0.1f;
EffectSsFhgFlash_SpawnLightBall(globalCtx, &this->actor.world.pos, &sp6C, &sp60,
(s16)(Rand_ZeroOne() * 50.0f) + 100, lightBallColor2);
}
if (killMode == BALL_BURST) {
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FHG_FIRE,
this->actor.world.pos.x, player->actor.world.pos.y + 20.0f,
this->actor.world.pos.z, 0xC8, 0, 0, FHGFIRE_LIGHTNING_BURST);
}
bossGnd->flyMode = GND_FLY_NEUTRAL;
this->work[FHGFIRE_KILL_TIMER] = 30;
this->actor.draw = NULL;
if (killMode == BALL_FIZZLE) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_THUNDER_GND);
}
return;
} else {
Collider_UpdateCylinder(&this->actor, &this->collider);
osSyncPrintf("BEFORE setAC %d\n", this->collider.base.shape);
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
osSyncPrintf("AFTER setAC\n");
}
}
Lights_PointNoGlowSetInfo(&this->lightInfo, (s16)this->actor.world.pos.x, (s16)this->actor.world.pos.y,
(s16)this->actor.world.pos.z, 255, 255, 255, 200);
if (this->actor.speedXZ > 20.0f) {
this->actor.speedXZ = 20.0f;
}
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_FIRE - SFX_FLAG);
// Why ah ah ah ah
osSyncPrintf("なぜだああああああああ %d\n", this->work[FHGFIRE_VARIANCE_TIMER]);
}
}
void EnFhgFire_PhantomWarp(EnFhgFire* this, GlobalContext* globalCtx) {
EnfHG* horse = (EnfHG*)this->actor.parent;
f32 phi_f0;
s32 tmp;
f32 scrollDirection;
this->unk_174 = (this->unk_174 + (25.0f * this->unk_184));
this->unk_178 = (this->unk_178 - (40.0f * this->unk_184));
this->unk_17C = (this->unk_17C + (5.0f * this->unk_184));
this->unk_180 = (this->unk_180 - (30.0f * this->unk_184));
this->fwork[FHGFIRE_WARP_TEX_1_X] += 25.0f * this->fwork[FHGFIRE_WARP_TEX_SPEED];
this->fwork[FHGFIRE_WARP_TEX_1_Y] -= 40.0f * this->fwork[FHGFIRE_WARP_TEX_SPEED];
this->fwork[FHGFIRE_WARP_TEX_2_X] += 5.0f * this->fwork[FHGFIRE_WARP_TEX_SPEED];
this->fwork[FHGFIRE_WARP_TEX_2_Y] -= 30.0f * this->fwork[FHGFIRE_WARP_TEX_SPEED];
if (this->actor.params == 0x29) {
if (this->unk_150.x >= 0x47) {
if (this->actor.params == FHGFIRE_WARP_DEATH) {
if (this->work[FHGFIRE_TIMER] > 70) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_FANTOM_WARP_L - SFX_FLAG);
Audio_PlayActorSound2(&this->actor, NA_SE_EV_FANTOM_WARP_L2 - SFX_FLAG);
}
if (this->unk_150.x == 0x46) {
if (this->work[FHGFIRE_TIMER] == 70) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_FANTOM_WARP_S);
Audio_PlayActorSound2(&this->actor, NA_SE_EV_FANTOM_WARP_S2);
}
}
if (this->unk_150.x >= 0x33) {
phi_f0 = 1.0f;
if (this->actor.params >= 0x28) {
phi_f0 = -1.0f;
}
Math_ApproachF(&this->unk_184, phi_f0, 1.0f, 0.04f);
Math_ApproachF(&this->unk_188, 255.0f, 1.0f, 10.2f);
} else {
if (this->unk_150.x < 0x1A) {
Math_ApproachZeroF(&this->unk_184, 1.0f, 0.04f);
Math_ApproachZeroF(&this->unk_188, 1.0f, 10.2f);
if (this->work[FHGFIRE_TIMER] > 50) {
scrollDirection = 1.0f;
if (this->actor.params > FHGFIRE_WARP_EMERGE) {
scrollDirection = -1.0f;
}
Math_ApproachF(&this->fwork[FHGFIRE_WARP_TEX_SPEED], scrollDirection, 1.0f, 0.04f);
Math_ApproachF(&this->fwork[FHGFIRE_WARP_ALPHA], 255.0f, 1.0f, 10.2f);
} else if (this->work[FHGFIRE_TIMER] <= 25) {
Math_ApproachZeroF(&this->fwork[FHGFIRE_WARP_TEX_SPEED], 1.0f, 0.04f);
Math_ApproachZeroF(&this->fwork[FHGFIRE_WARP_ALPHA], 1.0f, 10.2f);
}
osSyncPrintf("EFC 1\n");
if ((this->unk_150.x == 0) || ((this->actor.params == 0x27) && (horse->unk_14F != 0))) {
if ((this->work[FHGFIRE_TIMER] == 0) || ((this->actor.params == FHGFIRE_WARP_EMERGE) && horse->fhgFireKillWarp)) {
Actor_Kill(&this->actor);
}
osSyncPrintf("EFC 2\n");
}
void EnFhgFire_Update(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnFhgFire* this = THIS;
this->unk_156++;
this->work[FHGFIRE_VARIANCE_TIMER]++;
DECR(this->unk_150.x);
DECR(this->unk_150.y);
if (this->work[FHGFIRE_TIMER] != 0) {
this->work[FHGFIRE_TIMER]--;
}
if (this->work[FHGFIRE_FX_TIMER] != 0) {
this->work[FHGFIRE_FX_TIMER]--;
}
this->actionFunc(this, globalCtx);
this->updateFunc(this, globalCtx);
}
static u64* sDustTextures[] = {
gDust1Tex, gDust2Tex, gDust3Tex, gDust4Tex, gDust5Tex, gDust6Tex, gDust7Tex, gDust8Tex,
};
void EnFhgFire_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnFhgFire* this = THIS;
s32 pad;
EnFhgFire* this = THIS;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_fhg_fire.c", 1723);
if (thisx->params == 0x24) {
if (this->actor.params == FHGFIRE_LIGHTNING_BURST) {
func_80093D84(globalCtx->state.gfxCtx);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s8)this->unk_160);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s8)this->fwork[FHGFIRE_ALPHA]);
gDPSetEnvColor(POLY_XLU_DISP++, 165, 255, 75, 0);
gDPPipeSync(POLY_XLU_DISP++);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_fhg_fire.c", 1745),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(D_0600FCF8));
} else if ((thisx->params == 0x26) || (thisx->params == 0x32)) {
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gPhantomLightningBlastDL));
} else if ((this->actor.params == FHGFIRE_SPEAR_LIGHT) || (this->actor.params == FHGFIRE_ENERGY_BALL)) {
osSyncPrintf("yari hikari draw 1\n");
func_800D1FD4(&globalCtx->mf_11DA0);
func_80093D84(globalCtx->state.gfxCtx);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s8)this->unk_160);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s8)this->fwork[FHGFIRE_ALPHA]);
if (this->fireMode > 0) {
if (this->work[FHGFIRE_FIRE_MODE] > FHGFIRE_LIGHT_GREEN) {
gDPSetEnvColor(POLY_XLU_DISP++, 0, 255, 255, 0);
} else {
gDPSetEnvColor(POLY_XLU_DISP++, 165, 255, 75, 0);
}
gDPPipeSync(POLY_XLU_DISP++);
Matrix_RotateZ((thisx->shape.rot.z / 32768.0f) * 3.1416f, 1);
Matrix_RotateZ((this->actor.shape.rot.z / (f32)0x8000) * 3.1416f, 1);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_fhg_fire.c", 1801),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, D_06012160);
} else if ((thisx->params == 0x27) || (thisx->params == 0x28) || (thisx->params == 0x29)) {
gSPDisplayList(POLY_XLU_DISP++, gPhantomEnergyBallDL);
} else if ((this->actor.params == FHGFIRE_WARP_EMERGE) || (this->actor.params == FHGFIRE_WARP_RETREAT) ||
(this->actor.params == FHGFIRE_WARP_DEATH)) {
func_80093D84(globalCtx->state.gfxCtx);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, (u8)this->unk_188);
gDPSetEnvColor(POLY_XLU_DISP++, 90, 50, 95, (s8)(this->unk_188 * 0.5f));
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, (u8)this->fwork[FHGFIRE_WARP_ALPHA]);
gDPSetEnvColor(POLY_XLU_DISP++, 90, 50, 95, (s8)(this->fwork[FHGFIRE_WARP_ALPHA] * 0.5f));
gDPPipeSync(POLY_XLU_DISP++);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_fhg_fire.c", 1833),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (s16)this->unk_174, (s16)this->unk_178, 0x40, 0x40, 1,
(s16)this->unk_17C, (s16)this->unk_180, 0x40, 0x40));
gSPDisplayList(POLY_XLU_DISP++, D_0600FAA0);
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (s16)this->fwork[FHGFIRE_WARP_TEX_1_X],
(s16)this->fwork[FHGFIRE_WARP_TEX_1_Y], 0x40, 0x40, 1,
(s16)this->fwork[FHGFIRE_WARP_TEX_2_X], (s16)this->fwork[FHGFIRE_WARP_TEX_2_Y],
0x40, 0x40));
gSPDisplayList(POLY_XLU_DISP++, gPhantomWarpDL);
} else {
osSyncPrintf("FF DRAW 1\n");
Matrix_Translate(0.0f, -100.0f, 0.0f, 1);
func_80093D84(globalCtx->state.gfxCtx);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s8)this->unk_160);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s8)this->fwork[FHGFIRE_ALPHA]);
gDPSetEnvColor(POLY_XLU_DISP++, 0, 255, 30, 0);
gDPPipeSync(POLY_XLU_DISP++);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_fhg_fire.c", 1892),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, D_060105E0);
gSPDisplayList(POLY_XLU_DISP++, gPhantomLightningDL);
osSyncPrintf("FF DRAW 2\n");
}

View file

@ -6,37 +6,64 @@
struct EnFhgFire;
typedef void (*EnFhgFireActionFunc)(struct EnFhgFire*, GlobalContext *globalCtx);
typedef void (*EnFhgFireUpdateFunc)(struct EnFhgFire*, GlobalContext*);
typedef enum {
/* 1 */ FHGFIRE_LIGHTNING_STRIKE = 1,
/* 35 */ FHGFIRE_LIGHTNING_SHOCK = 35,
/* 36 */ FHGFIRE_LIGHTNING_BURST,
/* 38 */ FHGFIRE_SPEAR_LIGHT = 38,
/* 39 */ FHGFIRE_WARP_EMERGE,
/* 40 */ FHGFIRE_WARP_RETREAT,
/* 41 */ FHGFIRE_WARP_DEATH,
/* 50 */ FHGFIRE_ENERGY_BALL = 50,
/* 100 */ FHGFIRE_LIGHTNING_TRAIL = 100
} FhgFireParam;
typedef enum {
/* 0 */ FHGFIRE_LIGHT_GREEN,
/* 1 */ FHGFIRE_LIGHT_BLUE,
/* 2 */ FHGFIRE_LIGHT_REFLECT
} FhgLightMode;
typedef enum {
/* 0 */ FHGFIRE_TIMER,
/* 1 */ FHGFIRE_FX_TIMER,
/* 2 */ FHGFIRE_US_2,
/* 3 */ FHGFIRE_VARIANCE_TIMER,
/* 4 */ FHGFIRE_FIRE_MODE,
/* 5 */ FHGFIRE_RETURN_COUNT,
/* 6 */ FHGFIRE_KILL_TIMER,
/* 7 */ FHGFIRE_SHORT_COUNT
} FhgFireS16Var;
typedef enum {
/* 0 */ FHGFIRE_ALPHA,
/* 1 */ FHGFIRE_UF_1,
/* 2 */ FHGFIRE_UF_2,
/* 3 */ FHGFIRE_SCALE,
/* 4 */ FHGFIRE_UF_4,
/* 5 */ FHGFIRE_WARP_TEX_1_X,
/* 6 */ FHGFIRE_WARP_TEX_1_Y,
/* 7 */ FHGFIRE_WARP_TEX_2_X,
/* 8 */ FHGFIRE_WARP_TEX_2_Y,
/* 9 */ FHGFIRE_WARP_TEX_SPEED,
/* 10 */ FHGFIRE_WARP_ALPHA,
/* 11 */ FHGFIRE_BURST_SCALE,
/* 15 */ FHGFIRE_FLOAT_COUNT = 15
} FhgFireF32Var;
typedef struct EnFhgFire {
/* 0x0000 */ Actor actor;
/* 0x014C */ EnFhgFireActionFunc actionFunc;
/* 0x0150 */ Vec3s unk_150; // rotation
/* 0x0156 */ s16 unk_156;
/* 0x0158 */ s16 fireMode;
/* 0x015a */ s16 unk_15A;
/* 0x015C */ s16 unk_15C;
/* 0x015E */ char unk_15E[0x02];
/* 0x0160 */ f32 unk_160;
/* 0x0164 */ char unk_164[0x08];
/* 0x016C */ f32 scale;
/* 0x0170 */ char unk_170[0x04];
/* 0x0174 */ f32 unk_174;
/* 0x0178 */ f32 unk_178;
/* 0x017C */ f32 unk_17C;
/* 0x0180 */ f32 unk_180;
/* 0x0184 */ f32 unk_184;
/* 0x0188 */ f32 unk_188;
/* 0x018C */ f32 unk_18C;
/* 0x0190 */ char unk_190[0x0C];
/* 0x014C */ EnFhgFireUpdateFunc updateFunc;
/* 0x0150 */ s16 work[FHGFIRE_SHORT_COUNT];
/* 0x0160 */ f32 fwork[FHGFIRE_FLOAT_COUNT];
/* 0x019C */ LightNode* lightNode;
/* 0x01A0 */ LightInfo lightInfo;
/* 0x01AE */ char unk_1AE[2];
/* 0x01B0 */ ColliderCylinder collider;
/* 0x01FC */ u8 unk_1FC;
/* 0x01FD */ char unk_1FD;
/* 0x01FE */ s16 unk_1FE;
/* 0x0200 */ f32 unk_200;
/* 0x01FC */ u8 lensFlareOn;
/* 0x01FE */ s16 lensFlareTimer;
/* 0x0200 */ f32 lensFlareScale;
} EnFhgFire; // size = 0x0204
extern const ActorInit En_Fhg_Fire_InitVars;

View file

@ -5,17 +5,51 @@
*/
#include "z_en_fhg.h"
#include "objects/object_fhg/object_fhg.h"
#include "objects/object_fhg/object_fhg.h"
#include "overlays/actors/ovl_Door_Shutter/z_door_shutter.h"
#include "overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h"
#include "overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.h"
#define FLAGS 0x00000010
#define THIS ((EnfHG*)thisx)
typedef struct {
/* 0x00 */ Vec3f pos;
/* 0x0C */ s16 yRot;
} EnfHGPainting; // size = 0x10;
typedef enum {
/* 0 */ INTRO_WAIT,
/* 1 */ INTRO_START,
/* 2 */ INTRO_FENCE,
/* 3 */ INTRO_BACK,
/* 4 */ INTRO_REVEAL,
/* 5 */ INTRO_CUT,
/* 6 */ INTRO_LAUGH,
/* 7 */ INTRO_TITLE,
/* 8 */ INTRO_RETREAT,
/* 9 */ INTRO_FINISH,
/* 15 */ INTRO_READY = 15
} EnfHGIntroState;
void EnfHG_Init(Actor* thisx, GlobalContext* globalCtx);
void EnfHG_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnfHG_Update(Actor* thisx, GlobalContext* globalCtx);
void EnfHG_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void EnfHG_SetupIntro(EnfHG* this, GlobalContext* globalCtx);
void EnfHG_Intro(EnfHG* this, GlobalContext* globalCtx);
void EnfHG_SetupApproach(EnfHG* this, GlobalContext* globalCtx, s16 paintingIndex);
void EnfHG_Approach(EnfHG* this, GlobalContext* globalCtx);
void EnfHG_Attack(EnfHG* this, GlobalContext* globalCtx);
void EnfHG_Damage(EnfHG* this, GlobalContext* globalCtx);
void EnfHG_Retreat(EnfHG* this, GlobalContext* globalCtx);
void EnfHG_Done(EnfHG* this, GlobalContext* globalCtx);
void EnfHG_Noop(Actor* thisx, GlobalContext* globalCtx, PSkinAwb* skin);
const ActorInit En_fHG_InitVars = {
ACTOR_EN_FHG,
ACTORCAT_BG,
@ -27,29 +61,673 @@ const ActorInit En_fHG_InitVars = {
(ActorFunc)EnfHG_Update,
(ActorFunc)EnfHG_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_fHG/EnfHG_Init.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_fHG/EnfHG_Destroy.s")
static EnfHGPainting sPaintings[] = {
{ { 0.0f, 60.0f, -315.0f }, 0x0000 }, { { -260.0f, 60.0f, -145.0f }, 0x2AAA },
{ { -260.0f, 60.0f, 165.0f }, 0x5554 }, { { 0.0f, 60.0f, 315.0f }, 0x7FFE },
{ { 260.0f, 60.0f, 155.0f }, 0xAAA8 }, { { 260.0f, 60.0f, -155.0f }, 0xD552 },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_fHG/func_80B62B04.s")
static InitChainEntry sInitChain[] = {
ICHAIN_S8(naviEnemyId, 26, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 1200, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_fHG/func_80B62B6C.s")
void EnfHG_Init(Actor* thisx, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = globalCtx2;
EnfHG* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_fHG/func_80B63D84.s")
Actor_ProcessInitChain(&this->actor, sInitChain);
Flags_SetSwitch(globalCtx, 0x14);
Actor_SetScale(&this->actor, 0.011499999f);
this->actor.gravity = -3.5f;
ActorShape_Init(&this->actor.shape, -2600.0f, NULL, 20.0f);
this->actor.speedXZ = 0.0f;
this->actor.focus.pos = this->actor.world.pos;
this->actor.focus.pos.y += 70.0f;
func_800A663C(globalCtx, &this->skin, &gPhantomHorseSkel, &gPhantomHorseRunningAnim);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_fHG/func_80B6404C.s")
if (this->actor.params >= GND_FAKE_BOSS) {
EnfHG_SetupApproach(this, globalCtx, this->actor.params - GND_FAKE_BOSS);
} else {
EnfHG_SetupIntro(this, globalCtx);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_fHG/func_80B6424C.s")
void EnfHG_Destroy(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnfHG* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_fHG/func_80B6476C.s")
osSyncPrintf("F DT1\n");
func_800A6888(globalCtx, &this->skin);
osSyncPrintf("F DT2\n");
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_fHG/func_80B64AA8.s")
void EnfHG_SetupIntro(EnfHG* this, GlobalContext* globalCtx) {
Animation_PlayLoop(&this->skin.skelAnime, &gPhantomHorseIdleAnim);
this->actionFunc = EnfHG_Intro;
this->actor.world.pos.x = GND_BOSSROOM_CENTER_X;
this->actor.world.pos.y = GND_BOSSROOM_CENTER_Y - 267.0f;
this->actor.world.pos.z = GND_BOSSROOM_CENTER_Z;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_fHG/func_80B64CF4.s")
void EnfHG_Intro(EnfHG* this, GlobalContext* globalCtx) {
static Vec3f audioVec = { 0.0f, 0.0f, 50.0f };
s32 pad64;
Player* player = PLAYER;
BossGanondrof* bossGnd = (BossGanondrof*)this->actor.parent;
s32 pad58;
s32 pad54;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_fHG/EnfHG_Update.s")
if (this->cutsceneState != INTRO_FINISH) {
SkelAnime_Update(&this->skin.skelAnime);
}
switch (this->cutsceneState) {
case INTRO_WAIT:
if ((fabsf(player->actor.world.pos.x - (GND_BOSSROOM_CENTER_X + 0.0f)) < 150.0f) &&
(fabsf(player->actor.world.pos.z - (GND_BOSSROOM_CENTER_Z + 0.0f)) < 150.0f)) {
this->cutsceneState = INTRO_READY;
}
break;
case INTRO_READY:
if ((fabsf(player->actor.world.pos.x - (GND_BOSSROOM_CENTER_X + 0.0f)) < 100.0f) &&
(fabsf(player->actor.world.pos.z - (GND_BOSSROOM_CENTER_Z + 315.0f)) < 100.0f)) {
this->cutsceneState = INTRO_START;
if (gSaveContext.eventChkInf[7] & 4) {
this->timers[0] = 57;
}
}
break;
case INTRO_START:
if (gSaveContext.eventChkInf[7] & 4) {
if (this->timers[0] == 55) {
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_DOOR_SHUTTER,
GND_BOSSROOM_CENTER_X + 0.0f, GND_BOSSROOM_CENTER_Y - 97.0f,
GND_BOSSROOM_CENTER_Z + 308.0f, 0, 0, 0, (SHUTTER_PG_BARS << 6));
}
if (this->timers[0] == 51) {
Audio_PlayActorSound2(this->actor.child, NA_SE_EV_SPEAR_FENCE);
Audio_SetBGM(0x1B);
}
if (this->timers[0] == 0) {
EnfHG_SetupApproach(this, globalCtx, Rand_ZeroOne() * 5.99f);
this->bossGndSignal = FHG_START_FIGHT;
}
break;
}
func_80064520(globalCtx, &globalCtx->csCtx);
func_8002DF54(globalCtx, &this->actor, 8);
this->cutsceneCamera = Gameplay_CreateSubCamera(globalCtx);
Gameplay_ChangeCameraStatus(globalCtx, 0, 1);
Gameplay_ChangeCameraStatus(globalCtx, this->cutsceneCamera, 7);
this->cutsceneState = INTRO_FENCE;
this->timers[0] = 60;
this->actor.world.pos.y = GND_BOSSROOM_CENTER_Y - 7.0f;
Audio_SetBGM(0x100100FF);
gSaveContext.eventChkInf[7] |= 4;
Flags_SetSwitch(globalCtx, 0x23);
case INTRO_FENCE:
player->actor.world.pos.x = GND_BOSSROOM_CENTER_X + 0.0f;
player->actor.world.pos.y = GND_BOSSROOM_CENTER_Y + 7.0f;
player->actor.world.pos.z = GND_BOSSROOM_CENTER_Z + 155.0f;
player->actor.world.rot.y = player->actor.shape.rot.y = 0;
player->actor.speedXZ = 0.0f;
this->cameraEye.x = GND_BOSSROOM_CENTER_X + 0.0f;
this->cameraEye.y = GND_BOSSROOM_CENTER_Y + 37.0f;
this->cameraEye.z = GND_BOSSROOM_CENTER_Z + 170.0f;
this->cameraAt.x = GND_BOSSROOM_CENTER_X + 0.0f;
this->cameraAt.y = GND_BOSSROOM_CENTER_Y + 47.0f;
this->cameraAt.z = GND_BOSSROOM_CENTER_Z + 315.0f;
if (this->timers[0] == 25) {
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_DOOR_SHUTTER,
GND_BOSSROOM_CENTER_X + 0.0f, GND_BOSSROOM_CENTER_Y - 97.0f,
GND_BOSSROOM_CENTER_Z + 308.0f, 0, 0, 0, (SHUTTER_PG_BARS << 6));
}
if (this->timers[0] == 21) {
Audio_PlayActorSound2(this->actor.child, NA_SE_EV_SPEAR_FENCE);
}
if (this->timers[0] == 0) {
this->cutsceneState = INTRO_BACK;
this->timers[0] = 80;
}
break;
case INTRO_BACK:
if (this->timers[0] == 25) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_GANON_HORSE_GROAN);
}
if (this->timers[0] == 20) {
func_8002DF54(globalCtx, &this->actor, 9);
}
if (this->timers[0] == 1) {
Audio_SetBGM(0x23);
}
Math_ApproachF(&this->cameraEye.x, GND_BOSSROOM_CENTER_X + 40.0f, 0.05f, this->cameraSpeedMod * 20.0f);
Math_ApproachF(&this->cameraEye.y, GND_BOSSROOM_CENTER_Y + 37.0f, 0.05f, this->cameraSpeedMod * 20.0f);
Math_ApproachF(&this->cameraEye.z, GND_BOSSROOM_CENTER_Z + 80.0f, 0.05f, this->cameraSpeedMod * 20.0f);
Math_ApproachF(&this->cameraAt.x, GND_BOSSROOM_CENTER_X - 100.0f, 0.05f, this->cameraSpeedMod * 20.0f);
Math_ApproachF(&this->cameraAt.y, GND_BOSSROOM_CENTER_Y + 47.0f, 0.05f, this->cameraSpeedMod * 20.0f);
Math_ApproachF(&this->cameraAt.z, GND_BOSSROOM_CENTER_Z + 335.0f, 0.05f, this->cameraSpeedMod * 20.0f);
Math_ApproachF(&this->cameraSpeedMod, 1.0f, 1.0f, 0.01f);
if (this->timers[0] == 0) {
this->cutsceneState = INTRO_REVEAL;
this->timers[0] = 50;
this->cameraSpeedMod = 0.0f;
}
break;
case INTRO_REVEAL:
Math_ApproachF(&this->cameraEye.x, GND_BOSSROOM_CENTER_X + 70.0f, 0.1f, this->cameraSpeedMod * 20.0f);
Math_ApproachF(&this->cameraEye.y, GND_BOSSROOM_CENTER_Y + 7.0f, 0.1f, this->cameraSpeedMod * 20.0f);
Math_ApproachF(&this->cameraEye.z, GND_BOSSROOM_CENTER_Z + 200.0f, 0.1f, this->cameraSpeedMod * 20.0f);
Math_ApproachF(&this->cameraAt.x, GND_BOSSROOM_CENTER_X - 150.0f, 0.1f, this->cameraSpeedMod * 20.0f);
Math_ApproachF(&this->cameraAt.y, GND_BOSSROOM_CENTER_Y + 107.0f, 0.1f, this->cameraSpeedMod * 20.0f);
Math_ApproachF(&this->cameraAt.z, GND_BOSSROOM_CENTER_Z - 65.0f, 0.1f, this->cameraSpeedMod * 40.0f);
Math_ApproachF(&this->cameraSpeedMod, 1.0f, 1.0f, 0.05f);
if (this->timers[0] == 5) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_HORSE_SANDDUST);
}
if (this->timers[0] == 0) {
this->cutsceneState = INTRO_CUT;
this->timers[0] = 50;
this->cameraSpeedMod = 0.0f;
}
break;
case INTRO_CUT:
this->cutsceneState = INTRO_LAUGH;
this->cameraEye.x = GND_BOSSROOM_CENTER_X + 50.0f;
this->cameraEye.y = GND_BOSSROOM_CENTER_Y + 17.0f;
this->cameraEye.z = GND_BOSSROOM_CENTER_Z + 110.0f;
this->cameraAt.x = GND_BOSSROOM_CENTER_X - 150.0f;
this->cameraAt.y = GND_BOSSROOM_CENTER_Y + 207.0f;
this->cameraAt.z = GND_BOSSROOM_CENTER_Z - 155.0f;
this->cameraEyeVel.x = fabsf(this->cameraEye.x - (GND_BOSSROOM_CENTER_X + 20.0f));
this->cameraEyeVel.y = fabsf(this->cameraEye.y - (GND_BOSSROOM_CENTER_Y + 102.0f));
this->cameraEyeVel.z = fabsf(this->cameraEye.z - (GND_BOSSROOM_CENTER_Z + 25.0f));
this->cameraAtVel.x = fabsf(this->cameraAt.x - (GND_BOSSROOM_CENTER_X - 150.0f));
this->cameraAtVel.y = fabsf(this->cameraAt.y - (GND_BOSSROOM_CENTER_Y + 197.0f));
this->cameraAtVel.z = fabsf(this->cameraAt.z - (GND_BOSSROOM_CENTER_Z - 65.0f));
this->timers[0] = 250;
case INTRO_LAUGH:
Math_ApproachF(&this->cameraEye.x, GND_BOSSROOM_CENTER_X + 20.0f, 0.05f,
this->cameraSpeedMod * this->cameraEyeVel.x);
Math_ApproachF(&this->cameraEye.y, GND_BOSSROOM_CENTER_Y + 102.0f, 0.05f,
this->cameraSpeedMod * this->cameraEyeVel.y);
Math_ApproachF(&this->cameraEye.z, GND_BOSSROOM_CENTER_Z + 25.0f, 0.05f,
this->cameraSpeedMod * this->cameraEyeVel.z);
Math_ApproachF(&this->cameraAt.x, GND_BOSSROOM_CENTER_X - 150.0f, 0.05f,
this->cameraSpeedMod * this->cameraAtVel.x);
Math_ApproachF(&this->cameraAt.y, GND_BOSSROOM_CENTER_Y + 197.0f, 0.05f,
this->cameraSpeedMod * this->cameraAtVel.y);
Math_ApproachF(&this->cameraAt.z, GND_BOSSROOM_CENTER_Z - 65.0f, 0.05f,
this->cameraSpeedMod * this->cameraAtVel.z);
Math_ApproachF(&this->cameraSpeedMod, 0.01f, 1.0f, 0.001f);
if ((this->timers[0] == 245) || (this->timers[0] == 3)) {
Animation_MorphToPlayOnce(&this->skin.skelAnime, &gPhantomHorseRearingAnim, -8.0f);
this->bossGndSignal = FHG_REAR;
Audio_PlayActorSound2(&this->actor, NA_SE_EV_GANON_HORSE_NEIGH);
if (this->timers[0] == 3) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_VOICE);
}
}
if (this->timers[0] == 192) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_HORSE_SANDDUST);
}
if (this->timers[0] == 212) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_HORSE_LAND2);
Animation_Change(&this->skin.skelAnime, &gPhantomHorseIdleAnim, 0.3f, 0.0f, 5.0f, ANIMMODE_LOOP_INTERP,
-10.0f);
}
if (this->timers[0] == 90) {
globalCtx->envCtx.unk_BF = 2;
globalCtx->envCtx.unk_D6 = 0x14;
}
if (this->timers[0] == 100) {
this->bossGndSignal = FHG_LIGHTNING;
}
if (this->timers[0] == 60) {
this->bossGndSignal = FHG_RIDE;
}
if (this->timers[0] == 130) {
Audio_SetBGM(0x105000FF);
}
if (this->timers[0] == 30) {
bossGnd->work[GND_EYE_STATE] = GND_EYESTATE_BRIGHTEN;
}
if (this->timers[0] == 35) {
func_80078914(&audioVec, NA_SE_EN_FANTOM_EYE);
}
if (this->timers[0] == 130) {
bossGnd->work[GND_EYE_STATE] = GND_EYESTATE_FADE;
func_80078914(&audioVec, NA_SE_EN_FANTOM_ST_LAUGH);
}
if (this->timers[0] == 20) {
Audio_SetBGM(0x1B);
}
if (this->timers[0] == 2) {
this->cameraSpeedMod = 0.0f;
this->cutsceneState = INTRO_TITLE;
this->cameraEyeVel.x = fabsf(this->cameraEye.x - (GND_BOSSROOM_CENTER_X + 180.0f));
this->cameraEyeVel.y = fabsf(this->cameraEye.y - (GND_BOSSROOM_CENTER_Y + 7.0f));
this->cameraEyeVel.z = fabsf(this->cameraEye.z - (GND_BOSSROOM_CENTER_Z + 140.0f));
this->timers[0] = 100;
this->timers[1] = 34;
this->cameraAtVel.x = fabsf(this->cameraAt.x - this->actor.world.pos.x);
this->cameraAtVel.y = fabsf(this->cameraAt.y - ((this->actor.world.pos.y + 70.0f) - 20.0f));
this->cameraAtVel.z = fabsf(this->cameraAt.z - this->actor.world.pos.z);
}
break;
case INTRO_TITLE:
if (this->timers[1] == 1) {
Animation_Change(&this->skin.skelAnime, &gPhantomHorseIdleAnim, 0.5f, 0.0f,
Animation_GetLastFrame(&gPhantomHorseIdleAnim), ANIMMODE_LOOP_INTERP, -3.0f);
}
Math_ApproachF(&this->cameraEye.x, GND_BOSSROOM_CENTER_X + 180.0f, 0.1f,
this->cameraSpeedMod * this->cameraEyeVel.x);
Math_ApproachF(&this->cameraEye.y, GND_BOSSROOM_CENTER_Y + 7.0f, 0.1f,
this->cameraSpeedMod * this->cameraEyeVel.y);
Math_ApproachF(&this->cameraEye.z, this->cameraPanZ + (GND_BOSSROOM_CENTER_Z + 140.0f), 0.1f,
this->cameraSpeedMod * this->cameraEyeVel.z);
Math_ApproachF(&this->cameraPanZ, -100.0f, 0.1f, 1.0f);
Math_ApproachF(&this->cameraAt.x, this->actor.world.pos.x, 0.1f, this->cameraSpeedMod * 10.0f);
Math_ApproachF(&this->cameraAt.y, (this->actor.world.pos.y + 70.0f) - 20.0f, 0.1f,
this->cameraSpeedMod * 10.0f);
Math_ApproachF(&this->cameraAt.z, this->actor.world.pos.z, 0.1f, this->cameraSpeedMod * 10.0f);
Math_ApproachF(&this->actor.world.pos.y, 60.0f, 0.1f, 2.0f);
this->actor.world.pos.y += 2.0f * Math_SinS(this->gallopTimer * 0x5DC);
Math_ApproachF(&this->cameraSpeedMod, 1.0f, 1.0f, 0.05f);
if (this->timers[0] == 75) {
TitleCard_InitBossName(globalCtx, &globalCtx->actorCtx.titleCtx,
SEGMENTED_TO_VIRTUAL(&gPhantomGanonTitleCardTex), 0xA0, 0xB4, 0x80, 0x28);
}
if (this->timers[0] == 0) {
this->cutsceneState = INTRO_RETREAT;
this->timers[0] = 200;
this->timers[1] = 23;
this->cameraSpeedMod = 0.0f;
Animation_Change(&this->skin.skelAnime, &gPhantomHorseLeapAnim, 1.0f, 0.0f,
Animation_GetLastFrame(&gPhantomHorseLeapAnim), ANIMMODE_ONCE_INTERP, -4.0f);
this->bossGndSignal = FHG_SPUR;
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_VOICE);
Audio_PlayActorSound2(&this->actor, NA_SE_EV_GANON_HORSE_NEIGH);
}
break;
case INTRO_RETREAT:
if (this->timers[1] == 1) {
Animation_Change(&this->skin.skelAnime, &gPhantomHorseLandAnim, 0.5f, 0.0f,
Animation_GetLastFrame(&gPhantomHorseLandAnim), ANIMMODE_ONCE_INTERP, -3.0f);
this->bossGndSignal = FHG_FINISH;
}
if (this->timers[0] == 170) {
func_8002DF54(globalCtx, &this->actor, 8);
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_MASIC2);
}
Math_ApproachF(&this->cameraEye.z, this->cameraPanZ + (GND_BOSSROOM_CENTER_Z + 100.0f), 0.1f,
this->cameraSpeedMod * 1.5f);
Math_ApproachF(&this->cameraPanZ, -100.0f, 0.1f, 1.0f);
Math_ApproachF(&this->actor.world.pos.z, GND_BOSSROOM_CENTER_Z + 400.0f - 0.5f, 1.0f,
this->cameraSpeedMod * 10.0f);
Math_ApproachF(&this->cameraSpeedMod, 1.0f, 1.0f, 0.05f);
if ((fabsf(this->actor.world.pos.z - (GND_BOSSROOM_CENTER_Z + 400.0f - 0.5f)) < 300.0f) &&
!this->spawnedWarp) {
this->spawnedWarp = true;
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FHG_FIRE,
GND_BOSSROOM_CENTER_X + 0.0f, this->actor.world.pos.y + 50.0f,
GND_BOSSROOM_CENTER_Z + 400.0f - 0.5f, 0, this->actor.shape.rot.y, 0,
FHGFIRE_WARP_RETREAT);
this->fhgFireKillWarp = true;
}
Math_ApproachF(&this->cameraAt.x, this->actor.world.pos.x, 0.2f, 50.0f);
Math_ApproachF(&this->cameraAt.z, this->actor.world.pos.z, 0.2f, 50.0f);
osSyncPrintf("TIME %d-------------------------------------------------\n", this->timers[0]);
if (fabsf(this->actor.world.pos.z - (GND_BOSSROOM_CENTER_Z + 400.0f - 0.5f)) < 1.0f) {
globalCtx->envCtx.unk_BF = 0;
globalCtx->envCtx.unk_D6 = 0x14;
this->cutsceneState = INTRO_FINISH;
Animation_MorphToLoop(&this->skin.skelAnime, &gPhantomHorseRunningAnim, -3.0f);
this->bossGndSignal = FHG_START_FIGHT;
this->timers[1] = 75;
this->timers[0] = 140;
}
break;
case INTRO_FINISH:
EnfHG_Retreat(this, globalCtx);
Math_ApproachF(&this->cameraEye.z, this->cameraPanZ + (GND_BOSSROOM_CENTER_Z + 100.0f), 0.1f,
this->cameraSpeedMod * 1.5f);
Math_ApproachF(&this->cameraPanZ, -100.0f, 0.1f, 1.0f);
Math_ApproachF(&this->cameraAt.y, (this->actor.world.pos.y + 70.0f) - 20.0f, 0.1f,
this->cameraSpeedMod * 10.0f);
if (this->timers[1] == 0) {
Camera* camera = Gameplay_GetCamera(globalCtx, 0);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_fHG/func_80B64E94.s")
camera->eye = this->cameraEye;
camera->eyeNext = this->cameraEye;
camera->at = this->cameraAt;
func_800C08AC(globalCtx, this->cutsceneCamera, 0);
this->cutsceneCamera = 0;
func_80064534(globalCtx, &globalCtx->csCtx);
func_8002DF54(globalCtx, &this->actor, 7);
this->actionFunc = EnfHG_Retreat;
}
break;
}
if (this->cutsceneCamera != 0) {
Gameplay_CameraSetAtEye(globalCtx, this->cutsceneCamera, &this->cameraAt, &this->cameraEye);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_fHG/EnfHG_Draw.s")
void EnfHG_SetupApproach(EnfHG* this, GlobalContext* globalCtx, s16 paintingIndex) {
s16 oppositeIndex[6] = { 3, 4, 5, 0, 1, 2 };
Animation_MorphToLoop(&this->skin.skelAnime, &gPhantomHorseRunningAnim, 0.0f);
this->actionFunc = EnfHG_Approach;
this->curPainting = paintingIndex;
this->targetPainting = oppositeIndex[this->curPainting];
osSyncPrintf("KABE NO 1 = %d\n", this->curPainting);
osSyncPrintf("KABE NO 2 = %d\n", this->targetPainting);
this->actor.world.pos.x = (1.3f * sPaintings[this->curPainting].pos.x) + (GND_BOSSROOM_CENTER_X - 4.0f);
this->actor.world.pos.y = sPaintings[this->curPainting].pos.y + (GND_BOSSROOM_CENTER_Y + 153.0f);
this->actor.world.pos.z = (1.3f * sPaintings[this->curPainting].pos.z) - -(GND_BOSSROOM_CENTER_Z - 10.0f);
this->actor.world.rot.y = sPaintings[this->curPainting].yRot;
osSyncPrintf("XP1 = %f\n", this->actor.world.pos.x);
osSyncPrintf("ZP1 = %f\n", this->actor.world.pos.z);
this->inPaintingPos.x = (sPaintings[this->targetPainting].pos.x * 1.3f) + (GND_BOSSROOM_CENTER_X - 4.0f);
this->inPaintingPos.y = sPaintings[this->targetPainting].pos.y + (GND_BOSSROOM_CENTER_Y + 33.0f);
this->inPaintingPos.z = (sPaintings[this->targetPainting].pos.z * 1.3f) - -(GND_BOSSROOM_CENTER_Z - 10.0f);
this->inPaintingVelX = (fabsf(this->inPaintingPos.x - this->actor.world.pos.x) * 2) * 0.01f;
if (this->inPaintingVelX < 1.0f) {
this->inPaintingVelX = 1.0f;
}
this->inPaintingVelZ = (fabsf(this->inPaintingPos.z - this->actor.world.pos.z) * 2) * 0.01f;
if (this->inPaintingVelZ < 1.0f) {
this->inPaintingVelZ = 1.0f;
}
this->timers[0] = 100;
this->actor.scale.x = 0.002f;
this->actor.scale.y = 0.002f;
this->actor.scale.z = 0.001f;
this->approachRate = 0.0f;
this->warpColorFilterR = globalCtx->lightCtx.unk_07;
this->warpColorFilterG = globalCtx->lightCtx.unk_08;
this->warpColorFilterB = globalCtx->lightCtx.unk_09;
this->warpColorFilterUnk1 = 0.0f;
this->warpColorFilterUnk2 = 0.0f;
this->turnRot = 0;
this->turnTarget = 0;
this->spawnedWarp = false;
}
void EnfHG_Approach(EnfHG* this, GlobalContext* globalCtx) {
osSyncPrintf("STANDBY !!\n");
osSyncPrintf("XP2 = %f\n", this->actor.world.pos.x);
osSyncPrintf("ZP2 = %f\n", this->actor.world.pos.z);
if (this->actor.params == GND_REAL_BOSS) {
this->hoofSfxPos.x = this->actor.projectedPos.x / (this->actor.scale.x * 100.0f);
this->hoofSfxPos.y = this->actor.projectedPos.y / (this->actor.scale.x * 100.0f);
this->hoofSfxPos.z = this->actor.projectedPos.z / (this->actor.scale.x * 100.0f);
if ((this->gallopTimer % 8) == 0) {
func_80078914(&this->hoofSfxPos, NA_SE_EV_HORSE_RUN);
}
}
SkelAnime_Update(&this->skin.skelAnime);
Math_ApproachF(&this->actor.scale.x, 0.011499999f, 1.0f, this->approachRate);
Math_ApproachF(&this->approachRate, 0.0002f, 1.0f, 0.0000015f);
Math_ApproachF(&this->actor.world.pos.y, 60.0f, 0.1f, 1.0f);
this->actor.scale.y = this->actor.scale.x;
if (this->timers[0] == 0) {
osSyncPrintf("arg_data ------------------------------------>%d\n", this->actor.params);
if (this->actor.params != GND_REAL_BOSS) {
this->timers[0] = 140;
this->actionFunc = EnfHG_Retreat;
Animation_MorphToLoop(&this->skin.skelAnime, &gPhantomHorseRunningAnim, 0.0f);
this->turnTarget = -0x8000;
} else {
this->actionFunc = EnfHG_Attack;
Audio_PlayActorSound2(&this->actor, NA_SE_EV_GANON_HORSE_NEIGH);
this->timers[0] = 40;
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FHG_FIRE,
this->actor.world.pos.x, this->actor.world.pos.y + 50.0f, this->actor.world.pos.z, 0,
this->actor.shape.rot.y + 0x8000, 0, FHGFIRE_WARP_EMERGE);
this->fhgFireKillWarp = false;
}
}
}
void EnfHG_Attack(EnfHG* this, GlobalContext* globalCtx) {
osSyncPrintf("KABE OUT !!\n");
this->bossGndInPainting = false;
SkelAnime_Update(&this->skin.skelAnime);
if (this->timers[0] != 0) {
Math_ApproachF(&this->actor.scale.z, 0.011499999f, 1.0f, 0.0002f);
if (this->timers[0] == 1) {
this->bossGndSignal = FHG_RAISE_SPEAR;
this->timers[1] = 50;
Animation_MorphToPlayOnce(&this->skin.skelAnime, &gPhantomHorseLeapAnim, 0.0f);
}
Math_ApproachF(&this->warpColorFilterR, 255.0f, 1.0f, 10.0f);
Math_ApproachF(&this->warpColorFilterG, 255.0f, 1.0f, 10.0f);
Math_ApproachF(&this->warpColorFilterB, 255.0f, 1.0f, 10.0f);
Math_ApproachF(&this->warpColorFilterUnk1, -60.0f, 1.0f, 5.0f);
} else {
Math_ApproachF(&this->warpColorFilterR, globalCtx->lightCtx.unk_07, 1.0f, 10.0f);
Math_ApproachF(&this->warpColorFilterG, globalCtx->lightCtx.unk_07, 1.0f, 10.0f);
Math_ApproachF(&this->warpColorFilterB, globalCtx->lightCtx.unk_07, 1.0f, 10.0f);
Math_ApproachF(&this->warpColorFilterUnk1, 0.0f, 1.0f, 5.0f);
if (this->timers[1] == 29) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_MASIC2);
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_VOICE);
}
if (this->hitTimer == 0) {
if (this->timers[1] == 24) {
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FHG_FIRE,
this->actor.world.pos.x, (this->actor.world.pos.y + 100.0f) + 25.0f,
this->actor.world.pos.z, 0, 0, 0, FHGFIRE_LIGHTNING_STRIKE);
}
if (this->timers[1] == 45) {
Animation_MorphToLoop(&this->skin.skelAnime, &gPhantomHorseAirAnim, 0.0f);
}
if (this->timers[1] == 38) {
this->bossGndSignal = FHG_LIGHTNING;
}
if (this->timers[1] == 16) {
Animation_MorphToPlayOnce(&this->skin.skelAnime, &gPhantomHorseLandAnim, 0.0f);
this->bossGndSignal = FHG_RESET;
}
}
Math_ApproachF(&this->actor.scale.z, 0.011499999f, 1.0f, 0.002f);
Math_ApproachF(&this->actor.world.pos.x, this->inPaintingPos.x, 1.0f, this->inPaintingVelX);
Math_ApproachF(&this->actor.world.pos.y, 60.0f, 0.1f, 1.0f);
Math_ApproachF(&this->actor.world.pos.z, this->inPaintingPos.z, 1.0f, this->inPaintingVelZ);
}
if (this->hitTimer == 20) {
this->actionFunc = EnfHG_Damage;
this->spawnedWarp = false;
Animation_Change(&this->skin.skelAnime, &gPhantomHorseLandAnim, -1.0f, 0.0f,
Animation_GetLastFrame(&gPhantomHorseLandAnim), ANIMMODE_ONCE, -5.0f);
this->timers[0] = 10;
this->bossGndSignal = FHG_RESET;
this->damageSpeedMod = 1.0f;
} else {
f32 dx = this->actor.world.pos.x - this->inPaintingPos.x;
f32 dz = this->actor.world.pos.z - this->inPaintingPos.z;
f32 dxz = sqrtf(SQ(dx) + SQ(dz));
if (dxz < 350.0f) {
this->bossGndInPainting = true;
}
if ((dxz < 300.0f) && !this->spawnedWarp) {
this->spawnedWarp = true;
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FHG_FIRE, this->inPaintingPos.x,
this->actor.world.pos.y + 50.0f, this->inPaintingPos.z, 0, this->actor.shape.rot.y, 0,
FHGFIRE_WARP_RETREAT);
this->fhgFireKillWarp = true;
}
osSyncPrintf("SPD X %f\n", this->inPaintingVelX);
osSyncPrintf("SPD Z %f\n", this->inPaintingVelZ);
osSyncPrintf("X=%f\n", dx);
osSyncPrintf("Z=%f\n", dz);
if (dxz == 0.0f) {
this->timers[0] = 140;
this->actionFunc = EnfHG_Retreat;
Animation_MorphToLoop(&this->skin.skelAnime, &gPhantomHorseRunningAnim, 0.0f);
this->bossGndSignal = FHG_RIDE;
}
}
}
void EnfHG_Damage(EnfHG* this, GlobalContext* globalCtx) {
f32 dx;
f32 dz;
f32 dxz2;
osSyncPrintf("REVISE !!\n");
SkelAnime_Update(&this->skin.skelAnime);
Math_ApproachF(&this->warpColorFilterR, globalCtx->lightCtx.unk_07, 1.0f, 10.0f);
Math_ApproachF(&this->warpColorFilterG, globalCtx->lightCtx.unk_07, 1.0f, 10.0f);
Math_ApproachF(&this->warpColorFilterB, globalCtx->lightCtx.unk_07, 1.0f, 10.0f);
Math_ApproachF(&this->warpColorFilterUnk1, 0.0f, 1.0f, 5.0f);
Math_ApproachF(&this->actor.scale.z, 0.011499999f, 1.0f, 0.002f);
if (this->timers[0] != 0) {
Math_ApproachZeroF(&this->damageSpeedMod, 1.0f, 0.1f);
if (this->timers[0] == 1) {
this->targetPainting = this->curPainting;
this->inPaintingPos.x = (sPaintings[this->targetPainting].pos.x * 1.3f) + (GND_BOSSROOM_CENTER_X - 4.0f);
this->inPaintingPos.y = sPaintings[this->targetPainting].pos.y;
this->inPaintingPos.z = (sPaintings[this->targetPainting].pos.z * 1.3f) - -(GND_BOSSROOM_CENTER_Z - 10.0f);
}
} else {
Math_ApproachF(&this->damageSpeedMod, 1.0f, 1.0f, 0.1f);
}
Math_ApproachF(&this->actor.world.pos.x, this->inPaintingPos.x, 1.0f, this->damageSpeedMod * this->inPaintingVelX);
Math_ApproachF(&this->actor.world.pos.y, 60.0f, 0.1f, 1.0f);
Math_ApproachF(&this->actor.world.pos.z, this->inPaintingPos.z, 1.0f, this->damageSpeedMod * this->inPaintingVelZ);
dx = this->actor.world.pos.x - this->inPaintingPos.x;
dz = this->actor.world.pos.z - this->inPaintingPos.z;
dxz2 = sqrtf(SQ(dx) + SQ(dz));
if ((dxz2 < 300.0f) && (!this->spawnedWarp)) {
this->spawnedWarp = true;
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FHG_FIRE, this->inPaintingPos.x,
this->actor.world.pos.y + 50.0f, this->inPaintingPos.z, 0, this->actor.shape.rot.y + 0x8000,
0, FHGFIRE_WARP_RETREAT);
}
if (dxz2 == 0.0f) {
BossGanondrof* bossGnd = (BossGanondrof*)this->actor.parent;
this->timers[0] = 140;
this->actionFunc = EnfHG_Retreat;
Animation_MorphToLoop(&this->skin.skelAnime, &gPhantomHorseRunningAnim, 0.0f);
if (bossGnd->actor.colChkInfo.health > 24) {
this->bossGndSignal = FHG_RIDE;
} else {
bossGnd->flyMode = GND_FLY_NEUTRAL;
}
this->turnTarget = -0x8000;
}
}
void EnfHG_Retreat(EnfHG* this, GlobalContext* globalCtx) {
osSyncPrintf("KABE IN !!\n");
if (this->turnTarget != 0) {
Math_ApproachS(&this->turnRot, this->turnTarget, 5, 2000);
}
if (this->actor.params == GND_REAL_BOSS) {
this->hoofSfxPos.x = this->actor.projectedPos.x / (this->actor.scale.x * 100.0f);
this->hoofSfxPos.y = this->actor.projectedPos.y / (this->actor.scale.x * 100.0f);
this->hoofSfxPos.z = this->actor.projectedPos.z / (this->actor.scale.x * 100.0f);
if ((this->gallopTimer % 8) == 0) {
func_80078914(&this->hoofSfxPos, NA_SE_EV_HORSE_RUN);
}
}
SkelAnime_Update(&this->skin.skelAnime);
Math_ApproachF(&this->actor.scale.z, 0.001f, 1.0f, 0.001f);
Math_ApproachF(&this->actor.scale.x, 0.002f, 0.05f, 0.0001f);
Math_ApproachF(&this->actor.world.pos.y, 200.0f, 0.05f, 1.0f);
this->actor.scale.y = this->actor.scale.x;
if ((this->timers[0] == 80) && (this->actor.params == GND_REAL_BOSS)) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_FANTOM_LAUGH);
}
if (this->timers[0] == 0) {
BossGanondrof* bossGnd = (BossGanondrof*)this->actor.parent;
s16 paintingIdxReal;
s16 paintingIdxFake;
if (this->actor.params != GND_REAL_BOSS) {
this->killActor = true;
bossGnd->killActor = true;
} else if (bossGnd->flyMode != GND_FLY_PAINTING) {
this->actionFunc = EnfHG_Done;
this->actor.draw = NULL;
} else {
paintingIdxReal = Rand_ZeroOne() * 5.99f;
EnfHG_SetupApproach(this, globalCtx, paintingIdxReal);
do {
paintingIdxFake = Rand_ZeroOne() * 5.99f;
} while (paintingIdxFake == paintingIdxReal);
osSyncPrintf("ac1 = %x `````````````````````````````````````````````````\n",
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_BOSS_GANONDROF,
this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z,
0, 0, 0, paintingIdxFake + GND_FAKE_BOSS));
}
}
}
void EnfHG_Done(EnfHG* this, GlobalContext* globalCtx) {
this->bossGndInPainting = false;
}
void EnfHG_Update(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
EnfHG* this = THIS;
u8 i;
if (this->killActor) {
Actor_Kill(&this->actor);
return;
}
this->gallopTimer++;
this->bossGndInPainting = true;
for (i = 0; i < 5; i++) {
if (this->timers[i] != 0) {
this->timers[i]--;
}
}
this->actionFunc(this, globalCtx);
if (this->hitTimer != 0) {
this->hitTimer--;
}
this->actor.focus.pos = this->actor.world.pos;
this->actor.focus.pos.y += 70.0f;
this->actor.shape.rot.y = this->actor.world.rot.y;
this->actor.shape.yOffset = Math_SinS(this->hitTimer * 0x9000) * 700.0f * (this->hitTimer / 20.0f);
this->actor.shape.rot.z = (s16)(Math_SinS(this->hitTimer * 0x7000) * 1500.0f) * (this->hitTimer / 20.0f);
}
void EnfHG_Noop(Actor* thisx, GlobalContext* globalCtx, PSkinAwb* skin) {
}
void EnfHG_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnfHG* this = THIS;
BossGanondrof* bossGnd = (BossGanondrof*)this->actor.parent;
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_fhg.c", 2439);
func_80093D18(globalCtx->state.gfxCtx);
POLY_OPA_DISP = ((bossGnd->work[GND_INVINC_TIMER] & 4) && (bossGnd->flyMode == GND_FLY_PAINTING))
? Gfx_SetFog(POLY_OPA_DISP, 255, 50, 0, 0, 900, 1099)
: Gfx_SetFog(POLY_OPA_DISP, (u32)this->warpColorFilterR, (u32)this->warpColorFilterG,
(u32)this->warpColorFilterB, 0, (s32)this->warpColorFilterUnk1 + 995,
(s32)this->warpColorFilterUnk2 + 1000);
func_800A6330(&this->actor, globalCtx, &this->skin, EnfHG_Noop, 0x23);
POLY_OPA_DISP = func_800BC8A0(globalCtx, POLY_OPA_DISP);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_fhg.c", 2480);
}

View file

@ -6,21 +6,59 @@
struct EnfHG;
typedef void (*EnfHGActionFunc)(struct EnfHG*, GlobalContext*);
typedef enum {
/* 0 */ FHG_NO_SIGNAL,
/* 1 */ FHG_RAISE_SPEAR,
/* 2 */ FHG_REAR,
/* 3 */ FHG_LIGHTNING,
/* 4 */ FHG_RESET,
/* 5 */ FHG_RIDE,
/* 10 */ FHG_SPUR = 10,
/* 11 */ FHG_FINISH,
/* -1 */ FHG_START_FIGHT = 255
} EnfHGSignal;
typedef struct EnfHG {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x3];
/* 0x014F */ u8 unk_14F;
/* 0x0150 */ char unk_150[0x77];
/* 0x01C7 */ u8 unk_1C7;
/* 0x01C8 */ char unk_1C8;
/* 0x01C9 */ u8 flyMode;
/* 0x01CA */ u8 unk_1CA;
/* 0x01CB */ char unk_1CB[0x15];
/* 0x014C */ u8 bossGndSignal;
/* 0x014D */ u8 bossGndInPainting;
/* 0x014E */ u8 killActor;
/* 0x014F */ u8 fhgFireKillWarp;
/* 0x0150 */ Vec3f cameraEye;
/* 0x015C */ Vec3f cameraAt;
/* 0x0168 */ Vec3f cameraEyeVel;
/* 0x0174 */ Vec3f cameraAtVel;
/* 0x0180 */ Vec3f hoofSfxPos;
/* 0x018C */ Vec3f inPaintingPos;
/* 0x0198 */ f32 inPaintingVelX;
/* 0x019C */ f32 inPaintingVelZ;
/* 0x0198 */ f32 damageSpeedMod;
/* 0x01A4 */ f32 approachRate;
/* 0x01A8 */ f32 cameraSpeedMod;
/* 0x01AC */ f32 cameraPanZ;
/* 0x01B0 */ char unk_1B0[0x10];
/* 0x01C0 */ s16 gallopTimer;
/* 0x01C2 */ s16 curPainting;
/* 0x01C4 */ s16 targetPainting;
/* 0x01C6 */ s16 turnTarget;
/* 0x01C8 */ s16 spawnedWarp;
/* 0x01CA */ s16 cutsceneState;
/* 0x01CC */ s16 cutsceneCamera;
/* 0x01CE */ char unk_1CE[6];
/* 0x01D4 */ s16 timers[5];
/* 0x01DE */ s16 hitTimer;
/* 0x01E0 */ s16 turnRot;
/* 0x01E2 */ char unk_1E2[0x1E];
/* 0x0200 */ Vec3f unk_200;
/* 0x020C */ Vec3f unk_20C;
/* 0x0218 */ char unk_218[0x7C];
/* 0x01E2 */ char unk_1E2[6];
/* 0x01E8 */ f32 warpColorFilterR;
/* 0x01EC */ f32 warpColorFilterG;
/* 0x01F0 */ f32 warpColorFilterB;
/* 0x01F4 */ f32 warpColorFilterUnk1;
/* 0x01F8 */ f32 warpColorFilterUnk2;
/* 0x01FC */ EnfHGActionFunc actionFunc;
/* 0x0200 */ char unk_200[4];
/* 0x0204 */ PSkinAwb skin;
} EnfHG; // size = 0x0294
extern const ActorInit En_Fhg_InitVars;

View file

@ -5,6 +5,7 @@
*/
#include "z_item_b_heart.h"
#include "objects/object_gi_hearts/object_gi_hearts.h"
#define FLAGS 0x00000000
@ -17,9 +18,6 @@ void ItemBHeart_Draw(Actor* thisx, GlobalContext* globalCtx);
void func_80B85264(ItemBHeart* this, GlobalContext* globalCtx);
extern Gfx D_06001290[];
extern Gfx D_06001470[];
const ActorInit Item_B_Heart_InitVars = {
ACTOR_ITEM_B_HEART,
ACTORCAT_MISC,
@ -67,11 +65,11 @@ void ItemBHeart_Update(Actor* thisx, GlobalContext* globalCtx) {
}
void func_80B85264(ItemBHeart* this, GlobalContext* globalCtx) {
f32 temp;
f32 yOffset;
this->unk_164 += 1;
temp = ((Math_SinS(this->unk_164 * 1548) * 5.0f) + 20.0f);
Math_ApproachF(&this->actor.world.pos.y, this->actor.home.pos.y + temp, 0.1f, this->unk_158);
this->unk_164++;
yOffset = (Math_SinS(this->unk_164 * 0x60C) * 5.0f) + 20.0f;
Math_ApproachF(&this->actor.world.pos.y, this->actor.home.pos.y + yOffset, 0.1f, this->unk_158);
Math_ApproachF(&this->unk_158, 2.0f, 1.0f, 0.1f);
this->actor.shape.rot.y += 0x400;
@ -82,7 +80,7 @@ void func_80B85264(ItemBHeart* this, GlobalContext* globalCtx) {
void ItemBHeart_Draw(Actor* thisx, GlobalContext* globalCtx) {
ItemBHeart* this = THIS;
Actor* actorIt;
u8 flag = 0;
u8 flag = false;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_item_b_heart.c", 506);
@ -90,25 +88,24 @@ void ItemBHeart_Draw(Actor* thisx, GlobalContext* globalCtx) {
while (actorIt != NULL) {
if ((actorIt->id == ACTOR_DOOR_WARP1) && (actorIt->projectedPos.z > this->actor.projectedPos.z)) {
flag = 1;
flag = true;
break;
} else {
actorIt = actorIt->next;
}
actorIt = actorIt->next;
}
if (flag) {
func_80093D84(globalCtx->state.gfxCtx);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_item_b_heart.c", 551),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, D_06001290);
gSPDisplayList(POLY_XLU_DISP++, D_06001470);
gSPDisplayList(POLY_XLU_DISP++, gGiHeartBorderDL);
gSPDisplayList(POLY_XLU_DISP++, gGiHeartContainerDL);
} else {
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_item_b_heart.c", 557),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, D_06001290);
gSPDisplayList(POLY_OPA_DISP++, D_06001470);
gSPDisplayList(POLY_OPA_DISP++, gGiHeartBorderDL);
gSPDisplayList(POLY_OPA_DISP++, gGiHeartContainerDL);
}
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_item_b_heart.c", 561);