mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-08-13 17:03:47 -04:00
a5df9dddf0
* First batch some overlay
* Almost all overlay
* effect & gamestate
* kaleido stuffs
* more overlay
* more left over from code folder
* remaining hardcoded line and file
* Open & Close _DISP __FILE__ & __LINE__ clean up
* Some if (1) {} remove
* LOG_xxxx __FILE__ , __LINE__ cleaned
* ASSERT macro __FILE__ __LINE__
* mtx without line/file in functions
* " if (1) {} " & "if (0) {}" and tab/white place
* LogUtils as macro
* GameState_, GameAlloc_, SystemArena_ & ZeldaArena_
* Revert "GameState_, GameAlloc_, SystemArena_ & ZeldaArena_"
This reverts commit 0d85caaf7e
.
* Like last commit but as macro
* Fix matrix not using macros
* use function not macro
* DebugArena_* functions
GameAlloc_MallocDebug
BgCheck_PosErrorCheck as macros
removed issues with ; in macro file
510 lines
17 KiB
C
510 lines
17 KiB
C
/*
|
|
* File: z_en_kusa.c
|
|
* Overlay: ovl_en_kusa
|
|
* Description: Bush
|
|
*/
|
|
|
|
#include "z_en_kusa.h"
|
|
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
|
|
#include "objects/gameplay_keep/gameplay_keep.h"
|
|
#include "objects/gameplay_field_keep/gameplay_field_keep.h"
|
|
#include "objects/object_kusa/object_kusa.h"
|
|
#include "vt.h"
|
|
|
|
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_23)
|
|
|
|
void EnKusa_Init(Actor* thisx, GlobalContext* globalCtx);
|
|
void EnKusa_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|
void EnKusa_Update(Actor* thisx, GlobalContext* globalCtx);
|
|
void EnKusa_Draw(Actor* thisx, GlobalContext* globalCtx);
|
|
|
|
void EnKusa_SetupLiftedUp(EnKusa* this);
|
|
void EnKusa_SetupWaitObject(EnKusa* this);
|
|
void EnKusa_SetupMain(EnKusa* this);
|
|
void EnKusa_SetupFall(EnKusa* this);
|
|
void EnKusa_SetupCut(EnKusa* this);
|
|
void EnKusa_SetupUprootedWaitRegrow(EnKusa* this);
|
|
void EnKusa_SetupRegrow(EnKusa* this);
|
|
|
|
void EnKusa_Fall(EnKusa* this, GlobalContext* globalCtx);
|
|
void EnKusa_WaitObject(EnKusa* this, GlobalContext* globalCtx);
|
|
void EnKusa_Main(EnKusa* this, GlobalContext* globalCtx);
|
|
void EnKusa_LiftedUp(EnKusa* this, GlobalContext* globalCtx);
|
|
void EnKusa_CutWaitRegrow(EnKusa* this, GlobalContext* globalCtx);
|
|
void EnKusa_DoNothing(EnKusa* this, GlobalContext* globalCtx);
|
|
void EnKusa_UprootedWaitRegrow(EnKusa* this, GlobalContext* globalCtx);
|
|
void EnKusa_Regrow(EnKusa* this, GlobalContext* globalCtx);
|
|
|
|
static s16 rotSpeedXtarget = 0;
|
|
static s16 rotSpeedX = 0;
|
|
static s16 rotSpeedYtarget = 0;
|
|
static s16 rotSpeedY = 0;
|
|
|
|
const ActorInit En_Kusa_InitVars = {
|
|
ACTOR_EN_KUSA,
|
|
ACTORCAT_PROP,
|
|
FLAGS,
|
|
OBJECT_GAMEPLAY_KEEP,
|
|
sizeof(EnKusa),
|
|
(ActorFunc)EnKusa_Init,
|
|
(ActorFunc)EnKusa_Destroy,
|
|
(ActorFunc)EnKusa_Update,
|
|
NULL,
|
|
NULL,
|
|
};
|
|
|
|
static s16 sObjectIds[] = { OBJECT_GAMEPLAY_FIELD_KEEP, OBJECT_KUSA, OBJECT_KUSA };
|
|
|
|
static ColliderCylinderInit sCylinderInit = {
|
|
{
|
|
COLTYPE_NONE,
|
|
AT_NONE,
|
|
AC_ON | AC_TYPE_PLAYER,
|
|
OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_2,
|
|
OC2_TYPE_2,
|
|
COLSHAPE_CYLINDER,
|
|
},
|
|
{
|
|
ELEMTYPE_UNK0,
|
|
{ 0x00000000, 0x00, 0x00 },
|
|
{ 0x4FC00758, 0x00, 0x00 },
|
|
TOUCH_NONE,
|
|
BUMP_ON,
|
|
OCELEM_ON,
|
|
},
|
|
{ 12, 44, 0, { 0, 0, 0 } },
|
|
};
|
|
|
|
static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 30, MASS_IMMOVABLE };
|
|
|
|
static Vec3f sUnitDirections[] = {
|
|
{ 0.0f, 0.7071f, 0.7071f },
|
|
{ 0.7071f, 0.7071f, 0.0f },
|
|
{ 0.0f, 0.7071f, -0.7071f },
|
|
{ -0.7071f, 0.7071f, 0.0f },
|
|
};
|
|
|
|
static s16 sFragmentScales[] = { 108, 102, 96, 84, 66, 55, 42, 38 };
|
|
|
|
static InitChainEntry sInitChain[] = {
|
|
ICHAIN_VEC3F_DIV1000(scale, 400, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -3200, ICHAIN_CONTINUE),
|
|
ICHAIN_F32_DIV1000(minVelocityY, -17000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE),
|
|
ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 120, ICHAIN_STOP),
|
|
};
|
|
|
|
void EnKusa_SetupAction(EnKusa* this, EnKusaActionFunc actionFunc) {
|
|
this->timer = 0;
|
|
this->actionFunc = actionFunc;
|
|
}
|
|
|
|
s32 EnKusa_SnapToFloor(EnKusa* this, GlobalContext* globalCtx, f32 yOffset) {
|
|
s32 pad;
|
|
CollisionPoly* poly;
|
|
Vec3f pos;
|
|
s32 bgId;
|
|
f32 floorY;
|
|
|
|
pos.x = this->actor.world.pos.x;
|
|
pos.y = this->actor.world.pos.y + 30.0f;
|
|
pos.z = this->actor.world.pos.z;
|
|
|
|
floorY = BgCheck_EntityRaycastFloor4(&globalCtx->colCtx, &poly, &bgId, &this->actor, &pos);
|
|
|
|
if (floorY > BGCHECK_Y_MIN) {
|
|
this->actor.world.pos.y = floorY + yOffset;
|
|
Math_Vec3f_Copy(&this->actor.home.pos, &this->actor.world.pos);
|
|
return true;
|
|
} else {
|
|
osSyncPrintf(VT_COL(YELLOW, BLACK));
|
|
// "Failure attaching to ground"
|
|
osSyncPrintf("地面に付着失敗(%s %d)\n", __FILE__, __LINE__);
|
|
osSyncPrintf(VT_RST);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void EnKusa_DropCollectible(EnKusa* this, GlobalContext* globalCtx) {
|
|
s16 dropParams;
|
|
|
|
switch (this->actor.params & 3) {
|
|
case ENKUSA_TYPE_0:
|
|
case ENKUSA_TYPE_2:
|
|
dropParams = (this->actor.params >> 8) & 0xF;
|
|
|
|
if (dropParams >= 0xD) {
|
|
dropParams = 0;
|
|
}
|
|
Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, dropParams << 4);
|
|
break;
|
|
case ENKUSA_TYPE_1:
|
|
if (CVar_GetS32("gNoRandomDrops", 0)) {
|
|
}
|
|
else if (CVar_GetS32("gNoHeartDrops", 0)) {
|
|
Item_DropCollectible(globalCtx, &this->actor.world.pos, ITEM00_SEEDS);
|
|
}
|
|
else if (Rand_ZeroOne() < 0.5f) {
|
|
Item_DropCollectible(globalCtx, &this->actor.world.pos, ITEM00_SEEDS);
|
|
} else {
|
|
Item_DropCollectible(globalCtx, &this->actor.world.pos, ITEM00_HEART);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void EnKusa_UpdateVelY(EnKusa* this) {
|
|
this->actor.velocity.y += this->actor.gravity;
|
|
|
|
if (this->actor.velocity.y < this->actor.minVelocityY) {
|
|
this->actor.velocity.y = this->actor.minVelocityY;
|
|
}
|
|
}
|
|
|
|
void EnKusa_RandScaleVecToZero(Vec3f* vec, f32 scale) {
|
|
scale += ((Rand_ZeroOne() * 0.2f) - 0.1f) * scale;
|
|
vec->x -= vec->x * scale;
|
|
vec->y -= vec->y * scale;
|
|
vec->z -= vec->z * scale;
|
|
}
|
|
|
|
void EnKusa_SetScaleSmall(EnKusa* this) {
|
|
this->actor.scale.y = 0.16000001f;
|
|
this->actor.scale.x = 0.120000005f;
|
|
this->actor.scale.z = 0.120000005f;
|
|
}
|
|
|
|
void EnKusa_SpawnFragments(EnKusa* this, GlobalContext* globalCtx) {
|
|
Vec3f velocity;
|
|
Vec3f pos;
|
|
s32 i;
|
|
s32 scaleIndex;
|
|
Vec3f* dir;
|
|
s32 pad;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(sUnitDirections); i++) {
|
|
dir = &sUnitDirections[i];
|
|
|
|
pos.x = this->actor.world.pos.x + (dir->x * this->actor.scale.x * 20.0f);
|
|
pos.y = this->actor.world.pos.y + (dir->y * this->actor.scale.y * 20.0f) + 10.0f;
|
|
pos.z = this->actor.world.pos.z + (dir->z * this->actor.scale.z * 20.0f);
|
|
|
|
velocity.x = (Rand_ZeroOne() - 0.5f) * 8.0f;
|
|
velocity.y = Rand_ZeroOne() * 10.0f;
|
|
velocity.z = (Rand_ZeroOne() - 0.5f) * 8.0f;
|
|
|
|
scaleIndex = (s32)(Rand_ZeroOne() * 111.1f) & 7;
|
|
|
|
EffectSsKakera_Spawn(globalCtx, &pos, &velocity, &pos, -100, 64, 40, 3, 0, sFragmentScales[scaleIndex], 0, 0,
|
|
80, KAKERA_COLOR_NONE, OBJECT_GAMEPLAY_KEEP, gCuttableShrubStalkDL);
|
|
|
|
pos.x = this->actor.world.pos.x + (dir->x * this->actor.scale.x * 40.0f);
|
|
pos.y = this->actor.world.pos.y + (dir->y * this->actor.scale.y * 40.0f) + 10.0f;
|
|
pos.z = this->actor.world.pos.z + (dir->z * this->actor.scale.z * 40.0f);
|
|
|
|
velocity.x = (Rand_ZeroOne() - 0.5f) * 6.0f;
|
|
velocity.y = Rand_ZeroOne() * 10.0f;
|
|
velocity.z = (Rand_ZeroOne() - 0.5f) * 6.0f;
|
|
|
|
scaleIndex = (s32)(Rand_ZeroOne() * 111.1f) % 7;
|
|
|
|
EffectSsKakera_Spawn(globalCtx, &pos, &velocity, &pos, -100, 64, 40, 3, 0, sFragmentScales[scaleIndex], 0, 0,
|
|
80, KAKERA_COLOR_NONE, OBJECT_GAMEPLAY_KEEP, gCuttableShrubTipDL);
|
|
}
|
|
}
|
|
|
|
void EnKusa_SpawnBugs(EnKusa* this, GlobalContext* globalCtx) {
|
|
s32 i;
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
Actor* bug = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_INSECT, this->actor.world.pos.x,
|
|
this->actor.world.pos.y, this->actor.world.pos.z, 0, Rand_ZeroOne() * 0xFFFF, 0, 1);
|
|
|
|
if (bug == NULL) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnKusa_InitCollider(Actor* thisx, GlobalContext* globalCtx) {
|
|
EnKusa* this = (EnKusa*)thisx;
|
|
|
|
Collider_InitCylinder(globalCtx, &this->collider);
|
|
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
|
|
Collider_UpdateCylinder(&this->actor, &this->collider);
|
|
}
|
|
|
|
void EnKusa_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|
EnKusa* this = (EnKusa*)thisx;
|
|
|
|
Actor_ProcessInitChain(&this->actor, sInitChain);
|
|
|
|
if (globalCtx->csCtx.state != CS_STATE_IDLE) {
|
|
this->actor.uncullZoneForward += 1000.0f;
|
|
}
|
|
|
|
EnKusa_InitCollider(thisx, globalCtx);
|
|
CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit);
|
|
|
|
if (this->actor.shape.rot.y == 0) {
|
|
s16 rand = Rand_ZeroFloat(0x10000);
|
|
|
|
this->actor.world.rot.y = rand;
|
|
this->actor.home.rot.y = rand;
|
|
this->actor.shape.rot.y = rand;
|
|
}
|
|
|
|
if (!EnKusa_SnapToFloor(this, globalCtx, 0.0f)) {
|
|
Actor_Kill(&this->actor);
|
|
return;
|
|
}
|
|
|
|
this->objBankIndex = Object_GetIndex(&globalCtx->objectCtx, sObjectIds[thisx->params & 3]);
|
|
|
|
if (this->objBankIndex < 0) {
|
|
// "Bank danger!"
|
|
osSyncPrintf("Error : バンク危険! (arg_data 0x%04x)(%s %d)\n", thisx->params, __FILE__, __LINE__);
|
|
Actor_Kill(&this->actor);
|
|
return;
|
|
}
|
|
|
|
EnKusa_SetupWaitObject(this);
|
|
}
|
|
|
|
void EnKusa_Destroy(Actor* thisx, GlobalContext* globalCtx2) {
|
|
GlobalContext* globalCtx = globalCtx2;
|
|
EnKusa* this = (EnKusa*)thisx;
|
|
|
|
Collider_DestroyCylinder(globalCtx, &this->collider);
|
|
}
|
|
|
|
void EnKusa_SetupWaitObject(EnKusa* this) {
|
|
EnKusa_SetupAction(this, EnKusa_WaitObject);
|
|
}
|
|
|
|
void EnKusa_WaitObject(EnKusa* this, GlobalContext* globalCtx) {
|
|
if (Object_IsLoaded(&globalCtx->objectCtx, this->objBankIndex)) {
|
|
if (this->actor.flags & ACTOR_FLAG_ENKUSA_CUT) {
|
|
EnKusa_SetupCut(this);
|
|
} else {
|
|
EnKusa_SetupMain(this);
|
|
}
|
|
|
|
this->actor.draw = EnKusa_Draw;
|
|
this->actor.objBankIndex = this->objBankIndex;
|
|
this->actor.flags &= ~ACTOR_FLAG_4;
|
|
}
|
|
}
|
|
|
|
void EnKusa_SetupMain(EnKusa* this) {
|
|
EnKusa_SetupAction(this, EnKusa_Main);
|
|
this->actor.flags &= ~ACTOR_FLAG_4;
|
|
}
|
|
|
|
void EnKusa_Main(EnKusa* this, GlobalContext* globalCtx) {
|
|
s32 pad;
|
|
|
|
if (Actor_HasParent(&this->actor, globalCtx)) {
|
|
EnKusa_SetupLiftedUp(this);
|
|
SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_PL_PULL_UP_PLANT);
|
|
} else if (this->collider.base.acFlags & AC_HIT && gGlobalCtx->csCtx.state == 0) {
|
|
this->collider.base.acFlags &= ~AC_HIT;
|
|
EnKusa_SpawnFragments(this, globalCtx);
|
|
EnKusa_DropCollectible(this, globalCtx);
|
|
SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_PLANT_BROKEN);
|
|
|
|
if ((this->actor.params >> 4) & 1) {
|
|
EnKusa_SpawnBugs(this, globalCtx);
|
|
}
|
|
|
|
if ((this->actor.params & 3) == ENKUSA_TYPE_0) {
|
|
Actor_Kill(&this->actor);
|
|
return;
|
|
}
|
|
|
|
EnKusa_SetupCut(this);
|
|
this->actor.flags |= ACTOR_FLAG_ENKUSA_CUT;
|
|
} else {
|
|
if (!(this->collider.base.ocFlags1 & OC1_TYPE_PLAYER) && (this->actor.xzDistToPlayer > 12.0f)) {
|
|
this->collider.base.ocFlags1 |= OC1_TYPE_PLAYER;
|
|
}
|
|
|
|
if (this->actor.xzDistToPlayer < 600.0f) {
|
|
Collider_UpdateCylinder(&this->actor, &this->collider);
|
|
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
|
|
|
|
if (this->actor.xzDistToPlayer < 400.0f) {
|
|
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
|
|
if (this->actor.xzDistToPlayer < 100.0f) {
|
|
func_8002F580(&this->actor, globalCtx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnKusa_SetupLiftedUp(EnKusa* this) {
|
|
EnKusa_SetupAction(this, EnKusa_LiftedUp);
|
|
this->actor.room = -1;
|
|
this->actor.flags |= ACTOR_FLAG_4;
|
|
}
|
|
|
|
void EnKusa_LiftedUp(EnKusa* this, GlobalContext* globalCtx) {
|
|
if (Actor_HasNoParent(&this->actor, globalCtx)) {
|
|
this->actor.room = globalCtx->roomCtx.curRoom.num;
|
|
EnKusa_SetupFall(this);
|
|
this->actor.velocity.x = this->actor.speedXZ * Math_SinS(this->actor.world.rot.y);
|
|
this->actor.velocity.z = this->actor.speedXZ * Math_CosS(this->actor.world.rot.y);
|
|
this->actor.colChkInfo.mass = 240;
|
|
this->actor.gravity = -0.1f;
|
|
EnKusa_UpdateVelY(this);
|
|
EnKusa_RandScaleVecToZero(&this->actor.velocity, 0.005f);
|
|
func_8002D7EC(&this->actor);
|
|
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5);
|
|
this->actor.gravity = -3.2f;
|
|
}
|
|
}
|
|
|
|
void EnKusa_SetupFall(EnKusa* this) {
|
|
EnKusa_SetupAction(this, EnKusa_Fall);
|
|
rotSpeedXtarget = -0xBB8;
|
|
rotSpeedYtarget = (Rand_ZeroOne() - 0.5f) * 1600.0f;
|
|
rotSpeedX = 0;
|
|
rotSpeedY = 0;
|
|
}
|
|
|
|
void EnKusa_Fall(EnKusa* this, GlobalContext* globalCtx) {
|
|
s32 pad;
|
|
Vec3f contactPos;
|
|
|
|
if (this->actor.bgCheckFlags & 0xB) {
|
|
if (!(this->actor.bgCheckFlags & 0x20)) {
|
|
SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_PLANT_BROKEN);
|
|
}
|
|
EnKusa_SpawnFragments(this, globalCtx);
|
|
EnKusa_DropCollectible(this, globalCtx);
|
|
switch (this->actor.params & 3) {
|
|
case ENKUSA_TYPE_0:
|
|
case ENKUSA_TYPE_2:
|
|
Actor_Kill(&this->actor);
|
|
break;
|
|
|
|
case ENKUSA_TYPE_1:
|
|
EnKusa_SetupUprootedWaitRegrow(this);
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (this->actor.bgCheckFlags & 0x40) {
|
|
contactPos.x = this->actor.world.pos.x;
|
|
contactPos.y = this->actor.world.pos.y + this->actor.yDistToWater;
|
|
contactPos.z = this->actor.world.pos.z;
|
|
EffectSsGSplash_Spawn(globalCtx, &contactPos, NULL, NULL, 0, 400);
|
|
EffectSsGRipple_Spawn(globalCtx, &contactPos, 150, 650, 0);
|
|
EffectSsGRipple_Spawn(globalCtx, &contactPos, 400, 800, 4);
|
|
EffectSsGRipple_Spawn(globalCtx, &contactPos, 500, 1100, 8);
|
|
this->actor.minVelocityY = -3.0f;
|
|
rotSpeedX >>= 1;
|
|
rotSpeedXtarget >>= 1;
|
|
rotSpeedY >>= 1;
|
|
rotSpeedYtarget >>= 1;
|
|
this->actor.bgCheckFlags &= ~0x40;
|
|
SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L);
|
|
}
|
|
|
|
EnKusa_UpdateVelY(this);
|
|
Math_StepToS(&rotSpeedX, rotSpeedXtarget, 0x1F4);
|
|
Math_StepToS(&rotSpeedY, rotSpeedYtarget, 0xAA);
|
|
this->actor.shape.rot.x += rotSpeedX;
|
|
this->actor.shape.rot.y += rotSpeedY;
|
|
EnKusa_RandScaleVecToZero(&this->actor.velocity, 0.05f);
|
|
func_8002D7EC(&this->actor);
|
|
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5);
|
|
Collider_UpdateCylinder(&this->actor, &this->collider);
|
|
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
|
|
}
|
|
|
|
void EnKusa_SetupCut(EnKusa* this) {
|
|
switch (this->actor.params & 3) {
|
|
case ENKUSA_TYPE_2:
|
|
EnKusa_SetupAction(this, EnKusa_DoNothing);
|
|
break;
|
|
case ENKUSA_TYPE_1:
|
|
EnKusa_SetupAction(this, EnKusa_CutWaitRegrow);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void EnKusa_CutWaitRegrow(EnKusa* this, GlobalContext* globalCtx) {
|
|
if (this->timer >= 120) {
|
|
EnKusa_SetupRegrow(this);
|
|
}
|
|
}
|
|
|
|
void EnKusa_DoNothing(EnKusa* this, GlobalContext* globalCtx) {
|
|
}
|
|
|
|
void EnKusa_SetupUprootedWaitRegrow(EnKusa* this) {
|
|
this->actor.world.pos.x = this->actor.home.pos.x;
|
|
this->actor.world.pos.y = this->actor.home.pos.y - 9.0f;
|
|
this->actor.world.pos.z = this->actor.home.pos.z;
|
|
EnKusa_SetScaleSmall(this);
|
|
this->actor.shape.rot = this->actor.home.rot;
|
|
EnKusa_SetupAction(this, EnKusa_UprootedWaitRegrow);
|
|
}
|
|
|
|
void EnKusa_UprootedWaitRegrow(EnKusa* this, GlobalContext* globalCtx) {
|
|
if (this->timer > 120) {
|
|
if (Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 0.6f)) {
|
|
if (this->timer >= 170) {
|
|
EnKusa_SetupRegrow(this);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnKusa_SetupRegrow(EnKusa* this) {
|
|
EnKusa_SetupAction(this, EnKusa_Regrow);
|
|
EnKusa_SetScaleSmall(this);
|
|
this->actor.shape.rot = this->actor.home.rot;
|
|
this->actor.flags &= ~ACTOR_FLAG_ENKUSA_CUT;
|
|
}
|
|
|
|
void EnKusa_Regrow(EnKusa* this, GlobalContext* globalCtx) {
|
|
s32 isFullyGrown = true;
|
|
|
|
isFullyGrown &= Math_StepToF(&this->actor.scale.y, 0.4f, 0.014f);
|
|
isFullyGrown &= Math_StepToF(&this->actor.scale.x, 0.4f, 0.011f);
|
|
this->actor.scale.z = this->actor.scale.x;
|
|
|
|
if (isFullyGrown) {
|
|
Actor_SetScale(&this->actor, 0.4f);
|
|
EnKusa_SetupMain(this);
|
|
this->collider.base.ocFlags1 &= ~OC1_TYPE_PLAYER;
|
|
}
|
|
}
|
|
|
|
void EnKusa_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|
EnKusa* this = (EnKusa*)thisx;
|
|
|
|
this->timer++;
|
|
|
|
this->actionFunc(this, globalCtx);
|
|
|
|
if (this->actor.flags & ACTOR_FLAG_ENKUSA_CUT) {
|
|
this->actor.shape.yOffset = -6.25f;
|
|
} else {
|
|
this->actor.shape.yOffset = 0.0f;
|
|
}
|
|
}
|
|
|
|
void EnKusa_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|
static Gfx* dLists[] = { gFieldBushDL, object_kusa_DL_000140, object_kusa_DL_000140 };
|
|
EnKusa* this = (EnKusa*)thisx;
|
|
|
|
if (this->actor.flags & ACTOR_FLAG_ENKUSA_CUT) {
|
|
Gfx_DrawDListOpa(globalCtx, object_kusa_DL_0002E0);
|
|
} else {
|
|
Gfx_DrawDListOpa(globalCtx, dLists[thisx->params & 3]);
|
|
}
|
|
}
|