Shipwright/soh/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c

181 lines
6.1 KiB
C

/*
* File: z_obj_kibako2.c
* Overlay: ovl_Obj_Kibako2
* Description: Large crate
*/
#include "z_obj_kibako2.h"
#include "objects/object_kibako2/object_kibako2.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
#define FLAGS 0
void ObjKibako2_Init(Actor* thisx, GlobalContext* globalCtx);
void ObjKibako2_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjKibako2_Update(Actor* thisx, GlobalContext* globalCtx);
void ObjKibako2_Draw(Actor* thisx, GlobalContext* globalCtx);
void ObjKibako2_Idle(ObjKibako2* this, GlobalContext* globalCtx);
void ObjKibako2_Kill(ObjKibako2* this, GlobalContext* globalCtx);
const ActorInit Obj_Kibako2_InitVars = {
ACTOR_OBJ_KIBAKO2,
ACTORCAT_BG,
FLAGS,
OBJECT_KIBAKO2,
sizeof(ObjKibako2),
(ActorFunc)ObjKibako2_Init,
(ActorFunc)ObjKibako2_Destroy,
(ActorFunc)ObjKibako2_Update,
(ActorFunc)ObjKibako2_Draw,
NULL,
};
static ColliderCylinderInit sCylinderInit = {
{
COLTYPE_NONE,
AT_NONE,
AC_ON | AC_TYPE_PLAYER,
OC1_NONE,
OC2_TYPE_2,
COLSHAPE_CYLINDER,
},
{
ELEMTYPE_UNK0,
{ 0x00000000, 0x00, 0x00 },
{ 0x40000040, 0x00, 0x00 },
TOUCH_NONE,
BUMP_ON,
OCELEM_NONE,
},
{ 31, 48, 0, { 0, 0, 0 } },
};
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 3000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 500, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_STOP),
};
void ObjKibako2_InitCollider(Actor* thisx, GlobalContext* globalCtx) {
ObjKibako2* this = (ObjKibako2*)thisx;
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit);
Collider_UpdateCylinder(&this->dyna.actor, &this->collider);
}
void ObjKibako2_Break(ObjKibako2* this, GlobalContext* globalCtx) {
s32 pad[2];
Vec3f* thisPos;
Vec3f pos;
Vec3f velocity;
s16 angle;
s32 i;
thisPos = &this->dyna.actor.world.pos;
for (i = 0, angle = 0; i < 0x10; i++, angle += 0x4E20) {
f32 sn = Math_SinS(angle);
f32 cs = Math_CosS(angle);
f32 temp_rand;
s32 phi_s0;
temp_rand = Rand_ZeroOne() * 30.0f;
pos.x = sn * temp_rand;
pos.y = (Rand_ZeroOne() * 10.0f) + 2.0f;
pos.z = cs * temp_rand;
velocity.x = pos.x * 0.2f;
velocity.y = (Rand_ZeroOne() * 10.0f) + 2.0f;
velocity.z = pos.z * 0.2f;
pos.x += thisPos->x;
pos.y += thisPos->y;
pos.z += thisPos->z;
temp_rand = Rand_ZeroOne();
if (temp_rand < 0.05f) {
phi_s0 = 0x60;
} else if (temp_rand < 0.7f) {
phi_s0 = 0x40;
} else {
phi_s0 = 0x20;
}
EffectSsKakera_Spawn(globalCtx, &pos, &velocity, &pos, -200, phi_s0, 28, 2, 0, (Rand_ZeroOne() * 30.0f) + 5.0f,
0, 0, 70, KAKERA_COLOR_NONE, OBJECT_KIBAKO2, gLargeCrateFragmentDL);
}
func_80033480(globalCtx, thisPos, 90.0f, 6, 100, 160, 1);
}
void ObjKibako2_SpawnCollectible(ObjKibako2* this, GlobalContext* globalCtx) {
s16 itemDropped;
s16 collectibleFlagTemp;
collectibleFlagTemp = this->collectibleFlag;
itemDropped = this->dyna.actor.home.rot.x;
if (itemDropped >= 0 && itemDropped < 0x1A) {
Item_DropCollectible(globalCtx, &this->dyna.actor.world.pos, itemDropped | (collectibleFlagTemp << 8));
}
}
void ObjKibako2_Init(Actor* thisx, GlobalContext* globalCtx) {
ObjKibako2* this = (ObjKibako2*)thisx;
s16 pad;
CollisionHeader* colHeader = NULL;
u32 bgId;
DynaPolyActor_Init(&this->dyna, 0);
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
ObjKibako2_InitCollider(thisx, globalCtx);
CollisionHeader_GetVirtual(&gLargeCrateCol, &colHeader);
bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
this->collectibleFlag = this->dyna.actor.home.rot.z & 0x3F;
this->dyna.bgId = bgId;
this->actionFunc = ObjKibako2_Idle;
this->dyna.actor.home.rot.z = this->dyna.actor.world.rot.z = this->dyna.actor.shape.rot.z =
this->dyna.actor.world.rot.x = this->dyna.actor.shape.rot.x = 0;
// "Wooden box (stationary)"
osSyncPrintf("木箱(据置)(arg %04xH)(item %04xH %d)\n", this->dyna.actor.params, this->collectibleFlag,
this->dyna.actor.home.rot.x);
}
void ObjKibako2_Destroy(Actor* thisx, GlobalContext* globalCtx) {
ObjKibako2* this = (ObjKibako2*)thisx;
Collider_DestroyCylinder(globalCtx, &this->collider);
DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
}
void ObjKibako2_Idle(ObjKibako2* this, GlobalContext* globalCtx) {
if ((this->collider.base.acFlags & AC_HIT) || (this->dyna.actor.home.rot.z != 0) ||
func_80033684(globalCtx, &this->dyna.actor) != NULL) {
ObjKibako2_Break(this, globalCtx);
SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->dyna.actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK);
this->dyna.actor.flags |= ACTOR_FLAG_4;
func_8003EBF8(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
this->dyna.actor.draw = NULL;
this->actionFunc = ObjKibako2_Kill;
} else if (this->dyna.actor.xzDistToPlayer < 600.0f) {
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
}
void ObjKibako2_Kill(ObjKibako2* this, GlobalContext* globalCtx) {
s16 params = this->dyna.actor.params;
if ((params & 0x8000) == 0) {
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_SW, this->dyna.actor.world.pos.x,
this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, 0, this->dyna.actor.shape.rot.y, 0,
params | 0x8000);
}
ObjKibako2_SpawnCollectible(this, globalCtx);
Actor_Kill(&this->dyna.actor);
}
void ObjKibako2_Update(Actor* thisx, GlobalContext* globalCtx) {
ObjKibako2* this = (ObjKibako2*)thisx;
this->actionFunc(this, globalCtx);
}
void ObjKibako2_Draw(Actor* thisx, GlobalContext* globalCtx) {
Gfx_DrawDListOpa(globalCtx, gLargeCrateDL);
}