mirror of
https://github.com/zeldaret/oot.git
synced 2025-07-03 06:24:30 +00:00
EnEncount2 and EnFireRock OK (#659)
* first two funcs done * fixing struct var name due to external use * func_80A07CA4 done * started EnEncount2_Update * EnEncount2_Update done * Encount2 done! * EnFireRock_Init done (but will only match once initvars are uncommented * progress * 4 funcs left * Fully matching * minor formatting * renames * change structs back to normal * formatting * removing unused comments * even more formatting stuff * removed unused asm * pr stuff * pr stuff * added newline at end of file * some merge suggestions * more pr stuff * review Co-authored-by: fig02 <fig02srl@gmail.com>
This commit is contained in:
parent
8e0fa07a7e
commit
ca5a9aa7d1
27 changed files with 755 additions and 2752 deletions
|
@ -1,16 +1,30 @@
|
|||
#include "z_en_encount2.h"
|
||||
#include "overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.h"
|
||||
#include "vt.h"
|
||||
|
||||
#define FLAGS 0x00000030
|
||||
|
||||
#define THIS ((EnEncount2*)thisx)
|
||||
|
||||
typedef enum {
|
||||
/* 0x0 */ ENCOUNT2_INACTIVE,
|
||||
/* 0x1 */ ENCOUNT2_ACTIVE_DEATH_MOUNTAIN,
|
||||
/* 0x2 */ ENCOUNT2_ACTIVE_GANONS_TOWER
|
||||
} Encount2State;
|
||||
|
||||
void EnEncount2_Init(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnEncount2_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnEncount2_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
extern UNK_TYPE D_06000DE0;
|
||||
void EnEncount2_Wait(EnEncount2* this, GlobalContext* globalCtx);
|
||||
void EnEncount2_SpawnRocks(EnEncount2* this, GlobalContext* globalCtx);
|
||||
|
||||
void EnEncount2_ParticleInit(EnEncount2* this, Vec3f* particlePos, f32 scale);
|
||||
void EnEncount2_ParticleDraw(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnEncount2_ParticleUpdate(EnEncount2* this, GlobalContext* globalCtx);
|
||||
|
||||
extern Gfx* D_06000DE0[];
|
||||
|
||||
/*
|
||||
const ActorInit En_Encount2_InitVars = {
|
||||
ACTOR_EN_ENCOUNT2,
|
||||
ACTORCAT_ENEMY,
|
||||
|
@ -22,19 +36,339 @@ const ActorInit En_Encount2_InitVars = {
|
|||
(ActorFunc)EnEncount2_Update,
|
||||
(ActorFunc)EnEncount2_Draw,
|
||||
};
|
||||
*/
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Encount2/EnEncount2_Init.s")
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Encount2/func_80A07A4C.s")
|
||||
void EnEncount2_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnEncount2* this = THIS;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Encount2/func_80A07CA4.s")
|
||||
if (globalCtx->sceneNum != SCENE_SPOT16) {
|
||||
this->isNotDeathMountain = true;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Encount2/EnEncount2_Update.s")
|
||||
if (!this->isNotDeathMountain) {
|
||||
osSyncPrintf("\n\n");
|
||||
// "☆☆☆☆☆ Death Mountain Encount2 set ☆☆☆☆☆"
|
||||
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ デスマウンテンエンカウント2セットされました ☆☆☆☆☆ %d\n" VT_RST,
|
||||
this->actor.params);
|
||||
if (LINK_IS_ADULT && (gSaveContext.eventChkInf[4] & 0x200)) { // flag for having used fire temple blue warp
|
||||
Actor_Kill(thisx);
|
||||
}
|
||||
} else {
|
||||
osSyncPrintf("\n\n");
|
||||
// "☆☆☆☆☆ Ganon Tower Escape Encount2 set ☆☆☆☆☆"
|
||||
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ ガノンタワー脱出エンカウント2セットされました ☆☆☆☆☆ %d\n" VT_RST,
|
||||
this->actor.params);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Encount2/EnEncount2_Draw.s")
|
||||
this->actionFunc = EnEncount2_Wait;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Encount2/func_80A08694.s")
|
||||
void EnEncount2_Wait(EnEncount2* this, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
s16 quakeIndex;
|
||||
s16 spawnerState;
|
||||
Player* player = PLAYER;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Encount2/func_80A08748.s")
|
||||
spawnerState = ENCOUNT2_INACTIVE;
|
||||
if (!this->isNotDeathMountain) {
|
||||
if ((player->actor.world.pos.y > 1500.0f) && (player->actor.world.pos.x > -700.0f) &&
|
||||
(player->actor.world.pos.x < 100.0f) && (player->actor.world.pos.z < -1290.0f) &&
|
||||
(player->actor.world.pos.z > -3600.0f)) {
|
||||
spawnerState = ENCOUNT2_ACTIVE_DEATH_MOUNTAIN;
|
||||
}
|
||||
} else if ((this->actor.xzDistToPlayer < 700.0f) && (Flags_GetSwitch(globalCtx, 0x37))) {
|
||||
s16 scene = globalCtx->sceneNum;
|
||||
if (((scene == SCENE_GANON_DEMO) || (scene == SCENE_GANON_FINAL) || (scene == SCENE_GANON_SONOGO) ||
|
||||
(scene == SCENE_GANONTIKA_SONOGO)) &&
|
||||
(!this->collapseSpawnerInactive)) {
|
||||
spawnerState = ENCOUNT2_ACTIVE_GANONS_TOWER;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Encount2/func_80A0891C.s")
|
||||
switch (spawnerState) {
|
||||
case ENCOUNT2_INACTIVE:
|
||||
this->isQuaking = false;
|
||||
this->envEffectsTimer--;
|
||||
if (this->envEffectsTimer <= 0) {
|
||||
this->envEffectsTimer = 0;
|
||||
}
|
||||
break;
|
||||
case ENCOUNT2_ACTIVE_DEATH_MOUNTAIN:
|
||||
if ((this->deathMountainSpawnerTimer == 1) || (!this->isQuaking)) {
|
||||
quakeIndex = Quake_Add(ACTIVE_CAM, 1);
|
||||
Quake_SetSpeed(quakeIndex, 0x7FFF);
|
||||
Quake_SetQuakeValues(quakeIndex, 50, 0, 0, 0);
|
||||
Quake_SetCountdown(quakeIndex, 300);
|
||||
this->isQuaking = true;
|
||||
}
|
||||
case ENCOUNT2_ACTIVE_GANONS_TOWER:
|
||||
this->envEffectsTimer++;
|
||||
if (this->envEffectsTimer > 60) {
|
||||
this->envEffectsTimer = 60;
|
||||
}
|
||||
if (this->deathMountainSpawnerTimer == 0) {
|
||||
this->deathMountainSpawnerTimer = 200;
|
||||
this->numSpawnedRocks = 0;
|
||||
this->actionFunc = EnEncount2_SpawnRocks;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void EnEncount2_SpawnRocks(EnEncount2* this, GlobalContext* globalCtx) {
|
||||
Player* player = PLAYER;
|
||||
EnFireRock* spawnedRock;
|
||||
f32 tempVec1X;
|
||||
f32 tempVec1Y;
|
||||
f32 tempVec1Z;
|
||||
f32 magnitude;
|
||||
f32 tempVec2X;
|
||||
f32 tempVec2Y;
|
||||
f32 tempVec2Z;
|
||||
f32 particleScale;
|
||||
Vec3f particlePos;
|
||||
s16 spawnedRockType;
|
||||
s16 spawnerState;
|
||||
s16 maxRocks;
|
||||
|
||||
this->envEffectsTimer++;
|
||||
|
||||
if (this->envEffectsTimer > 60) {
|
||||
this->envEffectsTimer = 60;
|
||||
}
|
||||
|
||||
spawnerState = ENCOUNT2_INACTIVE;
|
||||
|
||||
if (!this->isNotDeathMountain) {
|
||||
if (this->deathMountainSpawnerTimer == 0) {
|
||||
this->deathMountainSpawnerTimer = 100;
|
||||
this->actionFunc = EnEncount2_Wait;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((player->actor.world.pos.y > 1500.0f) && (player->actor.world.pos.x > -700.0f) &&
|
||||
(player->actor.world.pos.x < 100.0f) && (player->actor.world.pos.z < -1290.0f) &&
|
||||
(player->actor.world.pos.z > -3860.0f)) {
|
||||
maxRocks = 2;
|
||||
spawnerState = ENCOUNT2_ACTIVE_DEATH_MOUNTAIN;
|
||||
}
|
||||
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EV_VOLCANO - SFX_FLAG);
|
||||
} else if ((this->actor.xzDistToPlayer < 700.0f) && (Flags_GetSwitch(globalCtx, 0x37) != 0)) {
|
||||
s16 scene = globalCtx->sceneNum;
|
||||
|
||||
if (((scene == SCENE_GANON_DEMO) || (scene == SCENE_GANON_FINAL) || (scene == SCENE_GANON_SONOGO) ||
|
||||
(scene == SCENE_GANONTIKA_SONOGO)) &&
|
||||
(!this->collapseSpawnerInactive)) {
|
||||
maxRocks = 1;
|
||||
spawnerState = ENCOUNT2_ACTIVE_GANONS_TOWER;
|
||||
}
|
||||
}
|
||||
if (spawnerState != ENCOUNT2_INACTIVE) {
|
||||
// Direction vector for the direction the camera is facing
|
||||
tempVec1X = globalCtx->view.lookAt.x - globalCtx->view.eye.x;
|
||||
tempVec1Y = globalCtx->view.lookAt.y - globalCtx->view.eye.y;
|
||||
tempVec1Z = globalCtx->view.lookAt.z - globalCtx->view.eye.z;
|
||||
|
||||
// Normalised direction vector for the direction the camera is facing
|
||||
magnitude = sqrtf(SQ(tempVec1X) + SQ(tempVec1Y) + SQ(tempVec1Z));
|
||||
tempVec2X = tempVec1X / magnitude;
|
||||
tempVec2Y = tempVec1Y / magnitude;
|
||||
tempVec2Z = tempVec1Z / magnitude;
|
||||
|
||||
// Position between 160 and 300 units ahead of camera depending on camera pitch, plus a 400 unit offset in +y
|
||||
tempVec1X = globalCtx->view.eye.x + (tempVec2X * 300.0f);
|
||||
tempVec1Y = globalCtx->view.eye.y + (tempVec2Y * 160.0f) + 400.0f;
|
||||
tempVec1Z = globalCtx->view.eye.z + (tempVec2Z * 300.0f);
|
||||
|
||||
// Position between 160 and 200 units ahead of camera depending on camera pitch, plus a 400 unit offset in +y
|
||||
// (plus some random variation)
|
||||
particlePos.x = Rand_CenteredFloat(200.0f) + (globalCtx->view.eye.x + (tempVec2X * 200.0f));
|
||||
particlePos.y = Rand_CenteredFloat(50.0f) + tempVec1Y;
|
||||
particlePos.z = Rand_CenteredFloat(200.0f) + (globalCtx->view.eye.z + (tempVec2Z * 200.0f));
|
||||
particleScale = Rand_CenteredFloat(0.005f) + 0.007f;
|
||||
|
||||
if (spawnerState == ENCOUNT2_ACTIVE_DEATH_MOUNTAIN) {
|
||||
EnEncount2_ParticleInit(this, &particlePos, particleScale);
|
||||
} else if (this->particleSpawnTimer == 0) {
|
||||
EnEncount2_ParticleInit(this, &particlePos, particleScale);
|
||||
this->particleSpawnTimer = 5;
|
||||
}
|
||||
|
||||
if ((this->numSpawnedRocks < maxRocks) && (this->timerBetweenRockSpawns == 0)) {
|
||||
if (spawnerState == ENCOUNT2_ACTIVE_DEATH_MOUNTAIN) {
|
||||
this->timerBetweenRockSpawns = 4;
|
||||
spawnedRockType = FIRE_ROCK_SPAWNED_FALLING1;
|
||||
if ((Rand_ZeroFloat(1.99f) < 1.0f) && (LINK_IS_CHILD)) {
|
||||
// rock spawn pos X, Z near player
|
||||
tempVec2X = Rand_CenteredFloat(10.0f) + player->actor.world.pos.x;
|
||||
tempVec2Z = Rand_CenteredFloat(10.0f) + player->actor.world.pos.z;
|
||||
} else {
|
||||
if (player->linearVelocity != 0.0f) {
|
||||
// rock spawn pos is between 300 and 600 units from the camera depending on the camera yaw.
|
||||
// Rocks will generally spawn closer to the camera in the X axis than in the Z axis.
|
||||
tempVec2X = Rand_CenteredFloat(200.0f) + (globalCtx->view.eye.x + (tempVec2X * 300.0f));
|
||||
tempVec2Z = Rand_CenteredFloat(50.0f) + (globalCtx->view.eye.z + (tempVec2Z * 600.0f));
|
||||
} else {
|
||||
// rock spawn pos X, Z near player
|
||||
tempVec2X = Rand_CenteredFloat(10.0f) + player->actor.world.pos.x;
|
||||
tempVec2Z = Rand_CenteredFloat(10.0f) + player->actor.world.pos.z;
|
||||
}
|
||||
spawnedRockType = FIRE_ROCK_SPAWNED_FALLING2;
|
||||
}
|
||||
} else {
|
||||
this->timerBetweenRockSpawns = 50;
|
||||
spawnedRockType = FIRE_ROCK_SPAWNED_FALLING2;
|
||||
// rock spawn pos X,Z at a random position roughly 300 units ahead of camera
|
||||
tempVec2X = Rand_CenteredFloat(100.0f) + tempVec1X;
|
||||
tempVec2Z = Rand_CenteredFloat(100.0f) + tempVec1Z;
|
||||
|
||||
if (Rand_ZeroFloat(3.99f) < 1.0f) {
|
||||
// rock spawn pos X,Z at a random position near player
|
||||
tempVec2X = Rand_CenteredFloat(70.0f) + player->actor.world.pos.x;
|
||||
tempVec2Z = Rand_CenteredFloat(70.0f) + player->actor.world.pos.z;
|
||||
}
|
||||
}
|
||||
spawnedRock =
|
||||
(EnFireRock*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FIRE_ROCK,
|
||||
tempVec2X, tempVec1Y, tempVec2Z, 0, 0, 0, spawnedRockType);
|
||||
if (spawnedRock != NULL) {
|
||||
spawnedRock->spawner = this;
|
||||
this->numSpawnedRocks++;
|
||||
return;
|
||||
}
|
||||
// "☆☆☆☆☆ Can't occur! ☆☆☆☆☆"
|
||||
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発生できません! ☆☆☆☆☆\n" VT_RST);
|
||||
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発生できません! ☆☆☆☆☆\n" VT_RST);
|
||||
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発生できません! ☆☆☆☆☆\n" VT_RST);
|
||||
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発生できません! ☆☆☆☆☆\n" VT_RST);
|
||||
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発生できません! ☆☆☆☆☆\n\n" VT_RST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnEncount2_Update(Actor* thisx, GlobalContext* globalCtx2) {
|
||||
EnEncount2* this = THIS;
|
||||
GlobalContext* globalCtx = globalCtx2;
|
||||
|
||||
if (this->deathMountainSpawnerTimer != 0) {
|
||||
this->deathMountainSpawnerTimer--;
|
||||
}
|
||||
|
||||
if (this->timerBetweenRockSpawns != 0) {
|
||||
this->timerBetweenRockSpawns--;
|
||||
}
|
||||
|
||||
if (this->particleSpawnTimer != 0) {
|
||||
this->particleSpawnTimer--;
|
||||
}
|
||||
|
||||
this->actionFunc(this, globalCtx);
|
||||
|
||||
EnEncount2_ParticleUpdate(this, globalCtx);
|
||||
|
||||
if (!this->isNotDeathMountain) {
|
||||
this->unk17C = this->envEffectsTimer / 60.0f;
|
||||
this->unk160 = this->unk17C * -50.0f;
|
||||
globalCtx->envCtx.unk_8C[0][0] = (s16)this->unk160 * -1.5f;
|
||||
globalCtx->envCtx.unk_8C[0][1] = globalCtx->envCtx.unk_8C[0][2] = this->unk160;
|
||||
this->unk168 = this->unk17C * -20.0f;
|
||||
globalCtx->envCtx.unk_8C[1][0] = (s16)this->unk168 * -1.5f;
|
||||
globalCtx->envCtx.unk_8C[1][1] = globalCtx->envCtx.unk_8C[1][2] = this->unk168;
|
||||
this->unk170 = this->unk17C * -50.0f;
|
||||
globalCtx->envCtx.unk_9E = this->unk170;
|
||||
globalCtx->envCtx.unk_8C[2][0] = (u8)((160.0f - globalCtx->envCtx.unk_CF[0]) * this->unk17C);
|
||||
globalCtx->envCtx.unk_8C[2][1] = (u8)((160.0f - globalCtx->envCtx.unk_CF[1]) * this->unk17C);
|
||||
globalCtx->envCtx.unk_8C[2][2] = (u8)((150.0f - globalCtx->envCtx.unk_CF[2]) * this->unk17C);
|
||||
}
|
||||
}
|
||||
|
||||
void EnEncount2_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnEncount2* this = THIS;
|
||||
|
||||
EnEncount2_ParticleDraw(&this->actor, globalCtx);
|
||||
}
|
||||
|
||||
void EnEncount2_ParticleInit(EnEncount2* this, Vec3f* particlePos, f32 scale) {
|
||||
EnEncount2Particle* particle = this->particles;
|
||||
s16 i;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(this->particles); i++, particle++) {
|
||||
if (!particle->isAlive) {
|
||||
particle->pos = *particlePos;
|
||||
particle->scale = scale;
|
||||
particle->rot.x = 0.0f;
|
||||
particle->rot.y = 0.0f;
|
||||
particle->rot.z = 0.0f;
|
||||
particle->moveDirection.x = Rand_CenteredFloat(20.0f);
|
||||
particle->moveDirection.y = -20.0f;
|
||||
particle->moveDirection.z = Rand_CenteredFloat(20.0f);
|
||||
particle->isAlive = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnEncount2_ParticleUpdate(EnEncount2* this, GlobalContext* globalCtx) {
|
||||
s16 i;
|
||||
EnEncount2Particle* particle = this->particles;
|
||||
Player* player = PLAYER;
|
||||
Vec3f targetPos;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(this->particles); particle++, i++) {
|
||||
if (particle->isAlive) {
|
||||
particle->rot.x += Rand_ZeroOne() * 500.0f;
|
||||
particle->rot.y += Rand_ZeroOne() * 500.0f;
|
||||
particle->rot.z += Rand_ZeroOne() * 500.0f;
|
||||
targetPos.x = particle->pos.x + particle->moveDirection.x;
|
||||
targetPos.y = particle->pos.y + particle->moveDirection.y;
|
||||
targetPos.z = particle->pos.z + particle->moveDirection.z;
|
||||
Math_ApproachF(&particle->pos.x, targetPos.x, 0.3f, 30.0f);
|
||||
Math_ApproachF(&particle->pos.y, targetPos.y, 0.8f, 250.0f);
|
||||
Math_ApproachF(&particle->pos.z, targetPos.z, 0.3f, 30.0f);
|
||||
Math_ApproachF(&particle->moveDirection.y, -20.0f, 0.9f, 1.0f);
|
||||
|
||||
if (globalCtx->sceneNum != SCENE_SPOT16) {
|
||||
if (particle->pos.y < (player->actor.floorHeight - 50.0f)) {
|
||||
particle->isAlive = 0;
|
||||
}
|
||||
} else if (particle->pos.y < 1500.0f) {
|
||||
particle->isAlive = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnEncount2_ParticleDraw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnEncount2* this = THIS;
|
||||
EnEncount2Particle* particle = this->particles;
|
||||
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
|
||||
s16 i;
|
||||
s32 objBankIndex;
|
||||
|
||||
OPEN_DISPS(gfxCtx, "../z_en_encount2.c", 642);
|
||||
|
||||
objBankIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_EFC_STAR_FIELD);
|
||||
|
||||
if (objBankIndex >= 0) {
|
||||
gDPPipeSync(POLY_XLU_DISP++);
|
||||
gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[objBankIndex].segment);
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(this->particles); particle++, i++) {
|
||||
if (particle->isAlive) {
|
||||
Matrix_Translate(particle->pos.x, particle->pos.y, particle->pos.z, MTXMODE_NEW);
|
||||
Matrix_RotateX(particle->rot.x * (M_PI / 180), MTXMODE_APPLY);
|
||||
Matrix_RotateY(particle->rot.y * (M_PI / 180), MTXMODE_APPLY);
|
||||
Matrix_RotateZ(particle->rot.z * (M_PI / 180), MTXMODE_APPLY);
|
||||
Matrix_Scale(particle->scale, particle->scale, particle->scale, MTXMODE_APPLY);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 155, 55, 255);
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 155, 255, 55, 255);
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_encount2.c", 669),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, D_06000DE0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLOSE_DISPS(gfxCtx, "../z_en_encount2.c", 678);
|
||||
}
|
||||
|
|
|
@ -6,11 +6,36 @@
|
|||
|
||||
struct EnEncount2;
|
||||
|
||||
typedef void (*EnEncount2ActionFunc)(struct EnEncount2*, GlobalContext*);
|
||||
|
||||
typedef struct {
|
||||
/* 0x0000 */ Vec3f pos;
|
||||
/* 0x000C */ f32 scale;
|
||||
/* 0x0010 */ u8 isAlive;
|
||||
/* 0x0014 */ Vec3f moveDirection;
|
||||
/* 0x0020 */ Vec3f rot;
|
||||
} EnEncount2Particle; // size = 0x2C
|
||||
|
||||
typedef struct EnEncount2 {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ char unk_14C[0x10];
|
||||
/* 0x015C */ u16 unk_15C;
|
||||
/* 0x015E */ char unk_15E[0x8C2];
|
||||
/* 0x014C */ EnEncount2ActionFunc actionFunc;
|
||||
/* 0x0150 */ char unk150[0x4];
|
||||
/* 0x0154 */ s16 deathMountainSpawnerTimer;
|
||||
/* 0x0156 */ s16 timerBetweenRockSpawns;
|
||||
/* 0x0158 */ s16 numSpawnedRocks;
|
||||
/* 0x015A */ s16 isNotDeathMountain;
|
||||
/* 0x015C */ s16 collapseSpawnerInactive;
|
||||
/* 0x015E */ s16 particleSpawnTimer;
|
||||
/* 0x0160 */ f32 unk160;
|
||||
/* 0x0164 */ char unk164[0x4];
|
||||
/* 0x0168 */ f32 unk168;
|
||||
/* 0x016C */ char unk16C[0x4];
|
||||
/* 0x0178 */ f32 unk170;
|
||||
/* 0x0174 */ char unk174[0x4];
|
||||
/* 0x0178 */ s16 envEffectsTimer;
|
||||
/* 0x017C */ f32 unk17C;
|
||||
/* 0x0180 */ u64 isQuaking;
|
||||
/* 0x0188 */ EnEncount2Particle particles[50];
|
||||
} EnEncount2; // size = 0x0A20
|
||||
|
||||
extern const ActorInit En_Encount2_InitVars;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include "z_en_fire_rock.h"
|
||||
#include "overlays/actors/ovl_En_Encount2/z_en_encount2.h"
|
||||
#include "vt.h"
|
||||
|
||||
#define FLAGS 0x00000030
|
||||
|
||||
|
@ -9,9 +11,13 @@ void EnFireRock_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|||
void EnFireRock_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnFireRock_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
extern UNK_TYPE D_06000DE0;
|
||||
void FireRock_WaitSpawnRocksFromCeiling(EnFireRock* this, GlobalContext* globalCtx);
|
||||
void FireRock_WaitOnFloor(EnFireRock* this, GlobalContext* globalCtx);
|
||||
void EnFireRock_Fall(EnFireRock* this, GlobalContext* globalCtx);
|
||||
void EnFireRock_SpawnMoreBrokenPieces(EnFireRock* this, GlobalContext* globalCtx);
|
||||
|
||||
extern Gfx D_06000DE0[];
|
||||
|
||||
/*
|
||||
const ActorInit En_Fire_Rock_InitVars = {
|
||||
ACTOR_EN_FIRE_ROCK,
|
||||
ACTORCAT_ENEMY,
|
||||
|
@ -24,6 +30,26 @@ const ActorInit En_Fire_Rock_InitVars = {
|
|||
(ActorFunc)EnFireRock_Draw,
|
||||
};
|
||||
|
||||
static ColliderCylinderInit D_80A12CA0 = {
|
||||
{
|
||||
COLTYPE_HARD,
|
||||
AT_ON | AT_TYPE_ENEMY,
|
||||
AC_ON | AC_TYPE_PLAYER,
|
||||
OC1_NONE,
|
||||
OC2_TYPE_2,
|
||||
COLSHAPE_CYLINDER,
|
||||
},
|
||||
{
|
||||
ELEMTYPE_UNK0,
|
||||
{ 0xFFCFFFFF, 0x09, 0x08 },
|
||||
{ 0xFFCFFFFF, 0x00, 0x00 },
|
||||
TOUCH_ON | TOUCH_SFX_NORMAL,
|
||||
BUMP_ON,
|
||||
OCELEM_NONE,
|
||||
},
|
||||
{ 30, 30, -10, { 0, 0, 0 } },
|
||||
};
|
||||
|
||||
static ColliderCylinderInit D_80A12CCC = {
|
||||
{
|
||||
COLTYPE_HARD,
|
||||
|
@ -44,38 +70,331 @@ static ColliderCylinderInit D_80A12CCC = {
|
|||
{ 30, 30, -10, { 0, 0, 0 } },
|
||||
};
|
||||
|
||||
static ColliderCylinderInit D_80A12CA0 = {
|
||||
{
|
||||
COLTYPE_HARD,
|
||||
AT_ON | AT_TYPE_ENEMY,
|
||||
AC_ON | AC_TYPE_PLAYER,
|
||||
OC1_NONE,
|
||||
OC2_TYPE_2,
|
||||
COLSHAPE_CYLINDER,
|
||||
},
|
||||
{
|
||||
ELEMTYPE_UNK0,
|
||||
{ 0xFFCFFFFF, 0x09, 0x08 },
|
||||
{ 0xFFCFFFFF, 0x00, 0x00 },
|
||||
TOUCH_ON | TOUCH_SFX_NORMAL,
|
||||
BUMP_ON,
|
||||
OCELEM_NONE,
|
||||
},
|
||||
{ 30, 30, -10, { 0, 0, 0 } },
|
||||
};
|
||||
*/
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fire_Rock/EnFireRock_Init.s")
|
||||
void EnFireRock_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
GlobalContext* globalCtx2 = globalCtx;
|
||||
Player* player = PLAYER;
|
||||
EnFireRock* this = THIS;
|
||||
s16 temp;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fire_Rock/EnFireRock_Destroy.s")
|
||||
this->type = this->actor.params;
|
||||
if (this->type != FIRE_ROCK_CEILING_SPOT_SPAWNER) {
|
||||
ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 15.0f);
|
||||
if (this->type != FIRE_ROCK_ON_FLOOR) {
|
||||
this->angularVelocity.x = (Rand_ZeroFloat(10.0f) + 15.0f);
|
||||
this->angularVelocity.y = (Rand_ZeroFloat(10.0f) + 15.0f);
|
||||
this->angularVelocity.z = (Rand_ZeroFloat(10.0f) + 15.0f);
|
||||
}
|
||||
}
|
||||
switch (this->type) {
|
||||
case FIRE_ROCK_CEILING_SPOT_SPAWNER:
|
||||
this->actor.draw = NULL;
|
||||
// "☆☆☆☆☆ ceiling waiting rock ☆☆☆☆☆"
|
||||
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 天井待ち岩 ☆☆☆☆☆ \n" VT_RST);
|
||||
this->actionFunc = FireRock_WaitSpawnRocksFromCeiling;
|
||||
break;
|
||||
case FIRE_ROCK_ON_FLOOR:
|
||||
Actor_SetScale(&this->actor, 0.03f);
|
||||
Collider_InitCylinder(globalCtx, &this->collider);
|
||||
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &D_80A12CCC);
|
||||
// "☆☆☆☆☆ floor rock ☆☆☆☆☆"
|
||||
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 床岩 ☆☆☆☆☆ \n" VT_RST);
|
||||
this->collider.dim.radius = 23;
|
||||
this->collider.dim.height = 37;
|
||||
this->collider.dim.yShift = -10;
|
||||
Actor_ChangeCategory(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORCAT_PROP);
|
||||
this->actor.colChkInfo.mass = MASS_IMMOVABLE;
|
||||
this->actionFunc = FireRock_WaitOnFloor;
|
||||
break;
|
||||
case FIRE_ROCK_SPAWNED_FALLING1: // spawned by encount2
|
||||
// sets unused vars?
|
||||
this->unk17C.x = (f32)(Rand_CenteredFloat(50.0f) + player->actor.world.pos.x);
|
||||
this->unk17C.z = (f32)(Rand_CenteredFloat(50.0f) + player->actor.world.pos.z);
|
||||
case FIRE_ROCK_SPAWNED_FALLING2: // spawned by encount2 and by the ceilling spawner
|
||||
this->scale = (Rand_ZeroFloat(2.0f) / 100.0f) + 0.02f;
|
||||
Actor_SetScale(&this->actor, this->scale);
|
||||
Collider_InitCylinder(globalCtx, &this->collider);
|
||||
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &D_80A12CA0);
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y = Rand_CenteredFloat(65535.0f);
|
||||
this->actionFunc = EnFireRock_Fall;
|
||||
this->actor.shape.shadowScale = 15.0f;
|
||||
break;
|
||||
case FIRE_ROCK_BROKEN_PIECE1:
|
||||
this->actor.velocity.y = Rand_ZeroFloat(3.0f) + 4.0f;
|
||||
this->actor.speedXZ = Rand_ZeroFloat(3.0f) + 3.0f;
|
||||
this->scale = (Rand_ZeroFloat(1.0f) / 100.0f) + 0.02f;
|
||||
Actor_SetScale(&this->actor, this->scale);
|
||||
this->actor.gravity = -1.5f;
|
||||
Collider_InitCylinder(globalCtx, &this->collider);
|
||||
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &D_80A12CA0);
|
||||
this->actor.shape.shadowScale = 10.0f;
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y = Rand_CenteredFloat(65535.0f);
|
||||
this->actionFunc = EnFireRock_Fall;
|
||||
break;
|
||||
case FIRE_ROCK_BROKEN_PIECE2:
|
||||
this->actor.velocity.y = Rand_ZeroFloat(3.0f) + 4.0f;
|
||||
this->actor.speedXZ = Rand_ZeroFloat(3.0f) + 2.0f;
|
||||
this->scale = (Rand_ZeroFloat(1.0f) / 500.0f) + 0.01f;
|
||||
Actor_SetScale(&this->actor, this->scale);
|
||||
this->actor.gravity = -1.2f;
|
||||
this->actor.shape.shadowScale = 5.0f;
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y = Rand_CenteredFloat(65535.0f);
|
||||
this->actionFunc = EnFireRock_Fall;
|
||||
break;
|
||||
default:
|
||||
// "☆☆☆☆☆ No such rock! ERR !!!!!! ☆☆☆☆☆"
|
||||
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ そんな岩はねぇ!ERR!!!!!! ☆☆☆☆☆ \n" VT_RST);
|
||||
Actor_Kill(&this->actor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fire_Rock/func_80A120CC.s")
|
||||
void EnFireRock_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnFireRock* this = THIS;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fire_Rock/func_80A1241C.s")
|
||||
if ((this->actor.parent != NULL) && (this->actor.parent == &this->spawner->actor)) {
|
||||
EnEncount2* spawner = (EnEncount2*)this->actor.parent;
|
||||
if ((spawner->actor.update != NULL) && (spawner->numSpawnedRocks > 0)) {
|
||||
spawner->numSpawnedRocks--;
|
||||
osSyncPrintf("\n\n");
|
||||
// "☆☆☆☆☆ Number of spawned instances recovery ☆☆☆☆☆%d"
|
||||
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発生数回復 ☆☆☆☆☆%d\n" VT_RST, spawner->numSpawnedRocks);
|
||||
osSyncPrintf("\n\n");
|
||||
}
|
||||
}
|
||||
Collider_DestroyCylinder(globalCtx, &this->collider);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fire_Rock/func_80A125B8.s")
|
||||
void EnFireRock_Fall(EnFireRock* this, GlobalContext* globalCtx) {
|
||||
Player* player;
|
||||
Vec3f flamePos;
|
||||
s32 i;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fire_Rock/func_80A12730.s")
|
||||
player = PLAYER;
|
||||
if ((this->actor.floorHeight == -10000.0f) || (this->actor.world.pos.y < (player->actor.world.pos.y - 200.0f))) {
|
||||
Actor_Kill(&this->actor);
|
||||
return;
|
||||
}
|
||||
switch (this->type) {
|
||||
case FIRE_ROCK_SPAWNED_FALLING1:
|
||||
if (player->actor.world.pos.y < this->actor.world.pos.y) {
|
||||
if ((player->actor.world.pos.x > -700.0f) || (player->actor.world.pos.x < 100.0f) ||
|
||||
(player->actor.world.pos.z > -1290.0f) || (player->actor.world.pos.z < -3880.0f)) {
|
||||
Math_ApproachF(&this->actor.world.pos.x, player->actor.world.pos.x, 1.0f, 10.0f);
|
||||
Math_ApproachF(&this->actor.world.pos.z, player->actor.world.pos.z, 1.0f, 10.0f);
|
||||
}
|
||||
}
|
||||
case FIRE_ROCK_SPAWNED_FALLING2:
|
||||
flamePos.x = Rand_CenteredFloat(20.0f) + this->actor.world.pos.x;
|
||||
flamePos.y = Rand_CenteredFloat(20.0f) + this->actor.world.pos.y;
|
||||
flamePos.z = Rand_CenteredFloat(20.0f) + this->actor.world.pos.z;
|
||||
EffectSsEnFire_SpawnVec3f(globalCtx, &this->actor, &flamePos, 100, 0, 0, -1);
|
||||
break;
|
||||
case FIRE_ROCK_BROKEN_PIECE1:
|
||||
if ((globalCtx->gameplayFrames & 3) == 0) {
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_VALVAISA_ROCK);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ((this->actor.bgCheckFlags & 1) && (this->timer == 0)) {
|
||||
switch (this->type) {
|
||||
case FIRE_ROCK_SPAWNED_FALLING1:
|
||||
case FIRE_ROCK_SPAWNED_FALLING2:
|
||||
func_80033E88(&this->actor, globalCtx, 5, 2);
|
||||
case FIRE_ROCK_BROKEN_PIECE1:
|
||||
func_80033260(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, 8.0f,
|
||||
500, 10, 0);
|
||||
for (i = 0; i < 5; i++) {
|
||||
flamePos.x = Rand_CenteredFloat(20.0f) + this->actor.world.pos.x;
|
||||
flamePos.y = this->actor.floorHeight;
|
||||
flamePos.z = Rand_CenteredFloat(20.0f) + this->actor.world.pos.z;
|
||||
EffectSsEnFire_SpawnVec3f(globalCtx, &this->actor, &flamePos, 300, 0, 0, -1);
|
||||
}
|
||||
this->actionFunc = EnFireRock_SpawnMoreBrokenPieces;
|
||||
break;
|
||||
default:
|
||||
func_80033260(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 3, 8.0f,
|
||||
200, 10, 0);
|
||||
Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_EXPLOSION);
|
||||
Actor_Kill(&this->actor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fire_Rock/EnFireRock_Update.s")
|
||||
/**
|
||||
* After the rock has already hit the ground and started rolling, spawn two more, giving the illusion of breaking into
|
||||
* two pieces.
|
||||
*/
|
||||
void EnFireRock_SpawnMoreBrokenPieces(EnFireRock* this, GlobalContext* globalCtx) {
|
||||
EnFireRock* spawnedFireRock;
|
||||
s32 nextRockType;
|
||||
s32 i;
|
||||
s32 temp;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fire_Rock/EnFireRock_Draw.s")
|
||||
nextRockType = FIRE_ROCK_SPAWNED_FALLING1;
|
||||
switch (this->type) {
|
||||
case FIRE_ROCK_SPAWNED_FALLING1:
|
||||
case FIRE_ROCK_SPAWNED_FALLING2:
|
||||
nextRockType = FIRE_ROCK_BROKEN_PIECE1;
|
||||
break;
|
||||
case FIRE_ROCK_BROKEN_PIECE1:
|
||||
nextRockType = FIRE_ROCK_BROKEN_PIECE2;
|
||||
}
|
||||
|
||||
if (nextRockType != FIRE_ROCK_SPAWNED_FALLING1) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
spawnedFireRock = (EnFireRock*)Actor_Spawn(
|
||||
&globalCtx->actorCtx, globalCtx, ACTOR_EN_FIRE_ROCK, Rand_CenteredFloat(3.0f) + this->actor.world.pos.x,
|
||||
Rand_CenteredFloat(3.0f) + (this->actor.world.pos.y + 10.0f),
|
||||
Rand_CenteredFloat(3.0f) + this->actor.world.pos.z, 0, 0, 0, nextRockType);
|
||||
if (spawnedFireRock != NULL) {
|
||||
spawnedFireRock->actor.world.rot.y = this->actor.world.rot.y;
|
||||
if (i == 0) {
|
||||
spawnedFireRock->actor.shape.rot.y = this->actor.shape.rot.y;
|
||||
}
|
||||
spawnedFireRock->scale = this->scale - 0.01f;
|
||||
} else {
|
||||
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ イッパイデッス ☆☆☆☆☆ \n" VT_RST);
|
||||
}
|
||||
}
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EN_VALVAISA_ROCK);
|
||||
}
|
||||
Actor_Kill(&this->actor);
|
||||
}
|
||||
|
||||
void FireRock_WaitSpawnRocksFromCeiling(EnFireRock* this, GlobalContext* globalCtx) {
|
||||
EnFireRock* spawnedFireRock;
|
||||
|
||||
if (this->actor.xzDistToPlayer < 200.0f) {
|
||||
if ((this->playerNearby == 0) && (this->timer2 == 0)) {
|
||||
this->timer2 = 30;
|
||||
spawnedFireRock = (EnFireRock*)Actor_Spawn(
|
||||
&globalCtx->actorCtx, globalCtx, ACTOR_EN_FIRE_ROCK, Rand_CenteredFloat(3.0f) + this->actor.world.pos.x,
|
||||
this->actor.world.pos.y + 10.0f, Rand_CenteredFloat(3.0f) + this->actor.world.pos.z, 0, 0, 0,
|
||||
FIRE_ROCK_SPAWNED_FALLING2);
|
||||
if (spawnedFireRock != NULL) {
|
||||
spawnedFireRock->timer = 10;
|
||||
} else {
|
||||
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ イッパイデッス ☆☆☆☆☆ \n" VT_RST);
|
||||
}
|
||||
}
|
||||
this->playerNearby = 1;
|
||||
} else {
|
||||
this->playerNearby = 0;
|
||||
}
|
||||
if (BREG(0) != 0) {
|
||||
DebugDisplay_AddObject(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z,
|
||||
this->actor.world.rot.x, this->actor.world.rot.y, this->actor.world.rot.z, 1.0f, 1.0f,
|
||||
1.0f, 0, 255, 0, 255, 4, globalCtx->state.gfxCtx);
|
||||
}
|
||||
}
|
||||
|
||||
void FireRock_WaitOnFloor(EnFireRock* this, GlobalContext* globalCtx) {
|
||||
Vec3f flamePos;
|
||||
s16 scale;
|
||||
|
||||
if (this->timer2 == 0) {
|
||||
flamePos.x = Rand_CenteredFloat(20.0f) + this->actor.world.pos.x;
|
||||
flamePos.y = Rand_CenteredFloat(20.0f) + this->actor.world.pos.y;
|
||||
flamePos.z = Rand_CenteredFloat(20.0f) + this->actor.world.pos.z;
|
||||
scale = 130 + (s16)Rand_CenteredFloat(60.0f);
|
||||
this->timer2 = 3 + (s16)Rand_ZeroFloat(3.0f);
|
||||
EffectSsEnFire_SpawnVec3f(globalCtx, &this->actor, &flamePos, scale, 0, 0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void EnFireRock_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnFireRock* this = THIS;
|
||||
s16 setCollision;
|
||||
Player* player = PLAYER;
|
||||
Actor* playerActor = &PLAYER->actor;
|
||||
|
||||
if (this->timer2 != 0) {
|
||||
this->timer2--;
|
||||
}
|
||||
if (this->timer != 0) {
|
||||
this->timer--;
|
||||
}
|
||||
this->actionFunc(this, globalCtx);
|
||||
|
||||
if (this->type != FIRE_ROCK_CEILING_SPOT_SPAWNER) {
|
||||
f32 temp;
|
||||
this->rockRotation.x += this->angularVelocity.x;
|
||||
this->rockRotation.y += this->angularVelocity.y;
|
||||
this->rockRotation.z += this->angularVelocity.z;
|
||||
this->relativePos.y = 3.0f;
|
||||
|
||||
temp = 10.0f + (this->scale * 300.0f);
|
||||
thisx->shape.shadowScale = temp;
|
||||
if (thisx->shape.shadowScale < 10.0f) {
|
||||
thisx->shape.shadowScale = 10.0f;
|
||||
}
|
||||
if (thisx->shape.shadowScale > 20.0f) {
|
||||
thisx->shape.shadowScale = 20.0f;
|
||||
}
|
||||
|
||||
if ((this->type == FIRE_ROCK_SPAWNED_FALLING1) || (this->type == FIRE_ROCK_SPAWNED_FALLING2)) {
|
||||
thisx->gravity = -0.3f - (this->scale * 7.0f);
|
||||
}
|
||||
if (this->type != FIRE_ROCK_ON_FLOOR) {
|
||||
Actor_MoveForward(thisx);
|
||||
Actor_UpdateBgCheckInfo(globalCtx, thisx, 50.0f, 50.0f, 100.0f, 0x1C);
|
||||
}
|
||||
|
||||
setCollision = false;
|
||||
if (this->actionFunc != EnFireRock_SpawnMoreBrokenPieces) {
|
||||
if ((this->type == FIRE_ROCK_SPAWNED_FALLING1) || (this->type == FIRE_ROCK_SPAWNED_FALLING2) ||
|
||||
(this->type == FIRE_ROCK_BROKEN_PIECE1)) {
|
||||
if (this->collider.base.atFlags & 4) {
|
||||
this->collider.base.atFlags &= ~4;
|
||||
Audio_PlayActorSound2(thisx, NA_SE_EV_BRIDGE_OPEN_STOP);
|
||||
thisx->velocity.y = 0.0f;
|
||||
thisx->speedXZ = 0.0f;
|
||||
this->actionFunc = EnFireRock_SpawnMoreBrokenPieces;
|
||||
// "☆☆☆☆☆ Shield Defense Lv1 ☆☆☆☆☆"
|
||||
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ シールド防御 Lv1 ☆☆☆☆☆ \n" VT_RST);
|
||||
return;
|
||||
}
|
||||
setCollision = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->type == FIRE_ROCK_ON_FLOOR) {
|
||||
if (this->collider.base.atFlags & 2) {
|
||||
this->collider.base.atFlags &= ~2;
|
||||
if (this->collider.base.at == playerActor) {
|
||||
if (!(player->stateFlags1 & 0x04000000)) {
|
||||
func_8002F758(globalCtx, thisx, 2.0f, -player->actor.world.rot.y, 3.0f, 4);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
setCollision = true;
|
||||
}
|
||||
if (setCollision) {
|
||||
Collider_UpdateCylinder(thisx, &this->collider);
|
||||
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
|
||||
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnFireRock_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnFireRock* this = THIS;
|
||||
s32 pad;
|
||||
|
||||
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_fire_rock.c", 747);
|
||||
Matrix_Translate(thisx->world.pos.x + this->relativePos.x, thisx->world.pos.y + this->relativePos.y,
|
||||
thisx->world.pos.z + this->relativePos.z, MTXMODE_NEW);
|
||||
Matrix_RotateX(DEG_TO_RAD(this->rockRotation.x), MTXMODE_APPLY);
|
||||
Matrix_RotateY(DEG_TO_RAD(this->rockRotation.y), MTXMODE_APPLY);
|
||||
Matrix_RotateZ(DEG_TO_RAD(this->rockRotation.z), MTXMODE_APPLY);
|
||||
Matrix_Scale(thisx->scale.x, thisx->scale.y, thisx->scale.z, MTXMODE_APPLY);
|
||||
func_80093D18(globalCtx->state.gfxCtx);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 155, 55, 255);
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 155, 255, 55, 255);
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_fire_rock.c", 768),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, D_06000DE0);
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_fire_rock.c", 773);
|
||||
}
|
||||
|
|
|
@ -4,11 +4,36 @@
|
|||
#include "ultra64.h"
|
||||
#include "global.h"
|
||||
|
||||
#include "overlays/actors/ovl_En_Encount2/z_en_encount2.h"
|
||||
|
||||
typedef enum {
|
||||
/* 0x00 */ FIRE_ROCK_SPAWNED_FALLING1,
|
||||
/* 0x01 */ FIRE_ROCK_BROKEN_PIECE1,
|
||||
/* 0x02 */ FIRE_ROCK_BROKEN_PIECE2,
|
||||
/* 0x03 */ FIRE_ROCK_SPAWNED_FALLING2,
|
||||
/* 0x05 */ FIRE_ROCK_CEILING_SPOT_SPAWNER = 5,
|
||||
/* 0x06 */ FIRE_ROCK_ON_FLOOR
|
||||
} EnFireRockType;
|
||||
|
||||
struct EnFireRock;
|
||||
|
||||
typedef void (*EnFireRockActionFunc)(struct EnFireRock*, GlobalContext*);
|
||||
|
||||
typedef struct EnFireRock {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ char unk_14C[0x94];
|
||||
/* 0x014C */ Vec3f angularVelocity;
|
||||
/* 0x0158 */ Vec3f rockRotation;
|
||||
/* 0x0164 */ char unk164[0x4];
|
||||
/* 0x0168 */ EnFireRockActionFunc actionFunc;
|
||||
/* 0x016C */ f32 scale;
|
||||
/* 0x0170 */ Vec3f relativePos;
|
||||
/* 0x017C */ Vec3f unk17C; // set but unused?
|
||||
/* 0x0188 */ s16 timer;
|
||||
/* 0x018A */ s16 timer2;
|
||||
/* 0x018C */ s16 type;
|
||||
/* 0x018E */ u8 playerNearby;
|
||||
/* 0x0190 */ EnEncount2* spawner;
|
||||
/* 0x0194 */ ColliderCylinder collider;
|
||||
} EnFireRock; // size = 0x01E0
|
||||
|
||||
extern const ActorInit En_Fire_Rock_InitVars;
|
||||
|
|
|
@ -1926,10 +1926,10 @@ s32 func_80B57890(EnZl3* this, GlobalContext* globalCtx) {
|
|||
|
||||
void func_80B57A74(GlobalContext* globalCtx) {
|
||||
Actor* actorIt = globalCtx->actorCtx.actorLists[ACTORCAT_PROP].head;
|
||||
|
||||
//! @bug checks for encount2 in ACTORCAT_PROP but encount2 is in ACTORCAT_ENEMY so this condition is never met
|
||||
while (actorIt != NULL) {
|
||||
if (actorIt->id == ACTOR_EN_ENCOUNT2) {
|
||||
((EnEncount2*)actorIt)->unk_15C = 1;
|
||||
((EnEncount2*)actorIt)->collapseSpawnerInactive = true;
|
||||
}
|
||||
actorIt = actorIt->next;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue