mirror of
https://github.com/zeldaret/oot.git
synced 2025-08-06 06:10:21 +00:00
BgSpot08Iceblock OK, some documentation (#641)
* OK, spec * all functions and variables named, some docs on the complicated function * delete asm * updated to reflect Actor changes * simplify one thing into a ternary * Address review comments
This commit is contained in:
parent
7eaf57be59
commit
ced724fb9b
27 changed files with 448 additions and 1148 deletions
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
* File: z_bg_spot08_iceblock.c
|
||||
* Overlay: ovl_Bg_Spot08_Iceblock
|
||||
* Description: Floating ice platforms
|
||||
*/
|
||||
|
||||
#include "z_bg_spot08_iceblock.h"
|
||||
|
||||
#define FLAGS 0x00000000
|
||||
|
@ -9,12 +15,14 @@ void BgSpot08Iceblock_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|||
void BgSpot08Iceblock_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void BgSpot08Iceblock_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
extern UNK_TYPE D_06000DE0;
|
||||
extern UNK_TYPE D_06002BD0;
|
||||
extern UNK_TYPE D_06002FD8;
|
||||
extern UNK_TYPE D_06001904;
|
||||
void BgSpot08Iceblock_SetupFloatNonrotating(BgSpot08Iceblock* this);
|
||||
void BgSpot08Iceblock_FloatNonrotating(BgSpot08Iceblock* this, GlobalContext* globalCtx);
|
||||
void BgSpot08Iceblock_SetupFloatRotating(BgSpot08Iceblock* this);
|
||||
void BgSpot08Iceblock_FloatRotating(BgSpot08Iceblock* this, GlobalContext* globalCtx);
|
||||
void BgSpot08Iceblock_SetupFloatOrbitingTwins(BgSpot08Iceblock* this);
|
||||
void BgSpot08Iceblock_FloatOrbitingTwins(BgSpot08Iceblock* this, GlobalContext* globalCtx);
|
||||
void BgSpot08Iceblock_SetupNoAction(BgSpot08Iceblock* this);
|
||||
|
||||
/*
|
||||
const ActorInit Bg_Spot08_Iceblock_InitVars = {
|
||||
ACTOR_BG_SPOT08_ICEBLOCK,
|
||||
ACTORCAT_BG,
|
||||
|
@ -26,47 +34,418 @@ const ActorInit Bg_Spot08_Iceblock_InitVars = {
|
|||
(ActorFunc)BgSpot08Iceblock_Update,
|
||||
(ActorFunc)BgSpot08Iceblock_Draw,
|
||||
};
|
||||
*/
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B0960.s")
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B0968.s")
|
||||
extern Gfx D_06000DE0[]; // Large iceberg spawned in place of Jabu
|
||||
extern CollisionHeader D_06001904; // Large iceberg spawned in place of Jabu
|
||||
extern Gfx D_06002BD0[]; // Hexagonal ice floe
|
||||
extern CollisionHeader D_06002FD8; // Hexagonal ice floe
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B09F0.s")
|
||||
void BgSpot08Iceblock_SetupAction(BgSpot08Iceblock* this, BgSpot08IceblockActionFunc actionFunc) {
|
||||
this->actionFunc = actionFunc;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B0A84.s")
|
||||
void BgSpot08Iceblock_InitDynaPoly(BgSpot08Iceblock* this, GlobalContext* globalCtx, CollisionHeader* collision,
|
||||
DynaPolyMoveFlag flags) {
|
||||
s32 pad;
|
||||
CollisionHeader* colHeader = NULL;
|
||||
s32 pad2;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B0AE0.s")
|
||||
DynaPolyActor_Init(&this->dyna, flags);
|
||||
CollisionHeader_GetVirtual(collision, &colHeader);
|
||||
this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
|
||||
if (this->dyna.bgId == BG_ACTOR_MAX) {
|
||||
// Warning: move BG registration failed
|
||||
osSyncPrintf("Warning : move BG 登録失敗(%s %d)(name %d)(arg_data 0x%04x)\n", "../z_bg_spot08_iceblock.c", 0xD9,
|
||||
this->dyna.actor.id, this->dyna.actor.params);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B0B8C.s")
|
||||
// Sets params to 0x10 (medium, nonrotating) if not in the cases listed.
|
||||
void BgSpot08Iceblock_CheckParams(BgSpot08Iceblock* this) {
|
||||
switch (this->dyna.actor.params & 0xFF) {
|
||||
case 0xFF:
|
||||
this->dyna.actor.params = 0x10;
|
||||
break;
|
||||
default:
|
||||
// Error: arg_data setting error
|
||||
osSyncPrintf("Error : arg_data 設定ミスです。(%s %d)(arg_data 0x%04x)\n", "../z_bg_spot08_iceblock.c", 0xF6,
|
||||
this->dyna.actor.params);
|
||||
this->dyna.actor.params = 0x10;
|
||||
break;
|
||||
case 1:
|
||||
case 4:
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
case 0x14:
|
||||
case 0x20:
|
||||
case 0x23:
|
||||
case 0x24:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B0BA8.s")
|
||||
void BgSpot08Iceblock_Bobbing(BgSpot08Iceblock* this) {
|
||||
this->bobOffset = (Math_SinS(this->bobPhaseSlow) * 4.0f) + (Math_SinS(this->bobPhaseFast) * 3.0f);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B0BD4.s")
|
||||
void BgSpot08Iceblock_SinkUnderPlayer(BgSpot08Iceblock* this) {
|
||||
f32 target;
|
||||
f32 step;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B0C44.s")
|
||||
switch (this->dyna.actor.params & 0xF0) {
|
||||
case 0:
|
||||
step = 0.15f;
|
||||
break;
|
||||
case 0x10:
|
||||
step = 0.2f;
|
||||
break;
|
||||
case 0x20:
|
||||
step = 0.4f;
|
||||
break;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B0CE0.s")
|
||||
// Sink under Player's weight if standing on it
|
||||
target = (func_80043548(&this->dyna) ? -4.0f : 0.0f);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B1054.s")
|
||||
Math_StepToF(&this->sinkOffset, target, step);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/BgSpot08Iceblock_Init.s")
|
||||
void BgSpot08Iceblock_SetWaterline(BgSpot08Iceblock* this) {
|
||||
this->dyna.actor.world.pos.y = this->sinkOffset + this->bobOffset + this->dyna.actor.home.pos.y;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/BgSpot08Iceblock_Destroy.s")
|
||||
void BgSpot08Iceblock_MultVectorScalar(Vec3f* dest, Vec3f* v, f32 scale) {
|
||||
dest->x = v->x * scale;
|
||||
dest->y = v->y * scale;
|
||||
dest->z = v->z * scale;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B1388.s")
|
||||
void BgSpot08Iceblock_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_Spot08_Iceblock/func_808B13AC.s")
|
||||
s32 BgSpot08Iceblock_NormalizeVector(Vec3f* dest, Vec3f* v) {
|
||||
f32 magnitude;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B13FC.s")
|
||||
magnitude = Math3D_Vec3fMagnitude(v);
|
||||
if (magnitude < 0.001f) {
|
||||
dest->x = dest->y = 0.0f;
|
||||
dest->z = 1.0f;
|
||||
return false;
|
||||
} else {
|
||||
dest->x = v->x * (1.0f / magnitude);
|
||||
dest->y = v->y * (1.0f / magnitude);
|
||||
dest->z = v->z * (1.0f / magnitude);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B1420.s")
|
||||
static Vec3f sVerticalVector = { 0.0f, 1.0f, 0.0f };
|
||||
static Vec3f sZeroVector = { 0.0f, 0.0f, 0.0f };
|
||||
static f32 sInertias[] = { 1.0f / 70000000, 1.0f / 175000000, 1.0f / 700000000 };
|
||||
static f32 sDampingFactors[] = { 0.96f, 0.96f, 0.98f };
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B147C.s")
|
||||
static f32 sRollSins[] = {
|
||||
0.22495104f, // sin(13 degrees)
|
||||
0.22495104f, // sin(13 degrees)
|
||||
0.03489947f, // sin(2 degrees)
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B14A0.s")
|
||||
static f32 sRollCoss[] = {
|
||||
0.97437006f, // cos(13 degrees)
|
||||
0.97437006f, // cos(13 degrees)
|
||||
0.99939084f, // cos(2 degrees)
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/func_808B1574.s")
|
||||
/**
|
||||
* Handles all the factors that influence rolling: inertia, random oscillations, and most significantly, player weight,
|
||||
* and combines them to produce a matrix that rotates the actor to match the surface normal
|
||||
*/
|
||||
void BgSpot08Iceblock_Roll(BgSpot08Iceblock* this, GlobalContext* globalCtx) {
|
||||
f32 deviationFromVertSq;
|
||||
f32 stabilityCorrection;
|
||||
Vec3f surfaceNormalHorizontal;
|
||||
Vec3f playerCentroidDiff;
|
||||
Vec3f playerMoment;
|
||||
Vec3f surfaceNormalHorizontalScaled;
|
||||
Vec3f randomNutation;
|
||||
Vec3f tempVec; // reused with different meanings
|
||||
Vec3f torqueDirection;
|
||||
f32 playerCentroidDist;
|
||||
s32 rollDataIndex;
|
||||
MtxF mtx;
|
||||
s32 pad;
|
||||
Player* player = PLAYER;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/BgSpot08Iceblock_Update.s")
|
||||
switch (this->dyna.actor.params & 0xFF) {
|
||||
case 0x11: // Medium nonrotating
|
||||
rollDataIndex = 0;
|
||||
break;
|
||||
case 1:
|
||||
rollDataIndex = 1; // Large nonrotating
|
||||
break;
|
||||
default:
|
||||
rollDataIndex = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Spot08_Iceblock/BgSpot08Iceblock_Draw.s")
|
||||
Math_Vec3f_Diff(&player->actor.world.pos, &this->dyna.actor.world.pos, &playerCentroidDiff);
|
||||
playerCentroidDiff.y -= (150.0f * this->dyna.actor.scale.y);
|
||||
playerCentroidDist = Math3D_Vec3fMagnitude(&playerCentroidDiff);
|
||||
|
||||
randomNutation.x = (Rand_ZeroOne() - 0.5f) * (1.0f / 625);
|
||||
randomNutation.y = 0.0f;
|
||||
randomNutation.z = (Rand_ZeroOne() - 0.5f) * (1.0f / 625);
|
||||
|
||||
surfaceNormalHorizontal.x = this->surfaceNormal.x;
|
||||
surfaceNormalHorizontal.y = 0.0f;
|
||||
surfaceNormalHorizontal.z = this->surfaceNormal.z;
|
||||
|
||||
// If player is standing on it or holding the edge
|
||||
if (func_8004356C(&this->dyna) && (playerCentroidDist > 3.0f)) {
|
||||
Math_Vec3f_Diff(&playerCentroidDiff, &surfaceNormalHorizontal, &playerMoment);
|
||||
BgSpot08Iceblock_MultVectorScalar(&playerMoment, &playerMoment,
|
||||
(sInertias[rollDataIndex] * playerCentroidDist) / this->dyna.actor.scale.x);
|
||||
} else {
|
||||
playerMoment = sZeroVector;
|
||||
}
|
||||
|
||||
BgSpot08Iceblock_MultVectorScalar(&surfaceNormalHorizontalScaled, &surfaceNormalHorizontal, -0.01f);
|
||||
|
||||
// Add all three deviations
|
||||
Math_Vec3f_Sum(&this->normalDelta, &playerMoment, &this->normalDelta);
|
||||
Math_Vec3f_Sum(&this->normalDelta, &surfaceNormalHorizontalScaled, &this->normalDelta);
|
||||
Math_Vec3f_Sum(&this->normalDelta, &randomNutation, &this->normalDelta);
|
||||
|
||||
this->normalDelta.y = 0.0f;
|
||||
|
||||
Math_Vec3f_Sum(&this->surfaceNormal, &this->normalDelta, &tempVec);
|
||||
|
||||
tempVec.x *= sDampingFactors[rollDataIndex];
|
||||
tempVec.z *= sDampingFactors[rollDataIndex];
|
||||
|
||||
// Set up roll axis and final new angle
|
||||
if (BgSpot08Iceblock_NormalizeVector(&this->surfaceNormal, &tempVec)) {
|
||||
deviationFromVertSq = Math3D_Dist1DSq(this->surfaceNormal.z, this->surfaceNormal.x);
|
||||
|
||||
// Prevent overrolling
|
||||
if (sRollSins[rollDataIndex] < deviationFromVertSq) {
|
||||
stabilityCorrection = sRollSins[rollDataIndex] / deviationFromVertSq;
|
||||
|
||||
this->surfaceNormal.x *= stabilityCorrection;
|
||||
this->surfaceNormal.y = sRollCoss[rollDataIndex];
|
||||
this->surfaceNormal.z *= stabilityCorrection;
|
||||
}
|
||||
|
||||
BgSpot08Iceblock_CrossProduct(&tempVec, &sVerticalVector, &this->surfaceNormal);
|
||||
|
||||
if (BgSpot08Iceblock_NormalizeVector(&torqueDirection, &tempVec)) {
|
||||
this->rotationAxis = torqueDirection;
|
||||
}
|
||||
} else {
|
||||
this->surfaceNormal = sVerticalVector;
|
||||
}
|
||||
|
||||
// Rotation by the angle between surfaceNormal and the vertical about rotationAxis
|
||||
func_800D23FC(Math_FAcosF(Math3D_Cos(&sVerticalVector, &this->surfaceNormal)), &this->rotationAxis, MTXMODE_NEW);
|
||||
Matrix_RotateY(this->dyna.actor.shape.rot.y * (M_PI / 32768), MTXMODE_APPLY);
|
||||
Matrix_Get(&mtx);
|
||||
func_800D20CC(&mtx, &this->dyna.actor.shape.rot, MTXMODE_NEW);
|
||||
}
|
||||
|
||||
void BgSpot08Iceblock_SpawnTwinFloe(BgSpot08Iceblock* this, GlobalContext* globalCtx) {
|
||||
s32 pad[2];
|
||||
f32 sin;
|
||||
f32 cos;
|
||||
|
||||
sin = Math_SinS(this->dyna.actor.home.rot.y) * 100.0f;
|
||||
cos = Math_CosS(this->dyna.actor.home.rot.y) * 100.0f;
|
||||
|
||||
if (!(this->dyna.actor.params & 0x100)) {
|
||||
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->dyna.actor, globalCtx, ACTOR_BG_SPOT08_ICEBLOCK,
|
||||
this->dyna.actor.home.pos.x, this->dyna.actor.home.pos.y, this->dyna.actor.home.pos.z,
|
||||
this->dyna.actor.home.rot.x, this->dyna.actor.home.rot.y, this->dyna.actor.home.rot.z,
|
||||
0x123);
|
||||
|
||||
this->dyna.actor.world.pos.x += sin;
|
||||
this->dyna.actor.world.pos.z += cos;
|
||||
} else {
|
||||
this->dyna.actor.world.pos.x -= sin;
|
||||
this->dyna.actor.world.pos.z -= cos;
|
||||
}
|
||||
BgSpot08Iceblock_SetupFloatOrbitingTwins(this);
|
||||
}
|
||||
|
||||
static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_F32(uncullZoneForward, 3000, ICHAIN_CONTINUE),
|
||||
ICHAIN_F32(uncullZoneScale, 1000, ICHAIN_CONTINUE),
|
||||
ICHAIN_F32(uncullZoneDownward, 2200, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
void BgSpot08Iceblock_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
BgSpot08Iceblock* this = THIS;
|
||||
CollisionHeader* colHeader;
|
||||
|
||||
// spot08 ice floe
|
||||
osSyncPrintf("(spot08 流氷)(arg_data 0x%04x)\n", this->dyna.actor.params);
|
||||
BgSpot08Iceblock_CheckParams(this);
|
||||
|
||||
switch (this->dyna.actor.params & 0x200) {
|
||||
case 0:
|
||||
colHeader = &D_06002FD8;
|
||||
break;
|
||||
case 0x200:
|
||||
colHeader = &D_06001904;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (this->dyna.actor.params & 0xF) {
|
||||
case 2:
|
||||
case 3:
|
||||
BgSpot08Iceblock_InitDynaPoly(this, globalCtx, colHeader, DPM_UNK3);
|
||||
break;
|
||||
default:
|
||||
BgSpot08Iceblock_InitDynaPoly(this, globalCtx, colHeader, DPM_UNK);
|
||||
break;
|
||||
}
|
||||
|
||||
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
|
||||
Actor_Kill(&this->dyna.actor);
|
||||
return;
|
||||
}
|
||||
|
||||
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
|
||||
|
||||
switch (this->dyna.actor.params & 0xF0) {
|
||||
case 0:
|
||||
Actor_SetScale(&this->dyna.actor, 0.2f);
|
||||
break;
|
||||
case 0x10:
|
||||
Actor_SetScale(&this->dyna.actor, 0.1f);
|
||||
break;
|
||||
case 0x20:
|
||||
Actor_SetScale(&this->dyna.actor, 0.05f);
|
||||
break;
|
||||
}
|
||||
|
||||
this->bobPhaseSlow = (s32)(Rand_ZeroOne() * 65535.5f);
|
||||
this->bobPhaseFast = (s32)(Rand_ZeroOne() * 65535.5f);
|
||||
this->surfaceNormal.y = 1.0f;
|
||||
this->rotationAxis.x = 1.0f;
|
||||
|
||||
switch (this->dyna.actor.params & 0xF) {
|
||||
case 0:
|
||||
case 1:
|
||||
BgSpot08Iceblock_SetupFloatNonrotating(this);
|
||||
break;
|
||||
case 2:
|
||||
BgSpot08Iceblock_SetupFloatRotating(this);
|
||||
break;
|
||||
case 3:
|
||||
BgSpot08Iceblock_SpawnTwinFloe(this, globalCtx);
|
||||
break;
|
||||
case 4:
|
||||
BgSpot08Iceblock_SetupNoAction(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BgSpot08Iceblock_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
BgSpot08Iceblock* this = THIS;
|
||||
|
||||
DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
|
||||
}
|
||||
|
||||
void BgSpot08Iceblock_SetupFloatNonrotating(BgSpot08Iceblock* this) {
|
||||
BgSpot08Iceblock_SetupAction(this, BgSpot08Iceblock_FloatNonrotating);
|
||||
}
|
||||
|
||||
void BgSpot08Iceblock_FloatNonrotating(BgSpot08Iceblock* this, GlobalContext* globalCtx) {
|
||||
BgSpot08Iceblock_Bobbing(this);
|
||||
BgSpot08Iceblock_SinkUnderPlayer(this);
|
||||
BgSpot08Iceblock_SetWaterline(this);
|
||||
this->dyna.actor.shape.rot.y = this->dyna.actor.home.rot.y;
|
||||
BgSpot08Iceblock_Roll(this, globalCtx);
|
||||
}
|
||||
|
||||
void BgSpot08Iceblock_SetupFloatRotating(BgSpot08Iceblock* this) {
|
||||
BgSpot08Iceblock_SetupAction(this, BgSpot08Iceblock_FloatRotating);
|
||||
}
|
||||
|
||||
void BgSpot08Iceblock_FloatRotating(BgSpot08Iceblock* this, GlobalContext* globalCtx) {
|
||||
BgSpot08Iceblock_Bobbing(this);
|
||||
BgSpot08Iceblock_SinkUnderPlayer(this);
|
||||
BgSpot08Iceblock_SetWaterline(this);
|
||||
this->dyna.actor.world.rot.y = this->dyna.actor.world.rot.y + 0x190;
|
||||
this->dyna.actor.shape.rot.y = this->dyna.actor.world.rot.y;
|
||||
BgSpot08Iceblock_Roll(this, globalCtx);
|
||||
}
|
||||
|
||||
void BgSpot08Iceblock_SetupFloatOrbitingTwins(BgSpot08Iceblock* this) {
|
||||
BgSpot08Iceblock_SetupAction(this, BgSpot08Iceblock_FloatOrbitingTwins);
|
||||
}
|
||||
|
||||
void BgSpot08Iceblock_FloatOrbitingTwins(BgSpot08Iceblock* this, GlobalContext* globalCtx) {
|
||||
f32 cos;
|
||||
f32 sin;
|
||||
|
||||
BgSpot08Iceblock_Bobbing(this);
|
||||
BgSpot08Iceblock_SinkUnderPlayer(this);
|
||||
BgSpot08Iceblock_SetWaterline(this);
|
||||
|
||||
// parent handles rotations of both
|
||||
if (!(this->dyna.actor.params & 0x100)) {
|
||||
this->dyna.actor.world.rot.y += 0x190;
|
||||
sin = Math_SinS(this->dyna.actor.world.rot.y) * 100.0f;
|
||||
cos = Math_CosS(this->dyna.actor.world.rot.y) * 100.0f;
|
||||
|
||||
this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x + sin;
|
||||
this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z + cos;
|
||||
|
||||
if (this->dyna.actor.child != NULL) {
|
||||
this->dyna.actor.child->world.pos.x = this->dyna.actor.home.pos.x - sin;
|
||||
this->dyna.actor.child->world.pos.z = this->dyna.actor.home.pos.z - cos;
|
||||
}
|
||||
}
|
||||
|
||||
this->dyna.actor.shape.rot.y = this->dyna.actor.home.rot.y;
|
||||
BgSpot08Iceblock_Roll(this, globalCtx);
|
||||
}
|
||||
|
||||
void BgSpot08Iceblock_SetupNoAction(BgSpot08Iceblock* this) {
|
||||
BgSpot08Iceblock_SetupAction(this, NULL);
|
||||
}
|
||||
|
||||
void BgSpot08Iceblock_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
BgSpot08Iceblock* this = THIS;
|
||||
|
||||
if (Rand_ZeroOne() < 0.05f) {
|
||||
this->bobIncrSlow = Rand_S16Offset(300, 100);
|
||||
this->bobIncrFast = Rand_S16Offset(800, 400);
|
||||
}
|
||||
|
||||
this->bobPhaseSlow += this->bobIncrSlow;
|
||||
this->bobPhaseFast += this->bobIncrFast;
|
||||
if (this->actionFunc != NULL) {
|
||||
this->actionFunc(this, globalCtx);
|
||||
}
|
||||
}
|
||||
|
||||
void BgSpot08Iceblock_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
Gfx* dList;
|
||||
BgSpot08Iceblock* this = THIS;
|
||||
|
||||
switch (this->dyna.actor.params & 0x200) {
|
||||
case 0:
|
||||
dList = D_06002BD0;
|
||||
break;
|
||||
case 0x200:
|
||||
dList = D_06000DE0;
|
||||
break;
|
||||
}
|
||||
|
||||
Gfx_DrawDListOpa(globalCtx, dList);
|
||||
}
|
||||
|
|
|
@ -6,11 +6,49 @@
|
|||
|
||||
struct BgSpot08Iceblock;
|
||||
|
||||
typedef void (*BgSpot08IceblockActionFunc)(struct BgSpot08Iceblock*, GlobalContext*);
|
||||
|
||||
typedef struct BgSpot08Iceblock {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ char unk_14C[0x50];
|
||||
/* 0x0000 */ DynaPolyActor dyna;
|
||||
/* 0x0164 */ BgSpot08IceblockActionFunc actionFunc;
|
||||
/* 0x0168 */ Vec3f surfaceNormal;
|
||||
/* 0x0170 */ Vec3f normalDelta; // y always 0
|
||||
/* 0x0180 */ Vec3f rotationAxis;
|
||||
/* 0x018C */ s16 bobPhaseSlow;
|
||||
/* 0x018E */ s16 bobPhaseFast;
|
||||
/* 0x0190 */ s16 bobIncrSlow;
|
||||
/* 0x0192 */ s16 bobIncrFast;
|
||||
/* 0x0194 */ f32 sinkOffset;
|
||||
/* 0x0198 */ f32 bobOffset;
|
||||
} BgSpot08Iceblock; // size = 0x019C
|
||||
|
||||
extern const ActorInit Bg_Spot08_Iceblock_InitVars;
|
||||
|
||||
// Params
|
||||
/**
|
||||
* 0x200: Shape
|
||||
* 0x200 is the ice ramp where Jabu is as child
|
||||
*/
|
||||
|
||||
/**
|
||||
* 0x100: Twins
|
||||
* 0x100 is the spawned twin platform
|
||||
*/
|
||||
|
||||
/**
|
||||
* 0xF0: Size
|
||||
* 0x00 is large
|
||||
* 0x10 is medium
|
||||
* 0x20 is small
|
||||
*/
|
||||
|
||||
/**
|
||||
* 0xF: Action
|
||||
* 0 Floating, nonrotating
|
||||
* 1 same as 0, but does not roll as much (?)
|
||||
* 2 Floating, rotating
|
||||
* 3 Floating orbiting twins
|
||||
* 4 Completely static, does nothing
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue