z_obj_tsubo OK (#784)

* 4 unattempts left

* z_obj_tsubo OK

* name some functions

* implement suggestions

* implement EllipticEllipsis changes

* implement more suggestions
This commit is contained in:
mzxrules
2022-06-20 15:44:12 -04:00
committed by GitHub
parent c6963e27d0
commit 361d8573e9
10 changed files with 670 additions and 64 deletions
+1 -1
View File
@@ -450,7 +450,7 @@ Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, s32 para
void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3f* spawnPos, s16 params);
s32 func_800A8150(s32 index);
s32 func_800A817C(s32 index);
s32 func_800A81A4(GlobalContext* globalCtx, s32 a1, s32 a2);
s32 Item_CanDropBigFairy(GlobalContext* globalCtx, s32 index, s32 collectibleFlag);
void EffectBlure_AddVertex(EffectBlure* this, Vec3f* p1, Vec3f* p2);
void EffectBlure_AddSpace(EffectBlure* this);
void EffectBlure_Init1(void* thisx, void* initParamsx);
+1 -2
View File
@@ -1369,8 +1369,7 @@ beginseg
name "ovl_Obj_Tsubo"
compress
include "build/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.o"
include "build/data/ovl_Obj_Tsubo/ovl_Obj_Tsubo.data.o"
include "build/data/ovl_Obj_Tsubo/ovl_Obj_Tsubo.reloc.o"
include "build/src/overlays/actors/ovl_Obj_Tsubo/ovl_Obj_Tsubo_reloc.o"
endseg
beginseg
+2 -2
View File
@@ -1185,6 +1185,6 @@ s32 func_800A817C(s32 index) {
return D_801AE214[index];
}
s32 func_800A81A4(GlobalContext* globalCtx, s32 a1, s32 a2) {
return (func_800A8150(a1) == ITEM00_BIG_FAIRY) && (!Flags_GetCollectible(globalCtx, a2));
s32 Item_CanDropBigFairy(GlobalContext* globalCtx, s32 index, s32 collectibleFlag) {
return (func_800A8150(index) == ITEM00_BIG_FAIRY) && (!Flags_GetCollectible(globalCtx, collectibleFlag));
}
+1 -1
View File
@@ -487,7 +487,7 @@ void func_808D9894(EnSw* this, Vec3f* vec) {
s32 func_808D9968(EnSw* this, GlobalContext* globalCtx) {
s32 ret = false;
s32 param = ENSW_GET_3FC(&this->actor) & 0xFF;
s32 param = ENSW_GET_3FC(&this->actor);
if (ENSW_GET_3(&this->actor)) {
if ((param != 0x3F) && Flags_GetTreasure(globalCtx, param)) {
+4 -2
View File
@@ -7,8 +7,10 @@ struct EnSw;
typedef void (*EnSwActionFunc)(struct EnSw*, GlobalContext*);
#define ENSW_GET_3(thisx) (((thisx)->params & 3) & 0xFF)
#define ENSW_GET_3FC(thisx) (((thisx)->params & 0x3FC) >> 2)
#define ENSW_GETS_3(params) ((params & 3) & 0xFF)
#define ENSW_GET_3(thisx) (ENSW_GETS_3((thisx)->params))
#define ENSW_GETS_3FC(params) (((params & 0x3FC) >> 2) & 0xFF)
#define ENSW_GET_3FC(thisx) (ENSW_GETS_3FC((thisx)->params))
#define ENSW_GET_FF00(thisx) ((((thisx)->params & 0xFF00) >> 8) & 0xFF)
typedef struct EnSw {
@@ -341,7 +341,7 @@ void ObjComb_Init(Actor* thisx, GlobalContext* globalCtx) {
Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, &this->colliderElement);
if ((sp2C == 0) && func_800A81A4(globalCtx, OBJCOMB_GET_3F(&this->actor), OBJCOMB_GET_7F00(&this->actor))) {
if ((sp2C == 0) && Item_CanDropBigFairy(globalCtx, OBJCOMB_GET_3F(&this->actor), OBJCOMB_GET_7F00(&this->actor))) {
this->unk_1B7 = 1;
this->actor.flags |= ACTOR_FLAG_10;
}
@@ -158,8 +158,8 @@ void ObjKibako2_Init(Actor* thisx, GlobalContext* globalCtx) {
this->dyna.actor.world.rot.x = 0;
this->dyna.actor.shape.rot.x = 0;
if (contents == CONTENTS_COLLECTIBLE) {
if (func_800A81A4(globalCtx, KIBAKO2_COLLECTIBLE_ID(&this->dyna.actor),
KIBAKO2_COLLECTIBLE_FLAG(&this->dyna.actor))) {
if (Item_CanDropBigFairy(globalCtx, KIBAKO2_COLLECTIBLE_ID(&this->dyna.actor),
KIBAKO2_COLLECTIBLE_FLAG(&this->dyna.actor))) {
this->unk_1AC = 1;
this->dyna.actor.flags |= ACTOR_FLAG_10;
}
+622 -42
View File
@@ -5,6 +5,10 @@
*/
#include "z_obj_tsubo.h"
#include "overlays/actors/ovl_En_Sw/z_en_sw.h"
#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
#include "objects/object_tsubo/object_tsubo.h"
#include "objects/object_racetsubo/object_racetsubo.h"
#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_800000 | ACTOR_FLAG_4000000)
@@ -13,14 +17,30 @@
void ObjTsubo_Init(Actor* thisx, GlobalContext* globalCtx);
void ObjTsubo_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjTsubo_Update(Actor* thisx, GlobalContext* globalCtx);
void ObjTsubo_Draw(Actor* thisx, GlobalContext* globalCtx);
void ObjTsubo_PotBreak1(ObjTsubo* this, GlobalContext* globalCtx);
void ObjTsubo_RacePotBreak1(ObjTsubo* this, GlobalContext* globalCtx);
void ObjTsubo_PotBreak2(ObjTsubo* this, GlobalContext* globalCtx2);
void ObjTsubo_RacePotBreak2(ObjTsubo* this, GlobalContext* globalCtx2);
void ObjTsubo_PotBreak3(ObjTsubo* this, GlobalContext* globalCtx2);
void ObjTsubo_RacePotBreak3(ObjTsubo* this, GlobalContext* globalCtx2);
void func_80928914(ObjTsubo* this);
void func_80928928(ObjTsubo* this, GlobalContext* globalCtx);
void func_809289B4(ObjTsubo* this);
void func_809289E4(ObjTsubo* this, GlobalContext* globalCtx);
void func_80928D6C(ObjTsubo* this);
void func_80928D80(ObjTsubo* this, GlobalContext* globalCtx);
void func_80928E74(ObjTsubo* this);
void func_80928F18(ObjTsubo* this, GlobalContext* globalCtx);
void func_809291DC(ObjTsubo* this);
void func_8092926C(ObjTsubo* this, GlobalContext* globalCtx);
#if 0
s16 D_80929500 = 0;
s16 D_80929504 = 0;
s16 D_80929508 = 0;
s16 D_8092950C = 0;
const ActorInit Obj_Tsubo_InitVars = {
ACTOR_OBJ_TSUBO,
ACTORCAT_PROP,
@@ -33,79 +53,639 @@ const ActorInit Obj_Tsubo_InitVars = {
(ActorFunc)NULL,
};
// static ColliderCylinderInit sCylinderInit = {
static ColliderCylinderInit D_809295B0 = {
{ COLTYPE_HARD, AT_ON | AT_TYPE_PLAYER, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, },
{ ELEMTYPE_UNK0, { 0x00400000, 0x00, 0x02 }, { 0x05CBFFBE, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
typedef struct {
/* 0x00 */ s16 objId;
/* 0x04 */ f32 scale;
/* 0x08 */ Gfx* modelDL;
/* 0x0C */ Gfx* shardDL;
/* 0x10 */ s16 radius;
/* 0x12 */ s16 height;
/* 0x14 */ ObjTsuboUnkFunc breakPot1;
/* 0x18 */ ObjTsuboUnkFunc breakPot2;
/* 0x1C */ ObjTsuboUnkFunc breakPot3;
} ObjTsuboData;
ObjTsuboData sPotTypeData[4] = {
{ GAMEPLAY_DANGEON_KEEP, 0.197f, gameplay_dangeon_keep_DL_017EA0, gameplay_dangeon_keep_DL_018090, 12, 32,
ObjTsubo_PotBreak1, ObjTsubo_PotBreak2, ObjTsubo_PotBreak3 },
{ OBJECT_RACETSUBO, 0.29549998f, object_racetsubo_DL_000278, object_racetsubo_DL_001610, 18, 45,
ObjTsubo_RacePotBreak1, ObjTsubo_RacePotBreak2, ObjTsubo_RacePotBreak3 },
{ OBJECT_TSUBO, 0.197f, object_tsubo_DL_0017C0, object_tsubo_DL_001960, 12, 32, ObjTsubo_PotBreak1,
ObjTsubo_PotBreak2, ObjTsubo_PotBreak3 },
{ GAMEPLAY_DANGEON_KEEP, 0.197f, gameplay_dangeon_keep_DL_017EA0, gameplay_dangeon_keep_DL_018090, 12, 32,
ObjTsubo_PotBreak1, ObjTsubo_PotBreak2, ObjTsubo_PotBreak3 },
};
static ColliderCylinderInit sCylinderInit = {
{
COLTYPE_HARD,
AT_ON | AT_TYPE_PLAYER,
AC_ON | AC_TYPE_PLAYER,
OC1_ON | OC1_TYPE_ALL,
OC2_TYPE_2,
COLSHAPE_CYLINDER,
},
{
ELEMTYPE_UNK0,
{ 0x00400000, 0x00, 0x02 },
{ 0x05CBFFBE, 0x00, 0x00 },
TOUCH_ON | TOUCH_SFX_NORMAL,
BUMP_ON,
OCELEM_ON,
},
{ 12, 30, 0, { 0, 0, 0 } },
};
// static InitChainEntry sInitChain[] = {
static InitChainEntry D_809295DC[] = {
ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE),
ICHAIN_F32_DIV1000(terminalVelocity, -20000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE),
static InitChainEntry sInitChain[] = {
ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(terminalVelocity, -20000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP),
};
#endif
s32 func_809275C0(ObjTsubo* this, GlobalContext* globalCtx) {
s32 chestFlag = -1;
s32 skulltulaParams = (OBJ_TSUBO_P001F(&this->actor) << 2) | 0xFF01;
extern ColliderCylinderInit D_809295B0;
extern InitChainEntry D_809295DC[];
if (ENSW_GETS_3(skulltulaParams)) {
chestFlag = ENSW_GETS_3FC(skulltulaParams);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_809275C0.s")
return (chestFlag < 0) == true || !Flags_GetTreasure(globalCtx, chestFlag);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_8092762C.s")
void func_8092762C(ObjTsubo* this, GlobalContext* globalCtx) {
if (!OBJ_TSUBO_P0010(&this->actor) && (OBJ_TSUBO_ZROT(&this->actor) != 2)) {
Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, OBJ_TSUBO_P000F(&this->actor) << 4);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_80927690.s")
void func_80927690(ObjTsubo* this, GlobalContext* globalCtx) {
s32 itemDrop;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_80927714.s")
if (!this->unk_197 && (OBJ_TSUBO_ZROT(&this->actor) != 2)) {
itemDrop = func_800A8150(OBJ_TSUBO_P003F(&this->actor));
if (itemDrop > ITEM00_NO_DROP) {
Item_DropCollectible(globalCtx, &this->actor.world.pos, (OBJ_TSUBO_PFE00(&this->actor) << 8) | itemDrop);
this->unk_197 = true;
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_8092776C.s")
void ObjTsubo_SpawnBoes(ObjTsubo* this, GlobalContext* globalCtx, s32 arg2) {
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_MKK, this->actor.world.pos.x, this->actor.world.pos.y,
this->actor.world.pos.z, 0, 0, 0, 2);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_80927818.s")
void ObjTsubo_SpawnGoldSkulltula(ObjTsubo* this, GlobalContext* globalCtx, s32 arg2) {
Actor* child;
s32 params;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_80927864.s")
if (func_809275C0(this, globalCtx)) {
params = (OBJ_TSUBO_P001F(&this->actor) << 2) | 0xFF01;
child = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_SW, this->actor.world.pos.x,
this->actor.world.pos.y, this->actor.world.pos.z, 0, (u32)Rand_Next() >> 0x10, 0, params);
if (child != NULL) {
child->parent = &this->actor;
child->velocity.y = 0.0f;
child->speedXZ = 0.0f;
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_8092788C.s")
void func_80927818(ObjTsubo* this, GlobalContext* globalCtx, s32 arg2) {
if (OBJ_TSUBO_ZROT(&this->actor) == 1) {
ObjTsubo_SpawnBoes(this, globalCtx, arg2);
} else if (OBJ_TSUBO_ZROT(&this->actor) == 2) {
ObjTsubo_SpawnGoldSkulltula(this, globalCtx, arg2);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/ObjTsubo_Init.s")
s32 ObjTsubo_IsSceneNotGohtOrTwinmold(ObjTsubo* this, GlobalContext* globalCtx) {
return (globalCtx->sceneNum != SCENE_HAKUGIN_BS) && (globalCtx->sceneNum != SCENE_INISIE_BS);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/ObjTsubo_Destroy.s")
void func_8092788C(ObjTsubo* this, GlobalContext* globalCtx) {
if (!this->unk_197 && (globalCtx->roomCtx.currRoom.num != this->homeRoom)) {
this->unk_197 = true;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_80927A78.s")
void ObjTsubo_Init(Actor* thisx, GlobalContext* globalCtx) {
ObjTsubo* this = (ObjTsubo*)thisx;
s32 pad;
s32 type = OBJ_TSUBO_GET_TYPE(&this->actor);
s32 pad2;
s32 sp2C = OBJ_TSUBO_ZROT(&this->actor);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_80927D2C.s")
Actor_ProcessInitChain(&this->actor, sInitChain);
Actor_SetScale(&this->actor, sPotTypeData[type].scale);
this->actor.shape.rot.z = 0;
this->actor.world.rot.z = 0;
Collider_InitCylinder(globalCtx, &this->cylinderCollider);
Collider_SetCylinder(globalCtx, &this->cylinderCollider, &this->actor, &sCylinderInit);
Collider_UpdateCylinder(&this->actor, &this->cylinderCollider);
this->cylinderCollider.dim.radius = sPotTypeData[type].radius;
this->cylinderCollider.dim.height = sPotTypeData[type].height;
this->actor.colChkInfo.mass = MASS_IMMOVABLE;
this->objBankIndex = Object_GetIndex(&globalCtx->objectCtx, sPotTypeData[type].objId);
if (this->objBankIndex < 0) {
Actor_MarkForDeath(&this->actor);
} else {
this->actor.shape.shadowScale = 1.8f;
this->homeRoom = this->actor.room;
if ((type != OBJ_TSUBO_TYPE_3) && (sp2C != 2)) {
if (Item_CanDropBigFairy(globalCtx, OBJ_TSUBO_P003F(&this->actor), OBJ_TSUBO_PFE00(&this->actor))) {
this->unk_198 = true;
}
}
if ((type == OBJ_TSUBO_TYPE_3) || (sp2C != 2) || !func_809275C0(this, globalCtx)) {
this->unk_19A = -1;
}
func_80928914(this);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_80927FCC.s")
void ObjTsubo_Destroy(Actor* thisx, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = (GlobalContext*)globalCtx2;
ObjTsubo* this = (ObjTsubo*)thisx;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_809282F0.s")
Collider_DestroyCylinder(globalCtx, &this->cylinderCollider);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_8092860C.s")
void ObjTsubo_PotBreak1(ObjTsubo* this, GlobalContext* globalCtx) {
s16 rot;
s32 i;
s32 phi_s0;
s32 pad;
Vec3f pos;
Vec3f vel;
ObjTsuboData* typeData = &sPotTypeData[OBJ_TSUBO_GET_TYPE(&this->actor)];
f32 randf;
f32 sin;
f32 cos;
f32 scale;
s32 pad2;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_80928904.s")
for (i = 0, rot = 0; i < 18; rot += 0x4E20, i++) {
sin = Math_SinS(rot);
cos = Math_CosS(rot);
pos.x = sin * 8.0f;
pos.y = Rand_ZeroOne() * 12.0f + 2.0f;
pos.z = cos * 8.0f;
vel.x = pos.x * 0.23f;
vel.y = Rand_ZeroOne() * 5.0f + 2.5f;
vel.z = pos.z * 0.23f;
Math_Vec3f_Sum(&pos, &this->actor.world.pos, &pos);
randf = Rand_ZeroOne();
if (randf < 0.2f) {
phi_s0 = 0x60;
} else if (randf < 0.6f) {
phi_s0 = 0x40;
} else {
phi_s0 = 0x20;
}
scale = Rand_ZeroOne() * 110.0f + 15.0f;
EffectSsKakera_Spawn(globalCtx, &pos, &vel, &this->actor.world.pos, -260, phi_s0, 20, 0, 0, scale, 0, 0, 50, -1,
typeData->objId, typeData->shardDL);
}
func_800BBFB0(globalCtx, &this->actor.world.pos, 30.0f, 2, 20, 50, true);
func_800BBFB0(globalCtx, &this->actor.world.pos, 30.0f, 2, 10, 80, true);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_80928914.s")
void ObjTsubo_RacePotBreak1(ObjTsubo* this, GlobalContext* globalCtx) {
s16 rot;
s32 phi_s0;
s32 i;
ObjTsuboData* typeData = &sPotTypeData[OBJ_TSUBO_GET_TYPE(&this->actor)];
Vec3f pos;
Vec3f vel;
f32 randf;
f32 sin;
f32 cos;
f32 scale;
s32 pad[2];
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_80928928.s")
for (i = 0, rot = 0; i < 20; rot += 0x4E20, i++) {
sin = Math_SinS(rot);
cos = Math_CosS(rot);
pos.x = sin * 10.0f;
pos.y = Rand_ZeroOne() * 20.0f + 2.0f;
pos.z = cos * 10.0f;
vel.x = pos.x * 0.3f;
vel.y = Rand_ZeroOne() * 10.0f + 2.0f;
vel.z = pos.z * 0.3f;
Math_Vec3f_Sum(&pos, &this->actor.world.pos, &pos);
randf = Rand_ZeroOne();
if (randf < 0.2f) {
phi_s0 = 0xE0;
} else if (randf < 0.6f) {
phi_s0 = 0xC0;
} else {
phi_s0 = 0xA0;
}
scale = Rand_ZeroOne() * 160.0f + 15.0f;
EffectSsKakera_Spawn(globalCtx, &pos, &vel, &this->actor.world.pos, -340, phi_s0, 20, 0, 0, scale, 0, 0, 50, -1,
typeData->objId, typeData->shardDL);
}
func_800BBFB0(globalCtx, &this->actor.world.pos, 50.0f, 2, 40, 50, true);
func_800BBFB0(globalCtx, &this->actor.world.pos, 50.0f, 2, 20, 80, true);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_809289B4.s")
void ObjTsubo_PotBreak2(ObjTsubo* this, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = (GlobalContext*)globalCtx2;
s16 rot;
s32 i;
s32 phi_s0;
Vec3f pos;
Vec3f vel;
Vec3f* worldPos = &this->actor.world.pos;
ObjTsuboData* typeData = &sPotTypeData[OBJ_TSUBO_GET_TYPE(&this->actor)];
f32 sin;
f32 cos;
f32 scale;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_809289E4.s")
pos.y = worldPos->y + this->actor.depthInWater;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_80928D6C.s")
for (rot = 0, i = 0; i < 5; i++, rot += 0x10000 / 5) {
pos.x = Math_SinS((s32)(Rand_ZeroOne() * 6000) + rot) * 15.0f + worldPos->x;
pos.z = Math_CosS((s32)(Rand_ZeroOne() * 6000) + rot) * 15.0f + worldPos->z;
EffectSsGSplash_Spawn(globalCtx, &pos, NULL, NULL, 0, 350);
}
pos.x = worldPos->x;
pos.z = worldPos->z;
EffectSsGRipple_Spawn(globalCtx, &pos, 200, 600, 0);
for (i = 0, rot = 0; i < 13; rot += 0x4E20, i++) {
sin = Math_SinS(rot);
cos = Math_CosS(rot);
pos.x = sin * 8.0f;
pos.y = (Rand_ZeroOne() * 5.0f) + 2.0f;
pos.z = cos * 8.0f;
vel.x = pos.x * 0.2f;
vel.y = (Rand_ZeroOne() * 4.0f) + 2.0f;
vel.z = pos.z * 0.2f;
Math_Vec3f_Sum(&pos, worldPos, &pos);
if (Rand_ZeroOne() < .2f) {
phi_s0 = 0x40;
} else {
phi_s0 = 0x20;
}
scale = Rand_ZeroOne() * 105.0f + 10.0f;
EffectSsKakera_Spawn(globalCtx, &pos, &vel, worldPos, -170, phi_s0, 50, 5, 0, scale, 0, 0, 70, -1,
typeData->objId, typeData->shardDL);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_80928D80.s")
void ObjTsubo_RacePotBreak2(ObjTsubo* this, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = (GlobalContext*)globalCtx2;
s32 pad;
s16 rot;
s32 i;
Vec3f pos;
Vec3f vel;
ObjTsuboData* typeData = &sPotTypeData[OBJ_TSUBO_GET_TYPE(&this->actor)];
Vec3f* worldPos = &this->actor.world.pos;
f32 sin;
f32 cos;
s32 phi_s0;
s16 scale;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_80928E74.s")
pos.y = this->actor.world.pos.y + this->actor.depthInWater;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_80928F18.s")
for (rot = 0, i = 0; i < 5; i++, rot += 0x10000 / 5) {
pos.x = Math_SinS((s32)(Rand_ZeroOne() * 6000) + rot) * 30.0f + worldPos->x;
pos.z = Math_CosS((s32)(Rand_ZeroOne() * 6000) + rot) * 30.0f + worldPos->z;
EffectSsGSplash_Spawn(globalCtx, &pos, NULL, NULL, 0, 350);
}
pos.x = worldPos->x;
pos.z = worldPos->z;
EffectSsGRipple_Spawn(globalCtx, &pos, 300, 700, 0);
for (i = 0, rot = 0; i < 15; rot += 0x4E20, i++) {
sin = Math_SinS(rot);
cos = Math_CosS(rot);
pos.x = sin * 10.0f;
pos.y = (Rand_ZeroOne() * 15.0f) + 2.0f;
pos.z = cos * 10.0f;
vel.x = pos.x * 0.3f;
vel.y = (Rand_ZeroOne() * 4.0f) + 2.0f;
vel.z = pos.z * 0.3f;
Math_Vec3f_Sum(&pos, worldPos, &pos);
if (Rand_ZeroOne() < 0.2f) {
phi_s0 = 0xC0;
} else {
phi_s0 = 0xA0;
}
scale = (Rand_ZeroOne() * 150.0f) + 10.0f;
EffectSsKakera_Spawn(globalCtx, &pos, &vel, worldPos, -170, phi_s0, 50, 5, 0, scale, 0, 0, 70, -1,
typeData->objId, typeData->shardDL);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_809291DC.s")
void ObjTsubo_PotBreak3(ObjTsubo* this, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = (GlobalContext*)globalCtx2;
s32 i;
s16 rot;
s32 phi_s0;
Vec3f pos;
Vec3f vel;
ObjTsuboData* typeData = &sPotTypeData[OBJ_TSUBO_GET_TYPE(&this->actor)];
f32 randf;
f32 temp_f20;
f32 cos;
f32 sin;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_8092926C.s")
for (i = 0, rot = 0; i < 13; i++, rot += 0x4E20) {
randf = Rand_ZeroOne();
temp_f20 = (1.0f - SQ(randf)) * 4.8f + 3.2f;
if (this) {}
sin = Math_SinS(rot);
cos = Math_CosS(rot);
pos.x = sin * temp_f20;
pos.y = (Rand_ZeroOne() * 15.0f) + 2.0f;
pos.z = cos * temp_f20;
vel.x = pos.x * 0.4f;
vel.y = (Rand_ZeroOne() * 4.0f) + 4.0f;
vel.z = pos.z * 0.4f;
Math_Vec3f_Sum(&pos, &this->actor.world.pos, &pos);
if (Rand_ZeroOne() < 0.2f) {
phi_s0 = 0x40;
} else {
phi_s0 = 0x20;
}
EffectSsKakera_Spawn(globalCtx, &pos, &vel, &this->actor.world.pos, -170, phi_s0, 50, 3, 0,
(Rand_ZeroOne() * 105.0f) + 10.0f, 0, 0, 70, -1, typeData->objId, typeData->shardDL);
}
for (i = 0; i < 7; i++) {
EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, 20.0f, 30.0f, 40.0f, (Rand_ZeroOne() * 0.06f) + 0.09f);
EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, 10.0f, 10.0f, 10.0f, (Rand_ZeroOne() * 0.08f) + 0.09f);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/ObjTsubo_Update.s")
void ObjTsubo_RacePotBreak3(ObjTsubo* this, GlobalContext* globalCtx2) {
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tsubo/func_809294B0.s")
void func_80928914(ObjTsubo* this) {
this->actionFunc = func_80928928;
}
void func_80928928(ObjTsubo* this, GlobalContext* globalCtx) {
Actor_MoveWithGravity(&this->actor);
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 15.0f, 0.0f, 0x44);
if (Object_IsLoaded(&globalCtx->objectCtx, this->objBankIndex)) {
this->actor.objBankIndex = this->objBankIndex;
func_809289B4(this);
}
}
void func_809289B4(ObjTsubo* this) {
this->actor.draw = ObjTsubo_Draw;
this->actor.flags |= ACTOR_FLAG_10;
this->unk_195 = false;
this->actionFunc = func_809289E4;
}
void func_809289E4(ObjTsubo* this, GlobalContext* globalCtx) {
ObjTsuboData* typeData;
s32 pad;
s32 type = OBJ_TSUBO_GET_TYPE(&this->actor);
s32 pad2;
s32 acHit = (this->cylinderCollider.base.acFlags & AC_HIT) != 0;
if (acHit) {
this->cylinderCollider.base.acFlags &= ~AC_HIT;
}
if (this->cylinderCollider.base.ocFlags1 & OC1_HIT) {
this->cylinderCollider.base.ocFlags1 &= ~OC1_HIT;
}
if (Actor_HasParent(&this->actor, globalCtx)) {
this->actor.room = -1;
this->actor.flags |= ACTOR_FLAG_10;
if ((type != OBJ_TSUBO_TYPE_3) && func_800A817C(OBJ_TSUBO_P003F(&this->actor))) {
func_80927690(this, globalCtx);
}
func_80927818(this, globalCtx, 0);
//! @bug: This function should only pass Player*: it uses *(this + 0x153), which is meant to be
//! player->currentMask, but in this case is garbage in the collider
func_800B8E58((Player*)&this->actor, NA_SE_PL_PULL_UP_POT);
func_80928D6C(this);
} else if ((this->unk_19B != 0) ||
(acHit && (this->cylinderCollider.info.acHitInfo->toucher.dmgFlags & 0x058BFFBC))) {
typeData = &sPotTypeData[type];
this->unk_19B = 0;
if ((this->actor.bgCheckFlags & 0x20) && (this->actor.depthInWater > 15.0f)) {
typeData->breakPot3(this, globalCtx);
} else {
typeData->breakPot1(this, globalCtx);
}
if (type == OBJ_TSUBO_TYPE_3) {
func_8092762C(this, globalCtx);
} else {
func_80927690(this, globalCtx);
}
func_80927818(this, globalCtx, 1);
SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_POT_BROKEN);
if (ObjTsubo_IsSceneNotGohtOrTwinmold(this, globalCtx)) {
Actor_MarkForDeath(&this->actor);
} else {
func_809291DC(this);
}
} else {
if (!this->unk_195) {
Actor_MoveWithGravity(&this->actor);
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 15.0f, 0.0f, 0x44);
if ((this->actor.bgCheckFlags & 1) &&
(DynaPoly_GetActor(&globalCtx->colCtx, this->actor.floorBgId) == NULL)) {
this->unk_195 = true;
this->actor.flags &= ~ACTOR_FLAG_10;
}
}
if ((this->actor.xzDistToPlayer < 800.0f) || (gSaveContext.save.entranceIndex == 0xD010)) {
Collider_UpdateCylinder(&this->actor, &this->cylinderCollider);
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->cylinderCollider.base);
if (this->actor.xzDistToPlayer < 150.0f) {
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->cylinderCollider.base);
if (this->actor.xzDistToPlayer < 100.0f) {
s16 yawDiff = this->actor.yawTowardsPlayer - GET_PLAYER(globalCtx)->actor.world.rot.y;
s32 absYawDiff = ABS_ALT(yawDiff);
if (absYawDiff > DEGF_TO_BINANG(120.0f)) {
Actor_PickUp(&this->actor, globalCtx, 0, 36.0f, 30.0f);
}
}
}
}
}
}
void func_80928D6C(ObjTsubo* this) {
this->actionFunc = func_80928D80;
}
void func_80928D80(ObjTsubo* this, GlobalContext* globalCtx) {
s32 pad;
Vec3f pos;
s32 bgId;
func_8092788C(this, globalCtx);
if (Actor_HasNoParent(&this->actor, globalCtx)) {
this->actor.room = globalCtx->roomCtx.currRoom.num;
Actor_MoveWithGravity(&this->actor);
this->actor.flags &= ~ACTOR_FLAG_4000000;
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 15.0f, 0.0f, 0xC5);
func_80928E74(this);
} else {
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 =
BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &bgId, &this->actor, &pos);
}
}
void func_80928E74(ObjTsubo* this) {
this->unk_194 = 80;
this->actor.colChkInfo.mass = 180;
D_80929500 = (Rand_ZeroOne() - 0.78f) * 4500.0f;
D_80929508 = (Rand_ZeroOne() - 0.5f) * 2000.0f;
D_80929504 = 0;
D_8092950C = 0;
this->actionFunc = func_80928F18;
}
void func_80928F18(ObjTsubo* this, GlobalContext* globalCtx) {
s32 pad;
ObjTsuboData* typeData;
s32 type = OBJ_TSUBO_GET_TYPE(&this->actor);
s32 pad2;
s32 atHit = (this->cylinderCollider.base.atFlags & AT_HIT) != 0;
if (atHit) {
this->cylinderCollider.base.atFlags &= ~AT_HIT;
}
func_8092788C(this, globalCtx);
if (this->unk_194 > 0) {
this->unk_194--;
}
typeData = &sPotTypeData[type];
if ((this->actor.bgCheckFlags & 0xB) || atHit || (this->unk_194 <= 0)) {
typeData->breakPot1(this, globalCtx);
if (type == OBJ_TSUBO_TYPE_3) {
func_8092762C(this, globalCtx);
} else {
func_80927690(this, globalCtx);
}
SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_POT_BROKEN);
if (ObjTsubo_IsSceneNotGohtOrTwinmold(this, globalCtx)) {
Actor_MarkForDeath(&this->actor);
} else {
func_809291DC(this);
}
} else if (this->actor.bgCheckFlags & 0x40) {
typeData->breakPot2(this, globalCtx);
if (type == OBJ_TSUBO_TYPE_3) {
func_8092762C(this, globalCtx);
} else {
func_80927690(this, globalCtx);
}
SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_POT_BROKEN);
SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L);
if (ObjTsubo_IsSceneNotGohtOrTwinmold(this, globalCtx)) {
Actor_MarkForDeath(&this->actor);
} else {
func_809291DC(this);
}
} else {
Actor_MoveWithGravity(&this->actor);
Math_StepToS(&D_80929504, D_80929500, 150);
Math_StepToS(&D_8092950C, D_80929508, 150);
this->actor.shape.rot.x += D_80929504;
this->actor.shape.rot.y += D_8092950C;
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 15.0f, 0.0f, 0xC5);
Collider_UpdateCylinder(&this->actor, &this->cylinderCollider);
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->cylinderCollider.base);
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->cylinderCollider.base);
}
}
void func_809291DC(ObjTsubo* this) {
this->actor.draw = NULL;
this->actor.flags |= ACTOR_FLAG_10;
Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos);
this->actor.shape.rot.z = 0;
this->actor.world.rot.z = 0;
this->unk_197 = false;
this->actor.shape.rot.x = this->actor.home.rot.x;
this->actor.world.rot.x = this->actor.home.rot.x;
this->actor.velocity.y = 0.0f;
this->actor.speedXZ = 0.0f;
this->actor.shape.rot.y = this->actor.home.rot.y;
this->actor.world.rot.y = this->actor.home.rot.y;
Actor_SetScale(&this->actor, 0.0f);
this->unk_194 = 127;
this->actionFunc = func_8092926C;
}
void func_8092926C(ObjTsubo* this, GlobalContext* globalCtx) {
f32 scale;
if (this->unk_194 > 0) {
this->unk_194--;
if (this->unk_194 == 0) {
this->actor.draw = ObjTsubo_Draw;
}
} else {
scale = sPotTypeData[OBJ_TSUBO_GET_TYPE(&this->actor)].scale;
if (Math_StepToF(&this->actor.scale.x, scale, scale * 0.1f)) {
this->actor.flags |= ACTOR_FLAG_4000000;
func_809289B4(this);
}
this->actor.scale.z = this->actor.scale.y = this->actor.scale.x;
}
}
void ObjTsubo_Update(Actor* thisx, GlobalContext* globalCtx) {
ObjTsubo* this = (ObjTsubo*)thisx;
this->actionFunc(this, globalCtx);
if (this->actor.draw == NULL) {
this->actor.shape.shadowDraw = NULL;
} else if (this->actor.projectedPos.z < 811.0f) {
if (this->actor.projectedPos.z > 300.0f) {
this->actor.shape.shadowAlpha = (811 - (s32)this->actor.projectedPos.z) >> 1;
this->actor.shape.shadowDraw = ActorShadow_DrawCircle;
} else if (this->actor.projectedPos.z > -10.0f) {
this->actor.shape.shadowAlpha = 255;
this->actor.shape.shadowDraw = ActorShadow_DrawCircle;
} else {
this->actor.shape.shadowDraw = NULL;
}
} else {
this->actor.shape.shadowDraw = NULL;
}
if (!this->unk_197) {
if (this->unk_198) {
globalCtx->actorCtx.unk5 |= 8;
this->actor.flags |= ACTOR_FLAG_10;
}
if (this->unk_19A >= 0) {
if (this->unk_19A == 0) {
Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALGOLD_ROLL);
if (Rand_ZeroOne() < 0.1f) {
this->unk_19A = Rand_S16Offset(40, 80);
} else {
this->unk_19A = 8;
}
} else {
this->unk_19A--;
}
}
}
}
void ObjTsubo_Draw(Actor* thisx, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = (GlobalContext*)globalCtx2;
Gfx_DrawDListOpa(globalCtx, sPotTypeData[OBJ_TSUBO_GET_TYPE(thisx)].modelDL);
}
@@ -7,12 +7,37 @@ struct ObjTsubo;
typedef void (*ObjTsuboActionFunc)(struct ObjTsubo*, GlobalContext*);
typedef void (*ObjTsuboUnkFunc)(struct ObjTsubo*, GlobalContext*);
#define OBJ_TSUBO_P000F(thisx) ((thisx)->params & 0x0F)
#define OBJ_TSUBO_P001F(thisx) ((thisx)->params & 0x1F)
#define OBJ_TSUBO_P003F(thisx) ((thisx)->params & 0x3F)
#define OBJ_TSUBO_P0010(thisx) (((thisx)->params >> 4) & 1)
#define OBJ_TSUBO_GET_TYPE(thisx) (((thisx)->params >> 7) & 3)
#define OBJ_TSUBO_PFE00(thisx) (((thisx)->params >> 9) & 0x7F) //item collectable flag?
#define OBJ_TSUBO_ZROT(thisx) ((thisx)->home.rot.z)
typedef struct ObjTsubo {
/* 0x0000 */ Actor actor;
/* 0x0144 */ ObjTsuboActionFunc actionFunc;
/* 0x0148 */ char unk_148[0x54];
/* 0x0148 */ ColliderCylinder cylinderCollider;
/* 0x0194 */ s8 unk_194;
/* 0x0195 */ s8 unk_195;
/* 0x0196 */ s8 homeRoom;
/* 0x0197 */ s8 unk_197;
/* 0x0198 */ s8 unk_198;
/* 0x0199 */ s8 objBankIndex;
/* 0x019A */ s8 unk_19A;
/* 0x019B */ u8 unk_19B;
} ObjTsubo; // size = 0x19C
extern const ActorInit Obj_Tsubo_InitVars;
typedef enum {
/* 0 */ OBJ_TSUBO_TYPE_0,
/* 1 */ OBJ_TSUBO_TYPE_1,
/* 2 */ OBJ_TSUBO_TYPE_2,
/* 3 */ OBJ_TSUBO_TYPE_3
} ObjTsuboType;
#endif // Z_OBJ_TSUBO_H
+10 -10
View File
@@ -510,7 +510,7 @@
0x800A7D28:("Item_DropCollectibleRandom",),
0x800A8150:("func_800A8150",),
0x800A817C:("func_800A817C",),
0x800A81A4:("func_800A81A4",),
0x800A81A4:("Item_CanDropBigFairy",),
0x800A81F0:("EffectBlure_AddVertex",),
0x800A8514:("EffectBlure_AddSpace",),
0x800A8558:("EffectBlure_InitElements",),
@@ -7047,19 +7047,19 @@
0x809275C0:("func_809275C0",),
0x8092762C:("func_8092762C",),
0x80927690:("func_80927690",),
0x80927714:("func_80927714",),
0x8092776C:("func_8092776C",),
0x80927714:("ObjTsubo_SpawnEnMkk",),
0x8092776C:("ObjTsubo_SpawnEnSw",),
0x80927818:("func_80927818",),
0x80927864:("func_80927864",),
0x8092788C:("func_8092788C",),
0x809278C0:("ObjTsubo_Init",),
0x80927A4C:("ObjTsubo_Destroy",),
0x80927A78:("func_80927A78",),
0x80927D2C:("func_80927D2C",),
0x80927FCC:("func_80927FCC",),
0x809282F0:("func_809282F0",),
0x8092860C:("func_8092860C",),
0x80928904:("func_80928904",),
0x80927A78:("func_PotBreak1",),
0x80927D2C:("func_RacePotBreak1",),
0x80927FCC:("func_PotBreak2",),
0x809282F0:("func_RacePotBreak2",),
0x8092860C:("func_PotBreak3",),
0x80928904:("func_RacePotBreak3",),
0x80928914:("func_80928914",),
0x80928928:("func_80928928",),
0x809289B4:("func_809289B4",),
@@ -7071,7 +7071,7 @@
0x809291DC:("func_809291DC",),
0x8092926C:("func_8092926C",),
0x8092932C:("ObjTsubo_Update",),
0x809294B0:("func_809294B0",),
0x809294B0:("ObjTsubo_Draw",),
0x80929910:("EnIk_Init",),
0x80929A98:("EnIk_Destroy",),
0x80929AF8:("func_80929AF8",),