mirror of
https://github.com/zeldaret/oot.git
synced 2025-07-15 12:24:39 +00:00
Bg_Gnd_Iceblock and Bg_Ice_Objects (sliding ice blocks) (#534)
* Darkmeiro decompilation Bg_Gnd_Darkmeiro decompiled, matched, and documented. * give this a shot * fix conflict * one more try * could be useful * whoops * ZAP2 stuff * ZAP why * ZAP again * a good start * done * Log * formatting * thisx Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
This commit is contained in:
parent
21e367a7cb
commit
695bc37be4
34 changed files with 544 additions and 2154 deletions
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* File: z_bg_gnd_iceblock.c
|
||||
* Overlay: ovl_Bg_Gnd_Iceblock
|
||||
* Description: Pushable large square ice block (Inside Ganon's Castle)
|
||||
* Description: Pushable ice block (Inside Ganon's Castle)
|
||||
*/
|
||||
|
||||
#include "z_bg_gnd_iceblock.h"
|
||||
|
@ -10,21 +10,23 @@
|
|||
|
||||
#define THIS ((BgGndIceblock*)thisx)
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ GNDICE_IDLE,
|
||||
/* 1 */ GNDICE_FALL,
|
||||
/* 2 */ GNDICE_HOLE
|
||||
} BgGndIceblockAction;
|
||||
|
||||
void BgGndIceblock_Init(Actor* thisx, GlobalContext* globalCtx);
|
||||
void BgGndIceblock_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
||||
void BgGndIceblock_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void BgGndIceblock_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
void func_8087A0C8(BgGndIceblock* this, GlobalContext* globalCtx);
|
||||
void func_8087A184(BgGndIceblock* this, GlobalContext* globalCtx);
|
||||
void func_8087A248(BgGndIceblock* this, GlobalContext* globalCtx);
|
||||
void func_8087A300(BgGndIceblock* this, GlobalContext* globalCtx);
|
||||
void func_8087A39C(BgGndIceblock* this, GlobalContext* globalCtx);
|
||||
void BgGndIceblock_Idle(BgGndIceblock* this, GlobalContext* globalCtx);
|
||||
void BgGndIceblock_Slide(BgGndIceblock* this, GlobalContext* globalCtx);
|
||||
|
||||
extern UNK_TYPE D_06004420;
|
||||
extern UNK_TYPE D_06004618;
|
||||
extern Gfx D_06004420[];
|
||||
extern ColHeader D_06004618;
|
||||
|
||||
/*
|
||||
const ActorInit Bg_Gnd_Iceblock_InitVars = {
|
||||
ACTOR_BG_GND_ICEBLOCK,
|
||||
ACTORTYPE_PROP,
|
||||
|
@ -36,29 +38,330 @@ const ActorInit Bg_Gnd_Iceblock_InitVars = {
|
|||
(ActorFunc)BgGndIceblock_Update,
|
||||
(ActorFunc)BgGndIceblock_Draw,
|
||||
};
|
||||
*/
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Gnd_Iceblock/BgGndIceblock_Init.s")
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Gnd_Iceblock/BgGndIceblock_Destroy.s")
|
||||
static Color_RGBA8 sWhite = { 250, 250, 250, 255 };
|
||||
static Color_RGBA8 sGray = { 180, 180, 180, 255 };
|
||||
static Vec3f sZeroVec = { 0.0f, 0.0f, 0.0f };
|
||||
static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Gnd_Iceblock/func_80879C04.s")
|
||||
static u8 sBlockPositions[2];
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Gnd_Iceblock/func_80879D10.s")
|
||||
void BgGndIceblock_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
BgGndIceblock* this = THIS;
|
||||
ColHeader* colHeader = NULL;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Gnd_Iceblock/func_80879D4C.s")
|
||||
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
|
||||
DynaPolyInfo_SetActorMove(&this->dyna, 0);
|
||||
DynaPolyInfo_Alloc(&D_06004618, &colHeader);
|
||||
this->targetPos = this->dyna.actor.initPosRot.pos;
|
||||
this->actionFunc = BgGndIceblock_Idle;
|
||||
this->dyna.dynaPolyId =
|
||||
DynaPolyInfo_RegisterActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
|
||||
if (this->dyna.actor.posRot.pos.x == 2792.0f) {
|
||||
this->dyna.actor.params = 0;
|
||||
sBlockPositions[0] = 7;
|
||||
} else if (this->dyna.actor.posRot.pos.x == 3032.0f) {
|
||||
this->dyna.actor.params = 1;
|
||||
sBlockPositions[1] = 14;
|
||||
} else {
|
||||
LOG_FLOAT("thisx->world.position.x", this->dyna.actor.posRot.pos.x, "../z_bg_gnd_iceblock.c", 138);
|
||||
__assert("0", "../z_bg_gnd_iceblock.c", 139);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Gnd_Iceblock/func_80879D98.s")
|
||||
void BgGndIceblock_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
BgGndIceblock* this = THIS;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Gnd_Iceblock/func_8087A0C8.s")
|
||||
DynaPolyInfo_Free(globalCtx, &globalCtx->colCtx.dyna, this->dyna.dynaPolyId);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Gnd_Iceblock/func_8087A184.s")
|
||||
/*
|
||||
* Diagram of positions in the room:
|
||||
* __
|
||||
* _________|10|_________
|
||||
* |*0* 6 *13****16*|
|
||||
* |*1* 7 17 |
|
||||
* | 2 14 18 |
|
||||
* | 3 h8 15 19 |
|
||||
* | 4 9 11 XX *20*|
|
||||
* |*5* XX 12 *21*|
|
||||
* ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
* XX are rocks
|
||||
* ** are pits
|
||||
* h is the hole.
|
||||
* Block 0 starts at 7 and block 1 starts at 14
|
||||
*/
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Gnd_Iceblock/func_8087A248.s")
|
||||
void BgGndIceblock_SetPosition(BgGndIceblock* this, s32 blockPosition) {
|
||||
Actor* thisx = &this->dyna.actor;
|
||||
u8 xPosIdx[22] = {
|
||||
0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 6, 6, 6, 6, 6, 6,
|
||||
};
|
||||
u8 zPosIdx[22] = {
|
||||
5, 4, 3, 2, 1, 0, 5, 4, 2, 1, 6, 1, 0, 5, 3, 2, 5, 4, 3, 2, 1, 0,
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Gnd_Iceblock/func_8087A300.s")
|
||||
sBlockPositions[thisx->params] = blockPosition;
|
||||
this->targetPos.x = 2552.0f + (xPosIdx[blockPosition] * 120.0f);
|
||||
this->targetPos.z = -540.0f - (zPosIdx[blockPosition] * 120.0f);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Gnd_Iceblock/func_8087A39C.s")
|
||||
s32 BgGndIceblock_CheckForBlock(s32 blockPosition) {
|
||||
s32 i;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Gnd_Iceblock/BgGndIceblock_Update.s")
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (blockPosition == sBlockPositions[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Gnd_Iceblock/BgGndIceblock_Draw.s")
|
||||
s32 BgGndIceblock_NextAction(BgGndIceblock* this) {
|
||||
switch (sBlockPositions[this->dyna.actor.params]) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 5:
|
||||
case 13:
|
||||
case 16:
|
||||
case 20:
|
||||
case 21:
|
||||
return GNDICE_FALL;
|
||||
case 8:
|
||||
return GNDICE_HOLE;
|
||||
default:
|
||||
return GNDICE_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
void BgGndIceblock_SetNextPosition(BgGndIceblock* this) {
|
||||
if (this->dyna.unk_158 == 0) {
|
||||
switch (sBlockPositions[this->dyna.actor.params]) {
|
||||
case 3:
|
||||
case 4:
|
||||
BgGndIceblock_SetPosition(this, 5);
|
||||
break;
|
||||
case 7:
|
||||
if (BgGndIceblock_CheckForBlock(8)) {
|
||||
BgGndIceblock_SetPosition(this, 9);
|
||||
} else {
|
||||
BgGndIceblock_SetPosition(this, 8);
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
BgGndIceblock_SetPosition(this, 12);
|
||||
break;
|
||||
case 14:
|
||||
BgGndIceblock_SetPosition(this, 15);
|
||||
break;
|
||||
case 18:
|
||||
case 19:
|
||||
BgGndIceblock_SetPosition(this, 20);
|
||||
break;
|
||||
}
|
||||
} else if (this->dyna.unk_158 == -0x8000) {
|
||||
switch (sBlockPositions[this->dyna.actor.params]) {
|
||||
case 2:
|
||||
case 3:
|
||||
BgGndIceblock_SetPosition(this, 1);
|
||||
break;
|
||||
case 7:
|
||||
case 9:
|
||||
BgGndIceblock_SetPosition(this, 6);
|
||||
break;
|
||||
case 11:
|
||||
BgGndIceblock_SetPosition(this, 10);
|
||||
break;
|
||||
case 14:
|
||||
case 15:
|
||||
BgGndIceblock_SetPosition(this, 13);
|
||||
break;
|
||||
case 17:
|
||||
BgGndIceblock_SetPosition(this, 16);
|
||||
break;
|
||||
case 18:
|
||||
if (!BgGndIceblock_CheckForBlock(17)) {
|
||||
BgGndIceblock_SetPosition(this, 16);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (this->dyna.unk_158 == 0x4000) {
|
||||
switch (sBlockPositions[this->dyna.actor.params]) {
|
||||
case 6:
|
||||
BgGndIceblock_SetPosition(this, 13);
|
||||
break;
|
||||
case 7:
|
||||
BgGndIceblock_SetPosition(this, 17);
|
||||
break;
|
||||
case 9:
|
||||
BgGndIceblock_SetPosition(this, 11);
|
||||
break;
|
||||
case 12:
|
||||
BgGndIceblock_SetPosition(this, 21);
|
||||
break;
|
||||
case 14:
|
||||
BgGndIceblock_SetPosition(this, 18);
|
||||
break;
|
||||
case 15:
|
||||
BgGndIceblock_SetPosition(this, 19);
|
||||
break;
|
||||
}
|
||||
} else if (this->dyna.unk_158 == -0x4000) {
|
||||
switch (sBlockPositions[this->dyna.actor.params]) {
|
||||
case 6:
|
||||
BgGndIceblock_SetPosition(this, 0);
|
||||
break;
|
||||
case 7:
|
||||
BgGndIceblock_SetPosition(this, 1);
|
||||
break;
|
||||
case 9:
|
||||
case 11:
|
||||
BgGndIceblock_SetPosition(this, 4);
|
||||
break;
|
||||
case 14:
|
||||
BgGndIceblock_SetPosition(this, 2);
|
||||
break;
|
||||
case 15:
|
||||
if (BgGndIceblock_CheckForBlock(8)) {
|
||||
BgGndIceblock_SetPosition(this, 3);
|
||||
} else {
|
||||
BgGndIceblock_SetPosition(this, 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BgGndIceblock_Idle(BgGndIceblock* this, GlobalContext* globalCtx) {
|
||||
Player* player = PLAYER;
|
||||
|
||||
if (this->dyna.unk_150 != 0.0f) {
|
||||
player->stateFlags2 &= ~0x10;
|
||||
if (this->dyna.unk_150 > 0.0f) {
|
||||
BgGndIceblock_SetNextPosition(this);
|
||||
if (func_8002DBB0(&this->dyna.actor, &this->targetPos) > 1.0f) {
|
||||
func_8002DF54(globalCtx, &this->dyna.actor, 8);
|
||||
this->actionFunc = BgGndIceblock_Slide;
|
||||
}
|
||||
}
|
||||
this->dyna.unk_150 = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void BgGndIceblock_Reset(BgGndIceblock* this, GlobalContext* globalCtx) {
|
||||
Player* player = PLAYER;
|
||||
Actor* thisx = &this->dyna.actor;
|
||||
|
||||
if (this->dyna.unk_150 != 0.0f) {
|
||||
player->stateFlags2 &= ~0x10;
|
||||
this->dyna.unk_150 = 0.0f;
|
||||
}
|
||||
if (Math_StepToF(&thisx->posRot.pos.y, thisx->initPosRot.pos.y, 1.0f)) {
|
||||
this->targetPos = thisx->initPosRot.pos;
|
||||
thisx->speedXZ = 0.0f;
|
||||
this->actionFunc = BgGndIceblock_Idle;
|
||||
switch (thisx->params) {
|
||||
case 0:
|
||||
sBlockPositions[0] = 7;
|
||||
break;
|
||||
case 1:
|
||||
sBlockPositions[1] = 14;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BgGndIceblock_Fall(BgGndIceblock* this, GlobalContext* globalCtx) {
|
||||
Actor* thisx = &this->dyna.actor;
|
||||
|
||||
thisx->velocity.y += 1.0f;
|
||||
if (Math_StepToF(&thisx->posRot.pos.y, thisx->initPosRot.pos.y - 300.0f, thisx->velocity.y)) {
|
||||
thisx->velocity.y = 0.0f;
|
||||
thisx->posRot.pos.x = thisx->initPosRot.pos.x;
|
||||
thisx->posRot.pos.y = thisx->initPosRot.pos.y - 100.0f;
|
||||
thisx->posRot.pos.z = thisx->initPosRot.pos.z;
|
||||
if (Player_InCsMode(globalCtx)) {
|
||||
func_8002DF54(globalCtx, thisx, 7);
|
||||
}
|
||||
this->actionFunc = BgGndIceblock_Reset;
|
||||
}
|
||||
}
|
||||
|
||||
void BgGndIceblock_Hole(BgGndIceblock* this, GlobalContext* globalCtx) {
|
||||
Actor* thisx = &this->dyna.actor;
|
||||
|
||||
thisx->velocity.y += 1.0f;
|
||||
if (Math_StepToF(&thisx->posRot.pos.y, thisx->initPosRot.pos.y - 100.0f, thisx->velocity.y)) {
|
||||
thisx->velocity.y = 0.0f;
|
||||
if (Player_InCsMode(globalCtx)) {
|
||||
func_8002DF54(globalCtx, thisx, 7);
|
||||
}
|
||||
this->actionFunc = BgGndIceblock_Idle;
|
||||
}
|
||||
}
|
||||
|
||||
void BgGndIceblock_Slide(BgGndIceblock* this, GlobalContext* globalCtx) {
|
||||
s32 atTarget;
|
||||
Vec3f pos;
|
||||
Vec3f velocity;
|
||||
f32 spread;
|
||||
Actor* thisx = &this->dyna.actor;
|
||||
|
||||
Math_StepToF(&thisx->speedXZ, 10.0f, 0.5f);
|
||||
atTarget = Math_StepToF(&thisx->posRot.pos.x, this->targetPos.x, thisx->speedXZ);
|
||||
atTarget &= Math_StepToF(&thisx->posRot.pos.z, this->targetPos.z, thisx->speedXZ);
|
||||
if (atTarget) {
|
||||
thisx->speedXZ = 0.0f;
|
||||
this->targetPos.x = thisx->posRot.pos.x;
|
||||
this->targetPos.z = thisx->posRot.pos.z;
|
||||
Audio_PlayActorSound2(thisx, NA_SE_EV_BLOCK_BOUND);
|
||||
switch (BgGndIceblock_NextAction(this)) {
|
||||
case GNDICE_IDLE:
|
||||
this->actionFunc = BgGndIceblock_Idle;
|
||||
func_8002DF54(globalCtx, thisx, 7);
|
||||
break;
|
||||
case GNDICE_FALL:
|
||||
this->actionFunc = BgGndIceblock_Fall;
|
||||
break;
|
||||
case GNDICE_HOLE:
|
||||
this->actionFunc = BgGndIceblock_Hole;
|
||||
break;
|
||||
}
|
||||
} else if (thisx->speedXZ > 6.0f) {
|
||||
spread = Rand_CenteredFloat(120.0f);
|
||||
velocity.x = -(1.5f + Rand_ZeroOne()) * Math_SinS(this->dyna.unk_158);
|
||||
velocity.y = Rand_ZeroOne() + 1.0f;
|
||||
velocity.z = -(1.5f + Rand_ZeroOne()) * Math_CosS(this->dyna.unk_158);
|
||||
pos.x =
|
||||
thisx->posRot.pos.x - (60.0f * Math_SinS(this->dyna.unk_158)) - (Math_CosS(this->dyna.unk_158) * spread);
|
||||
pos.z =
|
||||
thisx->posRot.pos.z - (60.0f * Math_CosS(this->dyna.unk_158)) + (Math_SinS(this->dyna.unk_158) * spread);
|
||||
pos.y = thisx->posRot.pos.y;
|
||||
func_8002829C(globalCtx, &pos, &velocity, &sZeroVec, &sWhite, &sGray, 250, Rand_S16Offset(40, 15));
|
||||
spread = Rand_CenteredFloat(120.0f);
|
||||
pos.x =
|
||||
thisx->posRot.pos.x - (60.0f * Math_SinS(this->dyna.unk_158)) + (Math_CosS(this->dyna.unk_158) * spread);
|
||||
pos.z =
|
||||
thisx->posRot.pos.z - (60.0f * Math_CosS(this->dyna.unk_158)) - (Math_SinS(this->dyna.unk_158) * spread);
|
||||
func_8002829C(globalCtx, &pos, &velocity, &sZeroVec, &sWhite, &sGray, 250, Rand_S16Offset(40, 15));
|
||||
func_8002F974(thisx, NA_SE_PL_SLIP_ICE_LEVEL - SFX_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
void BgGndIceblock_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
BgGndIceblock* this = THIS;
|
||||
|
||||
this->actionFunc(this, globalCtx);
|
||||
}
|
||||
|
||||
void BgGndIceblock_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
BgGndIceblock* this = THIS;
|
||||
|
||||
Gfx_DrawDListOpa(globalCtx, D_06004420);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ typedef void (*BgGndIceblockActionFunc)(struct BgGndIceblock*, GlobalContext*);
|
|||
typedef struct BgGndIceblock {
|
||||
/* 0x0000 */ DynaPolyActor dyna;
|
||||
/* 0x0164 */ BgGndIceblockActionFunc actionFunc;
|
||||
/* 0x0168 */ Vec3f unk_168;
|
||||
/* 0x0168 */ Vec3f targetPos;
|
||||
} BgGndIceblock; // size = 0x0174
|
||||
|
||||
extern const ActorInit Bg_Gnd_Iceblock_InitVars;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* File: z_bg_ice_objects.c
|
||||
* Overlay: ovl_Bg_Ice_Objects
|
||||
* Description: Movable Ice Block.
|
||||
* Description: Pushable ice block (Ice Cavern)
|
||||
*/
|
||||
|
||||
#include "z_bg_ice_objects.h"
|
||||
|
@ -15,10 +15,18 @@ void BgIceObjects_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|||
void BgIceObjects_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void BgIceObjects_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
extern UNK_TYPE D_06000190;
|
||||
extern UNK_TYPE D_060003F0;
|
||||
void BgIceObjects_Idle(BgIceObjects* this, GlobalContext* globalCtx);
|
||||
void BgIceObjects_Slide(BgIceObjects* this, GlobalContext* globalCtx);
|
||||
void BgIceObjects_Reset(BgIceObjects* this, GlobalContext* globalCtx);
|
||||
void BgIceObjects_Stuck(BgIceObjects* this, GlobalContext* globalCtx);
|
||||
|
||||
extern Gfx D_06000190[];
|
||||
extern ColHeader D_060003F0;
|
||||
|
||||
static Color_RGBA8 sWhite = { 250, 250, 250, 255 };
|
||||
static Color_RGBA8 sGray = { 180, 180, 180, 255 };
|
||||
static Vec3f sZeroVec = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
/*
|
||||
const ActorInit Bg_Ice_Objects_InitVars = {
|
||||
ACTOR_BG_ICE_OBJECTS,
|
||||
ACTORTYPE_PROP,
|
||||
|
@ -30,23 +38,209 @@ const ActorInit Bg_Ice_Objects_InitVars = {
|
|||
(ActorFunc)BgIceObjects_Update,
|
||||
(ActorFunc)BgIceObjects_Draw,
|
||||
};
|
||||
*/
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ice_Objects/BgIceObjects_Init.s")
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ice_Objects/BgIceObjects_Destroy.s")
|
||||
InitChainEntry sInitChain[] = {
|
||||
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ice_Objects/func_8088F8C8.s")
|
||||
void BgIceObjects_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
BgIceObjects* this = THIS;
|
||||
ColHeader* colHeader = NULL;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ice_Objects/func_8088FD48.s")
|
||||
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
|
||||
DynaPolyInfo_SetActorMove(&this->dyna, 0);
|
||||
DynaPolyInfo_Alloc(&D_060003F0, &colHeader);
|
||||
Math_Vec3f_Copy(&this->targetPos, &this->dyna.actor.initPosRot.pos);
|
||||
this->actionFunc = BgIceObjects_Idle;
|
||||
this->dyna.dynaPolyId =
|
||||
DynaPolyInfo_RegisterActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
|
||||
this->dyna.actor.params = 0;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ice_Objects/func_8088FED0.s")
|
||||
void BgIceObjects_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
BgIceObjects* this = THIS;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ice_Objects/func_8088FFD0.s")
|
||||
DynaPolyInfo_Free(globalCtx, &globalCtx->colCtx.dyna, this->dyna.dynaPolyId);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ice_Objects/func_80890360.s")
|
||||
static s16 sXStarts[] = {
|
||||
-1060, -1200, -1240, -1387, -1580, -1680, -1780,
|
||||
};
|
||||
static s16 sZStarts[] = {
|
||||
-580, -660, -780, -820, -860, -900, -1087,
|
||||
};
|
||||
static s16 sZStops[7][2] = {
|
||||
{ -580, -1087 }, { -780, -1260 }, { -340, -820 }, { -260, -1260 }, { -340, -860 }, { -660, -1260 }, { -340, -740 },
|
||||
};
|
||||
static s16 sXStops[7][2] = {
|
||||
{ -860, -1580 }, { -1240, -1780 }, { -860, -1680 }, { -860, -1680 },
|
||||
{ -1387, -1680 }, { -860, -1200 }, { -860, -1800 },
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ice_Objects/func_808903FC.s")
|
||||
/*
|
||||
* Checks which of the eight possible x and z positions the block is at,
|
||||
* defaulting to the maximum x wall or minimum z wall. Each x and z position
|
||||
* has only one possible wall or pit on each side of it.
|
||||
*/
|
||||
void BgIceObjects_SetNextTarget(BgIceObjects* this, GlobalContext* globalCtx) {
|
||||
s16 x16;
|
||||
s16 z16 = 0; // needed to match
|
||||
s32 i;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ice_Objects/BgIceObjects_Update.s")
|
||||
if ((this->dyna.unk_158 == 0) || (this->dyna.unk_158 == -0x8000)) {
|
||||
x16 = this->dyna.actor.posRot.pos.x;
|
||||
for (i = 0; i < 7; i++) {
|
||||
if (x16 == sXStarts[i]) {
|
||||
z16 = (this->dyna.unk_158 == 0) ? sZStops[i][0] : sZStops[i][1];
|
||||
this->targetPos.z = z16;
|
||||
return;
|
||||
}
|
||||
}
|
||||
this->targetPos.z = (this->dyna.unk_158 == 0) ? -340 : -1260;
|
||||
} else {
|
||||
z16 = this->dyna.actor.posRot.pos.z;
|
||||
for (i = 0; i < 7; i++) {
|
||||
if (z16 == sZStarts[i]) {
|
||||
x16 = (this->dyna.unk_158 == 0x4000) ? sXStops[i][0] : sXStops[i][1];
|
||||
this->targetPos.x = x16;
|
||||
return;
|
||||
}
|
||||
}
|
||||
this->targetPos.x = (this->dyna.unk_158 == 0x4000) ? -860 : -1780;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Ice_Objects/BgIceObjects_Draw.s")
|
||||
/*
|
||||
* Checks if the block has fallen into any of the pits.
|
||||
*/
|
||||
void BgIceObjects_CheckPits(BgIceObjects* this, GlobalContext* globalCtx) {
|
||||
Actor* thisx = &this->dyna.actor;
|
||||
|
||||
if ((thisx->velocity.y > 0.0f) || ((thisx->posRot.pos.x <= -1660.0f) && (thisx->posRot.pos.z <= -1060.0f)) ||
|
||||
((thisx->posRot.pos.x <= -1580.0f) && (thisx->posRot.pos.z >= -420.0f)) ||
|
||||
((thisx->posRot.pos.x >= -980.0f) && (thisx->posRot.pos.z <= -1180.0f)) ||
|
||||
((thisx->posRot.pos.x >= -860.0f) && (thisx->posRot.pos.z >= -700.0f))) {
|
||||
|
||||
thisx->velocity.y += 1.0f;
|
||||
if (Math_StepToF(&thisx->posRot.pos.y, -300.0f, thisx->velocity.y)) {
|
||||
thisx->velocity.y = 0.0f;
|
||||
thisx->posRot.pos.x = thisx->initPosRot.pos.x;
|
||||
thisx->posRot.pos.y = thisx->initPosRot.pos.y - 60.0f;
|
||||
thisx->posRot.pos.z = thisx->initPosRot.pos.z;
|
||||
if (thisx->params != 0) {
|
||||
func_8002DF54(globalCtx, thisx, 7);
|
||||
}
|
||||
this->actionFunc = BgIceObjects_Reset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BgIceObjects_Idle(BgIceObjects* this, GlobalContext* globalCtx) {
|
||||
Player* player = PLAYER;
|
||||
Actor* thisx = &this->dyna.actor;
|
||||
|
||||
if (this->dyna.unk_150 != 0.0f) {
|
||||
player->stateFlags2 &= ~0x10;
|
||||
if ((this->dyna.unk_150 > 0.0f) && !Player_InCsMode(globalCtx)) {
|
||||
BgIceObjects_SetNextTarget(this, globalCtx);
|
||||
if (func_8002DBB0(thisx, &this->targetPos) > 1.0f) {
|
||||
thisx->flags |= 0x10;
|
||||
func_8002DF54(globalCtx, thisx, 8);
|
||||
thisx->params = 1;
|
||||
this->actionFunc = BgIceObjects_Slide;
|
||||
}
|
||||
}
|
||||
this->dyna.unk_150 = 0.0f;
|
||||
}
|
||||
if (thisx->velocity.y > 0.0f) {
|
||||
BgIceObjects_CheckPits(this, globalCtx);
|
||||
}
|
||||
}
|
||||
|
||||
void BgIceObjects_Slide(BgIceObjects* this, GlobalContext* globalCtx) {
|
||||
s32 atTarget;
|
||||
Vec3f pos;
|
||||
Vec3f velocity;
|
||||
f32 spread;
|
||||
Actor* thisx = &this->dyna.actor;
|
||||
|
||||
Math_StepToF(&thisx->speedXZ, 10.0f, 0.5f);
|
||||
atTarget = Math_StepToF(&thisx->posRot.pos.x, this->targetPos.x, thisx->speedXZ);
|
||||
atTarget &= Math_StepToF(&thisx->posRot.pos.z, this->targetPos.z, thisx->speedXZ);
|
||||
if (atTarget) {
|
||||
thisx->speedXZ = 0.0f;
|
||||
this->targetPos.x = thisx->posRot.pos.x;
|
||||
this->targetPos.z = thisx->posRot.pos.z;
|
||||
if (thisx->velocity.y <= 0.0f) {
|
||||
thisx->flags &= ~0x10;
|
||||
}
|
||||
thisx->params = 0;
|
||||
func_8002DF54(globalCtx, thisx, 7);
|
||||
Audio_PlayActorSound2(thisx, NA_SE_EV_BLOCK_BOUND);
|
||||
if ((fabsf(thisx->posRot.pos.x + 1387.0f) < 1.0f) && (fabsf(thisx->posRot.pos.z + 260.0f) < 1.0f)) {
|
||||
this->actionFunc = BgIceObjects_Stuck;
|
||||
} else {
|
||||
this->actionFunc = BgIceObjects_Idle;
|
||||
}
|
||||
} else if ((thisx->speedXZ > 6.0f) && (thisx->posRot.pos.y >= 0.0f)) {
|
||||
spread = Rand_CenteredFloat(120.0f);
|
||||
velocity.x = -(1.5f + Rand_ZeroOne()) * Math_SinS(this->dyna.unk_158);
|
||||
velocity.y = Rand_ZeroOne() + 1.0f;
|
||||
velocity.z = -(1.5f + Rand_ZeroOne()) * Math_CosS(this->dyna.unk_158);
|
||||
pos.x =
|
||||
thisx->posRot.pos.x - (60.0f * Math_SinS(this->dyna.unk_158)) - (Math_CosS(this->dyna.unk_158) * spread);
|
||||
pos.z =
|
||||
thisx->posRot.pos.z - (60.0f * Math_CosS(this->dyna.unk_158)) + (Math_SinS(this->dyna.unk_158) * spread);
|
||||
pos.y = thisx->posRot.pos.y;
|
||||
func_8002829C(globalCtx, &pos, &velocity, &sZeroVec, &sWhite, &sGray, 250, Rand_S16Offset(40, 15));
|
||||
spread = Rand_CenteredFloat(120.0f);
|
||||
pos.x =
|
||||
thisx->posRot.pos.x - (60.0f * Math_SinS(this->dyna.unk_158)) + (Math_CosS(this->dyna.unk_158) * spread);
|
||||
pos.z =
|
||||
thisx->posRot.pos.z - (60.0f * Math_CosS(this->dyna.unk_158)) - (Math_SinS(this->dyna.unk_158) * spread);
|
||||
func_8002829C(globalCtx, &pos, &velocity, &sZeroVec, &sWhite, &sGray, 250, Rand_S16Offset(40, 15));
|
||||
func_8002F974(thisx, NA_SE_PL_SLIP_ICE_LEVEL - SFX_FLAG);
|
||||
}
|
||||
BgIceObjects_CheckPits(this, globalCtx);
|
||||
}
|
||||
|
||||
void BgIceObjects_Reset(BgIceObjects* this, GlobalContext* globalCtx) {
|
||||
Player* player = PLAYER;
|
||||
Actor* thisx = &this->dyna.actor;
|
||||
|
||||
if (this->dyna.unk_150 != 0.0f) {
|
||||
player->stateFlags2 &= ~0x10;
|
||||
this->dyna.unk_150 = 0.0f;
|
||||
}
|
||||
if (Math_StepToF(&thisx->posRot.pos.y, thisx->initPosRot.pos.y, 1.0f)) {
|
||||
thisx->flags &= ~0x10;
|
||||
Math_Vec3f_Copy(&this->targetPos, &thisx->initPosRot.pos);
|
||||
this->actionFunc = BgIceObjects_Idle;
|
||||
thisx->speedXZ = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void BgIceObjects_Stuck(BgIceObjects* this, GlobalContext* globalCtx) {
|
||||
Player* player = PLAYER;
|
||||
|
||||
if (this->dyna.unk_150 != 0.0f) {
|
||||
player->stateFlags2 &= ~0x10;
|
||||
this->dyna.unk_150 = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void BgIceObjects_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
BgIceObjects* this = THIS;
|
||||
|
||||
this->actionFunc(this, globalCtx);
|
||||
}
|
||||
|
||||
void BgIceObjects_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
BgIceObjects* this = THIS;
|
||||
|
||||
Gfx_DrawDListOpa(globalCtx, D_06000190);
|
||||
}
|
||||
|
|
|
@ -6,9 +6,12 @@
|
|||
|
||||
struct BgIceObjects;
|
||||
|
||||
typedef void (*BgIceObjectsActionFunc) (struct BgIceObjects*, GlobalContext*);
|
||||
|
||||
typedef struct BgIceObjects {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ char unk_14C[0x28];
|
||||
/* 0x0000 */ DynaPolyActor dyna;
|
||||
/* 0x0164 */ BgIceObjectsActionFunc actionFunc;
|
||||
/* 0x0168 */ Vec3f targetPos;
|
||||
} BgIceObjects; // size = 0x0174
|
||||
|
||||
extern const ActorInit Bg_Ice_Objects_InitVars;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue