1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-08-07 23:10:22 +00:00

ovl_En_Goroiwa OK (#376)

* merge upstream

* Merge upstream

* Add block comment to c

* EnGoroiwa_Init

* Remove casts in EnGoroiwa_Init

* Matched named functions

* Add one prototype

* func_80A4BD04

* func_80A4BCA0

* func_80A4BD70 and fix incompatible pointer

* func_80A4BD8C and func_80A4BE54

* Remove forward declaration

* Order variable by address

* Cleanup warnings

* func_80A4C188

* Remove func_80A4C188 forward declaration

* Progress

* Rename unk_1CE to waypoint

* func_80A4C264

* func_80A4D5E0

* func_80A4C27C

* Separate necessary forward declarations from temporary

* func_80A4BE10

* func_80A4C080

* func_80A4C134 and func_80A4C164

* func_80A4D074

* Work on some (nonmatching)

* func_80A4D944

* func_80A4D9DC

* Progress

* func_80A4DB90 and func_80A4DC00

* func_80A4D8CC

* func_80A4CA50

* func_80A4C6C8

* work on func_80A4CED8

* Work on func_80A4CED8

* func_80A4CED8

* Use temp to avoid unused error

* Clarify comment

* Work on func_80A4C3A4

* func_80A4C3A4

* Clarify comment better

* func_80A4C594

* Angles

* Improve regalloc

* func_80A4BF28

* Cleanup point access

* Work on func_80A4C814

* func_80A4C814

* Use *=

* Work on func_80A4CB78

* Work on func_80A4D0FC

* Work on func_80A4CB78

* More on func_80A4CB78

* Implement dubious permuter suggestion

* Make janky hack less janky

* Update issue comment

* Move ptr func_80A4CB78

* func_80A4CB78

* Cleanup func_80A4CB78

* Various cleanup

* Add undefined sym

* Work on func_80A4D0FC

* Work more on func_80A4D0FC

* Work on func_80A4D624

* func_80A4D0FC

* Work on func_80A4D624

* Fix stack

* Wrap in NON_MATCHING ifdef to remember which function is not done

* Collapse goto

* Use -- for unk_1C4

* Collapse else if

* Add translation for 'Player ぶっ飛ばし'

* func_80A4D624

* Migrate data section

* Clang format

* Actually add unused note

* Name timers accordingly

* Remove & from sInitChain

* Give timer descriptive names

* Rename idleTimer to waitTimer

* Rename to sWaitDurations

* Name effect data

* Add s prefix (oops)

* Move some data into functions

* Rename params for func_80029E8C

* Unify whitespace for bool returns

* Name colliderHeightOffset

* Name duplicate of colliderHeightOffset and clang format everything

* Reorder vector assignments

* Rename params to pathIdx

* Rename temp to yawDiff

* Add 'f's because floating point

* Name a lot of stuff

* Name posDiff

* Nuke the bool

* Remove unnecessary return

Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>

* Remove useless forward declarations and use list[0]

* Clang format again

* Use switch statement

* Use hex for normalizing angle

* Use hex because angle

* Small fixes

* Small fixes

* Move function arrays out of function

* Correct colliderItems

* Don't separate static vars from others

* Clang format

Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
This commit is contained in:
Sirius902 2020-09-28 03:03:39 -07:00 committed by GitHub
parent 83fc21fea6
commit 00fb26a441
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 695 additions and 2546 deletions

View file

@ -1,15 +1,36 @@
/*
* File: z_en_goroiwa.c
* Overlay: ovl_En_Goroiwa
* Description: Rolling boulders
*/
#include "z_en_goroiwa.h"
#include <vt.h>
#define FLAGS 0x00000010
#define THIS ((EnGoroiwa*)thisx)
typedef s32 (*EnGoroiwaUnkFunc1)(EnGoroiwa* this, GlobalContext* globalCtx);
typedef void (*EnGoroiwaUnkFunc2)(EnGoroiwa* this);
void EnGoroiwa_Init(Actor* thisx, GlobalContext* globalCtx);
void EnGoroiwa_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnGoroiwa_Update(Actor* thisx, GlobalContext* globalCtx);
void EnGoroiwa_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void func_80A4D5E0(EnGoroiwa* this);
void func_80A4D624(EnGoroiwa* this, GlobalContext* globalCtx);
void func_80A4D8CC(EnGoroiwa* this);
void func_80A4D944(EnGoroiwa* this, GlobalContext* globalCtx);
void func_80A4D9DC(EnGoroiwa* this);
void func_80A4DA3C(EnGoroiwa* this, GlobalContext* globalCtx);
void func_80A4DA7C(EnGoroiwa* this);
void func_80A4DAD0(EnGoroiwa* this, GlobalContext* globalCtx);
void func_80A4DB90(EnGoroiwa* this);
void func_80A4DC00(EnGoroiwa* this, GlobalContext* globalCtx);
const ActorInit En_Goroiwa_InitVars = {
ACTOR_EN_GOROIWA,
ACTORTYPE_PROP,
@ -21,77 +42,690 @@ const ActorInit En_Goroiwa_InitVars = {
(ActorFunc)EnGoroiwa_Update,
(ActorFunc)EnGoroiwa_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4BCA0.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4BD04.s")
static ColliderJntSphItemInit sJntSphItemsInit[] = {
{
{ 0x00, { 0x20000000, 0x00, 0x04 }, { 0x00000000, 0x00, 0x00 }, 0x01, 0x00, 0x01 },
{ 0, { { 0, 0, 0 }, 58 }, 100 },
},
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4BD70.s")
static ColliderJntSphInit sJntSphInit = {
{ COLTYPE_UNK10, 0x11, 0x00, 0x39, 0x20, COLSHAPE_JNTSPH },
1,
sJntSphItemsInit,
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4BD8C.s")
static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 60, 254 };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4BE10.s")
// Unused
static f32 D_80A4DEBC[] = { 10.0f, 9.2f };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4BE54.s")
extern Gfx D_0400D340[];
extern Gfx D_060006B0[];
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4BF28.s")
void func_80A4BCA0(EnGoroiwa* this) {
static f32 colliderHeightOffset[] = { 0.0f, 59.5f };
Sphere16* worldSphere = &this->collider.list[0].dim.worldSphere;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4C080.s")
worldSphere->center.x = this->actor.posRot.pos.x;
worldSphere->center.y = this->actor.posRot.pos.y + colliderHeightOffset[(this->actor.params >> 10) & 1];
worldSphere->center.z = this->actor.posRot.pos.z;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4C134.s")
void func_80A4BD04(EnGoroiwa* this, GlobalContext* globalCtx) {
s32 pad;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4C164.s")
Collider_InitJntSph(globalCtx, &this->collider);
Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderItems);
func_80A4BCA0(this);
this->collider.list[0].dim.worldSphere.radius = 58;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4C188.s")
void func_80A4BD70(EnGoroiwa* this, u8 arg1) {
this->unk_1D3 &= ~3;
this->unk_1D3 |= arg1;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4C1C4.s")
s32 EnGoroiwa_Vec3fNormalize(Vec3f* ret, Vec3f* a) {
f32 magnitude = Math3D_Vec3fMagnitude(a);
f32 scale;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4C264.s")
if (magnitude < 0.001f) {
return false;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4C27C.s")
scale = 1.0f / magnitude;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4C3A4.s")
ret->x = a->x * scale;
ret->y = a->y * scale;
ret->z = a->z * scale;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4C594.s")
return true;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4C6C8.s")
void EnGoroiwa_SetSpeed(EnGoroiwa* this, GlobalContext* globalCtx) {
if (globalCtx->sceneNum == SCENE_SPOT04) {
this->isInKokiri = true;
mREG(12) = 920;
} else {
this->isInKokiri = false;
mREG(12) = 1000;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4C814.s")
void func_80A4BE54(EnGoroiwa* this, GlobalContext* globalCtx) {
Path* path = &globalCtx->setupPathList[this->actor.params & 0xFF];
Vec3s* nextPos = (Vec3s*)SEGMENTED_TO_VIRTUAL(path->points) + this->nextWaypoint;
Vec3f nextPosF;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4CA50.s")
nextPosF.x = nextPos->x;
nextPosF.y = nextPos->y;
nextPosF.z = nextPos->z;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4CB78.s")
this->actor.posRot.rot.y = Math_Vec3f_Yaw(&this->actor.posRot.pos, &nextPosF);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4CED8.s")
void func_80A4BF28(EnGoroiwa* this, GlobalContext* globalCtx, Vec3f* arg2) {
s16 temp_v0 = (this->actor.params >> 8) & 3;
Path* path = &globalCtx->setupPathList[this->actor.params & 0xFF];
s16 temp_t0 = this->currentWaypoint - this->pathDirection;
Vec3s* pointPos;
Vec3s* currentPointPos;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4D074.s")
if (temp_t0 < 0) {
if (temp_v0 == 0 || temp_v0 == 1) {
temp_t0 = this->endWaypoint;
} else if (temp_v0 == 3) {
temp_t0 = 1;
}
} else if (this->endWaypoint < temp_t0) {
if (temp_v0 == 0 || temp_v0 == 1) {
temp_t0 = 0;
} else if (temp_v0 == 3) {
temp_t0 = this->endWaypoint - 1;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4D0FC.s")
currentPointPos = (Vec3s*)SEGMENTED_TO_VIRTUAL(path->points) + this->currentWaypoint;
pointPos = (Vec3s*)SEGMENTED_TO_VIRTUAL(path->points) + temp_t0;
arg2->x = currentPointPos->x - pointPos->x;
arg2->y = currentPointPos->x - pointPos->y;
arg2->z = currentPointPos->x - pointPos->z;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/EnGoroiwa_Init.s")
void func_80A4C080(EnGoroiwa* this) {
s16 temp_v0 = (this->actor.params >> 8) & 3;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/EnGoroiwa_Destroy.s")
if (this->nextWaypoint < 0) {
if (temp_v0 == 0 || temp_v0 == 1) {
this->currentWaypoint = this->endWaypoint;
this->nextWaypoint = this->endWaypoint - 1;
this->pathDirection = -1;
} else if (temp_v0 == 3) {
this->currentWaypoint = 0;
this->nextWaypoint = 1;
this->pathDirection = 1;
}
} else if (this->nextWaypoint > this->endWaypoint) {
if (temp_v0 == 0 || temp_v0 == 1) {
this->currentWaypoint = 0;
this->nextWaypoint = 1;
this->pathDirection = 1;
} else if (temp_v0 == 3) {
this->currentWaypoint = this->endWaypoint;
this->nextWaypoint = this->endWaypoint - 1;
this->pathDirection = -1;
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4D5E0.s")
void func_80A4C134(EnGoroiwa* this) {
this->currentWaypoint = this->nextWaypoint;
this->nextWaypoint += this->pathDirection;
func_80A4C080(this);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4D624.s")
void func_80A4C164(EnGoroiwa* this) {
this->pathDirection *= -1;
this->currentWaypoint = this->nextWaypoint;
this->nextWaypoint += this->pathDirection;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4D8CC.s")
void func_80A4C188(EnGoroiwa* this, GlobalContext* globalCtx) {
this->endWaypoint = globalCtx->setupPathList[this->actor.params & 0xFF].count - 1;
this->currentWaypoint = 0;
this->nextWaypoint = 1;
this->pathDirection = 1;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4D944.s")
void func_80A4C1C4(EnGoroiwa* this, GlobalContext* globalCtx, s32 waypoint) {
Path* path = &globalCtx->setupPathList[this->actor.params & 0xFF];
Vec3s* pointPos = (Vec3s*)SEGMENTED_TO_VIRTUAL(path->points) + waypoint;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4D9DC.s")
this->actor.posRot.pos.x = pointPos->x;
this->actor.posRot.pos.y = pointPos->y;
this->actor.posRot.pos.z = pointPos->z;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4DA3C.s")
void func_80A4C264(EnGoroiwa* this) {
this->unk_1B0.x = 1.0f;
this->unk_1C0 = 1.0f;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4DA7C.s")
s32 func_80A4C27C(EnGoroiwa* this, GlobalContext* globalCtx) {
s32 pad;
Path* path = &globalCtx->setupPathList[this->actor.params & 0xFF];
Vec3s* nextPointPos = (Vec3s*)SEGMENTED_TO_VIRTUAL(path->points) + this->nextWaypoint;
Vec3s* currentPointPos = (Vec3s*)SEGMENTED_TO_VIRTUAL(path->points) + this->currentWaypoint;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4DAD0.s")
if (nextPointPos->x == currentPointPos->x && nextPointPos->z == currentPointPos->z) {
if (nextPointPos->y == currentPointPos->y) {
// Translation: Error: Invalid path data (points overlap)
osSyncPrintf("Error : レールデータ不正(点が重なっている)");
osSyncPrintf("(%s %d)(arg_data 0x%04x)\n", "../z_en_gr.c", 559, this->actor.params);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4DB90.s")
if (nextPointPos->y > currentPointPos->y) {
return 1;
} else {
return -1;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/func_80A4DC00.s")
return 0;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/EnGoroiwa_Update.s")
void func_80A4C3A4(GlobalContext* globalCtx, Vec3f* arg1) {
static Vec3f effectVelocity = { 0.0f, 0.0f, 0.0f };
static Vec3f effectAccel = { 0.0f, 0.3f, 0.0f };
Vec3f effectPos;
s32 i;
s16 angle = 0;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Goroiwa/EnGoroiwa_Draw.s")
for (i = 0; i < 8; i++) {
angle += 0x4E20;
effectPos.x = arg1->x + ((47.0f * ((Math_Rand_ZeroOne() * 0.5f) + 0.5f)) * Math_Sins(angle));
effectPos.y = arg1->y + ((Math_Rand_ZeroOne() - 0.5f) * 40.0f);
effectPos.z = arg1->z + ((47.0f * ((Math_Rand_ZeroOne() * 0.5f) + 0.5f))) * Math_Coss(angle);
func_800286CC(globalCtx, &effectPos, &effectVelocity, &effectAccel, (s16)(Math_Rand_ZeroOne() * 30.0f) + 100,
80);
func_800286CC(globalCtx, &effectPos, &effectVelocity, &effectAccel, (s16)(Math_Rand_ZeroOne() * 20.0f) + 80,
80);
}
}
void func_80A4C594(GlobalContext* globalCtx, Vec3f* arg1) {
Vec3f sp4C;
s32 i;
s16 angle = 0;
for (i = 0; i < 11; i++) {
angle += 0x1746;
sp4C.x = arg1->x + (Math_Sins(angle) * 55.0f);
sp4C.y = arg1->y;
sp4C.z = arg1->z + (Math_Coss(angle) * 55.0f);
func_8002949C(globalCtx, &sp4C, 0, 0, 0, 350);
}
func_80029444(globalCtx, arg1, 300, 700, 0);
func_80029444(globalCtx, arg1, 500, 900, 4);
func_80029444(globalCtx, arg1, 500, 1300, 8);
}
s32 func_80A4C6C8(EnGoroiwa* this, GlobalContext* globalCtx) {
Path* path;
s32 result;
s32 pad;
Vec3s* nextPointPos;
Math_ApproxF(&this->actor.speedXZ, mREG(12) * 0.01f, 0.3f);
func_8002D868(&this->actor);
path = &globalCtx->setupPathList[this->actor.params & 0xFF];
nextPointPos = (Vec3s*)SEGMENTED_TO_VIRTUAL(path->points) + this->nextWaypoint;
result = Math_ApproxF(&this->actor.posRot.pos.x, nextPointPos->x, fabsf(this->actor.velocity.x)) & 1;
result &= Math_ApproxF(&this->actor.posRot.pos.z, nextPointPos->z, fabsf(this->actor.velocity.z));
this->actor.posRot.pos.y += this->actor.velocity.y;
return result;
}
s32 func_80A4C814(EnGoroiwa* this, GlobalContext* globalCtx) {
Path* path = &globalCtx->setupPathList[this->actor.params & 0xFF];
s32 pad;
Vec3s* nextPointPos = (Vec3s*)SEGMENTED_TO_VIRTUAL(path->points) + this->nextWaypoint;
Vec3s* currentPointPos = (Vec3s*)SEGMENTED_TO_VIRTUAL(path->points) + this->currentWaypoint;
s32 result;
Vec3f posDiff;
Vec3f nextPointPosF;
nextPointPosF.x = nextPointPos->x;
nextPointPosF.y = nextPointPos->y;
nextPointPosF.z = nextPointPos->z;
Math_ApproxF(&this->actor.speedXZ, mREG(12) * 0.01f, 0.3f);
if (Math3D_Vec3fDistSq(&nextPointPosF, &this->actor.posRot.pos) < 25.0f) {
Math_Vec3f_Diff(&nextPointPosF, &this->actor.posRot.pos, &posDiff);
} else {
posDiff.x = nextPointPosF.x - currentPointPos->x;
posDiff.y = nextPointPosF.y - currentPointPos->y;
posDiff.z = nextPointPosF.z - currentPointPos->z;
}
EnGoroiwa_Vec3fNormalize(&this->actor.velocity, &posDiff);
this->actor.velocity.x *= this->actor.speedXZ;
this->actor.velocity.y *= this->actor.speedXZ;
this->actor.velocity.z *= this->actor.speedXZ;
result = Math_ApproxF(&this->actor.posRot.pos.x, nextPointPosF.x, fabsf(this->actor.velocity.x)) & 1;
result &= Math_ApproxF(&this->actor.posRot.pos.y, nextPointPosF.y, fabsf(this->actor.velocity.y));
result &= Math_ApproxF(&this->actor.posRot.pos.z, nextPointPosF.z, fabsf(this->actor.velocity.z));
return result;
}
s32 func_80A4CA50(EnGoroiwa* this, GlobalContext* globalCtx) {
s32 pad;
Path* path = &globalCtx->setupPathList[this->actor.params & 0xFF];
Vec3s* nextPointPos = (Vec3s*)SEGMENTED_TO_VIRTUAL(path->points) + this->nextWaypoint;
Math_ApproxF(&this->actor.velocity.y, (mREG(12) * 0.01f) * 0.5f, 0.18f);
this->actor.posRot.pos.x = nextPointPos->x;
this->actor.posRot.pos.z = nextPointPos->z;
return Math_ApproxF(&this->actor.posRot.pos.y, nextPointPos->y, fabsf(this->actor.velocity.y));
}
s32 func_80A4CB78(EnGoroiwa* this, GlobalContext* globalCtx) {
s32 pad;
Path* path = &globalCtx->setupPathList[this->actor.params & 0xFF];
Vec3s* nextPointPos = (Vec3s*)SEGMENTED_TO_VIRTUAL(path->points) + this->nextWaypoint;
f32 nextPointY;
f32 thisY;
f32 temp;
s32 quakeIdx;
CollisionPoly* sp68;
Vec3f sp5C;
f32 temp_f0_2;
s32 pad2;
u32 sp50;
Vec3f sp44;
WaterBox* waterBox;
f32 ySurface;
Vec3f sp30;
nextPointY = nextPointPos->y;
Math_ApproxF(&this->actor.velocity.y, -14.0f, 1.0f);
this->actor.posRot.pos.x = nextPointPos->x;
this->actor.posRot.pos.z = nextPointPos->z;
thisY = this->actor.posRot.pos.y;
if (1) {}
this->actor.posRot.pos.y += this->actor.velocity.y;
if (this->actor.velocity.y < 0.0f && this->actor.posRot.pos.y <= nextPointY) {
if (this->unk_1C6 == 0) {
if (this->actor.xzDistFromLink < 600.0f) {
quakeIdx = Quake_Add(ACTIVE_CAM, 3);
Quake_SetSpeed(quakeIdx, -0x3CB0);
Quake_SetQuakeValues(quakeIdx, 3, 0, 0, 0);
Quake_SetCountdown(quakeIdx, 7);
}
this->unk_1C0 = 0.0f;
if (!(this->unk_1D3 & 0x10)) {
sp5C.x = this->actor.posRot.pos.x;
sp5C.y = this->actor.posRot.pos.y + 50.0f;
sp5C.z = this->actor.posRot.pos.z;
temp_f0_2 = func_8003CA0C(globalCtx, &globalCtx->colCtx, &sp68, &sp50, &this->actor, &sp5C);
// temp needed to match
temp = temp_f0_2 - (this->actor.posRot.pos.y - 59.5f);
if (fabsf(temp) < 15.0f) {
sp44.x = this->actor.posRot.pos.x;
sp44.y = temp_f0_2 + 10.0f;
sp44.z = this->actor.posRot.pos.z;
func_80A4C3A4(globalCtx, &sp44);
}
}
}
if (this->unk_1C6 > 0) {
return true;
}
this->unk_1C6 += 1;
this->actor.velocity.y *= -0.3f;
this->actor.posRot.pos.y = nextPointY - ((this->actor.posRot.pos.y - nextPointY) * 0.3f);
}
if (this->unk_1C6 == 0 &&
func_80042244(globalCtx, &globalCtx->colCtx, this->actor.posRot.pos.x, this->actor.posRot.pos.z, &ySurface,
&waterBox) &&
this->actor.posRot.pos.y <= ySurface) {
this->unk_1D3 |= 0x10;
if (ySurface < thisY) {
sp30.x = this->actor.posRot.pos.x;
sp30.y = ySurface;
sp30.z = this->actor.posRot.pos.z;
func_80A4C594(globalCtx, &sp30);
this->actor.velocity.y *= 0.2f;
}
if (this->actor.velocity.y < -8.0f) {
this->actor.velocity.y = -8.0f;
}
}
return false;
}
void func_80A4CED8(EnGoroiwa* this, GlobalContext* globalCtx) {
static Vec3f unitY = { 0.0f, 1.0f, 0.0f };
s32 pad;
Vec3f* temp;
f32 sp8C;
Vec3f sp80;
Vec3f sp74;
MtxF mtx;
Vec3f sp28;
if (this->unk_1D3 & 8) {
sp8C = this->unk_1BC;
} else {
this->unk_1BC = Math3D_Vec3f_DistXYZ(&this->actor.posRot.pos, &this->actor.pos4) * 0.016806724f;
sp8C = this->unk_1BC;
}
sp8C *= this->unk_1C0;
// temp assignment needed to match
temp = &sp80;
if (this->unk_1D3 & 8) {
func_80A4BF28(this, globalCtx, &sp28);
Math3D_Vec3f_Cross(&unitY, &this->actor.velocity, temp);
} else {
Math3D_Vec3f_Cross(&unitY, &this->actor.velocity, temp);
}
if (EnGoroiwa_Vec3fNormalize(&sp74, temp)) {
this->unk_1B0 = sp74;
} else {
sp74 = this->unk_1B0;
}
func_800D23FC(sp8C, &sp74, 0);
Matrix_RotateY(this->actor.shape.rot.y * (2.0f * M_PI / 0x10000), 1);
Matrix_RotateX(this->actor.shape.rot.x * (2.0f * M_PI / 0x10000), 1);
Matrix_RotateZ(this->actor.shape.rot.z * (2.0f * M_PI / 0x10000), 1);
Matrix_Get(&mtx);
func_800D20CC(&mtx, &this->actor.shape.rot, 0);
}
void func_80A4D074(EnGoroiwa* this, GlobalContext* globalCtx) {
s16 temp_v0 = (this->actor.params >> 8) & 3;
func_80A4C134(this);
if (temp_v0 == 0 || temp_v0 == 1) {
if (this->currentWaypoint == 0 || this->currentWaypoint == this->endWaypoint) {
func_80A4C1C4(this, globalCtx, this->currentWaypoint);
}
}
func_80A4BE54(this, globalCtx);
}
void func_80A4D0FC(EnGoroiwa* this, GlobalContext* globalCtx) {
static f32 colliderHeightOffset[] = { 0.0f, 59.5f };
s16 angle1;
s16 angle2;
s32 pad;
Vec3f* thisPos = &this->actor.posRot.pos;
Vec3f effectPos;
Vec3f effectVelocity;
f32 temp_f24;
f32 temp_f22;
f32 temp_f20;
f32 temp_f20_2;
s16 temp_v0 = (this->actor.params >> 10) & 1;
s32 i;
for (i = 0, angle1 = 0; i < 16; i++, angle1 += 0x4E20) {
temp_f22 = Math_Sins(angle1);
temp_f24 = Math_Coss(angle1);
angle2 = Math_Rand_ZeroOne() * 0xFFFF;
effectPos.x = ((Math_Rand_ZeroOne() * 50.0f) * temp_f22) * Math_Sins(angle2);
temp_f20_2 = Math_Sins(angle2);
effectPos.y = (((Math_Rand_ZeroOne() - 0.5f) * 100.0f) * temp_f20_2) + colliderHeightOffset[temp_v0];
effectPos.z = ((Math_Rand_ZeroOne() * 50.0f) * temp_f24) * Math_Sins(angle2);
effectVelocity.x = effectPos.x * 0.2f;
effectVelocity.y = (Math_Rand_ZeroOne() * 15.0f) + 2.0f;
effectVelocity.z = effectPos.z * 0.2f;
Math_Vec3f_Sum(&effectPos, thisPos, &effectPos);
func_80029E8C(globalCtx, &effectPos, &effectVelocity, &effectPos, -340, 33, 28, 2, 0,
(Math_Rand_ZeroOne() * 7.0f) + 1.0f, 1, 0, 70, -1, 1, D_0400D340);
}
effectPos.x = thisPos->x;
effectPos.y = thisPos->y + colliderHeightOffset[temp_v0];
effectPos.z = thisPos->z;
func_80033480(globalCtx, &effectPos, 80.0f, 5, 70, 110, 1);
func_80033480(globalCtx, &effectPos, 90.0f, 5, 110, 160, 1);
}
static InitChainEntry sInitChain[] = {
ICHAIN_F32_DIV1000(gravity, -860, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(minVelocityY, -15000, ICHAIN_CONTINUE),
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1500, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 150, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 1500, ICHAIN_STOP),
};
void EnGoroiwa_Init(Actor* thisx, GlobalContext* globalCtx) {
static f32 D_80A4DF10[] = { 0.0f, 595.0f };
EnGoroiwa* this = THIS;
s32 pathIdx;
Actor_ProcessInitChain(&this->actor, sInitChain);
func_80A4BD04(this, globalCtx);
pathIdx = this->actor.params & 0xFF;
if (pathIdx == 0xFF) {
// Translation: Error: Invalid arg_data
osSyncPrintf(" : arg_data が不正(%s %d)(arg_data 0x%04x)\n", "../z_en_gr.c", 1033,
this->actor.params);
Actor_Kill(&this->actor);
return;
}
if (globalCtx->setupPathList[pathIdx].count < 2) {
// Translation: Error: Invalid Path Data
osSyncPrintf(" : レールデータ が不正(%s %d)\n", "../z_en_gr.c", 1043);
Actor_Kill(&this->actor);
return;
}
func_80061ED4(&this->actor.colChkInfo, NULL, &sColChkInfoInit);
ActorShape_Init(&this->actor.shape, D_80A4DF10[(this->actor.params >> 10) & 1], ActorShadow_DrawFunc_Circle, 9.4f);
this->actor.shape.unk_14 = 200;
EnGoroiwa_SetSpeed(this, globalCtx);
func_80A4C188(this, globalCtx);
func_80A4C1C4(this, globalCtx, 0);
func_80A4C264(this);
func_80A4BE54(this, globalCtx);
func_80A4D5E0(this);
// Translation: (Goroiwa)
osSyncPrintf("(ごろ岩)(arg 0x%04x)(rail %d)(end %d)(bgc %d)(hit %d)\n", this->actor.params,
this->actor.params & 0xFF, (this->actor.params >> 8) & 3, (this->actor.params >> 10) & 1,
this->actor.initPosRot.rot.z & 1);
}
void EnGoroiwa_Destroy(Actor* thisx, GlobalContext* globalCtx) {
Collider_DestroyJntSph(globalCtx, &THIS->collider);
}
void func_80A4D5E0(EnGoroiwa* this) {
this->actionFunc = func_80A4D624;
func_80A4BD70(this, 3);
this->unk_1C0 = 1.0f;
}
static EnGoroiwaUnkFunc1 D_80A4DF18[] = { func_80A4C814, func_80A4C6C8 };
static EnGoroiwaUnkFunc2 D_80A4DF20[] = { func_80A4D9DC, func_80A4D8CC };
void func_80A4D624(EnGoroiwa* this, GlobalContext* globalCtx) {
s32 temp_v0_5;
s16 yawDiff;
s16 temp_v1_2;
if (this->collider.base.atFlags & 2) {
this->collider.base.atFlags &= ~2;
this->unk_1D3 &= ~4;
yawDiff = this->actor.yawTowardsLink - this->actor.posRot.rot.y;
if (yawDiff > -0x4000 && yawDiff < 0x4000) {
this->unk_1D3 |= 4;
if ((this->actor.params >> 10) & 1 || (this->actor.initPosRot.rot.z & 1) != 1) {
func_80A4C164(this);
func_80A4BE54(this, globalCtx);
}
}
func_8002F6D4(globalCtx, &this->actor, 2.0f, this->actor.yawTowardsLink, 0.0f, 0);
osSyncPrintf(VT_FGCOL(CYAN));
// Translation: Player knocked down
osSyncPrintf("Player ぶっ飛ばし\n");
osSyncPrintf(VT_RST);
D_80A4DF20[(this->actor.params >> 10) & 1](this);
func_8002F7DC(&PLAYER->actor, NA_SE_PL_BODY_HIT);
if ((this->actor.initPosRot.rot.z & 1) == 1) {
this->collisionTimer = 50;
}
} else if (D_80A4DF18[(this->actor.params >> 10) & 1](this, globalCtx)) {
temp_v1_2 = (this->actor.params >> 8) & 3;
if (temp_v1_2 == 1) {
if (this->nextWaypoint == 0 || this->nextWaypoint == this->endWaypoint) {
func_80A4D0FC(this, globalCtx);
}
}
func_80A4D074(this, globalCtx);
if ((temp_v1_2 == 3) && (this->currentWaypoint == 0 || this->currentWaypoint == this->endWaypoint)) {
func_80A4D9DC(this);
} else if (!((this->actor.params >> 10) & 1) && this->currentWaypoint != 0 &&
this->currentWaypoint != this->endWaypoint) {
temp_v0_5 = func_80A4C27C(this, globalCtx);
if (temp_v0_5 > 0) {
func_80A4DA7C(this);
} else if (temp_v0_5 < 0) {
func_80A4DB90(this);
} else {
func_80A4D5E0(this);
}
} else {
func_80A4D5E0(this);
}
}
Audio_PlayActorSound2(&this->actor, NA_SE_EV_BIGBALL_ROLL - SFX_FLAG);
}
void func_80A4D8CC(EnGoroiwa* this) {
this->actionFunc = func_80A4D944;
func_80A4BD70(this, 2);
this->actor.gravity = -0.86f;
this->actor.minVelocityY = -15.0f;
this->actor.speedXZ *= 0.15f;
this->actor.velocity.y = 5.0f;
this->unk_1C0 = 1.0f;
}
void func_80A4D944(EnGoroiwa* this, GlobalContext* globalCtx) {
func_80A4C6C8(this, globalCtx);
if (this->actor.bgCheckFlags & 1 && this->actor.velocity.y < 0.0f) {
if (this->unk_1D3 & 4 && (this->actor.initPosRot.rot.z & 1) == 1) {
func_80A4C164(this);
func_80A4BE54(this, globalCtx);
}
func_80A4D9DC(this);
}
}
void func_80A4D9DC(EnGoroiwa* this) {
static s16 waitDurations[] = { 20, 6 };
this->actionFunc = func_80A4DA3C;
this->actor.speedXZ = 0.0f;
func_80A4BD70(this, 2);
this->waitTimer = waitDurations[this->actor.initPosRot.rot.z & 1];
this->unk_1C0 = 0.0f;
}
void func_80A4DA3C(EnGoroiwa* this, GlobalContext* globalCtx) {
if (this->waitTimer > 0) {
this->waitTimer--;
} else {
this->collider.base.atFlags &= ~2;
func_80A4D5E0(this);
}
}
void func_80A4DA7C(EnGoroiwa* this) {
this->actionFunc = func_80A4DAD0;
func_80A4BD70(this, 3);
this->unk_1C0 = 0.0f;
this->actor.velocity.y = fabsf(this->actor.speedXZ) * 0.1f;
}
void func_80A4DAD0(EnGoroiwa* this, GlobalContext* globalCtx) {
if (this->collider.base.atFlags & 2) {
this->collider.base.atFlags &= ~2;
func_8002F6D4(globalCtx, &this->actor, 2.0f, this->actor.yawTowardsLink, 0.0f, 4);
func_8002F7DC(&PLAYER->actor, NA_SE_PL_BODY_HIT);
if ((this->actor.initPosRot.rot.z & 1) == 1) {
this->collisionTimer = 50;
}
} else if (func_80A4CA50(this, globalCtx)) {
func_80A4D074(this, globalCtx);
func_80A4D5E0(this);
this->actor.speedXZ = 0.0f;
}
}
void func_80A4DB90(EnGoroiwa* this) {
this->actionFunc = func_80A4DC00;
func_80A4BD70(this, 3);
this->unk_1C0 = 0.3f;
this->unk_1C6 = 0;
this->actor.velocity.y = fabsf(this->actor.speedXZ) * -0.3f;
this->unk_1D3 |= 8;
this->unk_1D3 &= ~0x10;
}
void func_80A4DC00(EnGoroiwa* this, GlobalContext* globalCtx) {
if (this->collider.base.atFlags & 2) {
this->collider.base.atFlags &= ~2;
func_8002F6D4(globalCtx, &this->actor, 2.0f, this->actor.yawTowardsLink, 0.0f, 4);
func_8002F7DC(&PLAYER->actor, NA_SE_PL_BODY_HIT);
if ((this->actor.initPosRot.rot.z & 1) == 1) {
this->collisionTimer = 50;
}
} else if (func_80A4CB78(this, globalCtx)) {
func_80A4D074(this, globalCtx);
func_80A4D5E0(this);
this->unk_1D3 &= ~8;
this->actor.speedXZ = 0.0f;
}
}
void EnGoroiwa_Update(Actor* thisx, GlobalContext* globalCtx) {
EnGoroiwa* this = THIS;
Player* player = PLAYER;
s32 pad;
UNK_TYPE sp30;
if (!(player->stateFlags1 & 0x300000C0)) {
if (this->collisionTimer > 0) {
this->collisionTimer--;
}
this->actionFunc(this, globalCtx);
switch ((this->actor.params >> 10) & 1) {
case 1:
func_8002E4B4(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 0x1C);
break;
case 0:
this->actor.groundY = func_8003C9A4(&globalCtx->colCtx, &this->actor.floorPoly, &sp30, &this->actor,
&this->actor.posRot.pos);
break;
}
func_80A4CED8(this, globalCtx);
if (this->actor.xzDistFromLink < 300.0f) {
func_80A4BCA0(this);
if (this->unk_1D3 & 1 && this->collisionTimer <= 0) {
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
if (this->unk_1D3 & 2 && this->collisionTimer <= 0) {
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
}
}
}
void EnGoroiwa_Draw(Actor* thisx, GlobalContext* globalCtx) {
Gfx_DrawDListOpa(globalCtx, D_060006B0);
}

View file

@ -6,9 +6,25 @@
struct EnGoroiwa;
typedef void (*EnGoroiwaActionFunc)(struct EnGoroiwa*, GlobalContext*);
typedef struct EnGoroiwa {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x88];
/* 0x014C */ EnGoroiwaActionFunc actionFunc;
/* 0x0150 */ ColliderJntSph collider;
/* 0x0170 */ ColliderJntSphItem colliderItems[1];
/* 0x01B0 */ Vec3f unk_1B0;
/* 0x01BC */ f32 unk_1BC;
/* 0x01C0 */ f32 unk_1C0;
/* 0x01C4 */ s16 waitTimer;
/* 0x01C6 */ s16 unk_1C6;
/* 0x01C8 */ s16 collisionTimer;
/* 0x01CA */ s16 endWaypoint;
/* 0x01CC */ s16 currentWaypoint;
/* 0x01CE */ s16 nextWaypoint;
/* 0x01D0 */ s16 pathDirection;
/* 0x01D2 */ u8 isInKokiri;
/* 0x01D3 */ u8 unk_1D3;
} EnGoroiwa; // size = 0x01D4
extern const ActorInit En_Goroiwa_InitVars;