1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-08-15 19:41:47 +00:00

Merge branch 'master' into ovl_En_Ik

This commit is contained in:
Sirius902 2020-10-04 12:31:32 -07:00
commit f56668c8e2
279 changed files with 4691 additions and 15675 deletions

View file

@ -36,8 +36,7 @@ const ActorInit Bg_Gnd_Darkmeiro_InitVars = {
extern Gfx D_060088B0[];
extern Gfx D_0600BEC0[];
extern UNK_TYPE D_0600C080;
extern ColHeader D_0600C080;
void BgGndDarkmeiro_ToggleBlock(BgGndDarkmeiro* this, GlobalContext* globalCtx) {
if (this->actionFlags & 2) {
@ -53,7 +52,7 @@ void BgGndDarkmeiro_ToggleBlock(BgGndDarkmeiro* this, GlobalContext* globalCtx)
void BgGndDarkmeiro_Init(Actor* thisx, GlobalContext* globalCtx) {
GlobalContext* globalCtx2 = globalCtx;
s32 local_c = 0;
ColHeader* colHeader = NULL;
BgGndDarkmeiro* this = THIS;
this->updateFunc = BgGndDarkmeiro_Noop;
@ -64,9 +63,9 @@ void BgGndDarkmeiro_Init(Actor* thisx, GlobalContext* globalCtx) {
this->dyna.actor.flags |= 0x80;
break;
case DARKMEIRO_CLEAR_BLOCK:
DynaPolyInfo_Alloc(&D_0600C080, &local_c);
DynaPolyInfo_Alloc(&D_0600C080, &colHeader);
this->dyna.dynaPolyId =
DynaPolyInfo_RegisterActor(globalCtx2, &globalCtx2->colCtx.dyna, &this->dyna.actor, local_c);
DynaPolyInfo_RegisterActor(globalCtx2, &globalCtx2->colCtx.dyna, &this->dyna.actor, colHeader);
if (((this->dyna.actor.params >> 8) & 0x3F) == 0x3F) {
this->updateFunc = BgGndDarkmeiro_UpdateStaticBlock;
this->dyna.actor.draw = BgGndDarkmeiro_DrawStaticBlock;

View file

@ -1,3 +1,9 @@
/*
* File: z_bg_hidan_curtain.c
* Overlay: ovl_Bg_Hidan_Curtain
* Description: Flame circle
*/
#include "z_bg_hidan_curtain.h"
#define FLAGS 0x00000010
@ -9,7 +15,33 @@ void BgHidanCurtain_Destroy(Actor* thisx, GlobalContext* globalCtx);
void BgHidanCurtain_Update(Actor* thisx, GlobalContext* globalCtx);
void BgHidanCurtain_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void BgHidanCurtain_WaitForSwitchOn(BgHidanCurtain* this, GlobalContext* globalCtx);
void BgHidanCurtain_WaitForCutscene(BgHidanCurtain* this, GlobalContext* globalCtx);
void BgHidanCurtain_WaitForClear(BgHidanCurtain* this, GlobalContext* globalCtx);
void BgHidanCurtain_TurnOn(BgHidanCurtain* this, GlobalContext* globalCtx);
void BgHidanCurtain_TurnOff(BgHidanCurtain* this, GlobalContext* globalCtx);
void BgHidanCurtain_WaitForTimer(BgHidanCurtain* this, GlobalContext* globalCtx);
extern Gfx D_040184B0[];
typedef struct {
/* 0x00 */ s16 radius;
/* 0x02 */ s16 height;
/* 0x04 */ f32 scale;
/* 0x08 */ f32 riseDist;
/* 0x0C */ f32 riseSpeed;
} BgHidanCurtainParams; // size = 0x10
static ColliderCylinderInit sCylinderInit = {
{ COLTYPE_UNK10, 0x11, 0x00, 0x09, 0x20, COLSHAPE_CYLINDER },
{ 0x00, { 0x20000000, 0x01, 0x04 }, { 0xFFCFFFFF, 0x00, 0x00 }, 0x19, 0x00, 0x01 },
{ 81, 144, 0, { 0, 0, 0 } },
};
static CollisionCheckInfoInit sCcInfoInit = { 1, 0x50, 0x64, 0xFF };
static BgHidanCurtainParams sHCParams[] = { { 81, 144, 0.090f, 144.0f, 5.0f }, { 46, 88, 0.055f, 88.0f, 3.0f } };
const ActorInit Bg_Hidan_Curtain_InitVars = {
ACTOR_BG_HIDAN_CURTAIN,
ACTORTYPE_PROP,
@ -21,25 +53,201 @@ const ActorInit Bg_Hidan_Curtain_InitVars = {
(ActorFunc)BgHidanCurtain_Update,
(ActorFunc)BgHidanCurtain_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Hidan_Curtain/BgHidanCurtain_Init.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Hidan_Curtain/BgHidanCurtain_Destroy.s")
void BgHidanCurtain_Init(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgHidanCurtain* this = THIS;
BgHidanCurtainParams* hcParams;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Hidan_Curtain/func_80885434.s")
osSyncPrintf("Curtain (arg_data 0x%04x)\n", this->actor.params);
Actor_SetHeight(&this->actor, 20.0f);
this->type = (thisx->params >> 0xC) & 0xF;
if (this->type > 6) {
// Type is not set
osSyncPrintf("Error : object のタイプが設定されていない(%s %d)(arg_data 0x%04x)\n", "../z_bg_hidan_curtain.c",
352, this->actor.params);
Actor_Kill(&this->actor);
return;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Hidan_Curtain/func_808854E8.s")
this->size = ((this->type == 2) || (this->type == 4)) ? 1 : 0;
hcParams = &sHCParams[this->size];
this->treasureFlag = (thisx->params >> 6) & 0x3F;
thisx->params &= 0x3F;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Hidan_Curtain/func_80885514.s")
if ((this->actor.params < 0) || (this->actor.params > 0x3F)) {
// Save bit is not set
osSyncPrintf("Warning : object のセーブビットが設定されていない(%s %d)(arg_data 0x%04x)\n",
"../z_bg_hidan_curtain.c", 373, this->actor.params);
}
Actor_SetScale(&this->actor, hcParams->scale);
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
this->collider.dim.pos.x = this->actor.posRot.pos.x;
this->collider.dim.pos.y = this->actor.posRot.pos.y;
this->collider.dim.pos.z = this->actor.posRot.pos.z;
this->collider.dim.radius = hcParams->radius;
this->collider.dim.height = hcParams->height;
Collider_CylinderUpdate(&this->actor, &this->collider);
func_80061ED4(&thisx->colChkInfo, NULL, &sCcInfoInit);
if (this->type == 0) {
this->actionFunc = BgHidanCurtain_WaitForClear;
} else {
this->actionFunc = BgHidanCurtain_WaitForSwitchOn;
if ((this->type == 4) || (this->type == 5)) {
this->actor.posRot.pos.y = this->actor.initPosRot.pos.y - hcParams->riseDist;
}
}
if (((this->type == 1) && Flags_GetTreasure(globalCtx, this->treasureFlag)) ||
(((this->type == 0) || (this->type == 6)) && Flags_GetClear(globalCtx, this->actor.room))) {
Actor_Kill(&this->actor);
}
this->texScroll = Math_Rand_ZeroOne() * 15.0f;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Hidan_Curtain/func_80885554.s")
void BgHidanCurtain_Destroy(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgHidanCurtain* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Hidan_Curtain/func_80885594.s")
Collider_DestroyCylinder(globalCtx, &this->collider);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Hidan_Curtain/func_80885604.s")
void BgHidanCurtain_WaitForSwitchOn(BgHidanCurtain* this, GlobalContext* globalCtx) {
if (Flags_GetSwitch(globalCtx, this->actor.params)) {
if (this->type == 1) {
this->actionFunc = BgHidanCurtain_WaitForCutscene;
func_800800F8(globalCtx, 3350, -99, &this->actor, 0);
this->timer = 50;
} else if (this->type == 3) {
this->actionFunc = BgHidanCurtain_WaitForCutscene;
func_800800F8(globalCtx, 3360, 60, &this->actor, 0);
this->timer = 30;
} else {
this->actionFunc = BgHidanCurtain_TurnOff;
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Hidan_Curtain/func_808856F4.s")
void BgHidanCurtain_WaitForCutscene(BgHidanCurtain* this, GlobalContext* globalCtx) {
if (this->timer-- == 0) {
this->actionFunc = BgHidanCurtain_TurnOff;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Hidan_Curtain/BgHidanCurtain_Update.s")
void BgHidanCurtain_WaitForClear(BgHidanCurtain* this, GlobalContext* globalCtx) {
if (Flags_GetClear(globalCtx, this->actor.room)) {
this->actionFunc = BgHidanCurtain_TurnOff;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Hidan_Curtain/BgHidanCurtain_Draw.s")
void BgHidanCurtain_WaitForSwitchOff(BgHidanCurtain* this, GlobalContext* globalCtx) {
if (!Flags_GetSwitch(globalCtx, this->actor.params)) {
this->actionFunc = BgHidanCurtain_TurnOn;
}
}
void BgHidanCurtain_TurnOn(BgHidanCurtain* this, GlobalContext* globalCtx) {
f32 riseSpeed = sHCParams[this->size].riseSpeed;
if (Math_ApproxF(&this->actor.posRot.pos.y, this->actor.initPosRot.pos.y, riseSpeed)) {
Flags_UnsetSwitch(globalCtx, this->actor.params);
this->actionFunc = BgHidanCurtain_WaitForSwitchOn;
}
}
void BgHidanCurtain_TurnOff(BgHidanCurtain* this, GlobalContext* globalCtx) {
BgHidanCurtainParams* hcParams = &sHCParams[this->size];
if (Math_ApproxF(&this->actor.posRot.pos.y, this->actor.initPosRot.pos.y - hcParams->riseDist,
hcParams->riseSpeed)) {
if ((this->type == 0) || (this->type == 6)) {
Actor_Kill(&this->actor);
} else if (this->type == 5) {
this->actionFunc = BgHidanCurtain_WaitForSwitchOff;
} else {
if (this->type == 2) {
this->timer = 400;
} else if (this->type == 4) {
this->timer = 200;
} else if (this->type == 3) {
this->timer = 160;
} else { // this->type == 1
this->timer = 300;
}
this->actionFunc = BgHidanCurtain_WaitForTimer;
}
}
}
void BgHidanCurtain_WaitForTimer(BgHidanCurtain* this, GlobalContext* globalCtx) {
DECR(this->timer);
if (this->timer == 0) {
this->actionFunc = BgHidanCurtain_TurnOn;
}
if ((this->type == 1) || (this->type == 3)) {
func_8002F994(&this->actor, this->timer);
}
}
void BgHidanCurtain_Update(Actor* thisx, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = globalCtx2;
BgHidanCurtain* this = THIS;
BgHidanCurtainParams* hcParams = &sHCParams[this->size];
f32 riseProgress;
if ((globalCtx->cameraPtrs[0]->setting == 0x28) || (globalCtx->cameraPtrs[0]->setting == 0x38)) {
this->collider.base.atFlags &= ~2;
} else {
if (this->collider.base.atFlags & 2) {
this->collider.base.atFlags &= ~2;
func_8002F71C(globalCtx, &this->actor, 5.0f, this->actor.yawTowardsLink, 1.0f);
}
if ((this->type == 4) || (this->type == 5)) {
this->actor.posRot.pos.y =
(2.0f * this->actor.initPosRot.pos.y) - hcParams->riseDist - this->actor.posRot.pos.y;
}
this->actionFunc(this, globalCtx);
if ((this->type == 4) || (this->type == 5)) {
this->actor.posRot.pos.y =
(2.0f * this->actor.initPosRot.pos.y) - hcParams->riseDist - this->actor.posRot.pos.y;
}
riseProgress =
(hcParams->riseDist - (this->actor.initPosRot.pos.y - this->actor.posRot.pos.y)) / hcParams->riseDist;
this->alpha = 255.0f * riseProgress;
if (this->alpha > 50) {
this->collider.dim.height = hcParams->height * riseProgress;
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
if (gSaveContext.sceneSetupIndex <= 3) {
func_8002F974(&this->actor, NA_SE_EV_FIRE_PILLAR_S - SFX_FLAG);
}
} else if ((this->type == 1) && Flags_GetTreasure(globalCtx, this->treasureFlag)) {
Actor_Kill(&this->actor);
}
this->texScroll++;
}
}
void BgHidanCurtain_Draw(Actor* thisx, GlobalContext* globalCtx) {
BgHidanCurtain* this = THIS;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_bg_hidan_curtain.c", 685);
func_80093D84(globalCtx->state.gfxCtx);
gDPSetPrimColor(oGfxCtx->polyXlu.p++, 0x80, 0x80, 255, 220, 0, this->alpha);
gDPSetEnvColor(oGfxCtx->polyXlu.p++, 255, 0, 0, 0);
gSPSegment(oGfxCtx->polyXlu.p++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, this->texScroll & 0x7F, 0, 0x20, 0x40, 1, 0,
(this->texScroll * -0xF) & 0xFF, 0x20, 0x40));
gSPMatrix(oGfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_bg_hidan_curtain.c", 698),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(oGfxCtx->polyXlu.p++, D_040184B0);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_bg_hidan_curtain.c", 702);
}

View file

@ -6,9 +6,18 @@
struct BgHidanCurtain;
typedef void (*BgHidanCurtainActionFunc)(struct BgHidanCurtain*, GlobalContext*);
typedef struct BgHidanCurtain {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x58];
/* 0x014C */ BgHidanCurtainActionFunc actionFunc;
/* 0x0150 */ u8 type;
/* 0x0151 */ u8 treasureFlag;
/* 0x0152 */ u8 size;
/* 0x0153 */ u8 alpha;
/* 0x0154 */ s16 timer;
/* 0x0156 */ s16 texScroll;
/* 0x0158 */ ColliderCylinder collider;
} BgHidanCurtain; // size = 0x01A4
extern const ActorInit Bg_Hidan_Curtain_InitVars;

View file

@ -1,3 +1,9 @@
/*
* File: z_bg_mori_kaitenkabe.c
* Overlay: ovl_Bg_Mori_Kaitenkabe
* Description: Rotating wall in Forest Temple basement
*/
#include "z_bg_mori_kaitenkabe.h"
#define FLAGS 0x00000000
@ -7,8 +13,17 @@
void BgMoriKaitenkabe_Init(Actor* thisx, GlobalContext* globalCtx);
void BgMoriKaitenkabe_Destroy(Actor* thisx, GlobalContext* globalCtx);
void BgMoriKaitenkabe_Update(Actor* thisx, GlobalContext* globalCtx);
void BgMoriKaitenkabe_Draw(Actor* thisx, GlobalContext* globalCtx);
void BgMoriKaitenkabe_WaitForMoriTex(BgMoriKaitenkabe* this, GlobalContext* globalCtx);
void BgMoriKaitenkabe_SetupWait(BgMoriKaitenkabe* this);
void BgMoriKaitenkabe_Wait(BgMoriKaitenkabe* this, GlobalContext* globalCtx);
void BgMoriKaitenkabe_SetupRotate(BgMoriKaitenkabe* this);
void BgMoriKaitenkabe_Rotate(BgMoriKaitenkabe* this, GlobalContext* globalCtx);
extern ColHeader D_060063B8;
extern Gfx D_060056B0[];
/*
const ActorInit Bg_Mori_Kaitenkabe_InitVars = {
ACTOR_BG_MORI_KAITENKABE,
ACTORTYPE_BG,
@ -20,23 +35,145 @@ const ActorInit Bg_Mori_Kaitenkabe_InitVars = {
(ActorFunc)BgMoriKaitenkabe_Update,
NULL,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Kaitenkabe/func_808A4DC0.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Kaitenkabe/BgMoriKaitenkabe_Init.s")
static InitChainEntry sInitChain[] = {
ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 1000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_CONTINUE),
ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Kaitenkabe/BgMoriKaitenkabe_Destroy.s")
void BgMoriKaitenkabe_CrossProduct(Vec3f* dest, Vec3f* v1, Vec3f* v2) {
dest->x = (v1->y * v2->z) - (v1->z * v2->y);
dest->y = (v1->z * v2->x) - (v1->x * v2->z);
dest->z = (v1->x * v2->y) - (v1->y * v2->x);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Kaitenkabe/func_808A4F3C.s")
void BgMoriKaitenkabe_Init(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgMoriKaitenkabe* this = THIS;
ColHeader* colHeader = NULL;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Kaitenkabe/func_808A4F90.s")
// Forest Temple object 【Rotating Wall (arg_data: 0x% 04x)】 appears
osSyncPrintf("◯◯◯森の神殿オブジェクト【回転壁(arg_data : 0x%04x)】出現 \n", this->dyna.actor.params);
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
DynaPolyInfo_SetActorMove(&this->dyna, 0);
DynaPolyInfo_Alloc(&D_060063B8, &colHeader);
this->dyna.dynaPolyId =
DynaPolyInfo_RegisterActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
this->moriTexObjIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_MORI_TEX);
if (this->moriTexObjIndex < 0) {
Actor_Kill(&this->dyna.actor);
// 【Rotating wall】 Bank danger!
osSyncPrintf("【回転壁】 バンク危険!(%s %d)\n", "../z_bg_mori_kaitenkabe.c", 176);
} else {
this->actionFunc = BgMoriKaitenkabe_WaitForMoriTex;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Kaitenkabe/func_808A4FA4.s")
void BgMoriKaitenkabe_Destroy(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgMoriKaitenkabe* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Kaitenkabe/func_808A5104.s")
DynaPolyInfo_Free(globalCtx, &globalCtx->colCtx.dyna, this->dyna.dynaPolyId);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Kaitenkabe/func_808A5120.s")
void BgMoriKaitenkabe_WaitForMoriTex(BgMoriKaitenkabe* this, GlobalContext* globalCtx) {
if (Object_IsLoaded(&globalCtx->objectCtx, this->moriTexObjIndex)) {
BgMoriKaitenkabe_SetupWait(this);
this->dyna.actor.draw = BgMoriKaitenkabe_Draw;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Kaitenkabe/BgMoriKaitenkabe_Update.s")
void BgMoriKaitenkabe_SetupWait(BgMoriKaitenkabe* this) {
this->actionFunc = BgMoriKaitenkabe_Wait;
this->timer = 0;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Kaitenkabe/func_808A52AC.s")
void BgMoriKaitenkabe_Wait(BgMoriKaitenkabe* this, GlobalContext* globalCtx) {
Vec3f push;
Vec3f leverArm;
Vec3f torque;
Player* player = PLAYER;
if (this->dyna.unk_150 > 0.001f) {
this->timer++;
if ((this->timer > 28) && !Player_InCsMode(globalCtx)) {
BgMoriKaitenkabe_SetupRotate(this);
func_8002DF54(globalCtx, &this->dyna.actor, 8);
Math_Vec3f_Copy(&this->lockedPlayerPos, &player->actor.posRot.pos);
push.x = Math_Sins(this->dyna.unk_158);
push.y = 0.0f;
push.z = Math_Coss(this->dyna.unk_158);
leverArm.x = this->dyna.actor.posRot.pos.x - player->actor.posRot.pos.x;
leverArm.y = 0.0f;
leverArm.z = this->dyna.actor.posRot.pos.z - player->actor.posRot.pos.z;
BgMoriKaitenkabe_CrossProduct(&torque, &push, &leverArm);
this->rotDirection = (torque.y > 0.0f) ? 1.0f : -1.0f;
}
} else {
this->timer = 0;
}
if (fabsf(this->dyna.unk_150) > 0.001f) {
this->dyna.unk_150 = 0.0f;
player->stateFlags2 &= ~0x10;
}
}
void BgMoriKaitenkabe_SetupRotate(BgMoriKaitenkabe* this) {
this->actionFunc = BgMoriKaitenkabe_Rotate;
this->rotSpeed = 0.0f;
this->rotYdeg = 0.0f;
}
void BgMoriKaitenkabe_Rotate(BgMoriKaitenkabe* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
Actor* thisx = &this->dyna.actor;
s16 rotY;
Math_ApproxF(&this->rotSpeed, 0.6f, 0.02f);
if (Math_ApproxF(&this->rotYdeg, this->rotDirection * 45.0f, this->rotSpeed)) {
BgMoriKaitenkabe_SetupWait(this);
func_8002DF54(globalCtx, thisx, 7);
if (this->rotDirection > 0.0f) {
thisx->initPosRot.rot.y += 0x2000;
} else {
thisx->initPosRot.rot.y -= 0x2000;
}
thisx->posRot.rot.y = thisx->shape.rot.y = thisx->initPosRot.rot.y;
func_800788CC(NA_SE_EV_STONEDOOR_STOP);
} else {
rotY = this->rotYdeg * (0x10000 / 360.0f);
thisx->posRot.rot.y = thisx->shape.rot.y = thisx->initPosRot.rot.y + rotY;
func_800788CC(NA_SE_EV_WALL_SLIDE - SFX_FLAG);
}
if (fabsf(this->dyna.unk_150) > 0.001f) {
this->dyna.unk_150 = 0.0f;
player->stateFlags2 &= ~0x10;
}
Math_Vec3f_Copy(&player->actor.posRot.pos, &this->lockedPlayerPos);
}
void BgMoriKaitenkabe_Update(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgMoriKaitenkabe* this = THIS;
this->actionFunc(this, globalCtx);
}
void BgMoriKaitenkabe_Draw(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgMoriKaitenkabe* this = THIS;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_bg_mori_kaitenkabe.c", 347);
func_80093D18(globalCtx->state.gfxCtx);
gSPSegment(oGfxCtx->polyOpa.p++, 0x08, globalCtx->objectCtx.status[this->moriTexObjIndex].segment);
gSPMatrix(oGfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_bg_mori_kaitenkabe.c", 352),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(oGfxCtx->polyOpa.p++, D_060056B0);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_bg_mori_kaitenkabe.c", 356);
}

View file

@ -6,9 +6,17 @@
struct BgMoriKaitenkabe;
typedef void (*BgMoriKaitenkabeActionFunc)(struct BgMoriKaitenkabe*, GlobalContext*);
typedef struct BgMoriKaitenkabe {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x3C];
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ BgMoriKaitenkabeActionFunc actionFunc;
/* 0x0168 */ s32 timer;
/* 0x016C */ f32 rotDirection;
/* 0x0170 */ f32 rotSpeed;
/* 0x0174 */ f32 rotYdeg;
/* 0x0178 */ Vec3f lockedPlayerPos;
/* 0x0184 */ s8 moriTexObjIndex;
} BgMoriKaitenkabe; // size = 0x0188
extern const ActorInit Bg_Mori_Kaitenkabe_InitVars;

View file

@ -1,3 +1,9 @@
/*
* File: z_bg_mori_rakkatenjo.c
* Overlay: ovl_Bg_Mori_Rakkatenjo
* Description: Falling ceiling in Forest Temple
*/
#include "z_bg_mori_rakkatenjo.h"
#define FLAGS 0x00000030
@ -7,8 +13,24 @@
void BgMoriRakkatenjo_Init(Actor* thisx, GlobalContext* globalCtx);
void BgMoriRakkatenjo_Destroy(Actor* thisx, GlobalContext* globalCtx);
void BgMoriRakkatenjo_Update(Actor* thisx, GlobalContext* globalCtx);
void BgMoriRakkatenjo_Draw(Actor* thisx, GlobalContext* globalCtx);
void BgMoriRakkatenjo_SetupWaitForMoriTex(BgMoriRakkatenjo* this);
void BgMoriRakkatenjo_WaitForMoriTex(BgMoriRakkatenjo* this, GlobalContext* globalCtx);
void BgMoriRakkatenjo_SetupWait(BgMoriRakkatenjo* this);
void BgMoriRakkatenjo_Wait(BgMoriRakkatenjo* this, GlobalContext* globalCtx);
void BgMoriRakkatenjo_SetupFall(BgMoriRakkatenjo* this);
void BgMoriRakkatenjo_Fall(BgMoriRakkatenjo* this, GlobalContext* globalCtx);
void BgMoriRakkatenjo_SetupRest(BgMoriRakkatenjo* this);
void BgMoriRakkatenjo_Rest(BgMoriRakkatenjo* this, GlobalContext* globalCtx);
void BgMoriRakkatenjo_SetupRise(BgMoriRakkatenjo* this);
void BgMoriRakkatenjo_Rise(BgMoriRakkatenjo* this, GlobalContext* globalCtx);
extern ColHeader D_060087AC;
extern Gfx D_06007690[];
static s16 sCamSetting = 0;
/*
const ActorInit Bg_Mori_Rakkatenjo_InitVars = {
ACTOR_BG_MORI_RAKKATENJO,
ACTORTYPE_BG,
@ -20,35 +42,199 @@ const ActorInit Bg_Mori_Rakkatenjo_InitVars = {
(ActorFunc)BgMoriRakkatenjo_Update,
NULL,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/BgMoriRakkatenjo_Init.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/BgMoriRakkatenjo_Destroy.s")
static InitChainEntry sInitChain[] = {
ICHAIN_F32(gravity, -1, ICHAIN_CONTINUE),
ICHAIN_F32(minVelocityY, -11, ICHAIN_CONTINUE),
ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/func_808A5724.s")
void BgMoriRakkatenjo_Init(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgMoriRakkatenjo* this = THIS;
ColHeader* colHeader = NULL;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/func_808A57D4.s")
DynaPolyInfo_SetActorMove(&this->dyna, DPM_PLAYER);
// Forest Temple obj. Falling Ceiling
osSyncPrintf("森の神殿 obj. 落下天井 (home posY %f)\n", this->dyna.actor.initPosRot.pos.y);
if ((fabsf(1991.0f - this->dyna.actor.initPosRot.pos.x) > 0.001f) ||
(fabsf(683.0f - this->dyna.actor.initPosRot.pos.y) > 0.001f) ||
(fabsf(-2520.0f - this->dyna.actor.initPosRot.pos.z) > 0.001f)) {
// The set position has been changed. Let's fix the program.
osSyncPrintf("Warning : セット位置が変更されています。プログラムを修正しましょう。\n");
}
if (this->dyna.actor.initPosRot.rot.y != 0x8000) {
// The set Angle has changed. Let's fix the program.
osSyncPrintf("Warning : セット Angle が変更されています。プログラムを修正しましょう。\n");
}
this->moriTexObjIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_MORI_TEX);
if (this->moriTexObjIndex < 0) {
// Forest Temple obj Falling Ceiling Bank Danger!
osSyncPrintf("Error : 森の神殿 obj 落下天井 バンク危険!(%s %d)\n", "../z_bg_mori_rakkatenjo.c", 205);
Actor_Kill(&this->dyna.actor);
return;
}
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
DynaPolyInfo_Alloc(&D_060087AC, &colHeader);
this->dyna.dynaPolyId =
DynaPolyInfo_RegisterActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
BgMoriRakkatenjo_SetupWaitForMoriTex(this);
sCamSetting = 0;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/func_808A5884.s")
void BgMoriRakkatenjo_Destroy(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgMoriRakkatenjo* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/func_808A5894.s")
DynaPolyInfo_Free(globalCtx, &globalCtx->colCtx.dyna, this->dyna.dynaPolyId);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/func_808A58E8.s")
s32 BgMoriRakkatenjo_IsLinkUnder(BgMoriRakkatenjo* this, GlobalContext* globalCtx) {
Vec3f* pos = &PLAYER->actor.posRot.pos;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/func_808A5920.s")
return (-3300.0f < pos->z) && (pos->z < -1840.0f) && (1791.0f < pos->x) && (pos->x < 2191.0f);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/func_808A59F0.s")
s32 BgMoriRakkatenjo_IsLinkClose(BgMoriRakkatenjo* this, GlobalContext* globalCtx) {
Vec3f* pos = &PLAYER->actor.posRot.pos;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/func_808A5A0C.s")
return (-3360.0f < pos->z) && (pos->z < -1840.0f) && (1791.0f < pos->x) && (pos->x < 2191.0f);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/func_808A5B80.s")
void BgMoriRakkatenjo_SetupWaitForMoriTex(BgMoriRakkatenjo* this) {
this->actionFunc = BgMoriRakkatenjo_WaitForMoriTex;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/func_808A5BA4.s")
void BgMoriRakkatenjo_WaitForMoriTex(BgMoriRakkatenjo* this, GlobalContext* globalCtx) {
if (Object_IsLoaded(&globalCtx->objectCtx, this->moriTexObjIndex)) {
BgMoriRakkatenjo_SetupWait(this);
this->dyna.actor.draw = BgMoriRakkatenjo_Draw;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/func_808A5BD4.s")
void BgMoriRakkatenjo_SetupWait(BgMoriRakkatenjo* this) {
this->timer = (this->fallCount > 0) ? 100 : 21;
this->dyna.actor.posRot.pos.y = 683.0f;
this->actionFunc = BgMoriRakkatenjo_Wait;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/func_808A5BF0.s")
void BgMoriRakkatenjo_Wait(BgMoriRakkatenjo* this, GlobalContext* globalCtx) {
if (this->fallCount == 0) {
if (BgMoriRakkatenjo_IsLinkClose(this, globalCtx) || (this->timer < 20)) {
if (this->timer <= 0) {
BgMoriRakkatenjo_SetupFall(this);
}
} else {
this->timer = 21;
}
} else {
if (BgMoriRakkatenjo_IsLinkUnder(this, globalCtx) || (this->timer < 20)) {
if (this->timer <= 0) {
BgMoriRakkatenjo_SetupFall(this);
}
} else {
this->timer = 100;
}
}
if (this->timer < 20) {
func_800788CC(NA_SE_EV_BLOCKSINK - SFX_FLAG);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/BgMoriRakkatenjo_Update.s")
void BgMoriRakkatenjo_SetupFall(BgMoriRakkatenjo* this) {
this->actionFunc = BgMoriRakkatenjo_Fall;
this->bounceCount = 0;
this->dyna.actor.velocity.y = 0.0f;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Mori_Rakkatenjo/func_808A5D60.s")
void BgMoriRakkatenjo_Fall(BgMoriRakkatenjo* this, GlobalContext* globalCtx) {
static f32 bounceVel[] = { 4.0f, 1.5f, 0.4f, 0.1f };
s32 pad;
Actor* thisx = &this->dyna.actor;
s32 quake;
Actor_MoveForward(thisx);
if ((thisx->velocity.y < 0.0f) && (thisx->posRot.pos.y <= 403.0f)) {
if (this->bounceCount >= ARRAY_COUNT(bounceVel)) {
BgMoriRakkatenjo_SetupRest(this);
} else {
if (this->bounceCount == 0) {
this->fallCount++;
func_800788CC(NA_SE_EV_STONE_BOUND);
func_800AA000(SQ(thisx->yDistFromLink), 0xFF, 0x14, 0x96);
}
thisx->posRot.pos.y =
403.0f - (thisx->posRot.pos.y - 403.0f) * bounceVel[this->bounceCount] / fabsf(thisx->velocity.y);
thisx->velocity.y = bounceVel[this->bounceCount];
this->bounceCount++;
quake = Quake_Add(ACTIVE_CAM, 3);
Quake_SetSpeed(quake, 50000);
Quake_SetQuakeValues(quake, 5, 0, 0, 0);
Quake_SetCountdown(quake, 5);
}
}
}
void BgMoriRakkatenjo_SetupRest(BgMoriRakkatenjo* this) {
this->actionFunc = BgMoriRakkatenjo_Rest;
this->dyna.actor.posRot.pos.y = 403.0f;
this->timer = 20;
}
void BgMoriRakkatenjo_Rest(BgMoriRakkatenjo* this, GlobalContext* globalCtx) {
if (this->timer <= 0) {
BgMoriRakkatenjo_SetupRise(this);
}
}
void BgMoriRakkatenjo_SetupRise(BgMoriRakkatenjo* this) {
this->actionFunc = BgMoriRakkatenjo_Rise;
this->dyna.actor.velocity.y = -0.1f;
}
void BgMoriRakkatenjo_Rise(BgMoriRakkatenjo* this, GlobalContext* globalCtx) {
Math_SmoothScaleMaxMinF(&this->dyna.actor.velocity.y, 5.0f, 0.06f, 0.1f, 0.0f);
this->dyna.actor.posRot.pos.y += this->dyna.actor.velocity.y;
if (this->dyna.actor.posRot.pos.y >= 683.0f) {
BgMoriRakkatenjo_SetupWait(this);
}
}
void BgMoriRakkatenjo_Update(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgMoriRakkatenjo* this = THIS;
if (this->timer > 0) {
this->timer--;
}
this->actionFunc(this, globalCtx);
if (BgMoriRakkatenjo_IsLinkUnder(this, globalCtx)) {
if (sCamSetting == 0) {
osSyncPrintf("camera changed (mori rakka tenjyo) ... \n");
sCamSetting = globalCtx->cameraPtrs[0]->setting;
Camera_SetCameraData(globalCtx->cameraPtrs[0], 1, &this->dyna.actor, NULL, 0, 0, 0);
func_8005A77C(globalCtx->cameraPtrs[0], 0x27);
}
} else if (sCamSetting != 0) {
osSyncPrintf("camera changed (previous) ... \n");
func_8005A77C(globalCtx->cameraPtrs[0], 4);
sCamSetting = 0;
}
}
void BgMoriRakkatenjo_Draw(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgMoriRakkatenjo* this = THIS;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_bg_mori_rakkatenjo.c", 497);
func_80093D18(globalCtx->state.gfxCtx);
gSPSegment(oGfxCtx->polyOpa.p++, 0x08, globalCtx->objectCtx.status[this->moriTexObjIndex].segment);
gSPMatrix(oGfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_bg_mori_rakkatenjo.c", 502),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(oGfxCtx->polyOpa.p++, D_06007690);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_bg_mori_rakkatenjo.c", 506);
}

View file

@ -6,9 +6,15 @@
struct BgMoriRakkatenjo;
typedef void (*BgMoriRakkatenjoActionFunction)(struct BgMoriRakkatenjo*, GlobalContext*);
typedef struct BgMoriRakkatenjo {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x2C];
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ BgMoriRakkatenjoActionFunction actionFunc;
/* 0x0168 */ s32 timer;
/* 0x016C */ s32 bounceCount;
/* 0x0170 */ s32 fallCount;
/* 0x0174 */ s8 moriTexObjIndex;
} BgMoriRakkatenjo; // size = 0x0178
extern const ActorInit Bg_Mori_Rakkatenjo_InitVars;

View file

@ -1,3 +1,9 @@
/*
* File: z_bg_po_event.c
* Overlay: ovl_Bg_Po_Event
* Description: Poe sisters' paintings and puzzle blocks
*/
#include "z_bg_po_event.h"
#define FLAGS 0x00000000
@ -9,7 +15,27 @@ void BgPoEvent_Destroy(Actor* thisx, GlobalContext* globalCtx);
void BgPoEvent_Update(Actor* thisx, GlobalContext* globalCtx);
void BgPoEvent_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void BgPoEvent_BlockWait(BgPoEvent* this, GlobalContext* globalCtx);
void BgPoEvent_BlockShake(BgPoEvent* this, GlobalContext* globalCtx);
void BgPoEvent_BlockFall(BgPoEvent* this, GlobalContext* globalCtx);
void BgPoEvent_BlockIdle(BgPoEvent* this, GlobalContext* globalCtx);
void BgPoEvent_BlockPush(BgPoEvent* this, GlobalContext* globalCtx);
void BgPoEvent_BlockReset(BgPoEvent* this, GlobalContext* globalCtx);
void BgPoEvent_BlockSolved(BgPoEvent* this, GlobalContext* globalCtx);
void BgPoEvent_AmyWait(BgPoEvent* this, GlobalContext* globalCtx); // Amy is the green Poe
void BgPoEvent_AmyPuzzle(BgPoEvent* this, GlobalContext* globalCtx);
void BgPoEvent_PaintingEmpty(BgPoEvent* this, GlobalContext* globalCtx);
void BgPoEvent_PaintingAppear(BgPoEvent* this, GlobalContext* globalCtx);
void BgPoEvent_PaintingPresent(BgPoEvent* this, GlobalContext* globalCtx);
void BgPoEvent_PaintingBurn(BgPoEvent* this, GlobalContext* globalCtx);
extern Gfx D_060075A0[];
extern Gfx D_060079E0[];
extern Gfx D_06006830[];
extern Gfx D_06006D60[];
extern Gfx D_06007230[];
extern ColHeader D_06007860;
const ActorInit Bg_Po_Event_InitVars = {
ACTOR_BG_PO_EVENT,
ACTORTYPE_BG,
@ -21,47 +47,573 @@ const ActorInit Bg_Po_Event_InitVars = {
(ActorFunc)BgPoEvent_Update,
(ActorFunc)BgPoEvent_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A6210.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A658C.s")
static ColliderTrisItemInit sTrisItemsInit[2] = {
{
{ 0x04, { 0x00000000, 0x00, 0x00 }, { 0x0001F820, 0x00, 0x00 }, 0x00, 0x01, 0x00 },
{ { { 25.0f, 33.0f, 0.0f }, { -25.0f, 33.0f, 0.0f }, { -25.0f, -33.0f, 0.0f } } },
},
{
{ 0x04, { 0x00000000, 0x00, 0x00 }, { 0x0001F820, 0x00, 0x00 }, 0x00, 0x01, 0x00 },
{ { { 25.0f, 33.0f, 0.0f }, { -25.0f, -33.0f, 0.0f }, { 25.0f, -33.0f, 0.0f } } },
},
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/BgPoEvent_Init.s")
static ColliderTrisInit sTrisInit = {
{ COLTYPE_UNK10, 0x00, 0x09, 0x00, 0x20, COLSHAPE_TRIS },
2,
sTrisItemsInit,
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/BgPoEvent_Destroy.s")
static u8 sBlocksAtRest = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A68D0.s")
static Vec3f sZeroVec = { 0.0f, 0.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A69DC.s")
static u8 sPuzzleState;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A6A94.s")
void BgPoEvent_InitPaintings(BgPoEvent* this, GlobalContext* globalCtx) {
static s16 paintingPosX[] = { -1302, -866, 1421, 985 };
static s16 paintingPosY[] = { 1107, 1091 };
static s16 paintingPosZ[] = { -3384, -3252 };
ColliderTrisItemInit* item;
Vec3f* vtxVec;
s32 i1;
s32 i2;
Vec3f sp9C[3];
f32 coss;
f32 sins;
f32 scaleY;
s32 phi_t2;
Actor* newPainting;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A6BC8.s")
sins = Math_Sins(this->dyna.actor.shape.rot.y);
coss = Math_Coss(this->dyna.actor.shape.rot.y);
if (this->type == 4) {
sins *= 2.4f;
scaleY = 1.818f;
coss *= 2.4f;
} else {
scaleY = 1.0f;
}
for (i1 = 0; i1 < sTrisInit.count; i1++) {
item = &sTrisInit.list[i1];
if (1) {} // This section looks like a macro of some sort.
for (i2 = 0; i2 < 3; i2++) {
vtxVec = &item->dim.vtx[i2];
sp9C[i2].x = (vtxVec->x * coss) + (this->dyna.actor.initPosRot.pos.x + (sins * vtxVec->z));
sp9C[i2].y = (vtxVec->y * scaleY) + this->dyna.actor.initPosRot.pos.y;
sp9C[i2].z = this->dyna.actor.initPosRot.pos.z + (coss * vtxVec->z) - (vtxVec->x * sins);
}
func_800627A0(&this->collider, i1, &sp9C[0], &sp9C[1], &sp9C[2]);
}
if ((this->type != 4) && (this->index != 2)) {
phi_t2 = (this->type == 2) ? this->index : this->index + 2;
newPainting = Actor_SpawnAsChild(&globalCtx->actorCtx, &this->dyna.actor, globalCtx, ACTOR_BG_PO_EVENT,
paintingPosX[phi_t2], paintingPosY[this->index], paintingPosZ[this->index], 0,
this->dyna.actor.shape.rot.y + 0x8000, 0,
((this->index + 1) << 0xC) + (this->type << 8) + this->dyna.actor.params);
if (newPainting == NULL) {
Actor_Kill(&this->dyna.actor);
return;
}
if (this->index == 0) {
if (this->dyna.actor.child->child == NULL) {
Actor_Kill(&this->dyna.actor);
return;
}
this->dyna.actor.parent = this->dyna.actor.child->child;
this->dyna.actor.child->child->child = &this->dyna.actor;
}
}
this->timer = 0;
if (this->type == 4) {
sPuzzleState = 0;
this->actionFunc = BgPoEvent_AmyWait;
} else {
sPuzzleState = (s32)(Math_Rand_ZeroOne() * 3.0f) % 3;
this->actionFunc = BgPoEvent_PaintingEmpty;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A6CCC.s")
void BgPoEvent_InitBlocks(BgPoEvent* this, GlobalContext* globalCtx) {
static s16 blockPosX[] = { 2149, 1969, 1909 };
static s16 blockPosZ[] = { -1410, -1350, -1530 };
Actor* newBlock;
ColHeader* colHeader = NULL;
s32 bgId;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A6F7C.s")
this->dyna.actor.flags |= 0x30;
DynaPolyInfo_Alloc(&D_06007860, &colHeader);
this->dyna.dynaPolyId =
DynaPolyInfo_RegisterActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
if ((this->type == 0) && (this->index != 3)) {
newBlock = Actor_SpawnAsChild(&globalCtx->actorCtx, &this->dyna.actor, globalCtx, ACTOR_BG_PO_EVENT,
blockPosX[this->index], this->dyna.actor.posRot.pos.y, blockPosZ[this->index], 0,
this->dyna.actor.shape.rot.y, this->dyna.actor.shape.rot.z - 0x4000,
((this->index + 1) << 0xC) + (this->type << 8) + this->dyna.actor.params);
if (newBlock == NULL) {
Actor_Kill(&this->dyna.actor);
return;
}
if (this->index == 0) {
if (this->dyna.actor.child->child == NULL) {
Actor_Kill(&this->dyna.actor);
return;
}
if (this->dyna.actor.child->child->child == NULL) {
Actor_Kill(&this->dyna.actor);
Actor_Kill(this->dyna.actor.child);
return;
}
this->dyna.actor.parent = this->dyna.actor.child->child->child;
this->dyna.actor.child->child->child->child = &this->dyna.actor;
}
}
this->dyna.actor.posRot.pos.y = 833.0f;
this->dyna.actor.groundY = func_8003C9A4(&globalCtx->colCtx, &this->dyna.actor.floorPoly, &bgId, &this->dyna.actor,
&this->dyna.actor.posRot.pos);
this->actionFunc = BgPoEvent_BlockWait;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A7138.s")
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A7238.s")
void BgPoEvent_Init(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgPoEvent* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A72AC.s")
Actor_ProcessInitChain(thisx, sInitChain);
this->type = (thisx->params >> 8) & 0xF;
this->index = (thisx->params >> 0xC) & 0xF;
thisx->params &= 0x3F;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A7328.s")
if (this->type >= 2) {
Collider_InitTris(globalCtx, &this->collider);
Collider_SetTris(globalCtx, &this->collider, thisx, &sTrisInit, this->colliderItems);
if (Flags_GetSwitch(globalCtx, thisx->params)) {
Actor_Kill(thisx);
} else {
BgPoEvent_InitPaintings(this, globalCtx);
}
} else {
DynaPolyInfo_SetActorMove(&this->dyna, DPM_UNK);
if (Flags_GetSwitch(globalCtx, thisx->params)) {
Actor_Kill(thisx);
} else {
BgPoEvent_InitBlocks(this, globalCtx);
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A7444.s")
void BgPoEvent_Destroy(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgPoEvent* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A7500.s")
if (this->type >= 2) {
Collider_DestroyTris(globalCtx, &this->collider);
} else {
DynaPolyInfo_Free(globalCtx, &globalCtx->colCtx.dyna, this->dyna.dynaPolyId);
if ((this->type == 1) && (gSaveContext.timer1Value > 0)) {
gSaveContext.timer1State = 0xA;
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A7530.s")
void BgPoEvent_BlockWait(BgPoEvent* this, GlobalContext* globalCtx) {
this->dyna.actor.posRot.pos.y = 833.0f;
if (sPuzzleState == 0x3F) {
if (this->type == 1) {
func_800800F8(globalCtx, 0xC4E, 0x41, NULL, 0);
}
this->timer = 45;
this->actionFunc = BgPoEvent_BlockShake;
} else if (this->dyna.actor.xzDistFromLink > 50.0f) {
if (this->type != 1) {
sPuzzleState |= (1 << this->index);
} else {
sPuzzleState |= 0x10;
}
} else if (this->type != 1) {
sPuzzleState &= ~(1 << this->index);
} else {
sPuzzleState &= ~0x10;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A7568.s")
void BgPoEvent_BlockShake(BgPoEvent* this, GlobalContext* globalCtx) {
DECR(this->timer);
if (this->timer < 15) {
this->dyna.actor.posRot.pos.x = this->dyna.actor.initPosRot.pos.x + 2.0f * ((this->timer % 3) - 1);
if (!(this->timer % 4)) {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_SHAKE);
}
}
if (this->timer == 0) {
this->dyna.actor.posRot.pos.x = this->dyna.actor.initPosRot.pos.x;
sPuzzleState = 0;
this->timer = 60;
this->actionFunc = BgPoEvent_BlockFall;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A75B8.s")
void BgPoEvent_CheckBlock(BgPoEvent* this) {
s32 phi_v1;
s32 phi_a1;
s32 phi_t0;
s32 phi_a3;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/func_808A780C.s")
if ((this->index == 3) || (this->index == 1)) {
phi_v1 = this->dyna.actor.posRot.pos.z;
phi_a1 = this->dyna.actor.child->posRot.pos.z;
if (this->index == 3) {
phi_a3 = this->dyna.actor.posRot.pos.x;
phi_t0 = this->dyna.actor.child->posRot.pos.x;
} else { // this->index == 1
phi_a3 = this->dyna.actor.child->posRot.pos.x;
phi_t0 = this->dyna.actor.posRot.pos.x;
}
} else {
phi_v1 = this->dyna.actor.posRot.pos.x;
phi_a1 = this->dyna.actor.child->posRot.pos.x;
if (this->index == 0) {
phi_a3 = this->dyna.actor.posRot.pos.z;
phi_t0 = this->dyna.actor.child->posRot.pos.z;
} else { // this->index == 2
phi_a3 = this->dyna.actor.child->posRot.pos.z;
phi_t0 = this->dyna.actor.posRot.pos.z;
}
}
if ((phi_v1 == phi_a1) && ((phi_t0 - phi_a3) == 60)) {
sPuzzleState |= (1 << this->index);
} else {
sPuzzleState &= ~(1 << this->index);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/BgPoEvent_Update.s")
void BgPoEvent_BlockFall(BgPoEvent* this, GlobalContext* globalCtx) {
static s32 firstFall = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Po_Event/BgPoEvent_Draw.s")
this->dyna.actor.velocity.y++;
if (Math_ApproxF(&this->dyna.actor.posRot.pos.y, 433.0f, this->dyna.actor.velocity.y)) {
this->dyna.actor.flags &= ~0x20;
this->dyna.actor.velocity.y = 0.0f;
sBlocksAtRest++;
if (this->type != 1) {
BgPoEvent_CheckBlock(this);
} else {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONE_BOUND);
func_80033E88(&this->dyna.actor, globalCtx, 5, 5);
func_80088B34(this->timer);
if (firstFall == 0) {
firstFall = 1;
} else {
func_8002DF54(globalCtx, &PLAYER->actor, 7);
}
}
this->direction = 0;
this->actionFunc = BgPoEvent_BlockIdle;
}
}
void BgPoEvent_BlockIdle(BgPoEvent* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
Actor* amy;
if (sPuzzleState == 0xF) {
this->actionFunc = BgPoEvent_BlockSolved;
if ((this->type == 0) && (this->index == 0)) {
amy =
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_PO_SISTERS, this->dyna.actor.posRot.pos.x + 30.0f,
this->dyna.actor.posRot.pos.y - 30.0f, this->dyna.actor.posRot.pos.z + 30.0f, 0,
this->dyna.actor.shape.rot.y, 0, this->dyna.actor.params + 0x300);
if (amy != NULL) {
func_800800F8(globalCtx, 0xC62, 0x1E, amy, 0);
}
func_80078884(NA_SE_SY_CORRECT_CHIME);
gSaveContext.timer1State = 0xA;
}
} else {
if ((gSaveContext.timer1Value == 0) && (sBlocksAtRest == 5)) {
player->stateFlags2 &= ~0x10;
sPuzzleState = 0x10;
sBlocksAtRest = 0;
}
if ((sPuzzleState == 0x40) || ((sPuzzleState == 0x10) && !Player_InCsMode(globalCtx))) {
this->dyna.actor.posRot.rot.z = this->dyna.actor.shape.rot.z;
this->actionFunc = BgPoEvent_BlockReset;
if (sPuzzleState == 0x10) {
sPuzzleState = 0x40;
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_RISING);
func_8002DF54(globalCtx, &player->actor, 8);
}
} else if (this->dyna.unk_150 != 0.0f) {
if (this->direction == 0) {
if (func_800435D8(globalCtx, &this->dyna, 0x1E, 0x32, -0x14) != 0) {
sBlocksAtRest--;
this->direction = (this->dyna.unk_150 >= 0.0f) ? 1.0f : -1.0f;
this->actionFunc = BgPoEvent_BlockPush;
} else {
player->stateFlags2 &= ~0x10;
this->dyna.unk_150 = 0.0f;
}
} else {
player->stateFlags2 &= ~0x10;
this->dyna.unk_150 = 0.0f;
DECR(this->direction);
}
} else {
this->direction = 0;
}
}
}
void BgPoEvent_BlockPush(BgPoEvent* this, GlobalContext* globalCtx) {
static f32 blockPushDist = 0.0f;
f32 displacement;
s32 blockStop;
Player* player = PLAYER;
this->dyna.actor.speedXZ += 0.1f;
this->dyna.actor.speedXZ = CLAMP_MAX(this->dyna.actor.speedXZ, 2.0f);
blockStop = Math_ApproxF(&blockPushDist, 20.0f, this->dyna.actor.speedXZ);
displacement = this->direction * blockPushDist;
this->dyna.actor.posRot.pos.x = (Math_Sins(this->dyna.unk_158) * displacement) + this->dyna.actor.initPosRot.pos.x;
this->dyna.actor.posRot.pos.z = (Math_Coss(this->dyna.unk_158) * displacement) + this->dyna.actor.initPosRot.pos.z;
if (blockStop) {
player->stateFlags2 &= ~0x10;
if ((this->dyna.unk_150 > 0.0f) && (func_800435D8(globalCtx, &this->dyna, 0x1E, 0x32, -0x14) == 0)) {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND);
}
this->dyna.unk_150 = 0.0f;
this->dyna.actor.initPosRot.pos.x = this->dyna.actor.posRot.pos.x;
this->dyna.actor.initPosRot.pos.z = this->dyna.actor.posRot.pos.z;
blockPushDist = 0.0f;
this->dyna.actor.speedXZ = 0.0f;
this->direction = 5;
sBlocksAtRest++;
this->actionFunc = BgPoEvent_BlockIdle;
if (this->type == 1) {
return;
}
BgPoEvent_CheckBlock(this);
BgPoEvent_CheckBlock((BgPoEvent*)this->dyna.actor.parent);
}
func_8002F974(&this->dyna.actor, NA_SE_EV_ROCK_SLIDE - SFX_FLAG);
}
void BgPoEvent_BlockReset(BgPoEvent* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
if (this->dyna.unk_150 != 0.0f) {
player->stateFlags2 &= ~0x10;
this->dyna.unk_150 = 0.0f;
}
if (Math_ApproxF(&this->dyna.actor.posRot.pos.y, 493.0f, 1.0f) &&
Math_ApproxUpdateScaledS(&this->dyna.actor.shape.rot.z, this->dyna.actor.posRot.rot.z - 0x4000, 0x400)) {
this->index = (this->index + 1) % 4;
this->actionFunc = BgPoEvent_BlockFall;
sPuzzleState = 0;
if (this->type == 1) {
this->timer += 10;
this->timer = CLAMP_MAX(this->timer, 120);
}
}
}
void BgPoEvent_BlockSolved(BgPoEvent* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
if (this->dyna.unk_150 != 0.0f) {
player->stateFlags2 &= ~0x10;
}
if (Math_ApproxF(&this->dyna.actor.posRot.pos.y, 369.0f, 2.0f)) {
sPuzzleState = 0x20;
Actor_Kill(&this->dyna.actor);
}
}
void BgPoEvent_AmyWait(BgPoEvent* this, GlobalContext* globalCtx) {
if (this->collider.base.acFlags & 2) {
sPuzzleState |= 0x20;
this->timer = 5;
func_8003426C(&this->dyna.actor, 0x4000, 0xFF, 0, 5);
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EN_PO_LAUGH2);
this->actionFunc = BgPoEvent_AmyPuzzle;
}
}
void BgPoEvent_AmyPuzzle(BgPoEvent* this, GlobalContext* globalCtx) {
Vec3f pos;
if (sPuzzleState == 0xF) {
pos.x = this->dyna.actor.posRot.pos.x - 5.0f;
pos.y = Math_Rand_CenteredFloat(120.0f) + this->dyna.actor.posRot.pos.y;
pos.z = Math_Rand_CenteredFloat(120.0f) + this->dyna.actor.posRot.pos.z;
EffectSsDeadDb_Spawn(globalCtx, &pos, &sZeroVec, &sZeroVec, 170, 0, 200, 255, 100, 170, 0, 255, 0, 1, 9, true);
} else if (sPuzzleState == 0x20) {
Actor_Kill(&this->dyna.actor);
} else {
DECR(this->timer);
}
}
s32 BgPoEvent_NextPainting(BgPoEvent* this) {
if ((this->dyna.actor.parent != NULL) && (this->dyna.actor.child != NULL)) {
if (Math_Rand_ZeroOne() < 0.5f) {
sPuzzleState = ((BgPoEvent*)this->dyna.actor.parent)->index;
} else {
sPuzzleState = ((BgPoEvent*)this->dyna.actor.child)->index;
}
} else if (this->dyna.actor.parent != NULL) {
sPuzzleState = ((BgPoEvent*)this->dyna.actor.parent)->index;
} else if (this->dyna.actor.child != NULL) {
sPuzzleState = ((BgPoEvent*)this->dyna.actor.child)->index;
} else {
return false;
}
return true;
}
void BgPoEvent_PaintingEmpty(BgPoEvent* this, GlobalContext* globalCtx) {
if (sPuzzleState == this->index) {
this->timer = 255;
this->actionFunc = BgPoEvent_PaintingAppear;
}
}
void BgPoEvent_PaintingAppear(BgPoEvent* this, GlobalContext* globalCtx) {
this->timer -= 20;
if (this->timer <= 0) {
this->timer = 1000;
this->actionFunc = BgPoEvent_PaintingPresent;
}
}
void BgPoEvent_PaintingVanish(BgPoEvent* this, GlobalContext* globalCtx) {
this->timer += 20;
if (this->timer >= 255) {
BgPoEvent_NextPainting(this);
this->actionFunc = BgPoEvent_PaintingEmpty;
}
}
void BgPoEvent_PaintingPresent(BgPoEvent* this, GlobalContext* globalCtx) {
Actor* thisx = &this->dyna.actor;
Player* player = PLAYER;
DECR(this->timer);
if (((this->timer == 0) || ((thisx->xzDistFromLink < 150.0f) && (thisx->yDistFromLink < 50.0f)) ||
(func_8002DD78(player) && (thisx->xzDistFromLink < 320.0f) &&
((this->index != 2) ? (thisx->yDistFromLink < 100.0f) : (thisx->yDistFromLink < 0.0f)) &&
func_8002DFC8(thisx, 0x2000, globalCtx))) &&
((thisx->parent != NULL) || (thisx->child != NULL))) {
/*The third condition in the || is checking if
1) Link is holding a ranged weapon
2) Link is too close in the xz plane
3) Link is too close in the y direction. The painting
under the balcony allows him to be closer.
4) Link is within 45 degrees of facing the painting. */
this->timer = 0;
Audio_PlayActorSound2(thisx, NA_SE_EN_PO_LAUGH);
this->actionFunc = BgPoEvent_PaintingVanish;
} else if (this->collider.base.acFlags & 2) {
if (!BgPoEvent_NextPainting(this)) {
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_PO_SISTERS, thisx->posRot.pos.x,
thisx->posRot.pos.y - 40.0f, thisx->posRot.pos.z, 0, thisx->shape.rot.y, 0,
thisx->params + ((this->type - 1) << 8));
func_800800F8(globalCtx, 0xC58, 0x50, thisx, 0);
func_80078884(NA_SE_SY_CORRECT_CHIME);
} else {
Audio_PlayActorSound2(thisx, NA_SE_EN_PO_LAUGH2);
func_800800F8(globalCtx, 0xC58, 0x23, thisx, 0);
}
if (thisx->parent != NULL) {
thisx->parent->child = NULL;
thisx->parent = NULL;
}
if (thisx->child != NULL) {
thisx->child->parent = NULL;
thisx->child = NULL;
}
this->timer = 20;
this->actionFunc = BgPoEvent_PaintingBurn;
}
}
void BgPoEvent_PaintingBurn(BgPoEvent* this, GlobalContext* globalCtx) {
Vec3f sp54;
this->timer--;
sp54.x = (Math_Sins(this->dyna.actor.shape.rot.y) * 5.0f) + this->dyna.actor.posRot.pos.x;
sp54.y = Math_Rand_CenteredFloat(66.0f) + this->dyna.actor.posRot.pos.y;
sp54.z = Math_Rand_CenteredFloat(50.0f) + this->dyna.actor.posRot.pos.z;
if (this->timer >= 0) {
if (this->type == 2) {
EffectSsDeadDb_Spawn(globalCtx, &sp54, &sZeroVec, &sZeroVec, 100, 0, 255, 255, 150, 170, 255, 0, 0, 1, 9,
true);
} else {
EffectSsDeadDb_Spawn(globalCtx, &sp54, &sZeroVec, &sZeroVec, 100, 0, 200, 255, 255, 170, 50, 100, 255, 1, 9,
true);
}
}
if (this->timer == 0) {
this->dyna.actor.draw = NULL;
}
if (this->timer < -60) {
Actor_Kill(&this->dyna.actor);
}
}
void BgPoEvent_Update(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgPoEvent* this = THIS;
this->actionFunc(this, globalCtx);
if ((this->actionFunc == BgPoEvent_AmyWait) || (this->actionFunc == BgPoEvent_PaintingPresent)) {
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
}
void BgPoEvent_Draw(Actor* thisx, GlobalContext* globalCtx) {
static Gfx* displayLists[] = { D_060075A0, D_060079E0, D_06006830, D_06006D60, D_06007230 };
s32 pad;
BgPoEvent* this = THIS;
u8 alpha;
Vec3f sp58;
Vec3f sp4C;
f32 sp48;
s32 pad2;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_bg_po_event.c", 1481);
func_80093D18(globalCtx->state.gfxCtx);
if ((this->type == 3) || (this->type == 2)) {
if (this->actionFunc == BgPoEvent_PaintingEmpty) {
alpha = 255;
} else if (this->actionFunc == BgPoEvent_PaintingPresent) {
alpha = 0;
} else {
alpha = this->timer;
}
gDPSetEnvColor(oGfxCtx->polyOpa.p++, 255, 255, 255, alpha);
}
gSPMatrix(oGfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_bg_po_event.c", 1501),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(oGfxCtx->polyOpa.p++, displayLists[this->type]);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_bg_po_event.c", 1508);
if ((this->type == 0) || (this->type == 1)) {
sp48 = (833.0f - this->dyna.actor.posRot.pos.y) * 0.0025f;
if (!(sp48 > 1.0f)) {
sp58.x = this->dyna.actor.posRot.pos.x;
sp58.y = this->dyna.actor.posRot.pos.y - 30.0f;
sp58.z = this->dyna.actor.posRot.pos.z;
sp4C.y = 1.0f;
sp4C.x = sp4C.z = (sp48 * 0.3f) + 0.4f;
func_80033C30(&sp58, &sp4C, (u8)(155.0f + sp48 * 100.0f), globalCtx);
}
}
}

View file

@ -6,9 +6,17 @@
struct BgPoEvent;
typedef void (*BgPoEventActionFunc)(struct BgPoEvent*, GlobalContext*);
typedef struct BgPoEvent {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0xFC];
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ BgPoEventActionFunc actionFunc;
/* 0x0168 */ u8 type;
/* 0x0169 */ u8 index;
/* 0x016A */ s8 direction;
/* 0x016C */ s16 timer;
/* 0x0170 */ ColliderTris collider;
/* 0x0190 */ ColliderTrisItem colliderItems[2];
} BgPoEvent; // size = 0x0248
extern const ActorInit Bg_Po_Event_InitVars;

View file

@ -15,7 +15,8 @@ void BgSpot03Taki_Destroy(Actor* thisx, GlobalContext* globalCtx);
void BgSpot03Taki_Update(Actor* thisx, GlobalContext* globalCtx);
void BgSpot03Taki_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void func_808ADEF0(BgSpot03Taki* this, GlobalContext* globalCtx);
const ActorInit Bg_Spot03_Taki_InitVars = {
ACTOR_BG_SPOT03_TAKI,
ACTORTYPE_BG,
@ -27,15 +28,142 @@ const ActorInit Bg_Spot03_Taki_InitVars = {
(ActorFunc)BgSpot03Taki_Update,
(ActorFunc)BgSpot03Taki_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot03_Taki/func_808ADAE0.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot03_Taki/BgSpot03Taki_Init.s")
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot03_Taki/BgSpot03Taki_Destroy.s")
extern UNK_TYPE D_06000C98;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot03_Taki/func_808ADEF0.s")
// These are identical vertex data for the waterfall.
extern Vtx* D_06000800[]; // Vertex buffer 0
extern Vtx* D_06000990[]; // Vertex buffer 1
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot03_Taki/BgSpot03Taki_Update.s")
extern Gfx* D_06000B20[];
extern Gfx* D_06000BC0[];
extern Gfx* D_06001580[];
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot03_Taki/BgSpot03Taki_Draw.s")
void BgSpot03Taki_ApplyOpeningAlpha(BgSpot03Taki* this, s32 bufferIndex) {
s32 i;
Vtx* vtx = (bufferIndex == 0) ? SEGMENTED_TO_VIRTUAL(D_06000800) : SEGMENTED_TO_VIRTUAL(D_06000990);
for (i = 0; i < 5; i++) {
vtx[i + 10].v.cn[3] = this->openingAlpha;
}
}
void BgSpot03Taki_Init(Actor* thisx, GlobalContext* globalCtx) {
BgSpot03Taki* this = THIS;
s16 pad;
s32 sp24 = 0;
this->switchFlag = (this->dyna.actor.params & 0x3F);
DynaPolyInfo_SetActorMove(&this->dyna, 0);
DynaPolyInfo_Alloc(&D_06000C98, &sp24);
this->dyna.dynaPolyId = DynaPolyInfo_RegisterActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, sp24);
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
this->bufferIndex = 0;
this->openingAlpha = 255.0f;
BgSpot03Taki_ApplyOpeningAlpha(this, 0);
BgSpot03Taki_ApplyOpeningAlpha(this, 1);
this->actionFunc = func_808ADEF0;
}
void BgSpot03Taki_Destroy(Actor* thisx, GlobalContext* globalCtx) {
BgSpot03Taki* this = THIS;
DynaPolyInfo_Free(globalCtx, &globalCtx->colCtx.dyna, this->dyna.dynaPolyId);
}
void func_808ADEF0(BgSpot03Taki* this, GlobalContext* globalCtx) {
if (this->state == WATERFALL_CLOSED) {
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
this->state = WATERFALL_OPENING_ANIMATED;
this->timer = 40;
func_800800F8(globalCtx, 0x1004, -0x63, NULL, 0);
}
} else if (this->state == WATERFALL_OPENING_IDLE) {
this->timer--;
if (this->timer < 0) {
this->state = WATERFALL_OPENING_ANIMATED;
}
} else if (this->state == WATERFALL_OPENING_ANIMATED) {
if (this->openingAlpha > 0) {
this->openingAlpha -= 5;
if (this->openingAlpha <= 0.0f) {
func_8003EBF8(globalCtx, &globalCtx->colCtx.dyna, this->dyna.dynaPolyId);
this->timer = 400;
this->state = WATERFALL_OPENED;
this->openingAlpha = 0;
}
}
} else if (this->state == WATERFALL_OPENED) {
this->timer--;
if (this->timer < 0) {
this->state = WATERFALL_CLOSING;
}
} else if (this->state == WATERFALL_CLOSING) {
if (this->openingAlpha < 255.0f) {
this->openingAlpha += 5.0f;
if (this->openingAlpha >= 255.0f) {
func_8003EC50(globalCtx, &globalCtx->colCtx.dyna, this->dyna.dynaPolyId);
this->state = WATERFALL_CLOSED;
this->openingAlpha = 255.0f;
Flags_UnsetSwitch(globalCtx, this->switchFlag);
}
}
}
BgSpot03Taki_ApplyOpeningAlpha(this, this->bufferIndex);
}
void BgSpot03Taki_Update(Actor* thisx, GlobalContext* globalCtx) {
BgSpot03Taki* this = THIS;
this->actionFunc(this, globalCtx);
}
void BgSpot03Taki_Draw(Actor* thisx, GlobalContext* globalCtx) {
BgSpot03Taki* this = THIS;
s32 pad;
u32 gameplayFrames;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_bg_spot03_taki.c", 321);
gameplayFrames = globalCtx->gameplayFrames;
gSPMatrix(oGfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_bg_spot03_taki.c", 325),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
func_80093D84(globalCtx->state.gfxCtx);
gSPSegment(
oGfxCtx->polyXlu.p++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, gameplayFrames * 5, 64, 64, 1, 0, gameplayFrames * 5, 64, 64));
gSPDisplayList(oGfxCtx->polyXlu.p++, D_06000B20);
if (this->bufferIndex == 0) {
gSPVertex(oGfxCtx->polyXlu.p++, D_06000800, 25, 0);
} else {
gSPVertex(oGfxCtx->polyXlu.p++, D_06000990, 25, 0);
}
gSPDisplayList(oGfxCtx->polyXlu.p++, D_06000BC0);
gSPSegment(oGfxCtx->polyXlu.p++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, gameplayFrames * 1, gameplayFrames * 3, 64, 64, 1,
-gameplayFrames, gameplayFrames * 3, 64, 64));
gSPDisplayList(oGfxCtx->polyXlu.p++, D_06001580);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_bg_spot03_taki.c", 358);
this->bufferIndex = this->bufferIndex == 0;
if (this->state > WATERFALL_CLOSED && this->state < WATERFALL_CLOSING) {
func_800F46E0(&this->dyna.actor.projectedPos, 0.5f);
} else {
func_800F46E0(&this->dyna.actor.projectedPos, 1.0f);
}
}

View file

@ -4,11 +4,26 @@
#include "ultra64.h"
#include "global.h"
typedef enum {
WATERFALL_CLOSED,
WATERFALL_OPENING_IDLE,
WATERFALL_OPENING_ANIMATED,
WATERFALL_OPENED,
WATERFALL_CLOSING,
} BgSpot03TakiState;
struct BgSpot03Taki;
typedef void (*BgSpot03TakiActionFunc)(struct BgSpot03Taki*, GlobalContext*);
typedef struct BgSpot03Taki {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x2C];
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ BgSpot03TakiActionFunc actionFunc;
/* 0x0168 */ s16 timer;
/* 0x016A */ u8 state;
/* 0x016C */ u16 switchFlag;
/* 0x0170 */ f32 openingAlpha;
/* 0x0174 */ u8 bufferIndex;
} BgSpot03Taki; // size = 0x0178
extern const ActorInit Bg_Spot03_Taki_InitVars;

View file

@ -8,7 +8,9 @@ struct EnArrow;
typedef struct EnArrow {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0xFC];
/* 0x014C */ char unk_14C[0x5C];
/* 0x01A8 */ s32 unk_1A8; // related to arrows being on fire
/* 0x01AC */ char unk_1AC[0x9C];
/* 0x0248 */ u8 timer; // used for dissapearing when flying or hitting a wall
/* 0x0249 */ u8 hitWall;
/* 0x024A */ char unk_24A[0x16];

View file

@ -8,7 +8,14 @@ struct EnEncount1;
typedef struct EnEncount1 {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x24];
/* 0x014C */ char unk_14C[0x6];
/* 0x0152 */ s16 unk_152;
/* 0x0154 */ char unk_154[0xA];
/* 0x015E */ s16 numLeeversDead;
/* 0x0160 */ char unk_160[0x4];
/* 0x0164 */ s16 unk_164;
/* 0x0166 */ char unk_166[0x6];
/* 0x016C */ UNK_TYPE unk_16C;
} EnEncount1; // size = 0x0170
extern const ActorInit En_Encount1_InitVars;

View file

@ -9,7 +9,18 @@ void EnIceHono_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnIceHono_Update(Actor* thisx, GlobalContext* globalCtx);
void EnIceHono_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void EnIceHono_CapturableFlame(EnIceHono* this, GlobalContext* globalCtx);
void EnIceHono_DropFlame(EnIceHono* this, GlobalContext* globalCtx);
void EnIceHono_SpreadFlames(EnIceHono* this, GlobalContext* globalCtx);
void EnIceHono_SmallFlameMove(EnIceHono* this, GlobalContext* globalCtx);
void EnIceHono_SetupActionCapturableFlame(EnIceHono* this);
void EnIceHono_SetupActionDroppedFlame(EnIceHono* this);
void EnIceHono_SetupActionSpreadFlames(EnIceHono* this);
void EnIceHono_SetupActionSmallFlame(EnIceHono* this);
extern Gfx D_0404D4E0[];
const ActorInit En_Ice_Hono_InitVars = {
ACTOR_EN_ICE_HONO,
ACTORTYPE_ITEMACTION,
@ -21,37 +32,334 @@ const ActorInit En_Ice_Hono_InitVars = {
(ActorFunc)EnIceHono_Update,
(ActorFunc)EnIceHono_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/func_80A72FF0.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/func_80A7301C.s")
static ColliderCylinderInit sCylinderInitCapturableFlame = {
{ COLTYPE_UNK10, 0x00, 0x00, 0x39, 0x20, COLSHAPE_CYLINDER },
{ 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, 0x00, 0x00, 0x01 },
{ 25, 80, 0, { 0, 0, 0 } },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/func_80A730BC.s")
static ColliderCylinderInit sCylinderInitDroppedFlame = {
{ COLTYPE_UNK10, 0x21, 0x00, 0x21, 0x20, COLSHAPE_CYLINDER },
{ 0x00, { 0xFFCFFFFF, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, 0x01, 0x00, 0x01 },
{ 12, 60, 0, { 0, 0, 0 } },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/func_80A731C0.s")
static InitChainEntry sInitChainCapturableFlame[] = {
ICHAIN_U8(unk_1F, 0, ICHAIN_CONTINUE),
ICHAIN_F32(unk_4C, 60, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/EnIceHono_Init.s")
static InitChainEntry sInitChainDroppedFlame[] = {
ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/EnIceHono_Destroy.s")
static InitChainEntry sInitChainSmallFlame[] = {
ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/func_80A733E8.s")
f32 EnIceHono_SquareDist(Vec3f* pos1, Vec3f* pos2) {
f32 dx = pos1->x - pos2->x;
f32 dz = pos1->z - pos2->z;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/func_80A734D4.s")
return SQ(dx) + SQ(dz);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/func_80A734F8.s")
void EnIceHono_InitCapturableFlame(Actor* thisx, GlobalContext* globalCtx) {
EnIceHono* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/func_80A735A0.s")
Actor_ProcessInitChain(&this->actor, sInitChainCapturableFlame);
Actor_SetScale(&this->actor, 0.0074f);
this->actor.flags |= 1;
Actor_SetHeight(&this->actor, 10.0f);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/func_80A735C0.s")
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInitCapturableFlame);
Collider_CylinderUpdate(&this->actor, &this->collider);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/func_80A73780.s")
this->actor.colChkInfo.mass = 0xFF;
EnIceHono_SetupActionCapturableFlame(this);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/func_80A737A0.s")
void EnIceHono_InitDroppedFlame(Actor* thisx, GlobalContext* globalCtx) {
EnIceHono* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/func_80A739FC.s")
Actor_ProcessInitChain(&this->actor, sInitChainDroppedFlame);
this->actor.scale.x = this->actor.scale.z = this->actor.scale.y = 0.00002f;
this->actor.gravity = -0.3f;
this->actor.minVelocityY = -4.0f;
this->actor.shape.unk_08 = 0.0f;
this->actor.shape.rot.x = this->actor.shape.rot.y = this->actor.shape.rot.z = this->actor.posRot.rot.x =
this->actor.posRot.rot.y = this->actor.posRot.rot.z = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/func_80A73AD0.s")
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInitDroppedFlame);
Collider_CylinderUpdate(&this->actor, &this->collider);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/EnIceHono_Update.s")
this->collider.dim.radius = this->actor.scale.x * 4000.4f;
this->collider.dim.height = this->actor.scale.y * 8000.2f;
this->actor.colChkInfo.mass = 253;
EnIceHono_SetupActionDroppedFlame(this);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ice_Hono/EnIceHono_Draw.s")
void EnIceHono_InitSmallFlame(Actor* thisx, GlobalContext* globalCtx) {
EnIceHono* this = THIS;
Actor_ProcessInitChain(&this->actor, sInitChainSmallFlame);
this->actor.scale.x = this->actor.scale.z = this->actor.scale.y = 0.0008f;
this->actor.gravity = -0.3f;
this->actor.minVelocityY = -4.0f;
this->actor.shape.unk_08 = 0.0f;
EnIceHono_SetupActionSmallFlame(this);
}
void EnIceHono_Init(Actor* thisx, GlobalContext* globalCtx) {
EnIceHono* this = THIS;
s16 params = this->actor.params;
switch (this->actor.params) {
case -1:
EnIceHono_InitCapturableFlame(&this->actor, globalCtx);
break;
case 0:
EnIceHono_InitDroppedFlame(&this->actor, globalCtx);
break;
case 1:
case 2:
EnIceHono_InitSmallFlame(&this->actor, globalCtx);
break;
}
if ((this->actor.params == -1) || (this->actor.params == 0)) {
Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.posRot.pos.x, (s16)this->actor.posRot.pos.y + 10,
this->actor.posRot.pos.z, 155, 210, 255, 0);
this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo);
this->unk_154 = Math_Rand_ZeroOne() * (0x1FFFF / 2.0f);
this->unk_156 = Math_Rand_ZeroOne() * (0x1FFFF / 2.0f);
// Translates to: "(ice flame)"
osSyncPrintf("(ice 炎)(arg_data 0x%04x)\n", this->actor.params);
}
}
void EnIceHono_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnIceHono* this = THIS;
if ((this->actor.params == -1) || (this->actor.params == 0)) {
LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode);
Collider_DestroyCylinder(globalCtx, &this->collider);
}
}
u32 EnIceHono_LinkCloseAndFacing(EnIceHono* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
if (this->actor.xzDistFromLink < 60.0f) {
Vec3f tempPos;
tempPos.x = Math_Sins(this->actor.yawTowardsLink + 0x8000) * 40.0f + player->actor.posRot.pos.x;
tempPos.y = player->actor.posRot.pos.y;
tempPos.z = Math_Coss(this->actor.yawTowardsLink + 0x8000) * 40.0f + player->actor.posRot.pos.z;
if (EnIceHono_SquareDist(&tempPos, &this->actor.posRot.pos) <= SQ(40.0f)) {
return 1;
}
}
return 0;
}
void EnIceHono_SetupActionCapturableFlame(EnIceHono* this) {
this->actionFunc = EnIceHono_CapturableFlame;
this->alpha = 255;
this->actor.shape.unk_08 = -1000.0f;
}
void EnIceHono_CapturableFlame(EnIceHono* this, GlobalContext* globalCtx) {
if (Actor_HasParent(&this->actor, globalCtx)) {
this->actor.parent = NULL;
} else if (EnIceHono_LinkCloseAndFacing(this, globalCtx)) {
func_8002F434(&this->actor, globalCtx, 0x7E, 60.0f, 100.0f);
}
if (this->actor.xzDistFromLink < 200.0f) {
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
func_8002F8F0(&this->actor, NA_SE_EV_FIRE_PILLAR_S - SFX_FLAG);
}
void EnIceHono_SetupActionDroppedFlame(EnIceHono* this) {
this->actionFunc = EnIceHono_DropFlame;
this->timer = 200;
this->alpha = 255;
}
void EnIceHono_DropFlame(EnIceHono* this, GlobalContext* globalCtx) {
u32 bgFlag = this->actor.bgCheckFlags & 1;
Math_ApproxF(&this->actor.scale.x, 0.0017f, 0.00008f);
this->actor.scale.z = this->actor.scale.x;
Math_ApproxF(&this->actor.scale.y, 0.0017f, 0.00008f);
if (bgFlag != 0) {
s32 i;
for (i = 0; i < 8; i++) {
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ICE_HONO, this->actor.posRot.pos.x,
this->actor.posRot.pos.y, this->actor.posRot.pos.z, 0,
((s32)(Math_Rand_ZeroOne() * 1000.0f) + i * 0x2000) - 0x1F4, 0, 1);
}
EnIceHono_SetupActionSpreadFlames(this);
}
Actor_MoveForward(&this->actor);
func_8002E4B4(globalCtx, &this->actor, 10.0f, this->actor.scale.x * 3500.0f, 0.0f, 5);
Collider_CylinderUpdate(&this->actor, &this->collider);
this->collider.dim.radius = this->actor.scale.x * 4000.0f;
this->collider.dim.height = this->actor.scale.y * 8000.0f;
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
if (this->timer <= 0) {
Actor_Kill(&this->actor);
}
}
void EnIceHono_SetupActionSpreadFlames(EnIceHono* this) {
this->actionFunc = EnIceHono_SpreadFlames;
this->timer = 60;
this->alpha = 255;
}
void EnIceHono_SpreadFlames(EnIceHono* this, GlobalContext* globalCtx) {
if (this->timer > 20) {
Math_ApproxF(&this->actor.scale.x, 0.011f, 0.00014f);
Math_ApproxF(&this->actor.scale.y, 0.006f, 0.00012f);
} else {
Math_ApproxF(&this->actor.scale.x, 0.0001f, 0.00015f);
Math_ApproxF(&this->actor.scale.y, 0.0001f, 0.00015f);
}
this->actor.scale.z = this->actor.scale.x;
Actor_MoveForward(&this->actor);
func_8002E4B4(globalCtx, &this->actor, 10.0f, this->actor.scale.x * 3500.0f, 0.0f, 4);
if (this->timer < 25) {
this->alpha -= 10;
this->alpha = CLAMP(this->alpha, 0, 255);
}
if ((this->alpha > 100) && (this->timer < 40)) {
Collider_CylinderUpdate(&this->actor, &this->collider);
this->collider.dim.radius = this->actor.scale.x * 6000.0f;
this->collider.dim.height = this->actor.scale.y * 8000.0f;
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
if (this->timer == 46) {
s32 i;
for (i = 0; i < 10; i++) {
s32 rot = i * 0x1999;
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ICE_HONO, this->actor.posRot.pos.x,
this->actor.posRot.pos.y, this->actor.posRot.pos.z, 0,
((s32)(Math_Rand_ZeroOne() * 1000.0f) + rot) - 0x1F4, 0, 2);
}
}
if (this->timer <= 0) {
Actor_Kill(&this->actor);
}
}
void EnIceHono_SetupActionSmallFlame(EnIceHono* this) {
this->actionFunc = EnIceHono_SmallFlameMove;
this->timer = 44;
this->alpha = 255;
if (this->actor.params == 1) {
this->smallFlameTargetYScale = (Math_Rand_ZeroOne() * 0.005f) + 0.004f;
this->actor.speedXZ = (Math_Rand_ZeroOne() * 1.6f) + 0.5f;
} else {
this->smallFlameTargetYScale = (Math_Rand_ZeroOne() * 0.005f) + 0.003f;
this->actor.speedXZ = (Math_Rand_ZeroOne() * 2.0f) + 0.5f;
}
}
void EnIceHono_SmallFlameMove(EnIceHono* this, GlobalContext* globalCtx) {
if (this->timer > 20) {
Math_ApproxF(&this->actor.scale.x, 0.006f, 0.00016f);
Math_ApproxF(&this->actor.scale.y, this->smallFlameTargetYScale * 0.667f, 0.00014f);
} else {
Math_ApproxF(&this->actor.scale.x, 0.0001f, 0.00015f);
Math_ApproxF(&this->actor.scale.y, 0.0001f, 0.00015f);
}
this->actor.scale.z = this->actor.scale.x;
Math_ApproxF(&this->actor.speedXZ, 0, 0.06f);
Actor_MoveForward(&this->actor);
func_8002E4B4(globalCtx, &this->actor, 10.0f, 10.0f, 0.0f, 5);
if (this->timer < 25) {
this->alpha -= 10;
this->alpha = CLAMP(this->alpha, 0, 255);
}
if (this->timer <= 0) {
Actor_Kill(&this->actor);
}
}
void EnIceHono_Update(Actor* thisx, GlobalContext* globalCtx) {
EnIceHono* this = THIS;
s32 pad1;
f32 intensity;
s32 pad2;
f32 sin154;
f32 sin156;
if (this->timer > 0) {
this->timer--;
}
if (this->actor.params == 0) {
func_8002F8F0(&this->actor, NA_SE_IT_FLAME - SFX_FLAG);
}
if ((this->actor.params == -1) || (this->actor.params == 0)) {
this->unk_154 += 0x1111;
this->unk_156 += 0x4000;
sin156 = Math_Sins(this->unk_156);
sin154 = Math_Sins(this->unk_154);
intensity = (Math_Rand_ZeroOne() * 0.05f) + ((sin154 * 0.125f) + (sin156 * 0.1f)) + 0.425f;
if ((intensity > 0.7f) || (intensity < 0.2f)) {
// Translates to: "impossible value(ratio = %f)"
osSyncPrintf("ありえない値(ratio = %f)\n", (f64)intensity);
}
Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.posRot.pos.x, (s16)this->actor.posRot.pos.y + 10,
this->actor.posRot.pos.z, (s32)(155.0f * intensity), (s32)(210.0f * intensity),
(s32)(255.0f * intensity), 1400);
}
if (this->actionFunc != NULL) {
this->actionFunc(this, globalCtx);
}
}
void EnIceHono_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnIceHono* this = THIS;
u32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_ice_hono.c", 695);
func_80093D84(globalCtx->state.gfxCtx);
gSPSegment(oGfxCtx->polyXlu.p++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, (globalCtx->state.frames * -20) % 512,
32, 128));
gDPSetPrimColor(oGfxCtx->polyXlu.p++, 0x80, 0x80, 170, 255, 255, this->alpha);
gDPSetEnvColor(oGfxCtx->polyXlu.p++, 0, 150, 255, 0);
Matrix_RotateY((s16)(func_8005A9F4(ACTIVE_CAM) - this->actor.shape.rot.y + 0x8000) * (M_PI / 0x8000),
MTXMODE_APPLY);
gSPMatrix(oGfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_ice_hono.c", 718),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(oGfxCtx->polyXlu.p++, D_0404D4E0);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_ice_hono.c", 722);
}

View file

@ -6,9 +6,19 @@
struct EnIceHono;
typedef void (*EnIceHonoActionFunc)(struct EnIceHono*, GlobalContext*);
typedef struct EnIceHono {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x70];
/* 0x014C */ EnIceHonoActionFunc actionFunc;
/* 0x0150 */ s16 alpha;
/* 0x0152 */ s16 timer;
/* 0x0154 */ s16 unk_154;
/* 0x0156 */ s16 unk_156;
/* 0x0158 */ f32 smallFlameTargetYScale;
/* 0x015C */ ColliderCylinder collider;
/* 0x01A8 */ LightNode* lightNode;
/* 0x01AC */ LightInfo lightInfo;
} EnIceHono; // size = 0x01BC
extern const ActorInit En_Ice_Hono_InitVars;

View file

@ -1,4 +1,13 @@
/*
* File: z_en_ishi.c
* Overlay: ovl_En_Ishi
* Description: Small and large gray rocks
*/
#include "z_en_ishi.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
#include "vt.h"
#define FLAGS 0x00800000
@ -9,7 +18,27 @@ void EnIshi_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnIshi_Update(Actor* thisx, GlobalContext* globalCtx);
void EnIshi_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void EnIshi_SetupWait(EnIshi* this);
void EnIshi_Wait(EnIshi* this, GlobalContext* globalCtx);
void EnIshi_SetupLiftedUp(EnIshi* this);
void EnIshi_LiftedUp(EnIshi* this, GlobalContext* globalCtx);
void EnIshi_SetupFly(EnIshi* this);
void EnIshi_Fly(EnIshi* this, GlobalContext* globalCtx);
void EnIshi_SpawnFragmentsSmall(EnIshi* this, GlobalContext* globalCtx);
void EnIshi_SpawnFragmentsLarge(EnIshi* this, GlobalContext* globalCtx);
void EnIshi_SpawnDustSmall(EnIshi* this, GlobalContext* globalCtx);
void EnIshi_SpawnDustLarge(EnIshi* this, GlobalContext* globalCtx);
extern Gfx D_0500A3B8[]; // Large gray rock
extern Gfx D_0500A5E8[]; // Large gray rock fragments
extern Gfx D_0500A880[]; // Small gray rock
typedef void (*EnIshiEffectSpawnFunc)(struct EnIshi*, GlobalContext*);
typedef void (*EnIshiDrawFunc)(struct EnIshi*, GlobalContext*);
static s16 sRotSpeedX = 0;
static s16 sRotSpeedY = 0;
const ActorInit En_Ishi_InitVars = {
ACTOR_EN_ISHI,
ACTORTYPE_PROP,
@ -21,47 +50,427 @@ const ActorInit En_Ishi_InitVars = {
(ActorFunc)EnIshi_Update,
(ActorFunc)EnIshi_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7E460.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7E4D8.s")
static f32 sRockScales[] = { 0.1f, 0.4f };
static f32 D_80A7FA20[] = { 58.0f, 80.0f };
static f32 D_80A7FA28[] = { 0.0f, 0.005f };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7E5A8.s")
// the sizes of these arrays are very large and take up way more space than it needs to.
// coincidentally the sizes are the same as the ID for NA_SE_EV_ROCK_BROKEN, which may explain a mistake that could
// have been made here
static u16 sBreakSounds[0x2852] = { NA_SE_EV_ROCK_BROKEN, NA_SE_EV_WALL_BROKEN };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7E824.s")
static u8 sBreakSoundDurations[0x2852] = { 20, 40 };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7EB10.s")
static EnIshiEffectSpawnFunc sFragmentSpawnFuncs[] = { EnIshi_SpawnFragmentsSmall, EnIshi_SpawnFragmentsLarge };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7EC04.s")
static EnIshiEffectSpawnFunc sDustSpawnFuncs[] = { EnIshi_SpawnDustSmall, EnIshi_SpawnDustLarge };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7ECF8.s")
static ColliderCylinderInit sCylinderInits[] = {
{
{ COLTYPE_UNK12, 0x00, 0x0D, 0x39, 0x20, COLSHAPE_CYLINDER },
{ 0x00, { 0x00000000, 0x00, 0x00 }, { 0x4FC1FFFE, 0x00, 0x00 }, 0x00, 0x01, 0x01 },
{ 10, 18, -2, { 0, 0, 0 } },
},
{
{ COLTYPE_UNK12, 0x00, 0x0D, 0x39, 0x20, COLSHAPE_CYLINDER },
{ 0x00, { 0x00000000, 0x00, 0x00 }, { 0x4FC1FFF6, 0x00, 0x00 }, 0x00, 0x01, 0x01 },
{ 55, 70, 0, { 0, 0, 0 } },
}
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7ED60.s")
static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 60, 0xFF };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7ED94.s")
void EnIshi_InitCollider(Actor* thisx, GlobalContext* globalCtx) {
EnIshi* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7EE1C.s")
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInits[this->actor.params & 1]);
Collider_CylinderUpdate(&this->actor, &this->collider);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/EnIshi_Init.s")
s32 EnIshi_SnapToFloor(EnIshi* this, GlobalContext* globalCtx, f32 arg2) {
CollisionPoly* sp34;
Vec3f sp28;
UNK_TYPE sp24;
f32 temp_f0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/EnIshi_Destroy.s")
sp28.x = this->actor.posRot.pos.x;
sp28.y = this->actor.posRot.pos.y + 30.0f;
sp28.z = this->actor.posRot.pos.z;
temp_f0 = func_8003C9A4(&globalCtx->colCtx, &sp34, &sp24, &this->actor, &sp28);
if (temp_f0 > -32000.0f) {
this->actor.posRot.pos.y = temp_f0 + arg2;
Math_Vec3f_Copy(&this->actor.initPosRot.pos, &this->actor.posRot.pos);
return true;
} else {
osSyncPrintf(VT_COL(YELLOW, BLACK));
// Translation: Failure attaching to ground
osSyncPrintf("地面に付着失敗(%s %d)\n", "../z_en_ishi.c", 388);
osSyncPrintf(VT_RST);
return false;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7F098.s")
void EnIshi_SpawnFragmentsSmall(EnIshi* this, GlobalContext* globalCtx) {
static s16 scales[] = { 16, 13, 11, 9, 7, 5 };
s32 pad;
Vec3f velocity;
Vec3f pos;
s16 phi_v0;
s32 i;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7F0A8.s")
for (i = 0; i < ARRAY_COUNT(scales); i++) {
pos.x = this->actor.posRot.pos.x + (Math_Rand_ZeroOne() - 0.5f) * 8.0f;
pos.y = this->actor.posRot.pos.y + (Math_Rand_ZeroOne() * 5.0f) + 5.0f;
pos.z = this->actor.posRot.pos.z + (Math_Rand_ZeroOne() - 0.5f) * 8.0f;
Math_Vec3f_Copy(&velocity, &this->actor.velocity);
if (this->actor.bgCheckFlags & 1) {
velocity.x *= 0.8f;
velocity.y *= -0.8f;
velocity.z *= 0.8f;
} else if (this->actor.bgCheckFlags & 8) {
velocity.x *= -0.8f;
velocity.y *= 0.8f;
velocity.z *= -0.8f;
}
velocity.x += (Math_Rand_ZeroOne() - 0.5f) * 11.0f;
velocity.y += Math_Rand_ZeroOne() * 6.0f;
velocity.z += (Math_Rand_ZeroOne() - 0.5f) * 11.0f;
if (Math_Rand_ZeroOne() < 0.5f) {
phi_v0 = 65;
} else {
phi_v0 = 33;
}
EffectSsKakera_Spawn(globalCtx, &pos, &velocity, &pos, -420, phi_v0, 30, 5, 0, scales[i], 3, 10, 40,
KAKERA_COLOR_NONE, OBJECT_GAMEPLAY_FIELD_KEEP, D_0500A880);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7F2F8.s")
void EnIshi_SpawnFragmentsLarge(EnIshi* this, GlobalContext* globalCtx) {
static s16 scales[] = { 145, 135, 120, 100, 70, 50, 45, 40, 35 };
Actor* thisx = &this->actor;
Vec3f velocity;
Vec3f pos;
s16 angle = 0x1000;
s32 i;
f32 rand;
s16 phi_v0;
s16 phi_v1;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7F31C.s")
for (i = 0; i < ARRAY_COUNT(scales); i++) {
angle += 0x4E20;
rand = Math_Rand_ZeroOne() * 10.0f;
pos.x = this->actor.posRot.pos.x + (Math_Sins(angle) * rand);
pos.y = this->actor.posRot.pos.y + (Math_Rand_ZeroOne() * 40.0f) + 5.0f;
pos.z = this->actor.posRot.pos.z + (Math_Coss(angle) * rand);
Math_Vec3f_Copy(&velocity, &thisx->velocity);
if (thisx->bgCheckFlags & 1) {
velocity.x *= 0.9f;
velocity.y *= -0.8f;
velocity.z *= 0.9f;
} else if (thisx->bgCheckFlags & 8) {
velocity.x *= -0.9f;
velocity.y *= 0.8f;
velocity.z *= -0.9f;
}
rand = Math_Rand_ZeroOne() * 10.0f;
velocity.x += rand * Math_Sins(angle);
velocity.y += (Math_Rand_ZeroOne() * 4.0f) + ((Math_Rand_ZeroOne() * i) * 0.7f);
velocity.z += rand * Math_Coss(angle);
if (i == 0) {
phi_v0 = 41;
phi_v1 = -450;
} else if (i < 4) {
phi_v0 = 37;
phi_v1 = -380;
} else {
phi_v0 = 69;
phi_v1 = -320;
}
EffectSsKakera_Spawn(globalCtx, &pos, &velocity, &this->actor.posRot.pos, phi_v1, phi_v0, 30, 5, 0, scales[i],
5, 2, 70, KAKERA_COLOR_WHITE, OBJECT_GAMEPLAY_FIELD_KEEP, D_0500A5E8);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7F3E8.s")
void EnIshi_SpawnDustSmall(EnIshi* this, GlobalContext* globalCtx) {
Vec3f pos;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7F514.s")
Math_Vec3f_Copy(&pos, &this->actor.posRot.pos);
if (this->actor.bgCheckFlags & 1) {
pos.x += 2.0f * this->actor.velocity.x;
pos.y -= 2.0f * this->actor.velocity.y;
pos.z += 2.0f * this->actor.velocity.z;
} else if (this->actor.bgCheckFlags & 8) {
pos.x -= 2.0f * this->actor.velocity.x;
pos.y += 2.0f * this->actor.velocity.y;
pos.z -= 2.0f * this->actor.velocity.z;
}
func_80033480(globalCtx, &pos, 60.0f, 3, 0x50, 0x3C, 1);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/EnIshi_Update.s")
void EnIshi_SpawnDustLarge(EnIshi* this, GlobalContext* globalCtx) {
Vec3f pos;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7F8A0.s")
Math_Vec3f_Copy(&pos, &this->actor.posRot.pos);
if (this->actor.bgCheckFlags & 1) {
pos.x += 2.0f * this->actor.velocity.x;
pos.y -= 2.0f * this->actor.velocity.y;
pos.z += 2.0f * this->actor.velocity.z;
} else if (this->actor.bgCheckFlags & 8) {
pos.x -= 2.0f * this->actor.velocity.x;
pos.y += 2.0f * this->actor.velocity.y;
pos.z -= 2.0f * this->actor.velocity.z;
}
func_80033480(globalCtx, &pos, 140.0f, 0xA, 0xB4, 0x5A, 1);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/func_80A7F8CC.s")
void EnIshi_DropCollectible(EnIshi* this, GlobalContext* globalCtx) {
s16 dropParams;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Ishi/EnIshi_Draw.s")
if ((this->actor.params & 1) == ROCK_SMALL) {
dropParams = (this->actor.params >> 8) & 0xF;
if (dropParams >= 0xD) {
dropParams = 0;
}
Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.posRot.pos, dropParams << 4);
}
}
void EnIshi_Fall(EnIshi* this) {
this->actor.velocity.y += this->actor.gravity;
if (this->actor.velocity.y < this->actor.minVelocityY) {
this->actor.velocity.y = this->actor.minVelocityY;
}
}
void func_80A7ED94(Vec3f* arg0, f32 arg1) {
arg1 += ((Math_Rand_ZeroOne() * 0.2f) - 0.1f) * arg1;
arg0->x -= arg0->x * arg1;
arg0->y -= arg0->y * arg1;
arg0->z -= arg0->z * arg1;
}
void EnIshi_SpawnBugs(EnIshi* this, GlobalContext* globalCtx) {
s32 i;
for (i = 0; i < 3; i++) {
Actor* bug =
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_INSECT, this->actor.posRot.pos.x,
this->actor.posRot.pos.y, this->actor.posRot.pos.z, 0, Math_Rand_ZeroOne() * 0xFFFF, 0, 1);
if (bug == NULL) {
break;
}
}
}
static InitChainEntry sInitChains[][5] = {
{
ICHAIN_F32_DIV1000(gravity, -1200, ICHAIN_CONTINUE),
ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 150, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP),
},
{
ICHAIN_F32_DIV1000(gravity, -2500, ICHAIN_CONTINUE),
ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 250, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 500, ICHAIN_STOP),
},
};
void EnIshi_Init(Actor* thisx, GlobalContext* globalCtx) {
EnIshi* this = THIS;
s16 type = this->actor.params & 1;
Actor_ProcessInitChain(&this->actor, sInitChains[type]);
if (globalCtx->csCtx.state != 0) {
this->actor.uncullZoneForward += 1000.0f;
}
if (this->actor.shape.rot.y == 0) {
this->actor.shape.rot.y = this->actor.posRot.rot.y = Math_Rand_ZeroFloat(0x10000);
}
Actor_SetScale(&this->actor, sRockScales[type]);
EnIshi_InitCollider(&this->actor, globalCtx);
if ((type == ROCK_LARGE) &&
Flags_GetSwitch(globalCtx, ((this->actor.params >> 0xA) & 0x3C) | ((this->actor.params >> 6) & 3))) {
Actor_Kill(&this->actor);
return;
}
func_80061ED4(&this->actor.colChkInfo, NULL, &sColChkInfoInit);
this->actor.shape.unk_08 = D_80A7FA20[type];
if (!((this->actor.params >> 5) & 1) && !EnIshi_SnapToFloor(this, globalCtx, 0.0f)) {
Actor_Kill(&this->actor);
return;
}
EnIshi_SetupWait(this);
}
void EnIshi_Destroy(Actor* thisx, GlobalContext* globalCtx) {
Collider_DestroyCylinder(globalCtx, &THIS->collider);
}
void EnIshi_SetupWait(EnIshi* this) {
this->actionFunc = EnIshi_Wait;
}
void EnIshi_Wait(EnIshi* this, GlobalContext* globalCtx) {
static u16 liftSounds[] = { NA_SE_PL_PULL_UP_ROCK, NA_SE_PL_PULL_UP_BIGROCK };
s32 pad;
s16 type = this->actor.params & 1;
if (Actor_HasParent(&this->actor, globalCtx)) {
EnIshi_SetupLiftedUp(this);
Audio_PlaySoundAtPosition(globalCtx, &this->actor.posRot.pos, 20, liftSounds[type]);
if ((this->actor.params >> 4) & 1) {
EnIshi_SpawnBugs(this, globalCtx);
}
} else if (this->collider.base.acFlags & 2 && (type == ROCK_SMALL) &&
this->collider.body.acHitItem->toucher.flags & 0x40000048) {
EnIshi_DropCollectible(this, globalCtx);
Audio_PlaySoundAtPosition(globalCtx, &this->actor.posRot.pos, sBreakSoundDurations[type], sBreakSounds[type]);
sFragmentSpawnFuncs[type](this, globalCtx);
sDustSpawnFuncs[type](this, globalCtx);
Actor_Kill(&this->actor);
} else if (this->actor.xzDistFromLink < 600.0f) {
Collider_CylinderUpdate(&this->actor, &this->collider);
this->collider.base.acFlags &= ~2;
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
if (this->actor.xzDistFromLink < 400.0f) {
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
if (this->actor.xzDistFromLink < 90.0f) {
if (type == ROCK_LARGE) {
func_8002F434(&this->actor, globalCtx, 0, 80.0f, 20.0f);
} else {
func_8002F434(&this->actor, globalCtx, 0, 50.0f, 10.0f);
}
}
}
}
}
void EnIshi_SetupLiftedUp(EnIshi* this) {
this->actionFunc = EnIshi_LiftedUp;
this->actor.room = -1;
this->actor.flags |= 0x10;
}
void EnIshi_LiftedUp(EnIshi* this, GlobalContext* globalCtx) {
if (Actor_HasNoParent(&this->actor, globalCtx)) {
this->actor.room = globalCtx->roomCtx.curRoom.num;
if ((this->actor.params & 1) == ROCK_LARGE) {
Flags_SetSwitch(globalCtx, ((this->actor.params >> 0xA) & 0x3C) | ((this->actor.params >> 6) & 3));
}
EnIshi_SetupFly(this);
EnIshi_Fall(this);
func_80A7ED94(&this->actor.velocity, D_80A7FA28[this->actor.params & 1]);
func_8002D7EC(&this->actor);
func_8002E4B4(globalCtx, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5);
}
}
void EnIshi_SetupFly(EnIshi* this) {
this->actor.velocity.x = Math_Sins(this->actor.posRot.rot.y) * this->actor.speedXZ;
this->actor.velocity.z = Math_Coss(this->actor.posRot.rot.y) * this->actor.speedXZ;
if ((this->actor.params & 1) == ROCK_SMALL) {
sRotSpeedX = (Math_Rand_ZeroOne() - 0.5f) * 16000.0f;
sRotSpeedY = (Math_Rand_ZeroOne() - 0.5f) * 2400.0f;
} else {
sRotSpeedX = (Math_Rand_ZeroOne() - 0.5f) * 8000.0f;
sRotSpeedY = (Math_Rand_ZeroOne() - 0.5f) * 1600.0f;
}
this->actor.colChkInfo.mass = 240;
this->actionFunc = EnIshi_Fly;
}
void EnIshi_Fly(EnIshi* this, GlobalContext* globalCtx) {
s32 pad;
s16 type = this->actor.params & 1;
s32 pad2;
s32 quakeIdx;
Vec3f contactPos;
if (this->actor.bgCheckFlags & 9) {
EnIshi_DropCollectible(this, globalCtx);
sFragmentSpawnFuncs[type](this, globalCtx);
if (!(this->actor.bgCheckFlags & 0x20)) {
Audio_PlaySoundAtPosition(globalCtx, &this->actor.posRot.pos, sBreakSoundDurations[type],
sBreakSounds[type]);
sDustSpawnFuncs[type](this, globalCtx);
}
if (type == ROCK_LARGE) {
quakeIdx = Quake_Add(ACTIVE_CAM, 3);
Quake_SetSpeed(quakeIdx, -0x3CB0);
Quake_SetQuakeValues(quakeIdx, 3, 0, 0, 0);
Quake_SetCountdown(quakeIdx, 7);
func_800AA000(this->actor.xyzDistFromLinkSq, 0xFF, 0x14, 0x96);
}
Actor_Kill(&this->actor);
return;
}
if (this->actor.bgCheckFlags & 0x40) {
contactPos.x = this->actor.posRot.pos.x;
contactPos.y = this->actor.posRot.pos.y + this->actor.waterY;
contactPos.z = this->actor.posRot.pos.z;
EffectSsGSplash_Spawn(globalCtx, &contactPos, 0, 0, 0, 350);
if (type == ROCK_SMALL) {
EffectSsGRipple_Spawn(globalCtx, &contactPos, 150, 650, 0);
EffectSsGRipple_Spawn(globalCtx, &contactPos, 400, 800, 4);
EffectSsGRipple_Spawn(globalCtx, &contactPos, 500, 1100, 8);
} else {
EffectSsGRipple_Spawn(globalCtx, &contactPos, 300, 700, 0);
EffectSsGRipple_Spawn(globalCtx, &contactPos, 500, 900, 4);
EffectSsGRipple_Spawn(globalCtx, &contactPos, 500, 1300, 8);
}
this->actor.minVelocityY = -6.0f;
sRotSpeedX >>= 2;
sRotSpeedY >>= 2;
Audio_PlaySoundAtPosition(globalCtx, &this->actor.posRot.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L);
this->actor.bgCheckFlags &= ~0x40;
}
Math_ApproxF(&this->actor.shape.unk_08, 0.0f, 2.0f);
EnIshi_Fall(this);
func_80A7ED94(&this->actor.velocity, D_80A7FA28[type]);
func_8002D7EC(&this->actor);
this->actor.shape.rot.x += sRotSpeedX;
this->actor.shape.rot.y += sRotSpeedY;
func_8002E4B4(globalCtx, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5);
Collider_CylinderUpdate(&this->actor, &this->collider);
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
void EnIshi_Update(Actor* thisx, GlobalContext* globalCtx) {
EnIshi* this = THIS;
this->actionFunc(this, globalCtx);
}
void EnIshi_DrawSmall(EnIshi* this, GlobalContext* globalCtx) {
Gfx_DrawDListOpa(globalCtx, D_0500A880);
}
void EnIshi_DrawLarge(EnIshi* this, GlobalContext* globalCtx) {
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_ishi.c", 1050);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(oGfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_ishi.c", 1055),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPSetPrimColor(oGfxCtx->polyOpa.p++, 0, 0, 255, 255, 255, 255);
gSPDisplayList(oGfxCtx->polyOpa.p++, D_0500A3B8);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_ishi.c", 1062);
}
static EnIshiDrawFunc sDrawFuncs[] = { EnIshi_DrawSmall, EnIshi_DrawLarge };
void EnIshi_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnIshi* this = THIS;
sDrawFuncs[this->actor.params & 1](this, globalCtx);
}

View file

@ -4,11 +4,19 @@
#include "ultra64.h"
#include "global.h"
typedef enum {
/* 0x00 */ ROCK_SMALL,
/* 0x01 */ ROCK_LARGE
} EnIshiType;
struct EnIshi;
typedef void (*EnIshiActionFunc)(struct EnIshi*, GlobalContext*);
typedef struct EnIshi {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x50];
/* 0x014C */ EnIshiActionFunc actionFunc;
/* 0x0150 */ ColliderCylinder collider;
} EnIshi; // size = 0x019C
extern const ActorInit En_Ishi_InitVars;

View file

@ -1,4 +1,11 @@
/*
* File: z_en_kakasi.c
* Overlay: ovl_En_Kakasi
* Description: Pierre the Scarecrow
*/
#include "z_en_kakasi.h"
#include "vt.h"
#define FLAGS 0x02000009
@ -9,7 +16,22 @@ void EnKakasi_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnKakasi_Update(Actor* thisx, GlobalContext* globalCtx);
void EnKakasi_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void func_80A8F660(EnKakasi* this, GlobalContext* globalCtx);
void func_80A8F75C(EnKakasi* this, GlobalContext* globalCtx);
void func_80A8F8D0(EnKakasi* this, GlobalContext* globalCtx);
void func_80A8F9C8(EnKakasi* this, GlobalContext* globalCtx);
void func_80A8FBB8(EnKakasi* this, GlobalContext* globalCtx);
void func_80A8FAA4(EnKakasi* this, GlobalContext* globalCtx);
static ColliderCylinderInit sCylinderInit = {
{ COLTYPE_UNK10, 0x00, 0x00, 0x39, 0x20, COLSHAPE_CYLINDER },
{ 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, 0x00, 0x04, 0x01 },
{ 20, 70, 0, { 0, 0, 0 } },
};
extern SkeletonHeader D_060065B0;
extern AnimationHeader D_06000214;
const ActorInit En_Kakasi_InitVars = {
ACTOR_EN_KAKASI,
ACTORTYPE_NPC,
@ -21,27 +43,301 @@ const ActorInit En_Kakasi_InitVars = {
(ActorFunc)EnKakasi_Update,
(ActorFunc)EnKakasi_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi/EnKakasi_Destroy.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi/EnKakasi_Init.s")
void EnKakasi_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnKakasi* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi/func_80A8F28C.s")
Collider_DestroyCylinder(globalCtx, &this->collider);
//! @bug Skelanime_Free is not called
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi/func_80A8F320.s")
void EnKakasi_Init(Actor* thisx, GlobalContext* globalCtx) {
EnKakasi* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi/func_80A8F660.s")
osSyncPrintf("\n\n");
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ ☆☆☆☆☆ %f\n" VT_RST, this->actor.posRot.pos.y);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi/func_80A8F75C.s")
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
this->actor.unk_1F = 6;
SkelAnime_InitSV(globalCtx, &this->skelanime, &D_060065B0, &D_06000214, NULL, NULL, 0);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi/func_80A8F8D0.s")
this->rot = this->actor.posRot.rot;
this->actor.flags |= 0x400;
this->actor.colChkInfo.mass = 0xFF;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi/func_80A8F9C8.s")
Actor_SetScale(&this->actor, 0.01f);
this->actionFunc = func_80A8F660;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi/func_80A8FAA4.s")
void func_80A8F28C(EnKakasi* this) {
this->unk_1A4 = 0;
this->skelanime.animPlaybackSpeed = 0.0f;
this->unk_1A8 = this->unk_1AC = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi/func_80A8FBB8.s")
Math_SmoothDownscaleMaxF(&this->skelanime.animCurrentFrame, 0.5f, 1.0f);
Math_SmoothScaleMaxMinS(&this->actor.shape.rot.x, this->rot.x, 5, 0x2710, 0);
Math_SmoothScaleMaxMinS(&this->actor.shape.rot.y, this->rot.y, 5, 0x2710, 0);
Math_SmoothScaleMaxMinS(&this->actor.shape.rot.z, this->rot.z, 5, 0x2710, 0);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi/EnKakasi_Update.s")
void func_80A8F320(EnKakasi* this, GlobalContext* globalCtx, s16 arg) {
s16 phi_v0;
s16 currentFrame;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi/EnKakasi_Draw.s")
phi_v0 = globalCtx->msgCtx.unk_E410[0];
if (arg != 0) {
if (this->unk_19C[3] == 0) {
this->unk_19C[3] = (s16)Math_Rand_ZeroFloat(10.99f) + 30;
this->unk_1A6 = (s16)Math_Rand_ZeroFloat(4.99f);
}
this->unk_19A = (s16)Math_Rand_ZeroFloat(2.99f) + 5;
phi_v0 = this->unk_1A6;
}
switch (phi_v0) {
case 0:
this->unk_19A++;
if (this->unk_1A4 == 0) {
this->unk_1A4 = 1;
Audio_PlayActorSound2(&this->actor, NA_SE_EV_KAKASHI_ROLL);
}
break;
case 1:
this->unk_19A++;
this->unk_1B8 = 1.0f;
break;
case 2:
this->unk_19A++;
if (this->unk_1AC == 0) {
this->unk_1AC = 0x1388;
}
break;
case 3:
this->unk_19A++;
if (this->unk_1A8 == 0) {
this->unk_1A8 = 0x1388;
}
break;
case 4:
this->unk_19A++;
this->unk_1B8 = 2.0f;
break;
}
if (this->unk_19A > 8) {
this->unk_19A = 8;
}
if (this->unk_19A != 0) {
this->actor.gravity = -1.0f;
if (this->unk_19A == 8 && (this->actor.bgCheckFlags & 1)) {
this->actor.velocity.y = 3.0f;
Audio_PlayActorSound2(&this->actor, NA_SE_IT_KAKASHI_JUMP);
}
Math_SmoothScaleMaxF(&this->skelanime.animPlaybackSpeed, this->unk_1B8, 0.1f, 0.2f);
Math_SmoothScaleMaxMinS(&this->actor.shape.rot.x, this->unk_1A8, 5, 0x3E8, 0);
Math_SmoothScaleMaxMinS(&this->actor.shape.rot.z, this->unk_1AC, 5, 0x3E8, 0);
if (this->unk_1A8 != 0 && fabsf(this->actor.shape.rot.x - this->unk_1A8) < 50.0f) {
this->unk_1A8 *= -1.0f;
}
if (this->unk_1AC != 0 && fabsf(this->actor.shape.rot.z - this->unk_1AC) < 50.0f) {
this->unk_1AC *= -1.0f;
}
if (this->unk_1A4 != 0) {
this->actor.shape.rot.y += 0x1000;
if (this->actor.shape.rot.y == 0) {
this->unk_1A4 = 0;
}
}
currentFrame = this->skelanime.animCurrentFrame;
if (currentFrame == 11 || currentFrame == 17) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_KAKASHI_SWING);
}
SkelAnime_FrameUpdateMatrix(&this->skelanime);
}
}
void func_80A8F660(EnKakasi* this, GlobalContext* globalCtx) {
f32 frameCount = SkelAnime_GetFrameCount(&D_06000214.genericHeader);
SkelAnime_ChangeAnim(&this->skelanime, &D_06000214, 1.0f, 0.0f, (s16)frameCount, 0, -10.0f);
this->actor.textId = 0x4076;
this->unk_196 = 6;
if (LINK_IS_CHILD) {
this->unk_194 = false;
if (gSaveContext.unk_F3C[4] != 0) {
this->actor.textId = 0x407A;
this->unk_196 = 5;
}
} else {
this->unk_194 = true;
if (gSaveContext.unk_F3C[4] != 0) {
this->actor.textId = 0x4079;
this->unk_196 = 5;
}
}
this->actionFunc = func_80A8F75C;
}
void func_80A8F75C(EnKakasi* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
s16 yawTowardsLink;
s16 absyawTowardsLink;
func_80A8F28C(this);
SkelAnime_FrameUpdateMatrix(&this->skelanime);
this->camId = -1;
if (func_8002F194(&this->actor, globalCtx)) {
if (this->unk_196 == 5) {
this->actionFunc = func_80A8F9C8;
} else {
this->actionFunc = func_80A8F660;
}
return;
}
yawTowardsLink = this->actor.yawTowardsLink - this->actor.shape.rot.y;
if (!(this->actor.xzDistFromLink > 120.0f)) {
absyawTowardsLink = ABS(yawTowardsLink);
if (absyawTowardsLink < 0x4300) {
if (!this->unk_194) {
if (player->stateFlags2 & 0x1000000) {
this->camId = func_800800F8(globalCtx, 0x8D4, -0x63, &this->actor, 0);
func_8010BD58(globalCtx, 0x2A);
this->unk_19A = 0;
this->unk_1B8 = 0.0;
player->stateFlags2 |= 0x800000;
this->actionFunc = func_80A8F8D0;
return;
}
if (this->actor.xzDistFromLink < 80.0f) {
player->stateFlags2 |= 0x800000;
}
}
func_8002F2CC(&this->actor, globalCtx, 100.0f);
}
}
}
void func_80A8F8D0(EnKakasi* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
if (globalCtx->msgCtx.unk_E3EE == 4 && globalCtx->msgCtx.msgMode == 0) {
// end?
osSyncPrintf(VT_FGCOL(BLUE) "☆☆☆☆☆ 終り? ☆☆☆☆☆ \n" VT_RST);
if (this->unk_19A != 0) {
func_80106CCC(globalCtx);
this->actor.textId = 0x4077;
this->unk_196 = 5;
func_8010B680(globalCtx, this->actor.textId, NULL);
this->actionFunc = func_80A8F9C8;
} else {
func_800803F0(globalCtx, this->camId);
this->camId = -1;
this->actionFunc = func_80A8F660;
}
} else if (globalCtx->msgCtx.unk_E3EE == 1) {
func_80A8F320(this, globalCtx, 0);
player->stateFlags2 |= 0x800000;
}
}
void func_80A8F9C8(EnKakasi* this, GlobalContext* globalCtx) {
func_80A8F28C(this);
SkelAnime_FrameUpdateMatrix(&this->skelanime);
func_8002DF54(globalCtx, NULL, 8);
if (this->unk_196 == func_8010BDBC(&globalCtx->msgCtx) && (func_80106BC8(globalCtx) != 0)) {
if (this->camId != -1) {
func_8005B1A4(globalCtx->cameraPtrs[this->camId]);
}
this->camId = func_800800F8(globalCtx, 0x8DE, -0x63, &this->actor, 0);
globalCtx->msgCtx.msgMode = 0x37;
func_8002DF54(globalCtx, NULL, 8);
func_8010BD58(globalCtx, 0x2B);
this->actionFunc = func_80A8FAA4;
}
}
void func_80A8FAA4(EnKakasi* this, GlobalContext* globalCtx) {
if (globalCtx->msgCtx.unk_E3EE != 0xF) {
func_80A8F320(this, globalCtx, 1);
return;
}
osSyncPrintf("game_play->message.msg_mode=%d\n", globalCtx->msgCtx.msgMode);
if (globalCtx->msgCtx.msgMode == 0) {
if (this->unk_194) {
this->actor.textId = 0x4077;
this->unk_196 = 5;
func_8010B680(globalCtx, this->actor.textId, NULL);
} else {
this->actor.textId = 0x4078;
this->unk_196 = 5;
func_8010B680(globalCtx, this->actor.textId, NULL);
}
this->actionFunc = func_80A8FBB8;
func_800803F0(globalCtx, this->camId);
this->camId = -1;
this->camId = func_800800F8(globalCtx, 0x8D4, -0x63, &this->actor, 0);
func_8005B1A4(globalCtx->cameraPtrs[this->camId]);
}
}
void func_80A8FBB8(EnKakasi* this, GlobalContext* globalCtx) {
func_80A8F28C(this);
SkelAnime_FrameUpdateMatrix(&this->skelanime);
if (this->unk_196 == func_8010BDBC(&globalCtx->msgCtx)) {
if (func_80106BC8(globalCtx) != 0) {
func_8005B1A4(globalCtx->cameraPtrs[this->camId]);
func_80106CCC(globalCtx);
func_8002DF54(globalCtx, NULL, 7);
this->actionFunc = func_80A8F660;
}
}
}
void EnKakasi_Update(Actor* thisx, GlobalContext* globalCtx) {
EnKakasi* this = THIS;
s32 pad;
s32 i;
this->unk_198++;
this->actor.posRot.rot = this->actor.shape.rot;
for (i = 0; i < ARRAY_COUNT(this->unk_19C); i++) {
if (this->unk_19C[i] != 0) {
this->unk_19C[i]--;
}
}
this->height = 60.0f;
Actor_SetHeight(&this->actor, this->height);
this->actionFunc(this, globalCtx);
Actor_MoveForward(&this->actor);
func_8002E4B4(globalCtx, &this->actor, 50.0f, 50.0f, 100.0f, 28);
Collider_CylinderUpdate(&this->actor, &this->collider);
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
void EnKakasi_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnKakasi* this = THIS;
if (BREG(3) != 0) {
osSyncPrintf("\n\n");
// flag!
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ フラグ! ☆☆☆☆☆ %d\n" VT_RST, gSaveContext.unk_F3C[4]);
}
func_80093D18(globalCtx->state.gfxCtx);
SkelAnime_DrawSV(globalCtx, this->skelanime.skeleton, this->skelanime.limbDrawTbl, this->skelanime.dListCount, NULL,
NULL, &this->actor);
}

View file

@ -6,9 +6,27 @@
struct EnKakasi;
typedef void (*EnKakasiFunc)(struct EnKakasi*, GlobalContext*);
typedef struct EnKakasi {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0xC0];
/* 0x014C */ EnKakasiFunc actionFunc;
/* 0x0150 */ SkelAnime skelanime;
/* 0x0194 */ u8 unk_194;
/* 0x0196 */ s16 unk_196;
/* 0x0198 */ s16 unk_198;
/* 0x019A */ s16 unk_19A;
/* 0x019C */ s16 unk_19C[4];
/* 0x01A4 */ s16 unk_1A4;
/* 0x01A6 */ s16 unk_1A6;
/* 0x01A8 */ s16 unk_1A8;
/* 0x01AA */ char unk_1AA[0x2];
/* 0x01AC */ s16 unk_1AC;
/* 0x01AE */ Vec3s rot;
/* 0x01B4 */ f32 height;
/* 0x01B8 */ f32 unk_1B8;
/* 0x01BC */ ColliderCylinder collider;
/* 0x0208 */ s16 camId;
} EnKakasi; // size = 0x020C
extern const ActorInit En_Kakasi_InitVars;

View file

@ -1,14 +1,36 @@
/*
* File: z_en_kakasi2.c
* Overlay: ovl_En_Kakasi2
* Description: Pierre the Scarecrow Spawn
*/
#include "z_en_kakasi2.h"
#include "vt.h"
#define FLAGS 0x0A000031
#define THIS ((EnKakasi2*)thisx)
static ColliderCylinderInit sCylinderInit = {
{ COLTYPE_UNK10, 0x00, 0x09, 0x39, 0x20, COLSHAPE_CYLINDER },
{ 0x00, { 0xFFCFFFFF, 0x00, 0x00 }, { 0xFFCFFFFF, 0x00, 0x00 }, 0x00, 0x05, 0x01 },
{ 20, 70, 0, { 0, 0, 0 } },
};
void EnKakasi2_Init(Actor* thisx, GlobalContext* globalCtx);
void EnKakasi2_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnKakasi2_Update(Actor* thisx, GlobalContext* globalCtx);
void func_80A90948(Actor* thisx, GlobalContext* globalCtx);
void func_80A9062C(EnKakasi2* this, GlobalContext* globalCtx);
void func_80A90264(EnKakasi2* this, GlobalContext* globalCtx);
void func_80A904D8(EnKakasi2* this, GlobalContext* globalCtx);
void func_80A90578(EnKakasi2* this, GlobalContext* globalCtx);
void func_80A906C4(EnKakasi2* this, GlobalContext* globalCtx);
extern SkeletonHeader D_060065B0;
extern AnimationHeader D_06000214;
/*
const ActorInit En_Kakasi2_InitVars = {
ACTOR_EN_KAKASI2,
ACTORTYPE_PROP,
@ -20,21 +42,193 @@ const ActorInit En_Kakasi2_InitVars = {
(ActorFunc)EnKakasi2_Update,
NULL,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi2/EnKakasi2_Init.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi2/EnKakasi2_Destroy.s")
void EnKakasi2_Init(Actor* thisx, GlobalContext* globalCtx) {
EnKakasi2* this = THIS;
s32 pad;
f32 spawnRangeY;
f32 spawnRangeXZ;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi2/func_80A90264.s")
osSyncPrintf("\n\n");
// Visit Umeda
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 梅田参号見参! ☆☆☆☆☆ \n" VT_RST);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi2/func_80A904D8.s")
this->switchFlag = this->actor.params & 0x3F;
spawnRangeY = (this->actor.params >> 6) & 0xFF;
spawnRangeXZ = this->actor.posRot.rot.z;
if (this->switchFlag == 0x3F) {
this->switchFlag = -1;
}
this->actor.unk_1F = 4;
this->maxSpawnDistance.x = (spawnRangeY * 40.0f) + 40.0f;
this->maxSpawnDistance.y = (spawnRangeXZ * 40.0f) + 40.0f;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi2/func_80A90578.s")
// Former? (Argument 0)
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 元?(引数0) ☆☆☆☆ %f\n" VT_RST, spawnRangeY);
// Former? (Z angle)
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 元?(Zアングル) ☆☆ %f\n" VT_RST, spawnRangeXZ);
// Correction coordinates X
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 補正座標X ☆☆☆☆☆ %f\n" VT_RST, this->maxSpawnDistance.x);
// Correction coordinates Y
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 補正座標Y ☆☆☆☆☆ %f\n" VT_RST, this->maxSpawnDistance.y);
// Correction coordinates Z
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 補正座標Z ☆☆☆☆☆ %f\n" VT_RST, this->maxSpawnDistance.z);
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ SAVE ☆☆☆☆☆ %d\n" VT_RST, this->switchFlag);
osSyncPrintf("\n\n");
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi2/func_80A9062C.s")
this->actor.colChkInfo.mass = 0xFF;
this->height = 60.0f;
Actor_SetScale(&this->actor, 0.01f);
this->actor.flags |= 0x400;
this->unk_198 = this->actor.shape.rot.y;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi2/func_80A906C4.s")
if (this->switchFlag >= 0 && Flags_GetSwitch(globalCtx, this->switchFlag)) {
this->actor.draw = func_80A90948;
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_060065B0, &D_06000214, NULL, NULL, 0);
this->actionFunc = func_80A9062C;
} else {
this->actionFunc = func_80A90264;
this->actor.shape.unk_08 = -8000.0f;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi2/EnKakasi2_Update.s")
void EnKakasi2_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnKakasi2* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi2/func_80A90948.s")
Collider_DestroyCylinder(globalCtx, &this->collider);
//! @bug Skelanime_Free is not called
}
void func_80A90264(EnKakasi2* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
this->unk_194++;
if ((BREG(1) != 0) && (this->actor.xzDistFromLink < this->maxSpawnDistance.x) &&
(fabsf(player->actor.posRot.pos.y - this->actor.posRot.pos.y) < this->maxSpawnDistance.y)) {
this->actor.draw = func_80A90948;
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_060065B0, &D_06000214, NULL, NULL, 0);
func_80080480(globalCtx, this);
this->actor.flags |= 0x8000001;
func_80078884(NA_SE_SY_CORRECT_CHIME);
if (this->switchFlag >= 0) {
Flags_SetSwitch(globalCtx, this->switchFlag);
}
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ SAVE 終了 ☆☆☆☆☆ %d\n" VT_RST, this->switchFlag);
this->actionFunc = func_80A904D8;
} else if ((this->actor.xzDistFromLink < this->maxSpawnDistance.x) &&
(fabsf(player->actor.posRot.pos.y - this->actor.posRot.pos.y) < this->maxSpawnDistance.y) &&
(gSaveContext.eventChkInf[9] & 0x1000)) {
this->unk_194 = 0;
if (globalCtx->msgCtx.unk_E3EE == 11) {
if (this->switchFlag >= 0) {
Flags_SetSwitch(globalCtx, this->switchFlag);
}
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ SAVE 終了 ☆☆☆☆☆ %d\n" VT_RST, this->switchFlag);
globalCtx->msgCtx.unk_E3EE = 4;
this->actor.draw = func_80A90948;
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_060065B0, &D_06000214, NULL, NULL, 0);
func_80080480(globalCtx, this);
func_80078884(NA_SE_SY_CORRECT_CHIME);
this->actor.flags |= 0x8000001;
this->actionFunc = func_80A904D8;
}
}
}
void func_80A904D8(EnKakasi2* this, GlobalContext* globalCtx) {
f32 frameCount = SkelAnime_GetFrameCount(&D_06000214.genericHeader);
SkelAnime_ChangeAnim(&this->skelAnime, &D_06000214, 1.0f, 0.0f, (s16)frameCount, 0, -10.0f);
Audio_PlayActorSound2(&this->actor, NA_SE_EV_COME_UP_DEKU_JR);
this->actionFunc = func_80A90578;
}
void func_80A90578(EnKakasi2* this, GlobalContext* globalCtx) {
s16 currentFrame;
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
currentFrame = this->skelAnime.animCurrentFrame;
if (currentFrame == 11 || currentFrame == 17) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_KAKASHI_SWING);
}
this->actor.shape.rot.y += 0x800;
Math_SmoothDownscaleMaxF(&this->actor.shape.unk_08, 0.5f, 500.0f);
if (this->actor.shape.unk_08 > -100.0f) {
this->actionFunc = func_80A9062C;
this->actor.shape.unk_08 = 0.0f;
}
}
void func_80A9062C(EnKakasi2* this, GlobalContext* globalCtx) {
f32 frameCount = SkelAnime_GetFrameCount(&D_06000214.genericHeader);
SkelAnime_ChangeAnim(&this->skelAnime, &D_06000214, 0.0f, 0.0f, (s16)frameCount, 2, -10.0f);
this->actionFunc = func_80A906C4;
}
void func_80A906C4(EnKakasi2* this, GlobalContext* globalCtx) {
if (this->skelAnime.animCurrentFrame != 0) {
Math_SmoothDownscaleMaxF(&this->skelAnime.animCurrentFrame, 0.5f, 1.0f);
}
Math_SmoothScaleMaxMinS(&this->actor.shape.rot.y, this->unk_198, 5, 0xBB8, 0);
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
}
void EnKakasi2_Update(Actor* thisx, GlobalContext* globalCtx) {
EnKakasi2* this = THIS;
GlobalContext* globalCtx2 = globalCtx;
this->actor.posRot.rot = this->actor.shape.rot;
Actor_SetHeight(&this->actor, this->height);
this->actionFunc(this, globalCtx2);
Actor_MoveForward(&this->actor);
if (this->actor.shape.unk_08 == 0.0f) {
Collider_CylinderUpdate(&this->actor, &this->collider);
CollisionCheck_SetAC(globalCtx2, &globalCtx2->colChkCtx, &this->collider.base);
CollisionCheck_SetOC(globalCtx2, &globalCtx2->colChkCtx, &this->collider.base);
}
if (BREG(0) != 0) {
if (BREG(5) != 0) {
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ this->actor.player_distance ☆☆☆☆☆ %f\n" VT_RST, this->actor.xzDistFromLink);
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ this->hosei.x ☆☆☆☆☆ %f\n" VT_RST, this->maxSpawnDistance.x);
osSyncPrintf("\n\n");
}
if (this->actor.draw == NULL) {
if (this->unk_194 != 0) {
if ((this->unk_194 % 2) == 0) {
DebugDisplay_AddObject(this->actor.posRot.pos.x, this->actor.posRot.pos.y, this->actor.posRot.pos.z,
this->actor.posRot.rot.x, this->actor.posRot.rot.y, this->actor.posRot.rot.z,
1.0f, 1.0f, 1.0f, 70, 70, 70, 255, 4, globalCtx2->state.gfxCtx);
}
} else {
DebugDisplay_AddObject(this->actor.posRot.pos.x, this->actor.posRot.pos.y, this->actor.posRot.pos.z,
this->actor.posRot.rot.x, this->actor.posRot.rot.y, this->actor.posRot.rot.z,
1.0f, 1.0f, 1.0f, 0, 255, 255, 255, 4, globalCtx2->state.gfxCtx);
}
}
}
}
void func_80A90948(Actor* thisx, GlobalContext* globalCtx) {
EnKakasi2* this = THIS;
func_80093D18(globalCtx->state.gfxCtx);
SkelAnime_DrawSV(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, this->skelAnime.dListCount, NULL,
NULL, &this->actor);
}

View file

@ -6,9 +6,18 @@
struct EnKakasi2;
typedef void (*EnKakasi2ActionFunc)(struct EnKakasi2*, GlobalContext*);
typedef struct EnKakasi2 {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0xAC];
/* 0x014C */ EnKakasi2ActionFunc actionFunc;
/* 0x0150 */ SkelAnime skelAnime;
/* 0x0194 */ s16 unk_194;
/* 0x0196 */ s16 switchFlag;
/* 0x0198 */ s16 unk_198;
/* 0x019C */ Vec3f maxSpawnDistance;
/* 0x01A8 */ f32 height;
/* 0x01AC */ ColliderCylinder collider;
} EnKakasi2; // size = 0x01F8
extern const ActorInit En_Kakasi2_InitVars;

View file

@ -1,4 +1,11 @@
/*
* File: z_en_kakasi3.c
* Overlay: ovl_En_Kakasi3
* Description: Bonooru the Scarecrow
*/
#include "z_en_kakasi3.h"
#include "vt.h"
#define FLAGS 0x02000009
@ -9,7 +16,26 @@ void EnKakasi3_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnKakasi3_Update(Actor* thisx, GlobalContext* globalCtx);
void EnKakasi3_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void func_80A911F0(EnKakasi3* this, GlobalContext* globalCtx);
void func_80A91284(EnKakasi3* this, GlobalContext* globalCtx);
void func_80A91348(EnKakasi3* this, GlobalContext* globalCtx);
void func_80A915B8(EnKakasi3* this, GlobalContext* globalCtx);
void func_80A91620(EnKakasi3* this, GlobalContext* globalCtx);
void func_80A91760(EnKakasi3* this, GlobalContext* globalCtx);
void func_80A917FC(EnKakasi3* this, GlobalContext* globalCtx);
void func_80A9187C(EnKakasi3* this, GlobalContext* globalCtx);
void func_80A918E4(EnKakasi3* this, GlobalContext* globalCtx);
void func_80A91A90(EnKakasi3* this, GlobalContext* globalCtx);
static ColliderCylinderInit sCylinderInit = {
{ COLTYPE_UNK10, 0x00, 0x09, 0x39, 0x20, COLSHAPE_CYLINDER },
{ 0x00, { 0xFFCFFFFF, 0x00, 0x00 }, { 0xFFCFFFFF, 0x00, 0x00 }, 0x00, 0x05, 0x01 },
{ 20, 70, 0, { 0, 0, 0 } },
};
extern SkeletonHeader D_060065B0;
extern AnimationHeader D_06000214;
const ActorInit En_Kakasi3_InitVars = {
ACTOR_EN_KAKASI3,
ACTORTYPE_NPC,
@ -21,35 +47,387 @@ const ActorInit En_Kakasi3_InitVars = {
(ActorFunc)EnKakasi3_Update,
(ActorFunc)EnKakasi3_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/EnKakasi3_Destroy.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/EnKakasi3_Init.s")
void EnKakasi3_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnKakasi3* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/func_80A90E28.s")
Collider_DestroyCylinder(globalCtx, &this->collider);
//! @bug Skelanime_Free is not called
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/func_80A90EBC.s")
void EnKakasi3_Init(Actor* thisx, GlobalContext* globalCtx) {
EnKakasi3* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/func_80A911F0.s")
osSyncPrintf("\n\n");
// Translates to: Obonur -- Related to the name of the scarecrow (Bonooru)
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ おーボヌール ☆☆☆☆☆ \n" VT_RST);
this->actor.unk_1F = 6;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/func_80A91284.s")
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_060065B0, &D_06000214, NULL, NULL, 0);
this->actor.flags |= 0x400;
this->rot = this->actor.posRot.rot;
this->actor.colChkInfo.mass = 0xFF;
Actor_SetScale(&this->actor, 0.01f);
this->actionFunc = func_80A911F0;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/func_80A91348.s")
void func_80A90E28(EnKakasi3* this) {
this->unk_1A4 = 0;
this->skelAnime.animPlaybackSpeed = 0.0f;
this->unk_1AA = this->unk_1AE = 0x0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/func_80A915B8.s")
Math_SmoothDownscaleMaxF(&this->skelAnime.animCurrentFrame, 0.5f, 1.0f);
Math_SmoothScaleMaxMinS(&this->actor.shape.rot.x, this->rot.x, 5, 0x2710, 0);
Math_SmoothScaleMaxMinS(&this->actor.shape.rot.y, this->rot.y, 5, 0x2710, 0);
Math_SmoothScaleMaxMinS(&this->actor.shape.rot.z, this->rot.z, 5, 0x2710, 0);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/func_80A91620.s")
void func_80A90EBC(EnKakasi3* this, GlobalContext* globalCtx, s32 arg) {
s16 currentFrame;
s16 phi_v0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/func_80A91760.s")
phi_v0 = globalCtx->msgCtx.unk_E410[0];
if (arg != 0) {
if (this->unk_19C[3] == 0) {
this->unk_19C[3] = (s16)Math_Rand_ZeroFloat(10.99f) + 30;
this->unk_1A6 = (s16)Math_Rand_ZeroFloat(4.99f);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/func_80A917FC.s")
this->unk_19A = (s16)Math_Rand_ZeroFloat(2.99f) + 5;
phi_v0 = this->unk_1A6;
}
switch (phi_v0) {
case 0:
this->unk_19A++;
if (this->unk_1A4 == 0) {
this->unk_1A4 = 1;
Audio_PlayActorSound2(&this->actor, NA_SE_EV_KAKASHI_ROLL);
}
break;
case 1:
this->unk_19A++;
this->unk_1B8 = 1.0f;
break;
case 2:
this->unk_19A++;
if (this->unk_1AE == 0x0) {
this->unk_1AE = 0x1388;
}
break;
case 3:
this->unk_19A++;
if (this->unk_1AA == 0x0) {
this->unk_1AA = 0x1388;
}
break;
case 4:
this->unk_19A++;
this->unk_1B8 = 2.0f;
break;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/func_80A9187C.s")
if (this->unk_19A > 8) {
this->unk_19A = 8;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/func_80A918E4.s")
if (this->unk_19A != 0) {
this->actor.gravity = -1.0f;
if (this->unk_19A == 8 && (this->actor.bgCheckFlags & 1)) {
this->actor.velocity.y = 3.0f;
Audio_PlayActorSound2(&this->actor, NA_SE_IT_KAKASHI_JUMP);
}
Math_SmoothScaleMaxF(&this->skelAnime.animPlaybackSpeed, this->unk_1B8, 0.1f, 0.2f);
Math_SmoothScaleMaxMinS(&this->actor.shape.rot.x, this->unk_1AA, 0x5, 0x3E8, 0);
Math_SmoothScaleMaxMinS(&this->actor.shape.rot.z, this->unk_1AE, 0x5, 0x3E8, 0);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/func_80A91A90.s")
if (this->unk_1AA != 0x0 && fabsf(this->actor.shape.rot.x - this->unk_1AA) < 50.0f) {
this->unk_1AA *= -1.0f;
}
if (this->unk_1AE != 0x0 && fabsf(this->actor.shape.rot.z - this->unk_1AE) < 50.0f) {
this->unk_1AE *= -1.0f;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/EnKakasi3_Update.s")
if (this->unk_1A4 != 0) {
this->actor.shape.rot.y += 0x1000;
if (this->actor.shape.rot.y == 0) {
this->unk_1A4 = 0;
}
}
currentFrame = this->skelAnime.animCurrentFrame;
if (currentFrame == 11 || currentFrame == 17) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_KAKASHI_SWING);
}
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Kakasi3/EnKakasi3_Draw.s")
void func_80A911F0(EnKakasi3* this, GlobalContext* globalCtx) {
f32 frameCount = SkelAnime_GetFrameCount(&D_06000214.genericHeader);
SkelAnime_ChangeAnim(&this->skelAnime, &D_06000214, 1.0f, 0.0f, (s16)frameCount, 0, -10.0f);
this->actionFunc = func_80A91284;
}
void func_80A91284(EnKakasi3* this, GlobalContext* globalCtx) {
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
this->actor.textId = 0x40A1;
this->dialogState = 6;
this->unk_19A = 0;
if (LINK_IS_CHILD) {
this->unk_194 = false;
if (gSaveContext.unk_12C5 != 0) {
this->actor.textId = 0x40A0;
this->dialogState = 5;
this->unk_1A8 = 1;
}
} else {
this->unk_194 = true;
if (gSaveContext.unk_12C5 != 0) {
if (this->unk_195) {
this->actor.textId = 0x40A2;
} else {
this->actor.textId = 0x40A3;
}
}
}
this->actionFunc = func_80A91348;
}
void func_80A91348(EnKakasi3* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
s16 angleTowardsLink;
s16 absAngleTowardsLink;
func_80A90E28(this);
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
this->camId = -1;
if (func_8002F194(&this->actor, globalCtx)) {
if (!this->unk_194) {
if (this->unk_1A8 == 0) {
this->actionFunc = func_80A91284;
} else {
this->actionFunc = func_80A91760;
}
} else {
this->actionFunc = func_80A91284;
}
return;
}
angleTowardsLink = this->actor.yawTowardsLink - this->actor.shape.rot.y;
if (!(this->actor.xzDistFromLink > 120.0f)) {
absAngleTowardsLink = ABS(angleTowardsLink);
if (absAngleTowardsLink < 0x4300) {
if (!this->unk_194) {
if (player->stateFlags2 & 0x1000000) {
this->camId = func_800800F8(globalCtx, 0x8D4, -0x63, &this->actor, 0);
globalCtx->msgCtx.msgMode = 0x37;
this->dialogState = 5;
this->unk_1B8 = 0.0f;
func_8010B680(globalCtx, 0x40A4, NULL);
player->stateFlags2 |= 0x800000;
this->actionFunc = func_80A915B8;
return;
}
if (this->actor.xzDistFromLink < 80.0f) {
player->stateFlags2 |= 0x800000;
}
} else if (gSaveContext.unk_12C5 != 0 && !this->unk_195) {
if (player->stateFlags2 & 0x1000000) {
this->camId = func_800800F8(globalCtx, 0x8D4, -0x63, &this->actor, 0);
globalCtx->msgCtx.msgMode = 0x37;
this->dialogState = 5;
this->unk_1B8 = 0.0f;
func_8010B680(globalCtx, 0x40A8, NULL);
player->stateFlags2 |= 0x800000;
this->actionFunc = func_80A9187C;
return;
}
if (this->actor.xzDistFromLink < 80.0f) {
player->stateFlags2 |= 0x800000;
}
}
func_8002F2CC(&this->actor, globalCtx, 100.0f);
}
}
}
void func_80A915B8(EnKakasi3* this, GlobalContext* globalCtx) {
if (func_8010BDBC(&globalCtx->msgCtx) == 5 && func_80106BC8(globalCtx)) {
func_80106CCC(globalCtx);
func_8010BD58(globalCtx, 0x2C);
this->actionFunc = func_80A91620;
}
}
void func_80A91620(EnKakasi3* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
if ((globalCtx->msgCtx.unk_E3EE == 4 || (globalCtx->msgCtx.unk_E3EE >= 5 && globalCtx->msgCtx.unk_E3EE < 11)) &&
(globalCtx->msgCtx.msgMode == 0)) {
func_800803F0(globalCtx, this->camId);
if (globalCtx->cameraPtrs[this->camId] == NULL) {
this->camId = -1;
}
if (this->camId != -1) {
func_8005B1A4(globalCtx->cameraPtrs[this->camId]);
}
this->actionFunc = func_80A911F0;
return;
}
if (globalCtx->msgCtx.unk_E3EE == 3 && globalCtx->msgCtx.msgMode == 0) {
this->dialogState = 5;
func_8010B680(globalCtx, 0x40A5, NULL);
func_8002DF54(globalCtx, NULL, 8);
this->actionFunc = func_80A91A90;
return;
}
if (globalCtx->msgCtx.unk_E3EE == 1) {
func_80A90EBC(this, globalCtx, 0);
player->stateFlags2 |= 0x800000;
}
}
void func_80A91760(EnKakasi3* this, GlobalContext* globalCtx) {
func_80A90E28(this);
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
if (this->dialogState == func_8010BDBC(&globalCtx->msgCtx) && func_80106BC8(globalCtx)) {
globalCtx->msgCtx.msgMode = 0x37;
func_8010BD58(globalCtx, 0x2D);
this->actionFunc = func_80A917FC;
this->camId = func_800800F8(globalCtx, 0x8E8, -0x63, &this->actor, 0);
}
}
void func_80A917FC(EnKakasi3* this, GlobalContext* globalCtx) {
if (globalCtx->msgCtx.unk_E3EE != 15) {
func_80A90EBC(this, globalCtx, 1);
} else {
globalCtx->msgCtx.unk_E3EE = 4;
func_80106CCC(globalCtx);
func_800803F0(globalCtx, this->camId);
this->actionFunc = func_80A911F0;
}
}
void func_80A9187C(EnKakasi3* this, GlobalContext* globalCtx) {
if (func_8010BDBC(&globalCtx->msgCtx) == 5 && func_80106BC8(globalCtx)) {
func_80106CCC(globalCtx);
func_8010BD58(globalCtx, 0x28);
this->actionFunc = func_80A918E4;
}
}
void func_80A918E4(EnKakasi3* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
if (BREG(3) != 0) {
// No way!
osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ まさか! ☆☆☆☆☆ %d\n" VT_RST, globalCtx->msgCtx.unk_E3EE);
}
if ((globalCtx->msgCtx.unk_E3EE == 4 || (globalCtx->msgCtx.unk_E3EE >= 5 && globalCtx->msgCtx.unk_E3EE < 11)) &&
globalCtx->msgCtx.msgMode == 0) {
func_8010B680(globalCtx, 0x40A6, NULL);
this->dialogState = 5;
func_800803F0(globalCtx, this->camId);
this->camId = -1;
func_8002DF54(globalCtx, NULL, 8);
this->actionFunc = func_80A91A90;
return;
}
if (globalCtx->msgCtx.unk_E3EE == 3 && globalCtx->msgCtx.msgMode == 0) {
globalCtx->msgCtx.unk_E3EE = 4;
if (BREG(3) != 0) {
osSyncPrintf("\n\n");
// With this, other guys are OK! That's it!
osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ これで、他の奴もOK!だ! ☆☆☆☆☆ %d\n" VT_RST,
globalCtx->msgCtx.unk_E3EE);
}
this->unk_195 = true;
func_8010B680(globalCtx, 0x40A7, NULL);
this->dialogState = 5;
func_8002DF54(globalCtx, NULL, 8);
this->actionFunc = func_80A91A90;
return;
}
if (globalCtx->msgCtx.unk_E3EE == 1) {
func_80A90EBC(this, globalCtx, 0);
player->stateFlags2 |= 0x800000;
}
}
void func_80A91A90(EnKakasi3* this, GlobalContext* globalCtx) {
func_80A90E28(this);
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
func_8002DF54(globalCtx, NULL, 8);
if (this->dialogState == func_8010BDBC(&globalCtx->msgCtx) && func_80106BC8(globalCtx)) {
if (this->unk_195) {
if (!(gSaveContext.eventChkInf[9] & 0x1000)) {
gSaveContext.eventChkInf[9] |= 0x1000;
}
}
if (globalCtx->cameraPtrs[this->camId] == NULL) {
this->camId = -1;
}
if (this->camId != -1) {
func_8005B1A4(globalCtx->cameraPtrs[this->camId]);
}
func_80106CCC(globalCtx);
globalCtx->msgCtx.unk_E3EE = 4;
func_8002DF54(globalCtx, NULL, 7);
this->actionFunc = func_80A911F0;
}
}
void EnKakasi3_Update(Actor* thisx, GlobalContext* globalCtx) {
EnKakasi3* this = THIS;
s32 pad;
s32 i;
if (BREG(2) != 0) {
osSyncPrintf("\n\n");
// flag!
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ フラグ! ☆☆☆☆☆ %d\n" VT_RST, gSaveContext.unk_12C5);
}
this->unk_198++;
this->actor.posRot.rot = this->actor.shape.rot;
for (i = 0; i < ARRAY_COUNT(this->unk_19C); i++) {
if (this->unk_19C[i] != 0) {
this->unk_19C[i]--;
}
}
Actor_SetHeight(&this->actor, 60.0f);
this->actionFunc(this, globalCtx);
Actor_MoveForward(&this->actor);
func_8002E4B4(globalCtx, &this->actor, 50.0f, 50.0f, 100.0f, 28);
Collider_CylinderUpdate(&this->actor, &this->collider);
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
void EnKakasi3_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnKakasi3* this = THIS;
func_80093D18(globalCtx->state.gfxCtx);
SkelAnime_DrawSV(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, this->skelAnime.dListCount, NULL,
NULL, &this->actor);
}

View file

@ -6,9 +6,28 @@
struct EnKakasi3;
typedef void (*EnKakasi3ActionFunc)(struct EnKakasi3*, GlobalContext*);
typedef struct EnKakasi3 {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0xC0];
/* 0x014C */ EnKakasi3ActionFunc actionFunc;
/* 0x0150 */ SkelAnime skelAnime;
/* 0x0194 */ u8 unk_194;
/* 0x0195 */ u8 unk_195;
/* 0x0196 */ s16 dialogState;
/* 0x0198 */ s16 unk_198;
/* 0x019A */ s16 unk_19A;
/* 0x019C */ s16 unk_19C[4];
/* 0x01A4 */ s16 unk_1A4;
/* 0x01A6 */ s16 unk_1A6;
/* 0x01A8 */ s16 unk_1A8;
/* 0x01AA */ s16 unk_1AA;
/* 0x01AC */ char unk_1AC[2];
/* 0x01AE */ s16 unk_1AE;
/* 0x01B0 */ Vec3s rot;
/* 0x01B8 */ f32 unk_1B8;
/* 0x01BC */ ColliderCylinder collider;
/* 0x0208 */ s16 camId;
} EnKakasi3; // size = 0x020C
extern const ActorInit En_Kakasi3_InitVars;

View file

@ -1,4 +1,13 @@
/*
* File: z_en_reeba.c
* Overlay: ovl_En_Reeba
* Description: Leever
*/
#include "z_en_reeba.h"
#include "overlays/actors/ovl_En_Encount1/z_en_encount1.h"
#include "vt.h"
#define FLAGS 0x08000015
@ -9,7 +18,24 @@ void EnReeba_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnReeba_Update(Actor* thisx, GlobalContext* globalCtx);
void EnReeba_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void func_80AE4F40(EnReeba* this, GlobalContext* globalCtx);
void func_80AE5054(EnReeba* this, GlobalContext* globalCtx);
void func_80AE5270(EnReeba* this, GlobalContext* globalCtx);
void func_80AE5688(EnReeba* this, GlobalContext* globalCtx);
void func_80AE56E0(EnReeba* this, GlobalContext* globalCtx);
void func_80AE538C(EnReeba* this, GlobalContext* globalCtx);
void func_80AE53AC(EnReeba* this, GlobalContext* globalCtx);
void func_80AE5E48(EnReeba* this, GlobalContext* globalCtx);
void func_80AE5854(EnReeba* this, GlobalContext* globalCtx);
void func_80AE5C38(EnReeba* this, GlobalContext* globalCtx);
void func_80AE5938(EnReeba* this, GlobalContext* globalCtx);
void func_80AE5A9C(EnReeba* this, GlobalContext* globalCtx);
static DamageTable sDamageTable = {
0x00, 0xE2, 0xE1, 0xE2, 0xC1, 0xE2, 0xE2, 0xD2, 0xE1, 0xE4, 0xE6, 0xE2, 0x34, 0xE2, 0xE2, 0xE2,
0xE2, 0x00, 0x34, 0x00, 0x00, 0x00, 0xE2, 0xE8, 0xE4, 0xE2, 0xE8, 0xE4, 0x10, 0x00, 0x00, 0x00,
};
const ActorInit En_Reeba_InitVars = {
ACTOR_EN_REEBA,
ACTORTYPE_MISC,
@ -21,45 +47,611 @@ const ActorInit En_Reeba_InitVars = {
(ActorFunc)EnReeba_Update,
(ActorFunc)EnReeba_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/EnReeba_Init.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/EnReeba_Destroy.s")
static ColliderCylinderInit sCylinderInit = {
{ COLTYPE_UNK5, 0x11, 0x09, 0x39, 0x10, COLSHAPE_CYLINDER },
{ 0x00, { 0xFFCFFFFF, 0x08, 0x08 }, { 0xFFCFFFFF, 0x00, 0x00 }, 0x01, 0x05, 0x01 },
{ 20, 40, 0, { 0, 0, 0 } },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE4F40.s")
extern AnimationHeader D_060001E4;
extern SkeletonHeader D_06001EE8;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE5054.s")
void EnReeba_Init(Actor* thisx, GlobalContext* globalCtx) {
EnReeba* this = THIS;
f32 temp_f0;
s32 surfaceType;
s32 pad;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE5270.s")
this->actor.naviEnemyId = 0x47;
this->actor.unk_1F = 3;
this->actor.gravity = -3.5f;
this->actor.posRot2.pos = this->actor.posRot.pos;
SkelAnime_Init(globalCtx, &this->skelanime, &D_06001EE8, &D_060001E4, this->limbDrawTable,
this->transitionDrawTable, 18);
this->actor.colChkInfo.mass = 0xFE;
this->actor.colChkInfo.health = 4;
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
this->isBig = this->actor.params;
this->scale = 0.04f;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE538C.s")
if (this->isBig) {
this->collider.dim.radius = 35;
this->collider.dim.height = 45;
this->scale *= 1.5f;
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ リーバぼす登場 ☆☆☆☆☆ %f\n" VT_RST, this->scale);
this->actor.colChkInfo.health = 20;
this->collider.body.toucher.effect = 4;
this->collider.body.toucher.damage = 16;
Actor_ChangeType(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORTYPE_ENEMY);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE53AC.s")
temp_f0 = this->scale * -27500.0f;
this->unk_284 = temp_f0;
this->actor.shape.unk_08 = temp_f0;
ActorShape_Init(&this->actor.shape, temp_f0, ActorShadow_DrawFunc_Circle, 0.0f);
this->actor.colChkInfo.damageTable = &sDamageTable;
func_8002E4B4(globalCtx, &this->actor, 35.0f, 60.0f, 60.0f, 0x1D);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE561C.s")
surfaceType = func_80041D4C(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorPolySource);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE5688.s")
if ((surfaceType != 4) && (surfaceType != 7)) {
Actor_Kill(&this->actor);
return;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE56E0.s")
this->actionfunc = func_80AE4F40;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE57F0.s")
void EnReeba_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnReeba* this = THIS;
EnEncount1* spawner;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE5854.s")
Collider_DestroyCylinder(globalCtx, &this->collider);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE58EC.s")
if (this->actor.parent != NULL) {
spawner = (EnEncount1*)this->actor.parent;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE5938.s")
if (spawner->actor.update != NULL) {
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE5A9C.s")
if (spawner->unk_152 > 0) {
spawner->unk_152--;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE5BC4.s")
if (this->isBig) {
spawner->unk_16C = 0;
spawner->unk_164 = 0x258;
}
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE5C38.s")
void func_80AE4F40(EnReeba* this, GlobalContext* globalCtx) {
f32 frames = SkelAnime_GetFrameCount(&D_060001E4.genericHeader);
Player* player = PLAYER;
s16 absPlayerVel;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE5E48.s")
SkelAnime_ChangeAnim(&this->skelanime, &D_060001E4, 2.0f, 0.0f, frames, 0, -10.0f);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/func_80AE5EDC.s")
absPlayerVel = fabsf(player->linearVelocity);
this->unk_278 = (20 - (absPlayerVel * 2));
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/EnReeba_Update.s")
if (this->unk_278 < 0) {
this->unk_278 = 2;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Reeba/EnReeba_Draw.s")
if (this->unk_278 > 20) {
this->unk_278 = 20;
}
this->actor.flags &= ~0x08000000;
this->actor.posRot.pos.y = this->actor.groundY;
if (this->isBig) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_BIG_APPEAR);
} else {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_APPEAR);
}
this->actionfunc = func_80AE5054;
}
void func_80AE5054(EnReeba* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
f32 playerLinearVel;
SkelAnime_FrameUpdateMatrix(&this->skelanime);
if ((globalCtx->gameplayFrames % 4) == 0) {
func_80033260(globalCtx, &this->actor, &this->actor.posRot.pos, this->actor.shape.unk_10, 1, 8.0f, 0x1F4, 0xA,
1);
}
if (this->unk_278 == 0) {
Math_SmoothScaleMaxF(&this->actor.shape.unk_10, 12.0f, 1.0f, 1.0f);
if (this->actor.shape.unk_08 < 0.0f) {
Math_SmoothDownscaleMaxF(&this->actor.shape.unk_08, 1.0f, this->unk_288);
Math_SmoothScaleMaxF(&this->unk_288, 300.0f, 1.0f, 5.0f);
} else {
this->unk_288 = 0.0f;
this->actor.shape.unk_08 = 0.0f;
playerLinearVel = player->linearVelocity;
switch (this->unk_280) {
case 0:
this->actor.posRot.rot.y = this->actor.yawTowardsLink;
break;
case 1:
this->actor.posRot.rot.y = this->actor.yawTowardsLink + (800.0f * playerLinearVel);
break;
case 2:
case 3:
this->actor.posRot.rot.y =
this->actor.yawTowardsLink +
(player->actor.shape.rot.y - this->actor.yawTowardsLink) * (playerLinearVel * 0.15f);
break;
case 4:
this->actor.posRot.rot.y = this->actor.yawTowardsLink - (800.0f * playerLinearVel);
}
if (this->isBig) {
this->actionfunc = func_80AE538C;
} else {
this->unk_272 = 130;
this->actor.speedXZ = Math_Rand_ZeroFloat(4.0f) + 6.0f;
this->actionfunc = func_80AE5270;
}
}
}
}
void func_80AE5270(EnReeba* this, GlobalContext* globalCtx) {
s32 surfaceType;
SkelAnime_FrameUpdateMatrix(&this->skelanime);
if (this->actor.shape.unk_10 < 12.0f) {
Math_SmoothScaleMaxF(&this->actor.shape.unk_10, 12.0f, 3.0f, 1.0f);
}
surfaceType = func_80041D4C(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorPolySource);
if ((surfaceType != 4) && (surfaceType != 7)) {
this->actor.speedXZ = 0.0f;
this->actionfunc = func_80AE5688;
return;
}
if ((this->unk_272 == 0) || (this->actor.xzDistFromLink < 30.0f) || (this->actor.xzDistFromLink > 400.0f) ||
(this->actor.bgCheckFlags & 8)) {
this->actionfunc = func_80AE5688;
return;
}
if (this->unk_274 == 0) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_MOVE);
this->unk_274 = 10;
}
}
void func_80AE538C(EnReeba* this, GlobalContext* globalCtx) {
this->actor.flags |= 5;
this->actionfunc = func_80AE53AC;
}
void func_80AE53AC(EnReeba* this, GlobalContext* globalCtx) {
f32 speed;
s16 yawDiff;
s16 yaw;
s32 surfaceType;
SkelAnime_FrameUpdateMatrix(&this->skelanime);
if (this->actor.shape.unk_10 < 12.0f) {
Math_SmoothScaleMaxF(&this->actor.shape.unk_10, 12.0f, 3.0f, 1.0f);
}
surfaceType = func_80041D4C(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorPolySource);
if (((surfaceType != 4) && (surfaceType != 7)) || (this->actor.xzDistFromLink > 400.0f) ||
(this->actor.bgCheckFlags & 8)) {
this->actionfunc = func_80AE5688;
return;
}
if ((this->actor.xzDistFromLink < 70.0f) && (this->unk_270 == 0)) {
this->unk_270 = 30;
}
speed = (this->actor.xzDistFromLink - 20.0f) / ((Math_Rand_ZeroOne() * 50.0f) + 150.0f);
this->actor.speedXZ += speed * 1.8f;
if (this->actor.speedXZ >= 3.0f) {
this->actor.speedXZ = 3.0f;
}
if (this->actor.speedXZ < -3.0f) {
this->actor.speedXZ = -3.0f;
}
yawDiff = (this->unk_270 == 0) ? this->actor.yawTowardsLink : -this->actor.yawTowardsLink;
yawDiff = yawDiff - this->actor.posRot.rot.y;
yaw = (yawDiff > 0) ? ((yawDiff / 31.0f) + 10.0f) : ((yawDiff / 31.0f) - 10.0f);
this->actor.posRot.rot.y += (yaw * 2.0f);
if (this->unk_274 == 0) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_MOVE);
this->unk_274 = 20;
}
}
void func_80AE561C(EnReeba* this, GlobalContext* globalCtx) {
Math_SmoothDownscaleMaxF(&this->actor.speedXZ, 1.0f, 0.3f);
if (this->unk_272 == 0) {
if (this->isBig) {
this->actionfunc = func_80AE538C;
} else {
this->actionfunc = func_80AE5688;
}
}
}
void func_80AE5688(EnReeba* this, GlobalContext* globalCtx) {
this->unk_27E = 0;
Audio_PlayActorSound2(&this->actor, NA_SE_EN_AKINDONUTS_HIDE);
this->actor.flags |= 0x8000000;
this->actor.flags &= ~5;
this->actionfunc = func_80AE56E0;
}
void func_80AE56E0(EnReeba* this, GlobalContext* globalCtx) {
Math_SmoothDownscaleMaxF(&this->actor.shape.unk_10, 1.0f, 0.3f);
Math_SmoothDownscaleMaxF(&this->actor.speedXZ, 0.1f, 0.3f);
SkelAnime_FrameUpdateMatrix(&this->skelanime);
if ((this->unk_284 + 10.0f) <= this->actor.shape.unk_08) {
if ((globalCtx->gameplayFrames & 3) == 0) {
func_80033260(globalCtx, &this->actor, &this->actor.posRot.pos, this->actor.shape.unk_10, 1, 8.0f, 500, 10,
1);
}
Math_SmoothScaleMaxF(&this->actor.shape.unk_08, this->unk_284, 1.0f, this->unk_288);
Math_SmoothScaleMaxF(&this->unk_288, 300.0f, 1.0f, 5.0f);
} else {
Actor_Kill(&this->actor);
}
}
void func_80AE57F0(EnReeba* this, GlobalContext* globalCtx) {
this->unk_276 = 14;
this->actor.speedXZ = -8.0f;
this->actor.posRot.rot.y = this->actor.yawTowardsLink;
func_8003426C(&this->actor, 0x4000, 0xFF, 0, 8);
this->actionfunc = func_80AE5854;
}
void func_80AE5854(EnReeba* this, GlobalContext* globalCtx) {
SkelAnime_FrameUpdateMatrix(&this->skelanime);
if (this->actor.speedXZ < 0.0f) {
this->actor.speedXZ++;
}
if (this->unk_276 == 0) {
if (this->isBig) {
this->unk_270 = 30;
this->actionfunc = func_80AE538C;
} else {
this->actionfunc = func_80AE5688;
}
}
}
void func_80AE58EC(EnReeba* this, GlobalContext* globalCtx) {
this->unk_278 = 14;
this->actor.posRot.rot.y = this->actor.yawTowardsLink;
this->actor.speedXZ = -8.0f;
this->actor.flags |= 0x8000000;
this->actor.flags &= ~5;
this->actionfunc = func_80AE5938;
}
void func_80AE5938(EnReeba* this, GlobalContext* globalCtx) {
Vec3f pos;
f32 scale;
if (this->unk_278 != 0) {
if (this->actor.speedXZ < 0.0f) {
this->actor.speedXZ += 1.0f;
}
} else {
this->actor.speedXZ = 0.0f;
if ((this->unk_27E == 4) || (this->actor.colChkInfo.health != 0)) {
if (this->unk_27E == 2) {
pos.x = this->actor.posRot.pos.x + Math_Rand_CenteredFloat(20.0f);
pos.y = this->actor.posRot.pos.y + Math_Rand_CenteredFloat(20.0f);
pos.z = this->actor.posRot.pos.z + Math_Rand_CenteredFloat(20.0f);
scale = 3.0f;
if (this->isBig) {
scale = 6.0f;
}
EffectSsEnIce_SpawnFlyingVec3f(globalCtx, &this->actor, &pos, 150, 150, 150, 250, 235, 245, 255, scale);
}
this->unk_278 = 66;
this->actionfunc = func_80AE5E48;
} else {
this->unk_278 = 30;
this->actionfunc = func_80AE5A9C;
}
}
}
void func_80AE5A9C(EnReeba* this, GlobalContext* globalCtx) {
Vec3f randPos;
f32 scale;
if (this->unk_278 != 0) {
if ((this->unk_27E == 2) && ((this->unk_278 & 0xF) == 0)) {
randPos.x = this->actor.posRot.pos.x + Math_Rand_CenteredFloat(20.0f);
randPos.y = this->actor.posRot.pos.y + Math_Rand_CenteredFloat(20.0f);
randPos.z = this->actor.posRot.pos.z + Math_Rand_CenteredFloat(20.0f);
scale = 3.0f;
if (this->isBig) {
scale = 6.0f;
}
EffectSsEnIce_SpawnFlyingVec3f(globalCtx, &this->actor, &randPos, 150, 150, 150, 250, 235, 245, 255, scale);
}
} else {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_DEAD);
func_80032C7C(globalCtx, &this->actor);
this->actionfunc = func_80AE5C38;
}
}
void func_80AE5BC4(EnReeba* this, GlobalContext* globalCtx) {
this->actor.speedXZ = -8.0f;
this->actor.posRot.rot.y = this->actor.yawTowardsLink;
func_8003426C(&this->actor, 0x4000, 0xFF, 0, 8);
this->unk_278 = 14;
this->actor.flags &= ~1;
this->actionfunc = func_80AE5C38;
}
void func_80AE5C38(EnReeba* this, GlobalContext* globalCtx) {
Vec3f pos;
Vec3f accel = { 0.0f, 0.0f, 0.0f };
Vec3f velocity = { 0.0f, 0.0f, 0.0f };
EnEncount1* spawner;
if (this->unk_278 != 0) {
if (this->actor.speedXZ < 0.0f) {
this->actor.speedXZ++;
}
} else {
this->actor.speedXZ = 0.0f;
Math_SmoothDownscaleMaxF(&this->scale, 0.1f, 0.01f);
if (this->scale < 0.01f) {
pos.x = this->actor.posRot.pos.x;
pos.y = this->actor.posRot.pos.y;
pos.z = this->actor.posRot.pos.z;
velocity.y = 4.0f;
EffectSsDeadDb_Spawn(globalCtx, &pos, &velocity, &accel, 120, 0, 255, 255, 255, 255, 255, 0, 0, 1, 9, true);
if (!this->isBig) {
Item_DropCollectibleRandom(globalCtx, &this->actor, &pos, 0xE0);
} else {
Item_DropCollectibleRandom(globalCtx, &this->actor, &pos, 0xC0);
}
if (this->actor.parent != NULL) {
spawner = (EnEncount1*)this->actor.parent;
if (spawner->actor.update != NULL) {
if (!this->isBig) {
if (spawner->numLeeversDead < 10) {
spawner->numLeeversDead++;
}
// How many are dead?
osSyncPrintf("\n\n");
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 何匹DEAD? ☆☆☆☆☆%d\n" VT_RST, spawner->numLeeversDead);
osSyncPrintf("\n\n");
}
}
Actor_Kill(&this->actor);
}
}
}
}
void func_80AE5E48(EnReeba* this, GlobalContext* globalCtx) {
if (this->unk_278 < 37) {
this->actor.shape.rot.x = Math_Rand_CenteredFloat(3000.0f);
this->actor.shape.rot.z = Math_Rand_CenteredFloat(3000.0f);
if (this->unk_278 == 0) {
if (this->isBig) {
this->actionfunc = func_80AE538C;
} else {
this->actionfunc = func_80AE5688;
}
}
}
}
void func_80AE5EDC(EnReeba* this, GlobalContext* globalCtx) {
if (this->collider.base.acFlags & 2) {
this->collider.base.acFlags &= ~2;
if ((this->actionfunc != func_80AE5C38) && (this->actionfunc != func_80AE5854)) {
this->actor.shape.rot.z = 0;
this->unk_27E = 0;
this->actor.shape.rot.x = this->actor.shape.rot.z;
switch (this->actor.colChkInfo.damageEffect) {
case 11: // none
case 12: // boomerang
if ((this->actor.colChkInfo.health > 1) && (this->unk_27E != 4)) {
this->unk_27E = 4;
Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOMA_JR_FREEZE);
func_8003426C(&this->actor, 0, 0xFF, 0, 0x50);
this->actionfunc = func_80AE58EC;
break;
}
case 13: // hookshot/longshot
if ((this->actor.colChkInfo.health > 2) && (this->unk_27E != 4)) {
this->unk_27E = 4;
func_8003426C(&this->actor, 0, 0xFF, 0, 0x50);
Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOMA_JR_FREEZE);
this->actionfunc = func_80AE58EC;
break;
}
case 14:
this->unk_27C = 6;
Actor_ApplyDamage(&this->actor);
if (this->actor.colChkInfo.health == 0) {
Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_DEAD);
func_80032C7C(globalCtx, &this->actor);
this->actionfunc = func_80AE5BC4;
break;
}
if (this->actionfunc == func_80AE5E48) {
this->actor.shape.rot.z = 0;
this->actor.shape.rot.x = this->actor.shape.rot.z;
}
Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIVA_DAMAGE);
this->actionfunc = func_80AE57F0;
break;
case 3: // ice arrows/ice magic
Actor_ApplyDamage(&this->actor);
this->unk_27C = 2;
this->unk_27E = 2;
func_8003426C(&this->actor, 0, 0xFF, 0, 0x50);
this->actionfunc = func_80AE58EC;
break;
case 1: // unknown
if (this->unk_27E != 4) {
this->unk_27E = 4;
func_8003426C(&this->actor, 0, 0xFF, 0, 0x50);
this->actionfunc = func_80AE58EC;
}
break;
}
}
}
}
void EnReeba_Update(Actor* thisx, GlobalContext* globalCtx) {
GlobalContext* globalCtx2 = globalCtx;
EnReeba* this = THIS;
Player* player = PLAYER;
func_80AE5EDC(this, globalCtx);
this->actionfunc(this, globalCtx2);
Actor_SetScale(&this->actor, this->scale);
if (this->unk_270 != 0) {
this->unk_270--;
}
if (this->unk_272 != 0) {
this->unk_272--;
}
if (this->unk_278 != 0) {
this->unk_278--;
}
if (this->unk_274 != 0) {
this->unk_274--;
}
if (this->unk_276 != 0) {
this->unk_276--;
}
Actor_MoveForward(&this->actor);
func_8002E4B4(globalCtx2, &this->actor, 35.0f, 60.0f, 60.0f, 0x1D);
if (this->collider.base.atFlags & 4) {
this->collider.base.atFlags &= ~4;
if ((this->actionfunc == func_80AE5270) || (this->actionfunc == func_80AE53AC)) {
this->actor.speedXZ = 8.0f;
this->actor.posRot.rot.y *= -1.0f;
this->unk_272 = 14;
this->actionfunc = func_80AE561C;
return;
}
}
if (this->collider.base.atFlags & 2) {
this->collider.base.atFlags &= ~2;
if ((this->collider.base.at == &player->actor) && !this->isBig && (this->actionfunc != func_80AE56E0)) {
this->actionfunc = func_80AE5688;
}
}
this->actor.posRot2.pos = this->actor.posRot.pos;
if (!this->isBig) {
this->actor.posRot2.pos.y += 15.0f;
} else {
this->actor.posRot2.pos.y += 30.0f;
}
Collider_CylinderUpdate(&this->actor, &this->collider);
if ((this->actor.shape.unk_08 >= -700.0f) && (this->actor.colChkInfo.health > 0) &&
(this->actionfunc != func_80AE56E0)) {
CollisionCheck_SetOC(globalCtx2, &globalCtx2->colChkCtx, &this->collider.base);
if (!(this->actor.shape.unk_08 < 0.0f)) {
CollisionCheck_SetAC(globalCtx2, &globalCtx2->colChkCtx, &this->collider.base);
if ((this->actionfunc == func_80AE5270) || (this->actionfunc == func_80AE53AC)) {
CollisionCheck_SetAT(globalCtx2, &globalCtx2->colChkCtx, &this->collider.base);
}
}
}
}
void EnReeba_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnReeba* this = THIS;
s32 pad;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_reeba.c", 1062);
func_80093D18(globalCtx->state.gfxCtx);
if (this->isBig) {
gDPSetPrimColor(oGfxCtx->polyOpa.p++, 0x0, 0x01, 155, 55, 255, 255);
} else {
gDPSetPrimColor(oGfxCtx->polyOpa.p++, 0x0, 0x01, 255, 255, 255, 255);
}
SkelAnime_Draw(globalCtx, this->skelanime.skeleton, this->skelanime.limbDrawTbl, NULL, NULL, &this->actor);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_reeba.c", 1088);
if (BREG(0)) {
Vec3f debugPos;
debugPos.x = (Math_Sins(this->actor.posRot.rot.y) * 30.0f) + this->actor.posRot.pos.x;
debugPos.y = this->actor.posRot.pos.y + 20.0f;
debugPos.z = (Math_Coss(this->actor.posRot.rot.y) * 30.0f) + this->actor.posRot.pos.z;
DebugDisplay_AddObject(debugPos.x, debugPos.y, debugPos.z, this->actor.posRot.rot.x, this->actor.posRot.rot.y,
this->actor.posRot.rot.z, 1.0f, 1.0f, 1.0f, 255, 0, 0, 255, 4, globalCtx->state.gfxCtx);
}
}

View file

@ -6,9 +6,28 @@
struct EnReeba;
typedef void (*EnReebaActionFunc)(struct EnReeba*, GlobalContext*);
typedef struct EnReeba {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x190];
/* 0x014C */ SkelAnime skelanime;
/* 0x0190 */ Vec3s limbDrawTable[18];
/* 0x01FC */ Vec3s transitionDrawTable[18];
/* 0x0268 */ char unk_268[0x4];
/* 0x026C */ EnReebaActionFunc actionfunc;
/* 0x0270 */ s16 unk_270;
/* 0x0272 */ s16 unk_272;
/* 0x0274 */ s16 unk_274;
/* 0x0276 */ s16 unk_276;
/* 0x0278 */ s16 unk_278;
/* 0x027A */ s16 isBig;
/* 0x027C */ s16 unk_27C;
/* 0x027E */ s16 unk_27E;
/* 0x0280 */ s16 unk_280;
/* 0x0284 */ f32 unk_284;
/* 0x0288 */ f32 unk_288;
/* 0x028C */ f32 scale;
/* 0x0290 */ ColliderCylinder collider;
} EnReeba; // size = 0x02DC
extern const ActorInit En_Reeba_InitVars;

View file

@ -1,4 +1,11 @@
/*
* File: z_en_rl.c
* Overlay: En_Rl
* Description: Rauru
*/
#include "z_en_rl.h"
#include "vt.h"
#define FLAGS 0x00000010
@ -9,7 +16,376 @@ void EnRl_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnRl_Update(Actor* thisx, GlobalContext* globalCtx);
void EnRl_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void func_80AE7798(EnRl* this, GlobalContext* globalCtx);
void func_80AE77B8(EnRl* this, GlobalContext* globalCtx);
void func_80AE77F8(EnRl* this, GlobalContext* globalCtx);
void func_80AE7838(EnRl* this, GlobalContext* globalCtx);
void func_80AE7C64(EnRl* this, GlobalContext* globalCtx);
void func_80AE7C94(EnRl* this, GlobalContext* globalCtx);
void func_80AE7CE8(EnRl* this, GlobalContext* globalCtx);
void func_80AE7D40(EnRl* this, GlobalContext* globalCtx);
void func_80AE7FD0(EnRl* this, GlobalContext* globalCtx);
void func_80AE7FDC(EnRl* this, GlobalContext* globalCtx);
void func_80AE7D94(EnRl* this, GlobalContext* globalCtx);
UNK_PTR D_80AE81A0[] = { 0x06003620, 0x06003960, 0x06003B60 };
extern SkeletonHeader D_06007B38;
extern AnimationHeader D_06000A3C;
extern AnimationHeader D_06000830;
extern AnimationHeader D_0600040C;
void EnRl_Destroy(Actor* thisx, GlobalContext* globalCtx) {
EnRl* this = THIS;
SkelAnime_Free(&this->skelAnime, globalCtx);
}
void func_80AE72D0(EnRl* this) {
s32 pad[3];
s16* timer = &this->timer;
s16* eyeTextureIndex = &this->eyeTextureIndex;
if (DECR(*timer) == 0) {
*timer = Math_Rand_S16Offset(60, 60);
}
*eyeTextureIndex = *timer;
if (*eyeTextureIndex > 2) {
*eyeTextureIndex = 0;
}
}
void func_80AE7358(EnRl* this) {
SkelAnime_ChangeAnim(&this->skelAnime, &D_06000A3C, 1.0f, 0.0f, SkelAnime_GetFrameCount(&D_06000A3C.genericHeader),
0, 0.0f);
this->action = 4;
this->drawConfig = 0;
this->alpha = 0;
this->lightBallSpawned = 0;
this->actor.shape.unk_14 = 0;
this->unk_19C = 0.0f;
}
void func_80AE73D8(EnRl* this, GlobalContext* globalCtx) {
static s32 D_80AE81AC = 0;
if (globalCtx->csCtx.state == 0) {
if (D_80AE81AC) {
if (this->actor.params == 2) {
func_80AE7358(this);
}
D_80AE81AC = 0;
}
} else if (!D_80AE81AC) {
D_80AE81AC = 1;
}
}
void func_80AE744C(EnRl* this, GlobalContext* globalCtx) {
func_8002E4B4(globalCtx, &this->actor, 75.0f, 30.0f, 30.0f, 5);
}
s32 func_80AE7494(EnRl* this) {
return SkelAnime_FrameUpdateMatrix(&this->skelAnime);
}
s32 func_80AE74B4(EnRl* this, GlobalContext* globalCtx, u16 arg2, s32 arg3) {
CsCmdActorAction* csCmdActorAction;
if (globalCtx->csCtx.state != 0) {
csCmdActorAction = globalCtx->csCtx.npcActions[arg3];
if (csCmdActorAction != NULL && csCmdActorAction->action == arg2) {
return 1;
}
}
return 0;
}
s32 func_80AE74FC(EnRl* this, GlobalContext* globalCtx, u16 arg2, s32 arg3) {
CsCmdActorAction* csCmdActorAction;
if (globalCtx->csCtx.state != 0) {
csCmdActorAction = globalCtx->csCtx.npcActions[arg3];
if (csCmdActorAction != NULL && csCmdActorAction->action != arg2) {
return 1;
}
}
return 0;
}
void func_80AE7544(EnRl* this, GlobalContext* globalCtx) {
SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_06007B38, &D_06000A3C, 0, 0, 0);
}
void func_80AE7590(EnRl* this, GlobalContext* globalCtx) {
s32 pad;
Player* player;
Vec3f pos;
s16 sceneNum = globalCtx->sceneNum;
if (gSaveContext.sceneSetupIndex == 4 && sceneNum == SCENE_KENJYANOMA && globalCtx->csCtx.state != 0 &&
globalCtx->csCtx.npcActions[6] != NULL && globalCtx->csCtx.npcActions[6]->action == 2 &&
!this->lightMedallionGiven) {
player = PLAYER;
pos.x = player->actor.posRot.pos.x;
pos.y = player->actor.posRot.pos.y + 80.0f;
pos.z = player->actor.posRot.pos.z;
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_DEMO_EFFECT, pos.x, pos.y, pos.z, 0, 0, 0, 0xE);
Item_Give(globalCtx, ITEM_MEDALLION_LIGHT);
this->lightMedallionGiven = 1;
}
}
void func_80AE7668(EnRl* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
this->drawConfig = 1;
this->action = 1;
player->actor.posRot.rot.y = player->actor.shape.rot.y = this->actor.posRot.rot.y + 0x8000;
}
void func_80AE7698(EnRl* this, GlobalContext* globalCtx) {
CsCmdActorAction* csCmdActorAction;
if (globalCtx->csCtx.state != 0) {
csCmdActorAction = globalCtx->csCtx.npcActions[0];
if (csCmdActorAction != NULL && csCmdActorAction->action == 3) {
SkelAnime_ChangeAnim(&this->skelAnime, &D_0600040C, 1.0f, 0.0f,
SkelAnime_GetFrameCount(&D_0600040C.genericHeader), 2, 0.0f);
this->action = 2;
}
}
}
void func_80AE772C(EnRl* this, s32 arg1) {
if (arg1) {
SkelAnime_ChangeAnim(&this->skelAnime, &D_06000830, 1.0f, 0.0f,
SkelAnime_GetFrameCount(&D_06000830.genericHeader), 0, 0.0f);
this->action = 3;
}
}
void func_80AE7798(EnRl* this, GlobalContext* globalCtx) {
func_80AE7668(this, globalCtx);
}
void func_80AE77B8(EnRl* this, GlobalContext* globalCtx) {
func_80AE744C(this, globalCtx);
func_80AE7494(this);
func_80AE72D0(this);
func_80AE7698(this, globalCtx);
}
void func_80AE77F8(EnRl* this, GlobalContext* globalCtx) {
s32 temp;
func_80AE744C(this, globalCtx);
temp = func_80AE7494(this);
func_80AE72D0(this);
func_80AE772C(this, temp);
}
void func_80AE7838(EnRl* this, GlobalContext* globalCtx) {
func_80AE744C(this, globalCtx);
func_80AE7494(this);
func_80AE72D0(this);
func_80AE7590(this, globalCtx);
}
void func_80AE7878(EnRl* this, GlobalContext* globalCtx) {
SkelAnime_InitSV(globalCtx, &this->skelAnime, &D_06007B38, &D_06000A3C, 0, 0, 0);
this->action = 4;
this->actor.shape.unk_14 = 0;
}
void func_80AE78D4(EnRl* this, GlobalContext* globalCtx) {
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_DEMO_6K, this->actor.posRot.pos.x,
kREG(18) + 22.0f + this->actor.posRot.pos.y, this->actor.posRot.pos.z, 0, 0, 0, 5);
}
void func_80AE7954(EnRl* this, GlobalContext* globalCtx) {
if (func_80AE74B4(this, globalCtx, 4, 0)) {
this->action = 5;
this->drawConfig = 2;
this->alpha = 0;
this->actor.shape.unk_14 = 0;
this->unk_19C = 0.0f;
}
}
void func_80AE79A4(EnRl* this, GlobalContext* globalCtx) {
f32* unk_19C = &this->unk_19C;
s32 alpha = 255;
if (func_80AE74B4(this, globalCtx, 4, 0)) {
*unk_19C += 1.0f;
if (*unk_19C >= kREG(5) + 10.0f) {
this->action = 7;
this->drawConfig = 1;
*unk_19C = kREG(5) + 10.0f;
this->alpha = alpha;
this->actor.shape.unk_14 = alpha;
return;
}
} else {
*unk_19C -= 1.0f;
if (*unk_19C <= 0.0f) {
this->action = 4;
this->drawConfig = 0;
*unk_19C = 0.0f;
this->alpha = 0;
this->actor.shape.unk_14 = 0;
return;
}
}
alpha = (*unk_19C / (kREG(5) + 10.0f)) * 255.0f;
this->alpha = alpha;
this->actor.shape.unk_14 = alpha;
}
void func_80AE7AF8(EnRl* this, GlobalContext* globalCtx) {
if (func_80AE74B4(this, globalCtx, 3, 0)) {
SkelAnime_ChangeAnim(&this->skelAnime, &D_0600040C, 1.0f, 0.0f,
SkelAnime_GetFrameCount(&D_0600040C.genericHeader), 2, -8.0f);
this->action = 6;
} else if (func_80AE74FC(this, globalCtx, 4, 0)) {
this->action = 5;
this->drawConfig = 2;
this->unk_19C = kREG(5) + 10.0f;
this->alpha = 255;
if (!this->lightBallSpawned) {
func_80AE78D4(this, globalCtx);
this->lightBallSpawned = 1;
}
this->actor.shape.unk_14 = 0xFF;
}
}
void func_80AE7BF8(EnRl* this, s32 arg1) {
if (arg1 != 0) {
SkelAnime_ChangeAnim(&this->skelAnime, &D_06000830, 1.0f, 0.0f,
SkelAnime_GetFrameCount(&D_06000830.genericHeader), 0, 0.0f);
this->action = 7;
}
}
void func_80AE7C64(EnRl* this, GlobalContext* globalCtx) {
func_80AE7954(this, globalCtx);
func_80AE73D8(this, globalCtx);
}
void func_80AE7C94(EnRl* this, GlobalContext* globalCtx) {
func_80AE744C(this, globalCtx);
func_80AE7494(this);
func_80AE72D0(this);
func_80AE79A4(this, globalCtx);
func_80AE73D8(this, globalCtx);
}
void func_80AE7CE8(EnRl* this, GlobalContext* globalCtx) {
s32 temp;
func_80AE744C(this, globalCtx);
temp = func_80AE7494(this);
func_80AE72D0(this);
func_80AE7BF8(this, temp);
func_80AE73D8(this, globalCtx);
}
void func_80AE7D40(EnRl* this, GlobalContext* globalCtx) {
func_80AE744C(this, globalCtx);
func_80AE7494(this);
func_80AE72D0(this);
func_80AE7AF8(this, globalCtx);
func_80AE73D8(this, globalCtx);
}
void func_80AE7D94(EnRl* this, GlobalContext* globalCtx) {
s32 pad[2];
s16 temp = this->eyeTextureIndex;
s32 addr = D_80AE81A0[temp];
SkelAnime* skelAnime = &this->skelAnime;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_rl_inKenjyanomaDemo02.c", 304);
func_80093D84(globalCtx->state.gfxCtx);
gSPSegment(oGfxCtx->polyXlu.p++, 0x08, SEGMENTED_TO_VIRTUAL(addr));
gSPSegment(oGfxCtx->polyXlu.p++, 0x09, SEGMENTED_TO_VIRTUAL(addr));
gDPSetEnvColor(oGfxCtx->polyXlu.p++, 0, 0, 0, this->alpha);
gSPSegment(oGfxCtx->polyXlu.p++, 0x0C, D_80116280);
oGfxCtx->polyXlu.p = SkelAnime_DrawSV2(globalCtx, skelAnime->skeleton, skelAnime->limbDrawTbl,
skelAnime->dListCount, NULL, NULL, NULL, oGfxCtx->polyXlu.p);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_rl_inKenjyanomaDemo02.c", 331);
}
EnRlActionFunc sActionFuncs[] = {
func_80AE7798, func_80AE77B8, func_80AE77F8, func_80AE7838,
func_80AE7C64, func_80AE7C94, func_80AE7CE8, func_80AE7D40,
};
void EnRl_Update(Actor* thisx, GlobalContext* globalCtx) {
EnRl* this = THIS;
if ((this->action < 0) || (this->action > 7) || (sActionFuncs[this->action] == NULL)) {
osSyncPrintf(VT_FGCOL(RED) "メインモードがおかしい!!!!!!!!!!!!!!!!!!!!!!!!!\n" VT_RST);
return;
}
sActionFuncs[this->action](this, globalCtx);
}
void EnRl_Init(Actor* thisx, GlobalContext* globalCtx) {
EnRl* this = THIS;
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawFunc_Circle, 50.0f);
if (this->actor.params == 2) {
func_80AE7878(this, globalCtx);
} else {
func_80AE7544(this, globalCtx);
}
}
void func_80AE7FD0(EnRl* this, GlobalContext* globalCtx) {
}
void func_80AE7FDC(EnRl* this, GlobalContext* globalCtx) {
s32 pad[2];
s16 temp = this->eyeTextureIndex;
s32 addr = D_80AE81A0[temp];
SkelAnime* skelAnime = &this->skelAnime;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_rl.c", 416);
func_80093D18(globalCtx->state.gfxCtx);
gSPSegment(oGfxCtx->polyOpa.p++, 0x08, SEGMENTED_TO_VIRTUAL(addr));
gSPSegment(oGfxCtx->polyOpa.p++, 0x09, SEGMENTED_TO_VIRTUAL(addr));
gDPSetEnvColor(oGfxCtx->polyOpa.p++, 0, 0, 0, 255);
gSPSegment(oGfxCtx->polyOpa.p++, 0x0C, &D_80116280[2]);
SkelAnime_DrawSV(globalCtx, skelAnime->skeleton, skelAnime->limbDrawTbl, skelAnime->dListCount, NULL, NULL,
&this->actor);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_rl.c", 437);
}
EnRlDrawFunc sDrawFuncs[] = {
func_80AE7FD0,
func_80AE7FDC,
func_80AE7D94,
};
void EnRl_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnRl* this = THIS;
if (this->drawConfig < 0 || this->drawConfig >= 3 || sDrawFuncs[this->drawConfig] == NULL) {
osSyncPrintf(VT_FGCOL(RED) "描画モードがおかしい!!!!!!!!!!!!!!!!!!!!!!!!!\n" VT_RST);
return;
}
sDrawFuncs[this->drawConfig](this, globalCtx);
}
const ActorInit En_Rl_InitVars = {
ACTOR_EN_RL,
ACTORTYPE_NPC,
@ -20,70 +396,4 @@ const ActorInit En_Rl_InitVars = {
(ActorFunc)EnRl_Destroy,
(ActorFunc)EnRl_Update,
(ActorFunc)EnRl_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/EnRl_Destroy.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE72D0.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7358.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE73D8.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE744C.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7494.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE74B4.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE74FC.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7544.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7590.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7668.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7698.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE772C.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7798.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE77B8.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE77F8.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7838.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7878.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE78D4.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7954.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE79A4.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7AF8.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7BF8.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7C64.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7C94.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7CE8.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7D40.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7D94.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/EnRl_Update.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/EnRl_Init.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7FD0.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/func_80AE7FDC.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Rl/EnRl_Draw.s")
};

View file

@ -6,9 +6,20 @@
struct EnRl;
typedef void (*EnRlActionFunc)(struct EnRl*, GlobalContext*);
typedef void (*EnRlDrawFunc)(struct EnRl*, GlobalContext*);
typedef struct EnRl {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x60];
/* 0x014C */ SkelAnime skelAnime;
/* 0x0190 */ s16 eyeTextureIndex;
/* 0x0192 */ s16 timer;
/* 0x0194 */ s32 action;
/* 0x0198 */ s32 drawConfig;
/* 0x019C */ f32 unk_19C;
/* 0x01A0 */ s32 alpha;
/* 0x01A4 */ u32 lightBallSpawned;
/* 0x01A8 */ s32 lightMedallionGiven;
} EnRl; // size = 0x01AC
extern const ActorInit En_Rl_InitVars;

View file

@ -1,10 +1,11 @@
/*
* File: z_obj_kibako.c
* Overlay: ovl_Obj_Kibako
* Description: Small, Liftable Crate
* Description: Small wooden box
*/
#include "z_obj_kibako.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
#define FLAGS 0x04000010
@ -15,7 +16,16 @@ void ObjKibako_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjKibako_Update(Actor* thisx, GlobalContext* globalCtx);
void ObjKibako_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void ObjKibako_SetupIdle(ObjKibako* this);
void ObjKibako_Idle(ObjKibako* this, GlobalContext* globalCtx);
void ObjKibako_SetupHeld(ObjKibako* this);
void ObjKibako_Held(ObjKibako* this, GlobalContext* globalCtx);
void ObjKibako_SetupThrown(ObjKibako* this);
void ObjKibako_Thrown(ObjKibako* this, GlobalContext* globalCtx);
extern Gfx D_05005290[];
extern Gfx D_05005380[];
const ActorInit Obj_Kibako_InitVars = {
ACTOR_OBJ_KIBAKO,
ACTORTYPE_PROP,
@ -27,33 +37,242 @@ const ActorInit Obj_Kibako_InitVars = {
(ActorFunc)ObjKibako_Update,
(ActorFunc)ObjKibako_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/func_80B94CA0.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/func_80B94D00.s")
static ColliderCylinderInit sCylinderInit = {
{ COLTYPE_UNK10, 0x09, 0x09, 0x39, 0x20, COLSHAPE_CYLINDER },
{ 0x00, { 0x00000002, 0x00, 0x01 }, { 0x4FC00748, 0x00, 0x00 }, 0x01, 0x01, 0x01 },
{ 12, 27, 0, { 0, 0, 0 } },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/func_80B94D34.s")
static CollisionCheckInfoInit sCCInfoInit = { 0, 0xC, 0x3C, 0xFE };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/ObjKibako_Init.s")
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 60, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/ObjKibako_Destroy.s")
void ObjKibako_SpawnCollectible(ObjKibako* this, GlobalContext* globalCtx) {
s16 collectible;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/func_80B94E38.s")
collectible = this->actor.params & 0x1F;
if ((collectible >= 0) && (collectible <= 0x19)) {
Item_DropCollectible(globalCtx, &this->actor.posRot.pos,
collectible | (((this->actor.params >> 8) & 0x3F) << 8));
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/func_80B950B8.s")
void ObjKibako_ApplyGravity(ObjKibako* this) {
this->actor.velocity.y += this->actor.gravity;
if (this->actor.velocity.y < this->actor.minVelocityY) {
this->actor.velocity.y = this->actor.minVelocityY;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/func_80B95334.s")
void ObjKibako_InitCollider(Actor* thisx, GlobalContext* globalCtx) {
ObjKibako* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/func_80B9534C.s")
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
Collider_CylinderUpdate(&this->actor, &this->collider);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/func_80B95540.s")
void ObjKibako_Init(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
ObjKibako* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/func_80B95574.s")
Actor_ProcessInitChain(&this->actor, sInitChain);
this->actor.gravity = -1.2f;
this->actor.minVelocityY = -13.0f;
ObjKibako_InitCollider(&this->actor, globalCtx);
func_80061ED4(&this->actor.colChkInfo, NULL, &sCCInfoInit);
ObjKibako_SetupIdle(this);
// wooden box
osSyncPrintf("(dungeon keep 木箱)(arg_data 0x%04x)\n", this->actor.params);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/func_80B95638.s")
void ObjKibako_Destroy(Actor* thisx, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = globalCtx2;
ObjKibako* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/func_80B9569C.s")
Collider_DestroyCylinder(globalCtx, &this->collider);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/ObjKibako_Update.s")
void ObjKibako_AirBreak(ObjKibako* this, GlobalContext* globalCtx) {
s16 angle;
s32 i;
Vec3f* breakPos = &this->actor.posRot.pos;
Vec3f pos;
Vec3f velocity;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Kibako/ObjKibako_Draw.s")
for (i = 0, angle = 0; i < 12; i++, angle += 0x4E20) {
f32 sn = Math_Sins(angle);
f32 cs = Math_Coss(angle);
f32 temp_rand;
s16 phi_s0;
pos.x = sn * 16.0f;
pos.y = (Math_Rand_ZeroOne() * 5.0f) + 2.0f;
pos.z = cs * 16.0f;
velocity.x = pos.x * 0.2f;
velocity.y = (Math_Rand_ZeroOne() * 6.0f) + 2.0f;
velocity.z = pos.z * 0.2f;
pos.x += breakPos->x;
pos.y += breakPos->y;
pos.z += breakPos->z;
temp_rand = Math_Rand_ZeroOne();
if (temp_rand < 0.1f) {
phi_s0 = 0x60;
} else if (temp_rand < 0.7f) {
phi_s0 = 0x40;
} else {
phi_s0 = 0x20;
}
EffectSsKakera_Spawn(globalCtx, &pos, &velocity, breakPos, -200, phi_s0, 10, 10, 0,
(Math_Rand_ZeroOne() * 30.0f) + 10.0f, 0, 32, 60, KAKERA_COLOR_NONE,
OBJECT_GAMEPLAY_DANGEON_KEEP, D_05005380);
}
func_80033480(globalCtx, &this->actor.posRot.pos, 40.0f, 3, 50, 140, 1);
}
void ObjKibako_WaterBreak(ObjKibako* this, GlobalContext* globalCtx) {
s16 angle;
s32 i;
Vec3f* breakPos = &this->actor.posRot.pos;
Vec3f pos;
Vec3f velocity;
pos = *breakPos;
pos.y += this->actor.waterY;
EffectSsGSplash_Spawn(globalCtx, &pos, NULL, NULL, 0, 500);
for (i = 0, angle = 0; i < 12; i++, angle += 0x4E20) {
f32 sn = Math_Sins(angle);
f32 cs = Math_Coss(angle);
f32 temp_rand;
s16 phi_s0;
pos.x = sn * 16.0f;
pos.y = (Math_Rand_ZeroOne() * 5.0f) + 2.0f;
pos.z = cs * 16.0f;
velocity.x = pos.x * 0.18f;
velocity.y = (Math_Rand_ZeroOne() * 4.0f) + 2.0f;
velocity.z = pos.z * 0.18f;
pos.x += breakPos->x;
pos.y += breakPos->y;
pos.z += breakPos->z;
temp_rand = Math_Rand_ZeroOne();
phi_s0 = (temp_rand < 0.2f) ? 0x40 : 0x20;
EffectSsKakera_Spawn(globalCtx, &pos, &velocity, breakPos, -180, phi_s0, 30, 30, 0,
(Math_Rand_ZeroOne() * 30.0f) + 10.0f, 0, 32, 70, KAKERA_COLOR_NONE,
OBJECT_GAMEPLAY_DANGEON_KEEP, D_05005380);
}
}
void ObjKibako_SetupIdle(ObjKibako* this) {
this->actionFunc = ObjKibako_Idle;
this->actor.colChkInfo.mass = 0xFE;
}
void ObjKibako_Idle(ObjKibako* this, GlobalContext* globalCtx) {
if (Actor_HasParent(&this->actor, globalCtx)) {
ObjKibako_SetupHeld(this);
} else if ((this->actor.bgCheckFlags & 0x20) && (this->actor.waterY > 19.0f)) {
ObjKibako_WaterBreak(this, globalCtx);
Audio_PlaySoundAtPosition(globalCtx, &this->actor.posRot.pos, 20, NA_SE_EV_WOODBOX_BREAK);
ObjKibako_SpawnCollectible(this, globalCtx);
Actor_Kill(&this->actor);
} else if (this->collider.base.acFlags & 2) {
ObjKibako_AirBreak(this, globalCtx);
Audio_PlaySoundAtPosition(globalCtx, &this->actor.posRot.pos, 20, NA_SE_EV_WOODBOX_BREAK);
ObjKibako_SpawnCollectible(this, globalCtx);
Actor_Kill(&this->actor);
} else {
Actor_MoveForward(&this->actor);
func_8002E4B4(globalCtx, &this->actor, 19.0f, 20.0f, 0.0f, 5);
if (!(this->collider.base.maskA & 8) && (this->actor.xzDistFromLink > 28.0f)) {
this->collider.base.maskA |= 8;
}
if (this->actor.xzDistFromLink < 600.0f) {
ColliderCylinder* collider = &this->collider;
Collider_CylinderUpdate(&this->actor, collider);
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &collider->base);
if (this->actor.xzDistFromLink < 180.0f) {
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &collider->base);
}
}
if (this->actor.xzDistFromLink < 100.0f) {
func_8002F580(&this->actor, globalCtx);
}
}
}
void ObjKibako_SetupHeld(ObjKibako* this) {
this->actionFunc = ObjKibako_Held;
this->actor.room = -1;
func_8002F7DC(&this->actor, 0x878);
}
void ObjKibako_Held(ObjKibako* this, GlobalContext* globalCtx) {
if (Actor_HasNoParent(&this->actor, globalCtx)) {
this->actor.room = globalCtx->roomCtx.curRoom.num;
if (fabsf(this->actor.speedXZ) < 0.1f) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_PUT_DOWN_WOODBOX);
ObjKibako_SetupIdle(this);
this->collider.base.maskA &= ~8;
} else {
ObjKibako_SetupThrown(this);
ObjKibako_ApplyGravity(this);
func_8002D7EC(&this->actor);
}
func_8002E4B4(globalCtx, &this->actor, 19.0f, 20.0f, 0.0f, 5);
}
}
void ObjKibako_SetupThrown(ObjKibako* this) {
this->actor.velocity.x = Math_Sins(this->actor.posRot.rot.y) * this->actor.speedXZ;
this->actor.velocity.z = Math_Coss(this->actor.posRot.rot.y) * this->actor.speedXZ;
this->actor.colChkInfo.mass = 240;
this->actionFunc = ObjKibako_Thrown;
}
void ObjKibako_Thrown(ObjKibako* this, GlobalContext* globalCtx) {
Actor* thisx = &this->actor;
if ((thisx->bgCheckFlags & 0xB) || (this->collider.base.atFlags & 2)) {
ObjKibako_AirBreak(this, globalCtx);
Audio_PlaySoundAtPosition(globalCtx, &thisx->posRot.pos, 20, NA_SE_EV_WOODBOX_BREAK);
ObjKibako_SpawnCollectible(this, globalCtx);
Actor_Kill(thisx);
} else if (this->actor.bgCheckFlags & 0x40) {
ObjKibako_WaterBreak(this, globalCtx);
Audio_PlaySoundAtPosition(globalCtx, &thisx->posRot.pos, 20, NA_SE_EV_WOODBOX_BREAK);
ObjKibako_SpawnCollectible(this, globalCtx);
Actor_Kill(thisx);
} else {
ColliderCylinder* collider = &this->collider;
ObjKibako_ApplyGravity(this);
func_8002D7EC(thisx);
func_8002E4B4(globalCtx, thisx, 19.0f, 20.0f, 0.0f, 5);
Collider_CylinderUpdate(thisx, collider);
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &collider->base);
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &collider->base);
}
}
void ObjKibako_Update(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
ObjKibako* this = THIS;
this->actionFunc(this, globalCtx);
}
void ObjKibako_Draw(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
ObjKibako* this = THIS;
Gfx_DrawDListOpa(globalCtx, D_05005290);
}

View file

@ -6,9 +6,12 @@
struct ObjKibako;
typedef void (*ObjKibakoActionFunc)(struct ObjKibako*, GlobalContext*);
typedef struct ObjKibako {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x50];
/* 0x014C */ ObjKibakoActionFunc actionFunc;
/* 0x0150 */ ColliderCylinder collider;
} ObjKibako; // size = 0x019C
extern const ActorInit Obj_Kibako_InitVars;

View file

@ -5,6 +5,7 @@
*/
#include "z_obj_syokudai.h"
#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h"
#define FLAGS 0x00000410
@ -15,7 +16,8 @@ void ObjSyokudai_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjSyokudai_Update(Actor* thisx, GlobalContext* globalCtx);
void ObjSyokudai_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
extern Gfx D_0404D4E0[];
const ActorInit Obj_Syokudai_InitVars = {
ACTOR_OBJ_SYOKUDAI,
ACTORTYPE_PROP,
@ -27,11 +29,255 @@ const ActorInit Obj_Syokudai_InitVars = {
(ActorFunc)ObjSyokudai_Update,
(ActorFunc)ObjSyokudai_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Syokudai/ObjSyokudai_Init.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Syokudai/ObjSyokudai_Destroy.s")
static ColliderCylinderInit sCylInitStand = {
{ COLTYPE_METAL_SHIELD, 0x00, 0x0D, 0x39, 0x20, COLSHAPE_CYLINDER },
{ 0x02, { 0x00100000, 0x00, 0x00 }, { 0xEE01FFFF, 0x00, 0x00 }, 0x00, 0x05, 0x01 },
{ 12, 45, 0, { 0, 0, 0 } },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Syokudai/ObjSyokudai_Update.s")
static ColliderCylinderInit sCylInitFlame = {
{ COLTYPE_UNK10, 0x00, 0x09, 0x00, 0x00, COLSHAPE_CYLINDER },
{ 0x02, { 0x00000000, 0x00, 0x00 }, { 0x00020820, 0x00, 0x00 }, 0x00, 0x01, 0x00 },
{ 15, 45, 45, { 0, 0, 0 } },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Syokudai/ObjSyokudai_Draw.s")
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 800, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 800, ICHAIN_STOP),
};
static s32 sLitTorchCount;
void ObjSyokudai_Init(Actor* thisx, GlobalContext* globalCtx) {
static u8 sColTypesStand[] = { 0x09, 0x0B, 0x0B };
s32 pad;
ObjSyokudai* this = THIS;
s32 torchType = this->actor.params & 0xF000;
Actor_ProcessInitChain(&this->actor, sInitChain);
ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f);
Collider_InitCylinder(globalCtx, &this->colliderStand);
Collider_SetCylinder(globalCtx, &this->colliderStand, &this->actor, &sCylInitStand);
this->colliderStand.base.type = sColTypesStand[this->actor.params >> 0xC];
Collider_InitCylinder(globalCtx, &this->colliderFlame);
Collider_SetCylinder(globalCtx, &this->colliderFlame, &this->actor, &sCylInitFlame);
this->actor.colChkInfo.mass = 0xFF;
Lights_PointGlowSetInfo(&this->lightInfo, this->actor.posRot.pos.x, this->actor.posRot.pos.y + 70.0f,
this->actor.posRot.pos.z, 255, 255, 180, -1);
this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo);
if ((this->actor.params & 0x400) || ((torchType != 2) && Flags_GetSwitch(globalCtx, this->actor.params & 0x3F))) {
this->litTimer = -1;
}
this->flameTexScroll = (s32)(Math_Rand_ZeroOne() * 20.0f);
sLitTorchCount = 0;
Actor_SetHeight(&this->actor, 60.0f);
}
void ObjSyokudai_Destroy(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
ObjSyokudai* this = THIS;
Collider_DestroyCylinder(globalCtx, &this->colliderStand);
Collider_DestroyCylinder(globalCtx, &this->colliderFlame);
LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode);
}
void ObjSyokudai_Update(Actor* thisx, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = globalCtx2;
ObjSyokudai* this = THIS;
s32 torchCount = (this->actor.params >> 6) & 0xF;
s32 switchFlag = this->actor.params & 0x3F;
s32 torchType = this->actor.params & 0xF000;
s32 litTimeScale;
WaterBox* dummy;
f32 waterSurface;
s32 lightRadius = -1;
u8 brightness = 0;
Player* player;
EnArrow* arrow;
s32 interactionType;
u32 toucherFlags;
Vec3f tipToFlame;
ColliderCylinder* colliderStand;
ColliderCylinder* colliderFlame;
litTimeScale = torchCount;
if (torchCount == 10) {
torchCount = 24;
}
if (func_80042244(globalCtx, &globalCtx->colCtx, this->actor.posRot.pos.x, this->actor.posRot.pos.z, &waterSurface,
&dummy) &&
((waterSurface - this->actor.posRot.pos.y) > 52.0f)) {
this->litTimer = 0;
if (torchType == 1) {
Flags_UnsetSwitch(globalCtx, switchFlag);
if (torchCount != 0) {
this->litTimer = 1;
}
}
} else {
player = PLAYER;
interactionType = 0;
if (this->actor.params & 0x400) {
this->litTimer = -1;
}
if (torchCount != 0) {
if (Flags_GetSwitch(globalCtx, switchFlag)) {
if (this->litTimer == 0) {
this->litTimer = -1;
if (torchType == 0) {
func_80080480(globalCtx, &this->actor);
}
} else if (this->litTimer > 0) {
this->litTimer = -1;
}
} else if (this->litTimer < 0) {
this->litTimer = 20;
}
}
if (this->colliderFlame.base.acFlags & 2) {
toucherFlags = this->colliderFlame.body.acHitItem->toucher.flags;
if (toucherFlags & 0x20820) {
interactionType = 1;
}
} else if (player->heldItemActionParam == 6) {
Math_Vec3f_Diff(&player->swordInfo[0].tip, &this->actor.posRot.pos, &tipToFlame);
tipToFlame.y -= 67.0f;
if ((SQ(tipToFlame.x) + SQ(tipToFlame.y) + SQ(tipToFlame.z)) < SQ(20.0f)) {
interactionType = -1;
}
}
if (interactionType != 0) {
if (this->litTimer != 0) {
if (interactionType < 0) {
if (player->unk_860 == 0) {
player->unk_860 = 210;
Audio_PlaySoundGeneral(NA_SE_EV_FLAME_IGNITION, &this->actor.projectedPos, 4, &D_801333E0,
&D_801333E0, &D_801333E8);
} else if (player->unk_860 < 200) {
player->unk_860 = 200;
}
} else if (toucherFlags & 0x20) {
arrow = (EnArrow*)this->colliderFlame.base.ac;
if ((arrow->actor.update != NULL) && (arrow->actor.id == ACTOR_EN_ARROW)) {
arrow->actor.params = 0;
arrow->unk_1A8 = 0x800;
}
}
if ((0 <= this->litTimer) && (this->litTimer < (50 * litTimeScale + 100)) && (torchType != 0)) {
this->litTimer = 50 * litTimeScale + 100;
}
} else if ((torchType != 0) && (((interactionType > 0) && (toucherFlags & 0x20800)) ||
((interactionType < 0) && (player->unk_860 != 0)))) {
if ((interactionType < 0) && (player->unk_860 < 200)) {
player->unk_860 = 200;
}
if (torchCount == 0) {
this->litTimer = -1;
if (torchType != 2) {
Flags_SetSwitch(globalCtx, switchFlag);
func_80080480(globalCtx, &this->actor);
}
} else {
sLitTorchCount++;
if (sLitTorchCount >= torchCount) {
Flags_SetSwitch(globalCtx, switchFlag);
func_80080480(globalCtx, &this->actor);
this->litTimer = -1;
} else {
this->litTimer = (litTimeScale * 50) + 110;
}
}
Audio_PlaySoundGeneral(NA_SE_EV_FLAME_IGNITION, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0,
&D_801333E8);
}
}
}
colliderStand = &this->colliderStand;
Collider_CylinderUpdate(&this->actor, colliderStand);
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &colliderStand->base);
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &colliderStand->base);
colliderFlame = &this->colliderFlame;
Collider_CylinderUpdate(&this->actor, colliderFlame);
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &colliderFlame->base);
if (this->litTimer > 0) {
this->litTimer--;
if ((this->litTimer == 0) && (torchType != 0)) {
sLitTorchCount--;
}
}
if (this->litTimer != 0) {
if ((this->litTimer < 0) || (this->litTimer >= 20)) {
lightRadius = 200;
} else {
lightRadius = (this->litTimer * 200.0f) / 20.0f;
}
brightness = (u8)(Math_Rand_ZeroOne() * 127.0f) + 128;
func_8002F974(&this->actor, NA_SE_EV_TORCH - SFX_FLAG);
}
Lights_PointSetColorAndRadius(&this->lightInfo, brightness, brightness, 0, lightRadius);
this->flameTexScroll++;
}
void ObjSyokudai_Draw(Actor* thisx, GlobalContext* globalCtx) {
static Gfx* displayLists[] = { 0x060003A0, 0x06000B90, 0x06000870 };
s32 pad;
ObjSyokudai* this = THIS;
s32 timerMax;
timerMax = (((this->actor.params >> 6) & 0xF) * 50) + 100;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_obj_syokudai.c", 707);
func_80093D18(globalCtx->state.gfxCtx);
gSPMatrix(oGfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_obj_syokudai.c", 714),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(oGfxCtx->polyOpa.p++, displayLists[(u16)this->actor.params >> 0xC]);
if (this->litTimer != 0) {
f32 flameScale = 1.0f;
if (this->litTimer > timerMax) {
flameScale = (timerMax - this->litTimer + 10) / 10.0f;
} else if ((this->litTimer > 0) && (this->litTimer < 20)) {
flameScale = this->litTimer / 20.0f;
}
flameScale *= 0.0027f;
func_80093D84(globalCtx->state.gfxCtx);
gSPSegment(oGfxCtx->polyXlu.p++, 0x08,
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0,
(this->flameTexScroll * -20) & 0x1FF, 0x20, 0x80));
gDPSetPrimColor(oGfxCtx->polyXlu.p++, 0x80, 0x80, 255, 255, 0, 255);
gDPSetEnvColor(oGfxCtx->polyXlu.p++, 255, 0, 0, 0);
Matrix_Translate(0.0f, 52.0f, 0.0f, MTXMODE_APPLY);
Matrix_RotateY(
(s16)(func_8005A9F4(ACTIVE_CAM) - this->actor.shape.rot.y + 0x8000) *
(M_PI / 0x8000),
MTXMODE_APPLY);
Matrix_Scale(flameScale, flameScale, flameScale, MTXMODE_APPLY);
gSPMatrix(oGfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_obj_syokudai.c", 745),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(oGfxCtx->polyXlu.p++, D_0404D4E0);
}
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_obj_syokudai.c", 749);
}

View file

@ -8,7 +8,12 @@ struct ObjSyokudai;
typedef struct ObjSyokudai {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0xB0];
/* 0x014C */ ColliderCylinder colliderStand;
/* 0x0198 */ ColliderCylinder colliderFlame;
/* 0x01E4 */ s16 litTimer;
/* 0x01E6 */ u8 flameTexScroll;
/* 0x01E8 */ LightNode* lightNode;
/* 0x01EC */ LightInfo lightInfo;
} ObjSyokudai; // size = 0x01FC
extern const ActorInit Obj_Syokudai_InitVars;