mirror of https://github.com/zeldaret/mm.git
ovl_Obj_Grass_Unit OK and some grass documentation (#1172)
* z_obj_grass_unit OK * document some grass * pr suggestions, add grass_unit comment * pr suggestions * implement constants
This commit is contained in:
parent
dd4206bb24
commit
f17e85d1fd
|
@ -39,6 +39,11 @@ typedef struct {
|
||||||
/* 0x8 */ s32 z;
|
/* 0x8 */ s32 z;
|
||||||
} Vec3i; // size = 0xC
|
} Vec3i; // size = 0xC
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/* 0x0 */ f32 distance;
|
||||||
|
/* 0x4 */ s16 angle;
|
||||||
|
} VecPolar; // size = 0x8
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* 0x0 */ Vec3s center;
|
/* 0x0 */ Vec3s center;
|
||||||
/* 0x6 */ s16 radius;
|
/* 0x6 */ s16 radius;
|
||||||
|
|
3
spec
3
spec
|
@ -2137,8 +2137,7 @@ beginseg
|
||||||
name "ovl_Obj_Grass_Unit"
|
name "ovl_Obj_Grass_Unit"
|
||||||
compress
|
compress
|
||||||
include "build/src/overlays/actors/ovl_Obj_Grass_Unit/z_obj_grass_unit.o"
|
include "build/src/overlays/actors/ovl_Obj_Grass_Unit/z_obj_grass_unit.o"
|
||||||
include "build/data/ovl_Obj_Grass_Unit/ovl_Obj_Grass_Unit.data.o"
|
include "build/src/overlays/actors/ovl_Obj_Grass_Unit/ovl_Obj_Grass_Unit_reloc.o"
|
||||||
include "build/data/ovl_Obj_Grass_Unit/ovl_Obj_Grass_Unit.reloc.o"
|
|
||||||
endseg
|
endseg
|
||||||
|
|
||||||
beginseg
|
beginseg
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* File: z_obj_grass.c
|
* File: z_obj_grass.c
|
||||||
* Overlay: ovl_Obj_Grass
|
* Overlay: ovl_Obj_Grass
|
||||||
* Description: "Master" instance of grass for unit spawned by Obj_Grass_Unit
|
* Description: Optimized manager for processing grass "spawned" by ObjGrassUnit
|
||||||
|
*
|
||||||
|
* Instances of ObjGrass must be spawned by ObjGrassUnit to function correctly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "prevent_bss_reordering.h"
|
#include "prevent_bss_reordering.h"
|
||||||
|
@ -18,10 +20,10 @@ void ObjGrass_Destroy(Actor* thisx, PlayState* play);
|
||||||
void ObjGrass_Update(Actor* thisx, PlayState* play);
|
void ObjGrass_Update(Actor* thisx, PlayState* play);
|
||||||
void ObjGrass_Draw(Actor* thisx, PlayState* play);
|
void ObjGrass_Draw(Actor* thisx, PlayState* play);
|
||||||
|
|
||||||
ObjGrassStruct1* D_809AADA0[4];
|
ObjGrassGroup* sNearestGrassGroups[OBJ_GRASS_NEAREST_GROUP_MAX];
|
||||||
f32 D_809AADB0[4];
|
f32 sNearestGrassGroupsDist[OBJ_GRASS_NEAREST_GROUP_MAX];
|
||||||
ObjGrassStruct1_1* D_809AADC0[20];
|
ObjGrassElement* sNearestGrassElements[OBJ_GRASS_NEAREST_ELEM_MAX];
|
||||||
f32 D_809AAE10[20];
|
f32 sNearestGrassElementsDistSq[OBJ_GRASS_NEAREST_ELEM_MAX];
|
||||||
|
|
||||||
#include "overlays/ovl_Obj_Grass/ovl_Obj_Grass.c"
|
#include "overlays/ovl_Obj_Grass/ovl_Obj_Grass.c"
|
||||||
|
|
||||||
|
@ -57,35 +59,35 @@ static ColliderCylinderInit sCylinderInit = {
|
||||||
{ 6, 44, 0, { 0, 0, 0 } },
|
{ 6, 44, 0, { 0, 0, 0 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
Vec3f D_809AAB4C[] = {
|
static Vec3f sUnitDirections[] = {
|
||||||
{ 0.0f, 0.707099974155f, 0.707099974155f },
|
{ 0.0f, 0.7071f, 0.7071f },
|
||||||
{ 0.707099974155f, 0.707099974155f, 0.0f },
|
{ 0.7071f, 0.7071f, 0.0f },
|
||||||
{ 0.0f, 0.707099974155f, -0.707099974155f },
|
{ 0.0f, 0.7071f, -0.7071f },
|
||||||
{ -0.707099974155f, 0.707099974155f, 0.0f },
|
{ -0.7071f, 0.7071f, 0.0f },
|
||||||
};
|
};
|
||||||
|
|
||||||
s16 D_809AAB7C[] = { 0x6C, 0x66, 0x60, 0x54, 0x42, 0x37, 0x2A, 0x26 };
|
static s16 sFragmentScales[] = { 108, 102, 96, 84, 66, 55, 42, 38 };
|
||||||
|
|
||||||
s32 func_809A9110(PlayState* play, Vec3f* arg1) {
|
s32 func_809A9110(PlayState* play, Vec3f* pos) {
|
||||||
f32 sp2C;
|
f32 w;
|
||||||
Vec3f sp20;
|
Vec3f projectedPos;
|
||||||
|
|
||||||
SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, arg1, &sp20, &sp2C);
|
SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, pos, &projectedPos, &w);
|
||||||
|
|
||||||
if ((play->projectionMtxFDiagonal.z * -130.13191f) < sp20.z) {
|
if ((play->projectionMtxFDiagonal.z * -130.13191f) < projectedPos.z) {
|
||||||
if (sp2C < 1.0f) {
|
if (w < 1.0f) {
|
||||||
sp2C = 1.0f;
|
w = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((fabsf(sp20.x) - (130.13191f * play->projectionMtxFDiagonal.x)) < sp2C) &&
|
if (((fabsf(projectedPos.x) - (130.13191f * play->projectionMtxFDiagonal.x)) < w) &&
|
||||||
((fabsf(sp20.y) - (130.13191f * play->projectionMtxFDiagonal.y)) < sp2C)) {
|
((fabsf(projectedPos.y) - (130.13191f * play->projectionMtxFDiagonal.y)) < w)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809A91FC(MtxF* matrix) {
|
void ObjGrass_OverrideMatrixCurrent(MtxF* matrix) {
|
||||||
s32 i;
|
s32 i;
|
||||||
MtxF* temp = Matrix_GetCurrent();
|
MtxF* temp = Matrix_GetCurrent();
|
||||||
f32* tmp = &temp->xx;
|
f32* tmp = &temp->xx;
|
||||||
|
@ -96,42 +98,44 @@ void func_809A91FC(MtxF* matrix) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809A92D0(ObjGrassStruct1_1* ptr, PlayState* play) {
|
void ObjGrass_DropCollectible(ObjGrassElement* grassElem, PlayState* play) {
|
||||||
if (!(ptr->unk_0E & 0x10)) {
|
if (!(grassElem->dropTable & 0x10)) {
|
||||||
Item_DropCollectibleRandom(play, NULL, &ptr->unk_00, ptr->unk_0E * 0x10);
|
Item_DropCollectibleRandom(play, NULL, &grassElem->pos, grassElem->dropTable * 0x10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809A9314(ObjGrassStruct1_1* ptr, PlayState* play) {
|
void ObjGrass_SpawnFragments(Vec3f* basePos, PlayState* play) {
|
||||||
Vec3f spBC;
|
Vec3f velocity;
|
||||||
Vec3f spB0;
|
Vec3f pos;
|
||||||
s32 i;
|
s32 i;
|
||||||
Vec3f* ptr2;
|
Vec3f* dir;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_COUNT(D_809AAB4C); i++) {
|
for (i = 0; i < ARRAY_COUNT(sUnitDirections); i++) {
|
||||||
ptr2 = &D_809AAB4C[i];
|
dir = &sUnitDirections[i];
|
||||||
|
|
||||||
spB0.x = ptr->unk_00.x + (ptr2->x * 8.0f);
|
pos.x = basePos->x + (dir->x * 8.0f);
|
||||||
spB0.y = (ptr->unk_00.y + (ptr2->y * 8.0f)) + 10.0f;
|
pos.y = basePos->y + (dir->y * 8.0f) + 10.0f;
|
||||||
spB0.z = ptr->unk_00.z + (ptr2->z * 8.0f);
|
pos.z = basePos->z + (dir->z * 8.0f);
|
||||||
|
|
||||||
spBC.x = (Rand_ZeroOne() - 0.5f) * 8.0f;
|
velocity.x = (Rand_ZeroOne() - 0.5f) * 8.0f;
|
||||||
spBC.y = Rand_ZeroOne() * 10.0f;
|
velocity.y = Rand_ZeroOne() * 10.0f;
|
||||||
spBC.z = (Rand_ZeroOne() - 0.5f) * 8.0f;
|
velocity.z = (Rand_ZeroOne() - 0.5f) * 8.0f;
|
||||||
|
|
||||||
EffectSsKakera_Spawn(play, &spB0, &spBC, &spB0, -100, 64, 40, 3, 0,
|
EffectSsKakera_Spawn(play, &pos, &velocity, &pos, -100, 64, 40, 3, 0,
|
||||||
D_809AAB7C[(s32)(Rand_ZeroOne() * 111.1f) & 7], 0, 0, 80, -1, 1, gKakeraLeafMiddleDL);
|
sFragmentScales[(s32)(Rand_ZeroOne() * 111.1f) & 7], 0, 0, 80, -1, GAMEPLAY_KEEP,
|
||||||
|
gKakeraLeafMiddleDL);
|
||||||
|
|
||||||
spB0.x = ptr->unk_00.x + (ptr2->x * 16.0f);
|
pos.x = basePos->x + (dir->x * 16.0f);
|
||||||
spB0.y = (ptr->unk_00.y + (ptr2->y * 16.0f)) + 10.0f;
|
pos.y = basePos->y + (dir->y * 16.0f) + 10.0f;
|
||||||
spB0.z = ptr->unk_00.z + (ptr2->z * 16.0f);
|
pos.z = basePos->z + (dir->z * 16.0f);
|
||||||
|
|
||||||
spBC.x = (Rand_ZeroOne() - 0.5f) * 6.0f;
|
velocity.x = (Rand_ZeroOne() - 0.5f) * 6.0f;
|
||||||
spBC.y = Rand_ZeroOne() * 10.0f;
|
velocity.y = Rand_ZeroOne() * 10.0f;
|
||||||
spBC.z = (Rand_ZeroOne() - 0.5f) * 6.0f;
|
velocity.z = (Rand_ZeroOne() - 0.5f) * 6.0f;
|
||||||
|
|
||||||
EffectSsKakera_Spawn(play, &spB0, &spBC, &spB0, -100, 64, 40, 3, 0,
|
EffectSsKakera_Spawn(play, &pos, &velocity, &pos, -100, 64, 40, 3, 0,
|
||||||
D_809AAB7C[(s32)(Rand_ZeroOne() * 111.1f) % 7], 0, 0, 80, -1, 1, gKakeraLeafTipDL);
|
sFragmentScales[(s32)(Rand_ZeroOne() * 111.1f) % 7], 0, 0, 80, -1, GAMEPLAY_KEEP,
|
||||||
|
gKakeraLeafTipDL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,9 +145,9 @@ void ObjGrass_Init(Actor* thisx, PlayState* play) {
|
||||||
|
|
||||||
Actor_SetScale(&this->actor, 0.4f);
|
Actor_SetScale(&this->actor, 0.4f);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_COUNT(this->unk_2948); i++) {
|
for (i = 0; i < ARRAY_COUNT(this->grassElemColliders); i++) {
|
||||||
Collider_InitCylinder(play, &this->unk_2948[i].collider);
|
Collider_InitCylinder(play, &this->grassElemColliders[i].collider);
|
||||||
Collider_SetCylinder(play, &this->unk_2948[i].collider, &this->actor, &sCylinderInit);
|
Collider_SetCylinder(play, &this->grassElemColliders[i].collider, &this->actor, &sCylinderInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->actor.colChkInfo.mass = MASS_IMMOVABLE;
|
this->actor.colChkInfo.mass = MASS_IMMOVABLE;
|
||||||
|
@ -158,117 +162,121 @@ void ObjGrass_Destroy(Actor* thisx, PlayState* play) {
|
||||||
ObjGrass* this = THIS;
|
ObjGrass* this = THIS;
|
||||||
s32 i;
|
s32 i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_COUNT(this->unk_2948); i++) {
|
for (i = 0; i < ARRAY_COUNT(this->grassElemColliders); i++) {
|
||||||
Collider_DestroyCylinder(play, &this->unk_2948[i].collider);
|
Collider_DestroyCylinder(play, &this->grassElemColliders[i].collider);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_COUNT(this->unk_3298); i++) {
|
for (i = 0; i < ARRAY_COUNT(this->grassCarry); i++) {
|
||||||
ObjGrassCarry** ptr = &this->unk_3298[i];
|
ObjGrassCarry** grassCarry = &this->grassCarry[i];
|
||||||
|
|
||||||
if (*ptr != NULL) {
|
if (*grassCarry != NULL) {
|
||||||
(*ptr)->unk_190 = 0;
|
(*grassCarry)->grassManager = NULL;
|
||||||
*ptr = NULL;
|
*grassCarry = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809A9790(ObjGrass* this, PlayState* play) {
|
void ObjGrass_ProcessColliders(ObjGrass* this, PlayState* play) {
|
||||||
s32 i;
|
s32 i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_COUNT(this->unk_2948); i++) {
|
for (i = 0; i < ARRAY_COUNT(this->grassElemColliders); i++) {
|
||||||
ObjGrassStruct1_1* ptr = this->unk_2948[i].unk_4C;
|
ObjGrassElement* grassElem = this->grassElemColliders[i].entity;
|
||||||
|
|
||||||
if ((ptr != NULL) && (this->unk_2948[i].collider.base.acFlags & AC_HIT)) {
|
if ((grassElem != NULL) && (this->grassElemColliders[i].collider.base.acFlags & AC_HIT)) {
|
||||||
func_809A9314(ptr, play);
|
ObjGrass_SpawnFragments(&grassElem->pos, play);
|
||||||
func_809A92D0(ptr, play);
|
ObjGrass_DropCollectible(grassElem, play);
|
||||||
ptr->unk_0F |= 4;
|
grassElem->flags |= OBJ_GRASS_ELEM_REMOVED;
|
||||||
SoundSource_PlaySfxAtFixedWorldPos(play, &ptr->unk_00, 20, NA_SE_EV_PLANT_BROKEN);
|
SoundSource_PlaySfxAtFixedWorldPos(play, &grassElem->pos, 20, NA_SE_EV_PLANT_BROKEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809A983C(ObjGrass* this, PlayState* play) {
|
void ObjGrass_UpdateGrass(ObjGrass* this, PlayState* play) {
|
||||||
Player* player = GET_PLAYER(play);
|
Player* player = GET_PLAYER(play);
|
||||||
s32 i;
|
s32 i;
|
||||||
s32 j;
|
s32 j;
|
||||||
s32 x;
|
s32 x;
|
||||||
s32 y;
|
s32 y;
|
||||||
f32 temp_f0;
|
f32 distSq;
|
||||||
ObjGrassStruct1* ptr;
|
ObjGrassGroup* grassGroup;
|
||||||
ObjGrassStruct1_1* ptr2;
|
|
||||||
ObjGrassStruct2* ptr3;
|
|
||||||
s16 yaw;
|
s16 yaw;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_COUNT(D_809AADC0); i++) {
|
for (i = 0; i < OBJ_GRASS_NEAREST_ELEM_MAX; i++) {
|
||||||
D_809AADC0[i] = NULL;
|
sNearestGrassElements[i] = NULL;
|
||||||
D_809AAE10[i] = 422500.0f;
|
sNearestGrassElementsDistSq[i] = SQ(650.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_COUNT(D_809AADA0); i++) {
|
for (i = 0; i < OBJ_GRASS_NEAREST_GROUP_MAX; i++) {
|
||||||
D_809AADA0[i] = NULL;
|
sNearestGrassGroups[i] = NULL;
|
||||||
D_809AADB0[i] = 422500.0f;
|
sNearestGrassGroupsDist[i] = SQ(650.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < this->unk_2944; i++) {
|
for (i = 0; i < this->activeGrassGroups; i++) {
|
||||||
ptr = &this->unk_144[i];
|
grassGroup = &this->grassGroups[i];
|
||||||
|
|
||||||
for (j = 0; j < ptr->unk_FC; j++) {
|
for (j = 0; j < grassGroup->count; j++) {
|
||||||
ptr->unk_0C[j].unk_0F &= (u16)~2;
|
grassGroup->elements[j].flags &= (u16)~OBJ_GRASS_ELEM_ANIM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < this->unk_2944; i++) {
|
for (i = 0; i < this->activeGrassGroups; i++) {
|
||||||
ptr = &this->unk_144[i];
|
grassGroup = &this->grassGroups[i];
|
||||||
temp_f0 = Math3D_Vec3fDistSq(&ptr->unk_00, &player->actor.world.pos);
|
distSq = Math3D_Vec3fDistSq(&grassGroup->homePos, &player->actor.world.pos);
|
||||||
|
|
||||||
for (j = 0; j < ARRAY_COUNT(D_809AADB0); j++) {
|
for (j = 0; j < OBJ_GRASS_NEAREST_GROUP_MAX; j++) {
|
||||||
if (temp_f0 < D_809AADB0[j]) {
|
if (distSq < sNearestGrassGroupsDist[j]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j < ARRAY_COUNT(D_809AADB0)) {
|
if (j < OBJ_GRASS_NEAREST_GROUP_MAX) {
|
||||||
for (x = 2; x >= j; x--) {
|
// Insert the grassGroup into the list
|
||||||
D_809AADB0[x + 1] = D_809AADB0[x];
|
|
||||||
D_809AADA0[x + 1] = D_809AADA0[x];
|
// Shift each element under j that remains in the list down 1
|
||||||
|
for (x = OBJ_GRASS_NEAREST_GROUP_MAX - 2; x >= j; x--) {
|
||||||
|
sNearestGrassGroupsDist[x + 1] = sNearestGrassGroupsDist[x];
|
||||||
|
sNearestGrassGroups[x + 1] = sNearestGrassGroups[x];
|
||||||
}
|
}
|
||||||
|
|
||||||
D_809AADB0[j] = temp_f0;
|
sNearestGrassGroupsDist[j] = distSq;
|
||||||
D_809AADA0[j] = ptr;
|
sNearestGrassGroups[j] = grassGroup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->unk_3294 = NULL;
|
this->carryGrassElem = NULL;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_COUNT(D_809AADA0); i++) {
|
for (i = 0; i < OBJ_GRASS_NEAREST_GROUP_MAX; i++) {
|
||||||
ptr = D_809AADA0[i];
|
grassGroup = sNearestGrassGroups[i];
|
||||||
|
|
||||||
if (ptr != NULL) {
|
if (grassGroup != NULL) {
|
||||||
for (j = 0; j < ptr->unk_FC; j++) {
|
for (j = 0; j < grassGroup->count; j++) {
|
||||||
if (!(ptr->unk_0C[j].unk_0F & 4)) {
|
if (!(grassGroup->elements[j].flags & OBJ_GRASS_ELEM_REMOVED)) {
|
||||||
temp_f0 = Math3D_Vec3fDistSq(&ptr->unk_0C[j].unk_00, &player->actor.world.pos);
|
distSq = Math3D_Vec3fDistSq(&grassGroup->elements[j].pos, &player->actor.world.pos);
|
||||||
|
|
||||||
for (x = 0; x < ARRAY_COUNT(D_809AAE10); x++) {
|
for (x = 0; x < OBJ_GRASS_NEAREST_ELEM_MAX; x++) {
|
||||||
if (temp_f0 < D_809AAE10[x]) {
|
if (distSq < sNearestGrassElementsDistSq[x]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x < ARRAY_COUNT(D_809AAE10)) {
|
if (x < OBJ_GRASS_NEAREST_ELEM_MAX) {
|
||||||
for (y = 18; y >= x; y--) {
|
// Insert the GrassElement into the list
|
||||||
D_809AAE10[y + 1] = D_809AAE10[y];
|
|
||||||
D_809AADC0[y + 1] = D_809AADC0[y];
|
// Shift each element under j that remains in the list down 1
|
||||||
|
for (y = OBJ_GRASS_NEAREST_ELEM_MAX - 2; y >= x; y--) {
|
||||||
|
sNearestGrassElementsDistSq[y + 1] = sNearestGrassElementsDistSq[y];
|
||||||
|
sNearestGrassElements[y + 1] = sNearestGrassElements[y];
|
||||||
}
|
}
|
||||||
|
|
||||||
D_809AAE10[x] = temp_f0;
|
sNearestGrassElementsDistSq[x] = distSq;
|
||||||
D_809AADC0[x] = &ptr->unk_0C[j];
|
sNearestGrassElements[x] = &grassGroup->elements[j];
|
||||||
|
|
||||||
if (temp_f0 < 2500.0f) {
|
if (distSq < SQ(50.0f)) {
|
||||||
yaw = player->actor.shape.rot.y -
|
yaw = player->actor.shape.rot.y -
|
||||||
Math_Vec3f_Yaw(&player->actor.world.pos, &ptr->unk_0C[j].unk_00);
|
Math_Vec3f_Yaw(&player->actor.world.pos, &grassGroup->elements[j].pos);
|
||||||
|
|
||||||
if (ABS_ALT(yaw) < 0x2000) {
|
if (ABS_ALT(yaw) < 0x2000) {
|
||||||
this->unk_3294 = &ptr->unk_0C[j];
|
this->carryGrassElem = &grassGroup->elements[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -277,28 +285,29 @@ void func_809A983C(ObjGrass* this, PlayState* play) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_COUNT(this->unk_2948); i++) {
|
for (i = 0; i < ARRAY_COUNT(this->grassElemColliders); i++) {
|
||||||
ptr3 = &this->unk_2948[i];
|
ObjGrassCollider* grassCol = &this->grassElemColliders[i];
|
||||||
|
ObjGrassElement* grassElem;
|
||||||
|
|
||||||
ptr3->collider.base.acFlags &= (u16)~AC_HIT;
|
grassCol->collider.base.acFlags &= (u16)~AC_HIT;
|
||||||
ptr3->collider.base.ocFlags1 &= (u16)~OC1_HIT;
|
grassCol->collider.base.ocFlags1 &= (u16)~OC1_HIT;
|
||||||
|
|
||||||
ptr2 = D_809AADC0[i];
|
grassElem = sNearestGrassElements[i];
|
||||||
if (ptr2 != NULL) {
|
if (grassElem != NULL) {
|
||||||
ptr3->collider.dim.pos.x = ptr2->unk_00.x;
|
grassCol->collider.dim.pos.x = grassElem->pos.x;
|
||||||
ptr3->collider.dim.pos.y = ptr2->unk_00.y;
|
grassCol->collider.dim.pos.y = grassElem->pos.y;
|
||||||
ptr3->collider.dim.pos.z = ptr2->unk_00.z;
|
grassCol->collider.dim.pos.z = grassElem->pos.z;
|
||||||
CollisionCheck_SetAC(play, &play->colChkCtx, &ptr3->collider.base);
|
CollisionCheck_SetAC(play, &play->colChkCtx, &grassCol->collider.base);
|
||||||
CollisionCheck_SetOC(play, &play->colChkCtx, &ptr3->collider.base);
|
CollisionCheck_SetOC(play, &play->colChkCtx, &grassCol->collider.base);
|
||||||
ptr2->unk_0F |= 2;
|
grassElem->flags |= OBJ_GRASS_ELEM_ANIM;
|
||||||
ptr3->unk_4C = ptr2;
|
grassCol->entity = grassElem;
|
||||||
} else {
|
} else {
|
||||||
ptr3->unk_4C = NULL;
|
grassCol->entity = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809A9DB8(ObjGrass* this) {
|
void ObjGrass_CalcAnimationMatrices(ObjGrass* this) {
|
||||||
s32 i;
|
s32 i;
|
||||||
s32 pad;
|
s32 pad;
|
||||||
f32* ptr;
|
f32* ptr;
|
||||||
|
@ -345,8 +354,8 @@ void func_809A9DB8(ObjGrass* this) {
|
||||||
sp6C[6] = (temp_f26 - temp_f22) * temp_f22 * temp_f20 * temp_f16 * 0.0015f;
|
sp6C[6] = (temp_f26 - temp_f22) * temp_f22 * temp_f20 * temp_f16 * 0.0015f;
|
||||||
sp6C[7] = (spA4 - temp_f20) * sp94 * sp90 * temp_f16 * 0.0015f;
|
sp6C[7] = (spA4 - temp_f20) * sp94 * sp90 * temp_f16 * 0.0015f;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_COUNT(this->unk_2F88); i++) {
|
for (i = 0; i < ARRAY_COUNT(this->distortionMtx); i++) {
|
||||||
ptr = &this->unk_2F88[i].mf[0][0];
|
ptr = &this->distortionMtx[i].mf[0][0];
|
||||||
|
|
||||||
tempf1 = sp6C[(i + 0) & 7];
|
tempf1 = sp6C[(i + 0) & 7];
|
||||||
tempf2 = sp6C[(i + 1) & 7];
|
tempf2 = sp6C[(i + 1) & 7];
|
||||||
|
@ -379,64 +388,65 @@ void func_809A9DB8(ObjGrass* this) {
|
||||||
void ObjGrass_Update(Actor* thisx, PlayState* play) {
|
void ObjGrass_Update(Actor* thisx, PlayState* play) {
|
||||||
ObjGrass* this = THIS;
|
ObjGrass* this = THIS;
|
||||||
|
|
||||||
func_809A9790(this, play);
|
ObjGrass_ProcessColliders(this, play);
|
||||||
func_809A983C(this, play);
|
ObjGrass_UpdateGrass(this, play);
|
||||||
func_809A9DB8(this);
|
ObjGrass_CalcAnimationMatrices(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AA278(ObjGrass* this, PlayState* play) {
|
void ObjGrass_InitDraw(ObjGrass* this, PlayState* play) {
|
||||||
ObjGrassStruct1* ptr;
|
ObjGrassGroup* grassGroup;
|
||||||
ObjGrassStruct1_1* ptr2;
|
ObjGrassElement* grassElem;
|
||||||
s32 i;
|
s32 i;
|
||||||
s32 j;
|
s32 j;
|
||||||
f32 distSq;
|
f32 distSq;
|
||||||
f32 temp_f22;
|
f32 eyeDist;
|
||||||
|
|
||||||
for (i = 0; i < this->unk_2944; i++) {
|
for (i = 0; i < this->activeGrassGroups; i++) {
|
||||||
ptr = &this->unk_144[i];
|
grassGroup = &this->grassGroups[i];
|
||||||
|
|
||||||
temp_f22 = Math3D_Vec3fDistSq(&ptr->unk_00, &GET_ACTIVE_CAM(play)->eye);
|
eyeDist = Math3D_Vec3fDistSq(&grassGroup->homePos, &GET_ACTIVE_CAM(play)->eye);
|
||||||
|
|
||||||
if ((temp_f22 < SQ(1280.0f)) && func_809A9110(play, &ptr->unk_00)) {
|
if ((eyeDist < SQ(1280.0f)) && func_809A9110(play, &grassGroup->homePos)) {
|
||||||
ptr->unk_FE |= 1;
|
grassGroup->flags |= OBJ_GRASS_GROUP_DRAW;
|
||||||
|
|
||||||
for (j = 0; j < ptr->unk_FC; j++) {
|
for (j = 0; j < grassGroup->count; j++) {
|
||||||
ptr2 = &ptr->unk_0C[j];
|
grassElem = &grassGroup->elements[j];
|
||||||
|
|
||||||
if (ptr2->unk_0F & 4) {
|
if (grassElem->flags & OBJ_GRASS_ELEM_REMOVED) {
|
||||||
ptr2->unk_10 = 255;
|
grassElem->alpha = 255;
|
||||||
ptr2->unk_0F &= ~1;
|
grassElem->flags &= ~OBJ_GRASS_ELEM_DRAW;
|
||||||
} else {
|
} else {
|
||||||
ptr2->unk_0F |= 1;
|
grassElem->flags |= OBJ_GRASS_ELEM_DRAW;
|
||||||
if (temp_f22 < SQ(980.0f)) {
|
if (eyeDist < SQ(980.0f)) {
|
||||||
ptr2->unk_10 = 255;
|
grassElem->alpha = 255;
|
||||||
} else {
|
} else {
|
||||||
distSq = Math3D_Vec3fDistSq(&ptr2->unk_00, &GET_ACTIVE_CAM(play)->eye);
|
distSq = Math3D_Vec3fDistSq(&grassElem->pos, &GET_ACTIVE_CAM(play)->eye);
|
||||||
if ((distSq <= SQ(1080.0f)) || ((ptr2->unk_0F & 8) && (distSq < SQ(1180.0f)))) {
|
if ((distSq <= SQ(1080.0f)) ||
|
||||||
ptr2->unk_10 = 255;
|
((grassElem->flags & OBJ_GRASS_ELEM_UNDERWATER) && (distSq < SQ(1180.0f)))) {
|
||||||
|
grassElem->alpha = 255;
|
||||||
} else if (distSq >= SQ(1180.0f)) {
|
} else if (distSq >= SQ(1180.0f)) {
|
||||||
ptr2->unk_10 = 0;
|
grassElem->alpha = 0;
|
||||||
} else {
|
} else {
|
||||||
ptr2->unk_10 = (1180.0f - sqrtf(distSq)) * 2.55f;
|
grassElem->alpha = (1180.0f - sqrtf(distSq)) * 2.55f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ptr->unk_FE &= ~1;
|
grassGroup->flags &= ~OBJ_GRASS_GROUP_DRAW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AA54C(Actor* thisx, PlayState* play2) {
|
void ObjGrass_DrawOpa(Actor* thisx, PlayState* play2) {
|
||||||
ObjGrass* this = THIS;
|
ObjGrass* this = THIS;
|
||||||
PlayState* play = play2;
|
PlayState* play = play2;
|
||||||
Lights* temp_s0;
|
Lights* lights;
|
||||||
ObjGrassStruct1* ptr;
|
ObjGrassGroup* grassGroup;
|
||||||
s32 i;
|
s32 i;
|
||||||
s32 j;
|
s32 j;
|
||||||
Vec3s sp70 = { 0, 0, 0 };
|
Vec3s rot = { 0, 0, 0 };
|
||||||
ObjGrassStruct1_1* ptr2;
|
ObjGrassElement* grassElem;
|
||||||
|
|
||||||
OPEN_DISPS(play->state.gfxCtx);
|
OPEN_DISPS(play->state.gfxCtx);
|
||||||
|
|
||||||
|
@ -445,23 +455,23 @@ void func_809AA54C(Actor* thisx, PlayState* play2) {
|
||||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255);
|
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255);
|
||||||
gSPDisplayList(POLY_OPA_DISP++, gObjGrass_D_809AA9F0);
|
gSPDisplayList(POLY_OPA_DISP++, gObjGrass_D_809AA9F0);
|
||||||
|
|
||||||
for (i = 0; i < this->unk_2944; i++) {
|
for (i = 0; i < this->activeGrassGroups; i++) {
|
||||||
ptr = &this->unk_144[i];
|
grassGroup = &this->grassGroups[i];
|
||||||
|
|
||||||
if (ptr->unk_FE & 1) {
|
if (grassGroup->flags & OBJ_GRASS_GROUP_DRAW) {
|
||||||
temp_s0 = LightContext_NewLights(&play->lightCtx, play->state.gfxCtx);
|
lights = LightContext_NewLights(&play->lightCtx, play->state.gfxCtx);
|
||||||
Lights_BindAll(temp_s0, play->lightCtx.listHead, &ptr->unk_00, play);
|
Lights_BindAll(lights, play->lightCtx.listHead, &grassGroup->homePos, play);
|
||||||
Lights_Draw(temp_s0, play->state.gfxCtx);
|
Lights_Draw(lights, play->state.gfxCtx);
|
||||||
|
|
||||||
for (j = 0; j < ptr->unk_FC; j++) {
|
for (j = 0; j < grassGroup->count; j++) {
|
||||||
ptr2 = &ptr->unk_0C[j];
|
grassElem = &grassGroup->elements[j];
|
||||||
|
|
||||||
if ((ptr2->unk_0F & 1) && (ptr2->unk_10 == 255)) {
|
if ((grassElem->flags & OBJ_GRASS_ELEM_DRAW) && (grassElem->alpha == 255)) {
|
||||||
sp70.y = ptr2->unk_0C;
|
rot.y = grassElem->rotY;
|
||||||
Matrix_SetTranslateRotateYXZ(ptr2->unk_00.x, ptr2->unk_00.y, ptr2->unk_00.z, &sp70);
|
Matrix_SetTranslateRotateYXZ(grassElem->pos.x, grassElem->pos.y, grassElem->pos.z, &rot);
|
||||||
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
|
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
|
||||||
if (ptr2->unk_0F & 2) {
|
if (grassElem->flags & OBJ_GRASS_ELEM_ANIM) {
|
||||||
func_809A91FC(&this->unk_2F88[j]);
|
ObjGrass_OverrideMatrixCurrent(&this->distortionMtx[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx),
|
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx),
|
||||||
|
@ -475,13 +485,13 @@ void func_809AA54C(Actor* thisx, PlayState* play2) {
|
||||||
CLOSE_DISPS(play->state.gfxCtx);
|
CLOSE_DISPS(play->state.gfxCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AA798(Actor* thisx, PlayState* play) {
|
void ObjGrass_DrawXlu(Actor* thisx, PlayState* play) {
|
||||||
ObjGrass* this = THIS;
|
ObjGrass* this = THIS;
|
||||||
ObjGrassStruct1* ptr;
|
ObjGrassGroup* grassGroup;
|
||||||
ObjGrassStruct1_1* ptr2;
|
ObjGrassElement* grassElem;
|
||||||
s32 i;
|
s32 i;
|
||||||
s32 j;
|
s32 j;
|
||||||
Vec3s sp6C = { 0, 0, 0 };
|
Vec3s rot = { 0, 0, 0 };
|
||||||
|
|
||||||
OPEN_DISPS(play->state.gfxCtx);
|
OPEN_DISPS(play->state.gfxCtx);
|
||||||
|
|
||||||
|
@ -489,21 +499,21 @@ void func_809AA798(Actor* thisx, PlayState* play) {
|
||||||
|
|
||||||
gSPDisplayList(POLY_XLU_DISP++, gObjGrass_D_809AAA68);
|
gSPDisplayList(POLY_XLU_DISP++, gObjGrass_D_809AAA68);
|
||||||
|
|
||||||
for (i = 0; i < this->unk_2944; i++) {
|
for (i = 0; i < this->activeGrassGroups; i++) {
|
||||||
ptr = &this->unk_144[i];
|
grassGroup = &this->grassGroups[i];
|
||||||
|
|
||||||
if (ptr->unk_FE & 1) {
|
if (grassGroup->flags & OBJ_GRASS_GROUP_DRAW) {
|
||||||
for (j = 0; j < ptr->unk_FC; j++) {
|
for (j = 0; j < grassGroup->count; j++) {
|
||||||
ptr2 = &ptr->unk_0C[j];
|
grassElem = &grassGroup->elements[j];
|
||||||
|
|
||||||
if ((ptr2->unk_0F & 1) && (ptr2->unk_10 > 0) && (ptr2->unk_10 < 255)) {
|
if ((grassElem->flags & OBJ_GRASS_ELEM_DRAW) && (grassElem->alpha > 0) && (grassElem->alpha < 255)) {
|
||||||
sp6C.y = ptr2->unk_0C;
|
rot.y = grassElem->rotY;
|
||||||
Matrix_SetTranslateRotateYXZ(ptr2->unk_00.x, ptr2->unk_00.y, ptr2->unk_00.z, &sp6C);
|
Matrix_SetTranslateRotateYXZ(grassElem->pos.x, grassElem->pos.y, grassElem->pos.z, &rot);
|
||||||
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
|
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
|
||||||
|
|
||||||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx),
|
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx),
|
||||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||||
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, ptr2->unk_10);
|
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, grassElem->alpha);
|
||||||
gSPDisplayList(POLY_XLU_DISP++, gObjGrass_D_809AAAE0);
|
gSPDisplayList(POLY_XLU_DISP++, gObjGrass_D_809AAAE0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -516,7 +526,7 @@ void func_809AA798(Actor* thisx, PlayState* play) {
|
||||||
void ObjGrass_Draw(Actor* thisx, PlayState* play) {
|
void ObjGrass_Draw(Actor* thisx, PlayState* play) {
|
||||||
ObjGrass* this = THIS;
|
ObjGrass* this = THIS;
|
||||||
|
|
||||||
func_809AA278(this, play);
|
ObjGrass_InitDraw(this, play);
|
||||||
func_809AA54C(thisx, play);
|
ObjGrass_DrawOpa(thisx, play);
|
||||||
func_809AA798(thisx, play);
|
ObjGrass_DrawXlu(thisx, play);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,40 +7,52 @@
|
||||||
struct ObjGrass;
|
struct ObjGrass;
|
||||||
struct ObjGrassCarry;
|
struct ObjGrassCarry;
|
||||||
|
|
||||||
typedef struct ObjGrassStruct1_1 {
|
#define OBJ_GRASS_NEAREST_GROUP_MAX 4
|
||||||
/* 0x00 */ Vec3f unk_00;
|
#define OBJ_GRASS_NEAREST_ELEM_MAX 20
|
||||||
/* 0x0C */ s16 unk_0C;
|
|
||||||
/* 0x0E */ s8 unk_0E;
|
#define OBJ_GRASS_GROUP_ELEM_COUNT_MAX 12
|
||||||
/* 0x0F */ u8 unk_0F;
|
|
||||||
/* 0x10 */ u8 unk_10;
|
#define OBJ_GRASS_GROUP_DRAW 1
|
||||||
} ObjGrassStruct1_1; // size = 0x14
|
|
||||||
|
#define OBJ_GRASS_ELEM_DRAW 1
|
||||||
|
#define OBJ_GRASS_ELEM_ANIM 2
|
||||||
|
#define OBJ_GRASS_ELEM_REMOVED 4
|
||||||
|
#define OBJ_GRASS_ELEM_UNDERWATER 8
|
||||||
|
|
||||||
|
typedef struct ObjGrassElement {
|
||||||
|
/* 0x00 */ Vec3f pos;
|
||||||
|
/* 0x0C */ s16 rotY;
|
||||||
|
/* 0x0E */ s8 dropTable;
|
||||||
|
/* 0x0F */ u8 flags;
|
||||||
|
/* 0x10 */ u8 alpha;
|
||||||
|
} ObjGrassElement; // size = 0x14
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* 0x00 */ Vec3f unk_00;
|
/* 0x00 */ Vec3f homePos;
|
||||||
/* 0x0C */ ObjGrassStruct1_1 unk_0C[12];
|
/* 0x0C */ ObjGrassElement elements[OBJ_GRASS_GROUP_ELEM_COUNT_MAX];
|
||||||
/* 0xFC */ s16 unk_FC;
|
/* 0xFC */ s16 count;
|
||||||
/* 0xFE */ u8 unk_FE;
|
/* 0xFE */ u8 flags;
|
||||||
} ObjGrassStruct1; // size = 0x100
|
} ObjGrassGroup; // size = 0x100
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* 0x00 */ ColliderCylinder collider;
|
/* 0x00 */ ColliderCylinder collider;
|
||||||
/* 0x4C */ ObjGrassStruct1_1* unk_4C;
|
/* 0x4C */ ObjGrassElement* entity;
|
||||||
} ObjGrassStruct2; // size = 0x50
|
} ObjGrassCollider; // size = 0x50
|
||||||
|
|
||||||
typedef struct ObjGrass {
|
typedef struct ObjGrass {
|
||||||
/* 0x0000 */ Actor actor;
|
/* 0x0000 */ Actor actor;
|
||||||
/* 0x0144 */ ObjGrassStruct1 unk_144[40];
|
/* 0x0144 */ ObjGrassGroup grassGroups[40];
|
||||||
/* 0x2944 */ s16 unk_2944;
|
/* 0x2944 */ s16 activeGrassGroups;
|
||||||
/* 0x2948 */ ObjGrassStruct2 unk_2948[20];
|
/* 0x2948 */ ObjGrassCollider grassElemColliders[OBJ_GRASS_NEAREST_ELEM_MAX];
|
||||||
/* 0x2F88 */ MtxF unk_2F88[12];
|
/* 0x2F88 */ MtxF distortionMtx[OBJ_GRASS_GROUP_ELEM_COUNT_MAX];
|
||||||
/* 0x3288 */ s16 unk_3288;
|
/* 0x3288 */ s16 unk_3288;
|
||||||
/* 0x328A */ s16 unk_328A;
|
/* 0x328A */ s16 unk_328A;
|
||||||
/* 0x328C */ s16 unk_328C;
|
/* 0x328C */ s16 unk_328C;
|
||||||
/* 0x328E */ s16 unk_328E;
|
/* 0x328E */ s16 unk_328E;
|
||||||
/* 0x3290 */ s16 unk_3290;
|
/* 0x3290 */ s16 unk_3290;
|
||||||
/* 0x3292 */ s16 unk_3292;
|
/* 0x3292 */ s16 activeGrassCarry;
|
||||||
/* 0x3294 */ ObjGrassStruct1_1* unk_3294;
|
/* 0x3294 */ ObjGrassElement* carryGrassElem;
|
||||||
/* 0x3298 */ struct ObjGrassCarry* unk_3298[2];
|
/* 0x3298 */ struct ObjGrassCarry* grassCarry[2];
|
||||||
} ObjGrass; // size = 0x32A0
|
} ObjGrass; // size = 0x32A0
|
||||||
|
|
||||||
#endif // Z_OBJ_GRASS_H
|
#endif // Z_OBJ_GRASS_H
|
||||||
|
|
|
@ -17,17 +17,17 @@ void ObjGrassCarry_Init(Actor* thisx, PlayState* play);
|
||||||
void ObjGrassCarry_Destroy(Actor* thisx, PlayState* play);
|
void ObjGrassCarry_Destroy(Actor* thisx, PlayState* play);
|
||||||
void ObjGrassCarry_Update(Actor* thisx, PlayState* play);
|
void ObjGrassCarry_Update(Actor* thisx, PlayState* play);
|
||||||
|
|
||||||
void func_809AB3C4(ObjGrassCarry* this);
|
void ObjGrassCarry_SetupAwaitSpawnManager(ObjGrassCarry* this);
|
||||||
void func_809AB3D8(ObjGrassCarry* this, PlayState* play);
|
void ObjGrassCarry_AwaitSpawnManager(ObjGrassCarry* this, PlayState* play);
|
||||||
void func_809AB428(ObjGrassCarry* this);
|
void ObjGrassCarry_SetupIdle(ObjGrassCarry* this);
|
||||||
void func_809AB43C(ObjGrassCarry* this, PlayState* play);
|
void ObjGrassCarry_Idle(ObjGrassCarry* this, PlayState* play);
|
||||||
void func_809AB474(ObjGrassCarry* this);
|
void ObjGrassCarry_Reset(ObjGrassCarry* this);
|
||||||
void func_809AB4A8(ObjGrassCarry* this, PlayState* play);
|
void ObjGrassCarry_Main(ObjGrassCarry* this, PlayState* play);
|
||||||
void func_809AB5FC(ObjGrassCarry* this);
|
void ObjGrassCarry_SetupLiftedUp(ObjGrassCarry* this);
|
||||||
void func_809AB610(ObjGrassCarry* this, PlayState* play);
|
void ObjGrassCarry_LiftedUp(ObjGrassCarry* this, PlayState* play);
|
||||||
void func_809AB6FC(ObjGrassCarry* this);
|
void ObjGrassCarry_SetupFall(ObjGrassCarry* this);
|
||||||
void func_809AB77C(ObjGrassCarry* this, PlayState* play);
|
void ObjGrassCarry_Fall(ObjGrassCarry* this, PlayState* play);
|
||||||
void func_809ABB7C(Actor* this, PlayState* play);
|
void ObjGrassCarry_Draw(Actor* this, PlayState* play);
|
||||||
|
|
||||||
ActorInit Obj_Grass_Carry_InitVars = {
|
ActorInit Obj_Grass_Carry_InitVars = {
|
||||||
ACTOR_OBJ_GRASS_CARRY,
|
ACTOR_OBJ_GRASS_CARRY,
|
||||||
|
@ -61,19 +61,19 @@ static ColliderCylinderInit sCylinderInit = {
|
||||||
{ 10, 44, 0, { 0, 0, 0 } },
|
{ 10, 44, 0, { 0, 0, 0 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
s16 D_809ABBFC = 0;
|
static s16 sRotSpeedXTarget = 0;
|
||||||
s16 D_809ABC00 = 0;
|
static s16 sRotSpeedX = 0;
|
||||||
s16 D_809ABC04 = 0;
|
static s16 sRotSpeedYTarget = 0;
|
||||||
s16 D_809ABC08 = 0;
|
static s16 sRotSpeedY = 0;
|
||||||
|
|
||||||
Vec3f D_809ABC0C[] = {
|
static Vec3f sUnitDirections[] = {
|
||||||
{ 0.0f, 0.7071f, 0.7071f },
|
{ 0.0f, 0.7071f, 0.7071f },
|
||||||
{ 0.7071f, 0.7071f, 0.0f },
|
{ 0.7071f, 0.7071f, 0.0f },
|
||||||
{ 0.0f, 0.7071f, -0.7071f },
|
{ 0.0f, 0.7071f, -0.7071f },
|
||||||
{ -0.7071f, 0.7071f, 0.0f },
|
{ -0.7071f, 0.7071f, 0.0f },
|
||||||
};
|
};
|
||||||
|
|
||||||
s16 D_809ABC3C[] = { 0x6C, 0x66, 0x60, 0x54, 0x42, 0x37, 0x2A, 0x26 };
|
static s16 sFragmentScales[] = { 108, 102, 96, 84, 66, 55, 42, 38 };
|
||||||
|
|
||||||
static InitChainEntry sInitChain[] = {
|
static InitChainEntry sInitChain[] = {
|
||||||
ICHAIN_F32_DIV1000(gravity, -3200, ICHAIN_CONTINUE),
|
ICHAIN_F32_DIV1000(gravity, -3200, ICHAIN_CONTINUE),
|
||||||
|
@ -81,69 +81,71 @@ static InitChainEntry sInitChain[] = {
|
||||||
ICHAIN_VEC3F_DIV1000(scale, 400, ICHAIN_STOP),
|
ICHAIN_VEC3F_DIV1000(scale, 400, ICHAIN_STOP),
|
||||||
};
|
};
|
||||||
|
|
||||||
void func_809AAE60(ObjGrassCarry* this) {
|
void ObjGrassCarry_UpdateVelY(ObjGrassCarry* this) {
|
||||||
this->actor.velocity.y += this->actor.gravity;
|
this->actor.velocity.y += this->actor.gravity;
|
||||||
if (this->actor.velocity.y < this->actor.terminalVelocity) {
|
if (this->actor.velocity.y < this->actor.terminalVelocity) {
|
||||||
this->actor.velocity.y = this->actor.terminalVelocity;
|
this->actor.velocity.y = this->actor.terminalVelocity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AAE94(Vec3f* arg0, f32 arg1) {
|
void ObjGrassCarry_RandScaleVecToZero(Vec3f* velocity, f32 scale) {
|
||||||
arg1 += ((Rand_ZeroOne() * 0.2f) - 0.1f) * arg1;
|
scale += ((Rand_ZeroOne() * 0.2f) - 0.1f) * scale;
|
||||||
|
|
||||||
arg0->x -= (arg0->x * arg1);
|
velocity->x -= velocity->x * scale;
|
||||||
arg0->y -= (arg0->y * arg1);
|
velocity->y -= velocity->y * scale;
|
||||||
arg0->z -= (arg0->z * arg1);
|
velocity->z -= velocity->z * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AAF18(ObjGrassCarry* this) {
|
void ObjGrassCarry_UpdatePos(ObjGrassCarry* this) {
|
||||||
func_809AAE60(this);
|
ObjGrassCarry_UpdateVelY(this);
|
||||||
func_809AAE94(&this->actor.velocity, 0.05f);
|
ObjGrassCarry_RandScaleVecToZero(&this->actor.velocity, 0.05f);
|
||||||
Actor_UpdatePos(&this->actor);
|
Actor_UpdatePos(&this->actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AAF58(ObjGrassCarry* this, PlayState* play) {
|
void ObjGrassCarry_UpdateBgCheckInfo(ObjGrassCarry* this, PlayState* play) {
|
||||||
Actor_UpdateBgCheckInfo(play, &this->actor, 7.5f, 35.0f, 0.0f,
|
Actor_UpdateBgCheckInfo(play, &this->actor, 7.5f, 35.0f, 0.0f,
|
||||||
UPDBGCHECKINFO_FLAG_1 | UPDBGCHECKINFO_FLAG_4 | UPDBGCHECKINFO_FLAG_40 |
|
UPDBGCHECKINFO_FLAG_1 | UPDBGCHECKINFO_FLAG_4 | UPDBGCHECKINFO_FLAG_40 |
|
||||||
UPDBGCHECKINFO_FLAG_80);
|
UPDBGCHECKINFO_FLAG_80);
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AAF9C(Vec3f* arg0, s16 arg1, PlayState* play) {
|
void ObjGrassCarry_DropCollectible(Vec3f* pos, s16 dropTable, PlayState* play) {
|
||||||
if (!(arg1 & 0x10)) {
|
if ((dropTable & 0x10) == 0) {
|
||||||
Item_DropCollectibleRandom(play, NULL, arg0, arg1 * 0x10);
|
Item_DropCollectibleRandom(play, NULL, pos, dropTable * 0x10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AAFE8(Vec3f* arg0, PlayState* play) {
|
void ObjGrassCarry_SpawnFragments(Vec3f* basePos, PlayState* play) {
|
||||||
Vec3f spBC;
|
Vec3f velocity;
|
||||||
Vec3f spB0;
|
Vec3f pos;
|
||||||
s32 i;
|
s32 i;
|
||||||
Vec3f* ptr;
|
Vec3f* dir;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_COUNT(D_809ABC0C); i++) {
|
for (i = 0; i < ARRAY_COUNT(sUnitDirections); i++) {
|
||||||
ptr = &D_809ABC0C[i];
|
dir = &sUnitDirections[i];
|
||||||
|
|
||||||
spB0.x = arg0->x + (ptr->x * 8.0f);
|
pos.x = basePos->x + (dir->x * 8.0f);
|
||||||
spB0.y = arg0->y + (ptr->y * 8.0f) + 10.0f;
|
pos.y = basePos->y + (dir->y * 8.0f) + 10.0f;
|
||||||
spB0.z = arg0->z + (ptr->z * 8.0f);
|
pos.z = basePos->z + (dir->z * 8.0f);
|
||||||
|
|
||||||
spBC.x = (Rand_ZeroOne() - 0.5f) * 8.0f;
|
velocity.x = (Rand_ZeroOne() - 0.5f) * 8.0f;
|
||||||
spBC.y = Rand_ZeroOne() * 10.0f;
|
velocity.y = Rand_ZeroOne() * 10.0f;
|
||||||
spBC.z = (Rand_ZeroOne() - 0.5f) * 8.0f;
|
velocity.z = (Rand_ZeroOne() - 0.5f) * 8.0f;
|
||||||
|
|
||||||
EffectSsKakera_Spawn(play, &spB0, &spBC, &spB0, -100, 64, 40, 3, 0,
|
EffectSsKakera_Spawn(play, &pos, &velocity, &pos, -100, 64, 40, 3, 0,
|
||||||
D_809ABC3C[(s32)(Rand_ZeroOne() * 111.1f) & 7], 0, 0, 80, -1, 1, gKakeraLeafMiddleDL);
|
sFragmentScales[(s32)(Rand_ZeroOne() * 111.1f) & 7], 0, 0, 80, -1, GAMEPLAY_KEEP,
|
||||||
|
gKakeraLeafMiddleDL);
|
||||||
|
|
||||||
spB0.x = arg0->x + (ptr->x * 16.0f);
|
pos.x = basePos->x + (dir->x * 16.0f);
|
||||||
spB0.y = arg0->y + (ptr->y * 16.0f) + 10.0f;
|
pos.y = basePos->y + (dir->y * 16.0f) + 10.0f;
|
||||||
spB0.z = arg0->z + (ptr->z * 16.0f);
|
pos.z = basePos->z + (dir->z * 16.0f);
|
||||||
|
|
||||||
spBC.x = (Rand_ZeroOne() - 0.5f) * 6.0f;
|
velocity.x = (Rand_ZeroOne() - 0.5f) * 6.0f;
|
||||||
spBC.y = Rand_ZeroOne() * 10.0f;
|
velocity.y = Rand_ZeroOne() * 10.0f;
|
||||||
spBC.z = (Rand_ZeroOne() - 0.5f) * 6.0f;
|
velocity.z = (Rand_ZeroOne() - 0.5f) * 6.0f;
|
||||||
|
|
||||||
EffectSsKakera_Spawn(play, &spB0, &spBC, &spB0, -100, 64, 40, 3, 0,
|
EffectSsKakera_Spawn(play, &pos, &velocity, &pos, -100, 64, 40, 3, 0,
|
||||||
D_809ABC3C[(s32)(Rand_ZeroOne() * 111.1f) % 7], 0, 0, 80, -1, 1, gKakeraLeafTipDL);
|
sFragmentScales[(s32)(Rand_ZeroOne() * 111.1f) % 7], 0, 0, 80, -1, GAMEPLAY_KEEP,
|
||||||
|
gKakeraLeafTipDL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +156,7 @@ void ObjGrassCarry_Init(Actor* thisx, PlayState* play) {
|
||||||
Collider_InitCylinder(play, &this->collider);
|
Collider_InitCylinder(play, &this->collider);
|
||||||
Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit);
|
Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit);
|
||||||
this->actor.colChkInfo.mass = 80;
|
this->actor.colChkInfo.mass = 80;
|
||||||
func_809AB3C4(this);
|
ObjGrassCarry_SetupAwaitSpawnManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjGrassCarry_Destroy(Actor* thisx, PlayState* play) {
|
void ObjGrassCarry_Destroy(Actor* thisx, PlayState* play) {
|
||||||
|
@ -162,73 +164,69 @@ void ObjGrassCarry_Destroy(Actor* thisx, PlayState* play) {
|
||||||
|
|
||||||
Collider_DestroyCylinder(play, &this->collider);
|
Collider_DestroyCylinder(play, &this->collider);
|
||||||
|
|
||||||
if (this->unk_190 != NULL) {
|
if (this->grassManager != NULL) {
|
||||||
ObjGrassCarry** carry = &this->unk_190->unk_3298[this->actor.params];
|
ObjGrassCarry** carry = &this->grassManager->grassCarry[this->actor.params];
|
||||||
|
|
||||||
if (this == *carry) {
|
if (this == *carry) {
|
||||||
*carry = NULL;
|
*carry = NULL;
|
||||||
this->unk_190 = NULL;
|
this->grassManager = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AB3C4(ObjGrassCarry* this) {
|
void ObjGrassCarry_SetupAwaitSpawnManager(ObjGrassCarry* this) {
|
||||||
this->actionFunc = func_809AB3D8;
|
this->actionFunc = ObjGrassCarry_AwaitSpawnManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AB3D8(ObjGrassCarry* this, PlayState* play) {
|
void ObjGrassCarry_AwaitSpawnManager(ObjGrassCarry* this, PlayState* play) {
|
||||||
if (this->unk_190 != NULL) {
|
if (this->grassManager != NULL) {
|
||||||
if (this->actor.params != this->unk_190->unk_3292) {
|
if (this->actor.params != this->grassManager->activeGrassCarry) {
|
||||||
func_809AB474(this);
|
ObjGrassCarry_Reset(this);
|
||||||
} else {
|
} else {
|
||||||
func_809AB428(this);
|
ObjGrassCarry_SetupIdle(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AB428(ObjGrassCarry* this) {
|
void ObjGrassCarry_SetupIdle(ObjGrassCarry* this) {
|
||||||
this->actionFunc = func_809AB43C;
|
this->actionFunc = ObjGrassCarry_Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AB43C(ObjGrassCarry* this, PlayState* play) {
|
void ObjGrassCarry_Idle(ObjGrassCarry* this, PlayState* play) {
|
||||||
if (this->actor.params != this->unk_190->unk_3292) {
|
if (this->actor.params != this->grassManager->activeGrassCarry) {
|
||||||
func_809AB474(this);
|
ObjGrassCarry_Reset(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AB474(ObjGrassCarry* this) {
|
void ObjGrassCarry_Reset(ObjGrassCarry* this) {
|
||||||
this->actor.shape.rot.z = 0;
|
this->actionFunc = ObjGrassCarry_Main;
|
||||||
this->actionFunc = func_809AB4A8;
|
this->grassElem = NULL;
|
||||||
this->unk_194 = NULL;
|
this->actor.world.rot.x = this->actor.world.rot.y = this->actor.world.rot.z = this->actor.shape.rot.x =
|
||||||
this->actor.shape.rot.y = this->actor.shape.rot.z;
|
this->actor.shape.rot.y = this->actor.shape.rot.z = 0;
|
||||||
this->actor.shape.rot.x = this->actor.shape.rot.z;
|
|
||||||
this->actor.world.rot.z = this->actor.shape.rot.z;
|
|
||||||
this->actor.world.rot.y = this->actor.shape.rot.z;
|
|
||||||
this->actor.world.rot.x = this->actor.shape.rot.z;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AB4A8(ObjGrassCarry* this, PlayState* play) {
|
void ObjGrassCarry_Main(ObjGrassCarry* this, PlayState* play) {
|
||||||
Actor* thisx = &this->actor;
|
Actor* thisx = &this->actor;
|
||||||
|
|
||||||
if (Actor_HasParent(thisx, play)) {
|
if (Actor_HasParent(thisx, play)) {
|
||||||
func_809AB5FC(this);
|
ObjGrassCarry_SetupLiftedUp(this);
|
||||||
if (this->unk_194 != NULL) {
|
if (this->grassElem != NULL) {
|
||||||
this->unk_194->unk_0F |= 4;
|
this->grassElem->flags |= OBJ_GRASS_ELEM_REMOVED;
|
||||||
}
|
}
|
||||||
thisx->draw = func_809ABB7C;
|
thisx->draw = ObjGrassCarry_Draw;
|
||||||
thisx->shape.shadowDraw = ActorShadow_DrawCircle;
|
thisx->shape.shadowDraw = ActorShadow_DrawCircle;
|
||||||
thisx->shape.shadowAlpha = 60;
|
thisx->shape.shadowAlpha = 60;
|
||||||
thisx->shape.shadowScale = 1.0f;
|
thisx->shape.shadowScale = 1.0f;
|
||||||
this->unk_190->unk_3292 ^= 1;
|
this->grassManager->activeGrassCarry ^= 1;
|
||||||
thisx->room = -1;
|
thisx->room = -1;
|
||||||
SoundSource_PlaySfxAtFixedWorldPos(play, &thisx->world.pos, 20, NA_SE_PL_PULL_UP_PLANT);
|
SoundSource_PlaySfxAtFixedWorldPos(play, &thisx->world.pos, 20, NA_SE_PL_PULL_UP_PLANT);
|
||||||
} else if (this->unk_190->unk_3294 != NULL) {
|
} else if (this->grassManager->carryGrassElem != NULL) {
|
||||||
Player* player = GET_PLAYER(play);
|
Player* player = GET_PLAYER(play);
|
||||||
|
|
||||||
this->unk_194 = this->unk_190->unk_3294;
|
this->grassElem = this->grassManager->carryGrassElem;
|
||||||
Math_Vec3f_Copy(&thisx->world.pos, &this->unk_194->unk_00);
|
Math_Vec3f_Copy(&thisx->world.pos, &this->grassElem->pos);
|
||||||
thisx->shape.rot.y = thisx->world.rot.y = this->unk_194->unk_0C;
|
thisx->shape.rot.y = thisx->world.rot.y = this->grassElem->rotY;
|
||||||
this->unk_198 = this->unk_194->unk_0E;
|
this->dropTable = this->grassElem->dropTable;
|
||||||
thisx->xzDistToPlayer = Actor_WorldDistXZToActor(&this->actor, &player->actor);
|
thisx->xzDistToPlayer = Actor_WorldDistXZToActor(&this->actor, &player->actor);
|
||||||
thisx->playerHeightRel = Actor_HeightDiff(&this->actor, &player->actor);
|
thisx->playerHeightRel = Actor_HeightDiff(&this->actor, &player->actor);
|
||||||
thisx->xyzDistToPlayerSq = SQ(thisx->xzDistToPlayer) + SQ(thisx->playerHeightRel);
|
thisx->xyzDistToPlayerSq = SQ(thisx->xzDistToPlayer) + SQ(thisx->playerHeightRel);
|
||||||
|
@ -237,87 +235,88 @@ void func_809AB4A8(ObjGrassCarry* this, PlayState* play) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AB5FC(ObjGrassCarry* this) {
|
void ObjGrassCarry_SetupLiftedUp(ObjGrassCarry* this) {
|
||||||
this->actionFunc = func_809AB610;
|
this->actionFunc = ObjGrassCarry_LiftedUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AB610(ObjGrassCarry* this, PlayState* play) {
|
void ObjGrassCarry_LiftedUp(ObjGrassCarry* this, PlayState* play) {
|
||||||
s32 pad;
|
s32 pad;
|
||||||
Vec3f sp30;
|
|
||||||
s32 sp2C;
|
|
||||||
|
|
||||||
if (Actor_HasNoParent(&this->actor, play)) {
|
if (Actor_HasNoParent(&this->actor, play)) {
|
||||||
func_809AB6FC(this);
|
ObjGrassCarry_SetupFall(this);
|
||||||
this->actor.velocity.x = Math_SinS(this->actor.world.rot.y) * this->actor.speed;
|
this->actor.velocity.x = Math_SinS(this->actor.world.rot.y) * this->actor.speed;
|
||||||
this->actor.velocity.z = Math_CosS(this->actor.world.rot.y) * this->actor.speed;
|
this->actor.velocity.z = Math_CosS(this->actor.world.rot.y) * this->actor.speed;
|
||||||
this->actor.gravity = -0.1f;
|
this->actor.gravity = -0.1f;
|
||||||
this->actor.terminalVelocity = -17.0f;
|
this->actor.terminalVelocity = -17.0f;
|
||||||
func_809AAF18(this);
|
ObjGrassCarry_UpdatePos(this);
|
||||||
func_809AAF58(this, play);
|
ObjGrassCarry_UpdateBgCheckInfo(this, play);
|
||||||
this->actor.gravity = -3.2f;
|
this->actor.gravity = -3.2f;
|
||||||
} else {
|
} else {
|
||||||
sp30.x = this->actor.world.pos.x;
|
Vec3f pos;
|
||||||
sp30.y = this->actor.world.pos.y + 20.0f;
|
s32 bgId;
|
||||||
sp30.z = this->actor.world.pos.z;
|
|
||||||
|
pos.x = this->actor.world.pos.x;
|
||||||
|
pos.y = this->actor.world.pos.y + 20.0f;
|
||||||
|
pos.z = this->actor.world.pos.z;
|
||||||
this->actor.floorHeight =
|
this->actor.floorHeight =
|
||||||
BgCheck_EntityRaycastFloor5(&play->colCtx, &this->actor.floorPoly, &sp2C, &this->actor, &sp30);
|
BgCheck_EntityRaycastFloor5(&play->colCtx, &this->actor.floorPoly, &bgId, &this->actor, &pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AB6FC(ObjGrassCarry* this) {
|
void ObjGrassCarry_SetupFall(ObjGrassCarry* this) {
|
||||||
this->actionFunc = func_809AB77C;
|
this->actionFunc = ObjGrassCarry_Fall;
|
||||||
D_809ABBFC = -0xBB8;
|
sRotSpeedXTarget = -0xBB8;
|
||||||
D_809ABC04 = (Rand_ZeroOne() - 0.5f) * 1600.0f;
|
sRotSpeedYTarget = (Rand_ZeroOne() - 0.5f) * 1600.0f;
|
||||||
D_809ABC00 = 0;
|
sRotSpeedX = 0;
|
||||||
D_809ABC08 = 0;
|
sRotSpeedY = 0;
|
||||||
this->unk_19A = 60;
|
this->fallTimer = 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809AB77C(ObjGrassCarry* this, PlayState* play) {
|
void ObjGrassCarry_Fall(ObjGrassCarry* this, PlayState* play) {
|
||||||
s16 phi_s0;
|
s16 angle;
|
||||||
s32 temp_v0 = (this->collider.base.atFlags & AT_HIT) != 0;
|
s32 atHit = (this->collider.base.atFlags & AT_HIT) != 0;
|
||||||
Vec3f sp5C;
|
Vec3f pos;
|
||||||
s32 i;
|
s32 i;
|
||||||
|
|
||||||
if (temp_v0) {
|
if (atHit) {
|
||||||
this->collider.base.atFlags &= ~AT_HIT;
|
this->collider.base.atFlags &= ~AT_HIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->unk_19A--;
|
this->fallTimer--;
|
||||||
|
|
||||||
if ((this->actor.bgCheckFlags & (BGCHECKFLAG_GROUND | BGCHECKFLAG_GROUND_TOUCH | BGCHECKFLAG_WALL)) || temp_v0 ||
|
if ((this->actor.bgCheckFlags & (BGCHECKFLAG_GROUND | BGCHECKFLAG_GROUND_TOUCH | BGCHECKFLAG_WALL)) || atHit ||
|
||||||
(this->unk_19A <= 0)) {
|
(this->fallTimer <= 0)) {
|
||||||
func_809AAFE8(&this->actor.world.pos, play);
|
ObjGrassCarry_SpawnFragments(&this->actor.world.pos, play);
|
||||||
func_809AAF9C(&this->actor.world.pos, this->unk_198, play);
|
ObjGrassCarry_DropCollectible(&this->actor.world.pos, this->dropTable, play);
|
||||||
|
|
||||||
this->actor.draw = NULL;
|
this->actor.draw = NULL;
|
||||||
this->actor.shape.shadowDraw = NULL;
|
this->actor.shape.shadowDraw = NULL;
|
||||||
|
|
||||||
if (this->unk_190 != NULL) {
|
if (this->grassManager != NULL) {
|
||||||
this->actor.room = this->unk_190->actor.room;
|
this->actor.room = this->grassManager->actor.room;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(this->actor.bgCheckFlags & BGCHECKFLAG_WATER)) {
|
if (!(this->actor.bgCheckFlags & BGCHECKFLAG_WATER)) {
|
||||||
SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 20, NA_SE_EV_PLANT_BROKEN);
|
SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 20, NA_SE_EV_PLANT_BROKEN);
|
||||||
}
|
}
|
||||||
func_809AB428(this);
|
ObjGrassCarry_SetupIdle(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->actor.bgCheckFlags & BGCHECKFLAG_WATER_TOUCH) {
|
if (this->actor.bgCheckFlags & BGCHECKFLAG_WATER_TOUCH) {
|
||||||
sp5C.y = this->actor.world.pos.y + this->actor.depthInWater;
|
pos.y = this->actor.world.pos.y + this->actor.depthInWater;
|
||||||
|
|
||||||
for (phi_s0 = 0, i = 0; i < 4; i++, phi_s0 += 0x4000) {
|
for (angle = 0, i = 0; i < 4; i++, angle += 0x4000) {
|
||||||
sp5C.x = (Math_SinS((s32)(Rand_ZeroOne() * 7200.0f) + phi_s0) * 15.0f) + this->actor.world.pos.x;
|
pos.x = (Math_SinS((s32)(Rand_ZeroOne() * 7200.0f) + angle) * 15.0f) + this->actor.world.pos.x;
|
||||||
sp5C.z = (Math_CosS((s32)(Rand_ZeroOne() * 7200.0f) + phi_s0) * 15.0f) + this->actor.world.pos.z;
|
pos.z = (Math_CosS((s32)(Rand_ZeroOne() * 7200.0f) + angle) * 15.0f) + this->actor.world.pos.z;
|
||||||
EffectSsGSplash_Spawn(play, &sp5C, NULL, NULL, 0, 190);
|
EffectSsGSplash_Spawn(play, &pos, NULL, NULL, 0, 190);
|
||||||
}
|
}
|
||||||
|
|
||||||
sp5C.x = this->actor.world.pos.x;
|
pos.x = this->actor.world.pos.x;
|
||||||
sp5C.z = this->actor.world.pos.z;
|
pos.z = this->actor.world.pos.z;
|
||||||
|
|
||||||
EffectSsGSplash_Spawn(play, &sp5C, NULL, NULL, 0, 280);
|
EffectSsGSplash_Spawn(play, &pos, NULL, NULL, 0, 280);
|
||||||
EffectSsGRipple_Spawn(play, &sp5C, 300, 700, 0);
|
EffectSsGRipple_Spawn(play, &pos, 300, 700, 0);
|
||||||
|
|
||||||
this->actor.terminalVelocity = -3.0f;
|
this->actor.terminalVelocity = -3.0f;
|
||||||
this->actor.velocity.x *= 0.1f;
|
this->actor.velocity.x *= 0.1f;
|
||||||
|
@ -325,20 +324,20 @@ void func_809AB77C(ObjGrassCarry* this, PlayState* play) {
|
||||||
this->actor.velocity.z *= 0.1f;
|
this->actor.velocity.z *= 0.1f;
|
||||||
this->actor.gravity *= 0.5f;
|
this->actor.gravity *= 0.5f;
|
||||||
|
|
||||||
D_809ABC00 = D_809ABC00 >> 1;
|
sRotSpeedX >>= 1;
|
||||||
D_809ABBFC = D_809ABBFC >> 1;
|
sRotSpeedXTarget >>= 1;
|
||||||
D_809ABC08 = D_809ABC08 >> 1;
|
sRotSpeedY >>= 1;
|
||||||
D_809ABC04 = D_809ABC04 >> 1;
|
sRotSpeedYTarget >>= 1;
|
||||||
this->actor.bgCheckFlags &= ~BGCHECKFLAG_WATER_TOUCH;
|
this->actor.bgCheckFlags &= ~BGCHECKFLAG_WATER_TOUCH;
|
||||||
SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L);
|
SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L);
|
||||||
}
|
}
|
||||||
|
|
||||||
Math_StepToS(&D_809ABC00, D_809ABBFC, 0x1F4);
|
Math_StepToS(&sRotSpeedX, sRotSpeedXTarget, 0x1F4);
|
||||||
Math_StepToS(&D_809ABC08, D_809ABC04, 0xAA);
|
Math_StepToS(&sRotSpeedY, sRotSpeedYTarget, 0xAA);
|
||||||
this->actor.shape.rot.x += D_809ABC00;
|
this->actor.shape.rot.x += sRotSpeedX;
|
||||||
this->actor.shape.rot.y += D_809ABC08;
|
this->actor.shape.rot.y += sRotSpeedY;
|
||||||
func_809AAF18(this);
|
ObjGrassCarry_UpdatePos(this);
|
||||||
func_809AAF58(this, play);
|
ObjGrassCarry_UpdateBgCheckInfo(this, play);
|
||||||
|
|
||||||
Collider_UpdateCylinder(&this->actor, &this->collider);
|
Collider_UpdateCylinder(&this->actor, &this->collider);
|
||||||
CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base);
|
CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base);
|
||||||
|
@ -348,8 +347,8 @@ void func_809AB77C(ObjGrassCarry* this, PlayState* play) {
|
||||||
void ObjGrassCarry_Update(Actor* thisx, PlayState* play) {
|
void ObjGrassCarry_Update(Actor* thisx, PlayState* play) {
|
||||||
ObjGrassCarry* this = THIS;
|
ObjGrassCarry* this = THIS;
|
||||||
|
|
||||||
if (this->unk_190 == NULL) {
|
if (this->grassManager == NULL) {
|
||||||
if ((this->actionFunc != func_809AB610) && (this->actionFunc != func_809AB77C)) {
|
if ((this->actionFunc != ObjGrassCarry_LiftedUp) && (this->actionFunc != ObjGrassCarry_Fall)) {
|
||||||
Actor_Kill(&this->actor);
|
Actor_Kill(&this->actor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -358,6 +357,6 @@ void ObjGrassCarry_Update(Actor* thisx, PlayState* play) {
|
||||||
this->actionFunc(this, play);
|
this->actionFunc(this, play);
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_809ABB7C(Actor* this, PlayState* play) {
|
void ObjGrassCarry_Draw(Actor* this, PlayState* play) {
|
||||||
Gfx_DrawDListOpa(play, gKusaBushType1DL);
|
Gfx_DrawDListOpa(play, gKusaBushType1DL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,17 +5,17 @@
|
||||||
|
|
||||||
struct ObjGrassCarry;
|
struct ObjGrassCarry;
|
||||||
struct ObjGrass;
|
struct ObjGrass;
|
||||||
struct ObjGrassStruct1_1;
|
struct ObjGrassElement;
|
||||||
|
|
||||||
typedef void (*ObjGrassCarryActionFunc)(struct ObjGrassCarry*, PlayState*);
|
typedef void (*ObjGrassCarryActionFunc)(struct ObjGrassCarry*, PlayState*);
|
||||||
|
|
||||||
typedef struct ObjGrassCarry {
|
typedef struct ObjGrassCarry {
|
||||||
/* 0x000 */ Actor actor;
|
/* 0x000 */ Actor actor;
|
||||||
/* 0x144 */ ColliderCylinder collider;
|
/* 0x144 */ ColliderCylinder collider;
|
||||||
/* 0x190 */ struct ObjGrass* unk_190;
|
/* 0x190 */ struct ObjGrass* grassManager;
|
||||||
/* 0x194 */ struct ObjGrassStruct1_1* unk_194;
|
/* 0x194 */ struct ObjGrassElement* grassElem;
|
||||||
/* 0x198 */ s16 unk_198;
|
/* 0x198 */ s16 dropTable;
|
||||||
/* 0x19A */ s16 unk_19A;
|
/* 0x19A */ s16 fallTimer;
|
||||||
/* 0x19C */ ObjGrassCarryActionFunc actionFunc;
|
/* 0x19C */ ObjGrassCarryActionFunc actionFunc;
|
||||||
} ObjGrassCarry; // size = 0x1A0
|
} ObjGrassCarry; // size = 0x1A0
|
||||||
|
|
||||||
|
|
|
@ -1,38 +1,168 @@
|
||||||
/*
|
/*
|
||||||
* File: z_obj_grass_unit.c
|
* File: z_obj_grass_unit.c
|
||||||
* Overlay: ovl_Obj_Grass_Unit
|
* Overlay: ovl_Obj_Grass_Unit
|
||||||
* Description: Spawner for circular patch of grass
|
* Description: Initializes a pattern of grass to be passed to an ObjGrass instance.
|
||||||
|
*
|
||||||
|
* ObjGrassUnit instances are intended to be spawned from room data so that just one ObjGrass instance manages the grass
|
||||||
|
* for that room. When a room with ObjGrassUnit spawns loads, it allocates ovl_Obj_Grass_Unit and creates N instances of
|
||||||
|
* ObjGrassUnit. The first instance processed initializes sGrassManager, then all instances live on that cycle pass type
|
||||||
|
* and position data to that ObjGrass instance before calling Actor_Kill. Since ovl_Obj_Grass_Unit uses
|
||||||
|
* ALLOCTYPE_NORMAL, it is deleted and loses the reference to the newly created ObjGrass. This allows for ObjGrassUnit
|
||||||
|
* spawned in a different room to be associated to a new ObjGrass instance.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "z_obj_grass_unit.h"
|
#include "z_obj_grass_unit.h"
|
||||||
|
#include "overlays/actors/ovl_Obj_Grass/z_obj_grass.h"
|
||||||
|
#include "overlays/actors/ovl_Obj_Grass_Carry/z_obj_grass_carry.h"
|
||||||
|
|
||||||
#define FLAGS 0x00000000
|
#define FLAGS 0x00000000
|
||||||
|
|
||||||
#define THIS ((ObjGrassUnit*)thisx)
|
#define THIS ((ObjGrassUnit*)thisx)
|
||||||
|
|
||||||
void ObjGrassUnit_Init(Actor* thisx, PlayState* play);
|
void ObjGrassUnit_Init(Actor* this, PlayState* play2);
|
||||||
|
|
||||||
#if 0
|
|
||||||
ActorInit Obj_Grass_Unit_InitVars = {
|
ActorInit Obj_Grass_Unit_InitVars = {
|
||||||
ACTOR_OBJ_GRASS_UNIT,
|
ACTOR_OBJ_GRASS_UNIT, ACTORCAT_BG, FLAGS,
|
||||||
ACTORCAT_BG,
|
GAMEPLAY_FIELD_KEEP, sizeof(ObjGrassUnit), (ActorFunc)ObjGrassUnit_Init,
|
||||||
FLAGS,
|
(ActorFunc)Actor_Noop, (ActorFunc)Actor_Noop, (ActorFunc)NULL,
|
||||||
GAMEPLAY_FIELD_KEEP,
|
|
||||||
sizeof(ObjGrassUnit),
|
|
||||||
(ActorFunc)ObjGrassUnit_Init,
|
|
||||||
(ActorFunc)Actor_Noop,
|
|
||||||
(ActorFunc)Actor_Noop,
|
|
||||||
(ActorFunc)NULL,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
// Neat circular pattern with a single bush in the center
|
||||||
|
static VecPolar sGrassPatternCircle[] = {
|
||||||
|
{ 0.0f, 0x0000 }, { 80.0f, 0x0000 }, { 80.0f, 0x2000 }, { 80.0f, 0x4000 }, { 80.0f, 0x6000 },
|
||||||
|
{ 80.0f, 0x8000 }, { 80.0f, 0xA000 }, { 80.0f, 0xC000 }, { 80.0f, 0xE000 },
|
||||||
|
};
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Unit/func_809ABDE0.s")
|
// "Random" looking pattern
|
||||||
|
static VecPolar sGrassPatternMixed[] = {
|
||||||
|
{ 40.0f, 0x0666 }, { 40.0f, 0x2CCC }, { 40.0f, 0x5999 }, { 40.0f, 0x8667 }, { 20.0f, 0xC000 }, { 80.0f, 0x1333 },
|
||||||
|
{ 80.0f, 0x4000 }, { 80.0f, 0x6CCC }, { 80.0f, 0x9334 }, { 80.0f, 0xACCD }, { 80.0f, 0xC667 }, { 60.0f, 0xE000 },
|
||||||
|
};
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Unit/func_809ABE54.s")
|
typedef struct {
|
||||||
|
/* 0x0 */ s32 count;
|
||||||
|
/* 0x4 */ VecPolar* positions;
|
||||||
|
} ObjGrassUnitPattern; // size = 0x8
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Unit/func_809ABEC4.s")
|
static ObjGrassUnitPattern sGrassPatterns[2] = {
|
||||||
|
{ ARRAY_COUNT(sGrassPatternCircle), sGrassPatternCircle },
|
||||||
|
{ ARRAY_COUNT(sGrassPatternMixed), sGrassPatternMixed },
|
||||||
|
};
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Unit/func_809ABF38.s")
|
ObjGrass* sGrassManager = NULL;
|
||||||
|
ObjGrassCarry* sGrassCarry0 = NULL;
|
||||||
|
ObjGrassCarry* sGrassCarry1 = NULL;
|
||||||
|
s32 sInitialized = false;
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Unit/ObjGrassUnit_Init.s")
|
s32 ObjGrassUnit_SpawnObjGrass(Actor* this, PlayState* play) {
|
||||||
|
sGrassManager = (ObjGrass*)Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_GRASS, 0.0f, 0.0f, 0.0f, 0, 0, 0, -1);
|
||||||
|
if (sGrassManager != NULL) {
|
||||||
|
sGrassManager->actor.room = this->room;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 ObjGrassUnit_SpawnObjGrassCarry0(Actor* this, PlayState* play) {
|
||||||
|
sGrassCarry0 =
|
||||||
|
(ObjGrassCarry*)Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_GRASS_CARRY, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0);
|
||||||
|
if (sGrassCarry0 != NULL) {
|
||||||
|
sGrassCarry0->actor.room = this->room;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 ObjGrassUnit_SpawnObjGrassCarry1(Actor* this, PlayState* play) {
|
||||||
|
sGrassCarry1 =
|
||||||
|
(ObjGrassCarry*)Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_GRASS_CARRY, 0.0f, 0.0f, 0.0f, 0, 0, 0, 1);
|
||||||
|
if (sGrassCarry1 != NULL) {
|
||||||
|
sGrassCarry1->actor.room = this->room;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 ObjGrassUnit_IsUnderwater(PlayState* play, Vec3f* pos) {
|
||||||
|
WaterBox* waterBox;
|
||||||
|
f32 ySurface;
|
||||||
|
s32 bgId;
|
||||||
|
|
||||||
|
if (WaterBox_GetSurfaceImpl(play, &play->colCtx, pos->x, pos->z, &ySurface, &waterBox, &bgId) &&
|
||||||
|
(pos->y < ySurface)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjGrassUnit_Init(Actor* this, PlayState* play2) {
|
||||||
|
PlayState* play = play2;
|
||||||
|
ObjGrassGroup* grassGroup;
|
||||||
|
ObjGrass* grassManager;
|
||||||
|
f32 homePosYSum;
|
||||||
|
f32 tmp;
|
||||||
|
s32 i;
|
||||||
|
VecPolar* grassPos;
|
||||||
|
CollisionPoly* poly;
|
||||||
|
s32 bgId;
|
||||||
|
ObjGrassElement* grassElem;
|
||||||
|
ObjGrassUnitPattern* grassPattern;
|
||||||
|
s8 dropTable = OBJGRASSUNIT_GET_DROPTABLE(this);
|
||||||
|
|
||||||
|
if ((sGrassManager == NULL) && !ObjGrassUnit_SpawnObjGrass(this, play)) {
|
||||||
|
Actor_Kill(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((sGrassCarry0 == NULL) && ObjGrassUnit_SpawnObjGrassCarry0(this, play)) {
|
||||||
|
sGrassCarry0->grassManager = sGrassManager;
|
||||||
|
}
|
||||||
|
if ((sGrassCarry1 == NULL) && ObjGrassUnit_SpawnObjGrassCarry1(this, play)) {
|
||||||
|
sGrassCarry1->grassManager = sGrassManager;
|
||||||
|
}
|
||||||
|
if (!sInitialized && (sGrassManager != NULL) && (sGrassCarry0 != NULL) && (sGrassCarry1 != NULL)) {
|
||||||
|
sInitialized = true;
|
||||||
|
sGrassManager->grassCarry[0] = sGrassCarry0;
|
||||||
|
sGrassManager->grassCarry[1] = sGrassCarry1;
|
||||||
|
sGrassCarry0->grassManager = sGrassManager;
|
||||||
|
sGrassCarry1->grassManager = sGrassManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
grassManager = sGrassManager;
|
||||||
|
if (sGrassManager->activeGrassGroups >= ARRAY_COUNT(sGrassManager->grassGroups)) {
|
||||||
|
Actor_Kill(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
homePosYSum = 0.0f;
|
||||||
|
grassGroup = &grassManager->grassGroups[sGrassManager->activeGrassGroups];
|
||||||
|
grassGroup->count = 0;
|
||||||
|
grassPattern = &sGrassPatterns[OBJGRASSUNIT_GET_PATTERN(this)];
|
||||||
|
|
||||||
|
for (i = 0; i < grassPattern->count; i++) {
|
||||||
|
grassElem = &grassGroup->elements[grassGroup->count];
|
||||||
|
grassPos = &grassPattern->positions[i];
|
||||||
|
|
||||||
|
grassElem->pos.x = (Math_CosS((this->home.rot.y + grassPos->angle)) * grassPos->distance) + this->home.pos.x;
|
||||||
|
grassElem->pos.y = this->home.pos.y + 100.0f;
|
||||||
|
grassElem->pos.z = (Math_SinS((this->home.rot.y + grassPos->angle)) * grassPos->distance) + this->home.pos.z;
|
||||||
|
|
||||||
|
grassElem->pos.y = BgCheck_EntityRaycastFloor5(&play->colCtx, &poly, &bgId, this, &grassElem->pos);
|
||||||
|
tmp = grassElem->pos.y - this->home.pos.y;
|
||||||
|
if ((fabsf(tmp) < 80.0f) && (grassElem->pos.y > BGCHECK_Y_MIN)) {
|
||||||
|
grassGroup->count++;
|
||||||
|
grassElem->rotY = (s16)(Rand_Next() >> 0x10);
|
||||||
|
grassElem->dropTable = dropTable;
|
||||||
|
if (ObjGrassUnit_IsUnderwater(play, &grassElem->pos)) {
|
||||||
|
grassElem->flags |= OBJ_GRASS_ELEM_UNDERWATER;
|
||||||
|
}
|
||||||
|
homePosYSum += grassElem->pos.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (grassGroup->count > 0) {
|
||||||
|
grassManager->activeGrassGroups++;
|
||||||
|
grassGroup->homePos.x = this->home.pos.x;
|
||||||
|
grassGroup->homePos.y = (homePosYSum / grassGroup->count);
|
||||||
|
grassGroup->homePos.z = this->home.pos.z;
|
||||||
|
}
|
||||||
|
Actor_Kill(this);
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
|
#define OBJGRASSUNIT_GET_DROPTABLE(thisx) (((thisx)->params >> 8) & 0x1F)
|
||||||
|
#define OBJGRASSUNIT_GET_PATTERN(thisx) ((thisx)->params & 1)
|
||||||
|
|
||||||
struct ObjGrassUnit;
|
struct ObjGrassUnit;
|
||||||
|
|
||||||
typedef struct ObjGrassUnit {
|
typedef struct ObjGrassUnit {
|
||||||
|
|
Loading…
Reference in New Issue