mirror of
https://github.com/zeldaret/mm.git
synced 2026-07-26 14:31:07 -04:00
EnGe2 (Gerudo in Purple) OK and documented, object_gla documented (#1071)
* OK, data imported * Permuter settings * Name data, a few functions and variables, cleanup * Small amount of cleanup on some related actors * Oops * Document object * Type and other macros * Some cutscene stuff and temporary function names * Proper path function names * Name a couple more functions * A couple more function names * Name PathStatus enum * Name rest of functions and formalise the documentation a bit * Apply suggestions from code review Co-authored-by: Derek Hensley <hensley.derek58@gmail.com> * limbs * Format * Review * format * weekeventregconvert and format --------- Co-authored-by: Derek Hensley <hensley.derek58@gmail.com> Co-authored-by: angie <angheloalf95@gmail.com>
This commit is contained in:
@@ -674,7 +674,7 @@ void EnArrow_Draw(Actor* thisx, PlayState* play) {
|
||||
gSPMatrix(POLY_XLU_DISP++, &D_01000000, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_06F9F0);
|
||||
} else {
|
||||
func_800B8050(&this->actor, play, MTXMODE_NEW);
|
||||
func_800B8050(&this->actor, play, 0);
|
||||
|
||||
gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_06F380);
|
||||
gDPSetCombineLERP(POLY_OPA_DISP++, TEXEL1, 0, PRIM_LOD_FRAC, TEXEL0, TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0,
|
||||
|
||||
@@ -189,13 +189,14 @@ void EnGe1_SetupPath(EnGe1* this, PlayState* play) {
|
||||
Vec3s* point;
|
||||
Vec3f nextPoint;
|
||||
|
||||
this->curPoint = 0;
|
||||
this->curPointIndex = 0;
|
||||
|
||||
if (GERUDO_WHITE_GET_PATH(&this->picto.actor) != 0x3F) {
|
||||
this->path = &play->setupPathList[GERUDO_WHITE_GET_PATH(&this->picto.actor)];
|
||||
if (this->path != NULL) {
|
||||
point = Lib_SegmentedToVirtual(this->path->points);
|
||||
Math_Vec3s_ToVec3f(&this->picto.actor.world.pos, point);
|
||||
this->curPoint++;
|
||||
this->curPointIndex++;
|
||||
point++;
|
||||
Math_Vec3s_ToVec3f(&nextPoint, point);
|
||||
|
||||
@@ -214,7 +215,7 @@ void EnGe1_SetupPath(EnGe1* this, PlayState* play) {
|
||||
s32 EnGe1_FollowPath(EnGe1* this) {
|
||||
s32 pad;
|
||||
Path* path = this->path;
|
||||
Vec3s* points;
|
||||
Vec3s* curPoint;
|
||||
Vec3f point;
|
||||
s16 yawTarget;
|
||||
s16 pitchTarget;
|
||||
@@ -223,10 +224,10 @@ s32 EnGe1_FollowPath(EnGe1* this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
points = Lib_SegmentedToVirtual(this->path->points);
|
||||
points += this->curPoint;
|
||||
curPoint = Lib_SegmentedToVirtual(this->path->points);
|
||||
curPoint += this->curPointIndex;
|
||||
|
||||
Math_Vec3s_ToVec3f(&point, points);
|
||||
Math_Vec3s_ToVec3f(&point, curPoint);
|
||||
yawTarget = Math_Vec3f_Yaw(&this->picto.actor.world.pos, &point);
|
||||
pitchTarget = Math_Vec3f_Pitch(&this->picto.actor.world.pos, &point);
|
||||
Math_SmoothStepToS(&this->picto.actor.world.rot.y, yawTarget, 0xA, 0x3E8, 0x64);
|
||||
@@ -260,9 +261,9 @@ void EnGe1_PerformCutsceneActions(EnGe1* this, PlayState* play) {
|
||||
EnGe1_ChangeAnim(this, GERUDO_WHITE_ANIM_STIFF_SHIVERING, ANIMMODE_LOOP, 0.0f);
|
||||
}
|
||||
|
||||
if (Cutscene_CheckActorAction(play, 0x79)) {
|
||||
if (Cutscene_CheckActorAction(play, 121)) {
|
||||
this->picto.actor.draw = EnGe1_Draw;
|
||||
csAction = play->csCtx.actorActions[Cutscene_GetActorActionIndex(play, 0x79)]->action;
|
||||
csAction = play->csCtx.actorActions[Cutscene_GetActorActionIndex(play, 121)]->action;
|
||||
switch (csAction) {
|
||||
case 8:
|
||||
this->stateFlags &= ~GERUDO_WHITE_STATE_DISABLE_MOVEMENT;
|
||||
@@ -339,22 +340,27 @@ void EnGe1_PerformCutsceneActions(EnGe1* this, PlayState* play) {
|
||||
this->picto.actor.draw = NULL;
|
||||
}
|
||||
|
||||
if (this->csAction == 9) {
|
||||
if ((this->curPoint < this->path->count) && EnGe1_FollowPath(this)) {
|
||||
this->curPoint++;
|
||||
}
|
||||
switch (this->csAction) {
|
||||
case 9:
|
||||
if ((this->curPointIndex < this->path->count) && EnGe1_FollowPath(this)) {
|
||||
this->curPointIndex++;
|
||||
}
|
||||
|
||||
// Tumble in the air
|
||||
this->picto.actor.shape.rot.x += 0x3E8;
|
||||
this->picto.actor.shape.rot.y += 0x7D0;
|
||||
this->picto.actor.shape.rot.z += 0x1F4;
|
||||
// Tumble in the air
|
||||
this->picto.actor.shape.rot.x += 0x3E8;
|
||||
this->picto.actor.shape.rot.y += 0x7D0;
|
||||
this->picto.actor.shape.rot.z += 0x1F4;
|
||||
|
||||
if (this->screamTimer > 0) {
|
||||
this->screamTimer--;
|
||||
} else {
|
||||
this->screamTimer = (s32)(Rand_ZeroFloat(10.0f) + 20.0f);
|
||||
EnGe1_Scream(this);
|
||||
}
|
||||
if (this->screamTimer > 0) {
|
||||
this->screamTimer--;
|
||||
} else {
|
||||
this->screamTimer = (s32)(Rand_ZeroFloat(10.0f) + 20.0f);
|
||||
EnGe1_Scream(this);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ typedef struct EnGe1 {
|
||||
/* 0x2A4 */ Vec3s headRot;
|
||||
/* 0x2AA */ Vec3s torsoRot;
|
||||
/* 0x2B0 */ Path* path;
|
||||
/* 0x2B4 */ s32 curPoint;
|
||||
/* 0x2B4 */ s32 curPointIndex;
|
||||
/* 0x2B8 */ s16 eyeIndex;
|
||||
/* 0x2BA */ s16 blinkTimer;
|
||||
/* 0x2BC */ u16 stateFlags;
|
||||
|
||||
@@ -15,18 +15,14 @@ void EnGe2_Destroy(Actor* thisx, PlayState* play);
|
||||
void EnGe2_Update(Actor* thisx, PlayState* play);
|
||||
void EnGe2_Draw(Actor* thisx, PlayState* play);
|
||||
|
||||
void func_80B8BCEC(EnGe2* this, PlayState* play);
|
||||
void func_80B8BD38(EnGe2* this, PlayState* play);
|
||||
void func_80B8BE08(EnGe2* this, PlayState* play);
|
||||
void func_80B8BF04(EnGe2* this, PlayState* play);
|
||||
void func_80B8C048(EnGe2* this, PlayState* play);
|
||||
void func_80B8C0B0(EnGe2* this, PlayState* play);
|
||||
void func_80B8C45C(EnGe2* this, PlayState* play);
|
||||
void func_80B8C59C(EnGe2* this, PlayState* play);
|
||||
void func_80B8C644(EnGe2* this, PlayState* play);
|
||||
void func_80B8C9B8(EnGe2* this, PlayState* play);
|
||||
s32 EnGe2_SetupPath(EnGe2* this, PlayState* play);
|
||||
|
||||
void EnGe2_LookAround(EnGe2* this, PlayState* play);
|
||||
void EnGe2_Walk(EnGe2* this, PlayState* play);
|
||||
void EnGe2_GuardStationary(EnGe2* this, PlayState* play);
|
||||
|
||||
s32 EnGe2_ValidatePictograph(PlayState* play, Actor* thisx);
|
||||
|
||||
#if 0
|
||||
ActorInit En_Ge2_InitVars = {
|
||||
ACTOR_EN_GE2,
|
||||
ACTORCAT_NPC,
|
||||
@@ -39,78 +35,741 @@ ActorInit En_Ge2_InitVars = {
|
||||
(ActorFunc)EnGe2_Draw,
|
||||
};
|
||||
|
||||
// static ColliderCylinderInit sCylinderInit = {
|
||||
static ColliderCylinderInit D_80B8CE40 = {
|
||||
{ COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, },
|
||||
{ ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x038BFBB3, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
|
||||
typedef enum {
|
||||
/* 0 */ GERUDO_PURPLE_DETECTION_UNDETECTED,
|
||||
/* 1 */ GERUDO_PURPLE_DETECTION_HEARD,
|
||||
/* 2 */ GERUDO_PURPLE_DETECTION_PROXIMITY //!< Higher priority
|
||||
} GerudoPurpleDetection;
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ GERUDO_PURPLE_PATHSTATUS_NORMAL, //!< not near waypoint
|
||||
/* 1 */ GERUDO_PURPLE_PATHSTATUS_AT_POINT, //!< no path or new waypoint
|
||||
/* 2 */ GERUDO_PURPLE_PATHSTATUS_END //!< reached end of path
|
||||
} GerudoPurplePathStatus;
|
||||
|
||||
#define GERUDO_PURPLE_STATE_PATH_REVERSE (1 << 0) //!< Follow path backwards instead of forwards.
|
||||
#define GERUDO_PURPLE_STATE_KO (1 << 1)
|
||||
#define GERUDO_PURPLE_STATE_STUNNED (1 << 2) //!< Specifically by Deku Nuts
|
||||
#define GERUDO_PURPLE_STATE_DISABLE_MOVEMENT \
|
||||
(1 << 3) //!< Disable normal movement to let pathing function control it completely.
|
||||
#define GERUDO_PURPLE_STATE_CAPTURING (1 << 5) //!< Set but not used
|
||||
|
||||
static ColliderCylinderInit sCylinderInit = {
|
||||
{
|
||||
COLTYPE_NONE,
|
||||
AT_NONE,
|
||||
AC_ON | AC_TYPE_PLAYER,
|
||||
OC1_ON | OC1_TYPE_ALL,
|
||||
OC2_TYPE_1,
|
||||
COLSHAPE_CYLINDER,
|
||||
},
|
||||
{
|
||||
ELEMTYPE_UNK0,
|
||||
{ 0x00000000, 0x00, 0x00 },
|
||||
{ 0x038BFBB3, 0x00, 0x00 },
|
||||
TOUCH_NONE | TOUCH_SFX_NORMAL,
|
||||
BUMP_ON,
|
||||
OCELEM_ON,
|
||||
},
|
||||
{ 30, 60, 0, { 0, 0, 0 } },
|
||||
};
|
||||
|
||||
#endif
|
||||
void EnGe2_Init(Actor* thisx, PlayState* play) {
|
||||
s32 pad;
|
||||
EnGe2* this = THIS;
|
||||
|
||||
extern ColliderCylinderInit D_80B8CE40;
|
||||
ActorShape_Init(&this->picto.actor.shape, 0.0f, ActorShadow_DrawCircle, 36.0f);
|
||||
SkelAnime_InitFlex(play, &this->skelAnime, &gGerudoPurpleSkel, NULL, this->jointTable, this->morphTable,
|
||||
GERUDO_PURPLE_LIMB_MAX);
|
||||
Animation_PlayLoop(&this->skelAnime, &gGerudoPurpleWalkingAnim);
|
||||
|
||||
extern UNK_TYPE D_06008DD8;
|
||||
extern UNK_TYPE D_060091D0;
|
||||
extern UNK_TYPE D_06009D1C;
|
||||
extern UNK_TYPE D_0600A344;
|
||||
Collider_InitAndSetCylinder(play, &this->collider, &this->picto.actor, &sCylinderInit);
|
||||
this->picto.actor.colChkInfo.mass = MASS_IMMOVABLE;
|
||||
Actor_SetScale(&this->picto.actor, 0.01f);
|
||||
this->picto.actor.uncullZoneForward = 1200.0f;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/EnGe2_Init.s")
|
||||
if (this->picto.actor.world.rot.z == 0) {
|
||||
this->verticalDetectRange = 40.0f;
|
||||
} else {
|
||||
this->verticalDetectRange = fabsf(this->picto.actor.world.rot.z * 20.0f);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/EnGe2_Destroy.s")
|
||||
this->picto.actor.world.rot.x = this->picto.actor.shape.rot.x = 0;
|
||||
this->picto.actor.world.rot.z = this->picto.actor.shape.rot.z = 0;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8B514.s")
|
||||
this->picto.actor.targetMode = 6;
|
||||
this->stateFlags = 0;
|
||||
this->detectedStatus = GERUDO_PURPLE_DETECTION_UNDETECTED;
|
||||
this->csAction = -1;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8B5AC.s")
|
||||
this->picto.actor.terminalVelocity = -9.0f;
|
||||
this->picto.actor.gravity = -1.0f;
|
||||
this->picto.actor.speedXZ = 1.5f;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8B6B4.s")
|
||||
this->actionFunc = EnGe2_Walk;
|
||||
this->picto.validationFunc = EnGe2_ValidatePictograph;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8B7A8.s")
|
||||
EnGe2_SetupPath(this, play);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8B848.s")
|
||||
this->picto.actor.flags |= ACTOR_FLAG_10;
|
||||
if (play->actorCtx.flags & ACTORCTX_FLAG_1) {
|
||||
this->picto.actor.flags |= (ACTOR_FLAG_10 | ACTOR_FLAG_20);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8B90C.s")
|
||||
switch (GERUDO_PURPLE_GET_TYPE(&this->picto.actor)) {
|
||||
case GERUDO_PURPLE_TYPE_BOAT_SENTRY:
|
||||
Animation_Change(&this->skelAnime, &gGerudoPurpleLookingAboutAnim, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame(&gGerudoPurpleLookingAboutAnim), 0, 0.0f);
|
||||
this->actionFunc = EnGe2_GuardStationary;
|
||||
this->picto.actor.speedXZ = 0.0f;
|
||||
this->picto.actor.uncullZoneForward = 4000.0f;
|
||||
break;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BA40.s")
|
||||
case GERUDO_PURPLE_TYPE_AVEIL_GUARD:
|
||||
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_83_02)) {
|
||||
Actor_Kill(&this->picto.actor);
|
||||
}
|
||||
break;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BB3C.s")
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BC1C.s")
|
||||
void EnGe2_Destroy(Actor* thisx, PlayState* play) {
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BC78.s")
|
||||
// Detect Player through hearing or proximity
|
||||
GerudoPurpleDetection EnGe2_DetectPlayer(PlayState* play, EnGe2* this) {
|
||||
if (this->picto.actor.xzDistToPlayer > 250.0f) {
|
||||
return GERUDO_PURPLE_DETECTION_UNDETECTED;
|
||||
} else if ((Player_GetMask(play) != PLAYER_MASK_STONE) && (this->picto.actor.xzDistToPlayer < 50.0f)) {
|
||||
return GERUDO_PURPLE_DETECTION_PROXIMITY;
|
||||
} else if (func_800B715C(play)) {
|
||||
return GERUDO_PURPLE_DETECTION_HEARD;
|
||||
} else {
|
||||
return GERUDO_PURPLE_DETECTION_UNDETECTED;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BCEC.s")
|
||||
/**
|
||||
* Spotted Player with line-of-sight
|
||||
*
|
||||
* @param play PlayState
|
||||
* @param thisx Actor to use for range and angle checks
|
||||
* @param pos Position to check from
|
||||
* @param yaw Center of yaw range to check
|
||||
* @param yawRange Spread of angles from `yaw` to check. If 0, do not check yaw
|
||||
* @param xzRange Horizontal range to check
|
||||
* @param yRange Vertical range to check
|
||||
* @return true if Player is visible with these settings
|
||||
*/
|
||||
s32 EnGe2_LookForPlayer(PlayState* play, Actor* actor, Vec3f* pos, s16 yaw, s16 yawRange, f32 xzRange, f32 yRange) {
|
||||
s16 yawToPlayer;
|
||||
Vec3f posResult;
|
||||
CollisionPoly* outPoly;
|
||||
Player* player = GET_PLAYER(play);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BD38.s")
|
||||
if (Player_GetMask(play) == PLAYER_MASK_STONE) {
|
||||
return false;
|
||||
}
|
||||
if (actor->xzDistToPlayer > xzRange) {
|
||||
return false;
|
||||
}
|
||||
if (fabsf(actor->playerHeightRel) > yRange) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BD90.s")
|
||||
yawToPlayer = actor->yawTowardsPlayer - yaw;
|
||||
if ((yawRange > 0) && (yawRange < ABS_ALT(yawToPlayer))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BE08.s")
|
||||
if (BgCheck_AnyLineTest1(&play->colCtx, pos, &player->bodyPartsPos[7], &posResult, &outPoly, false)) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BF04.s")
|
||||
/* Path functions */
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8BFC8.s")
|
||||
/**
|
||||
* Set up the path if it exists, choose the end and direction
|
||||
*
|
||||
* @return true if path is set up in reverse
|
||||
*/
|
||||
s32 EnGe2_SetupPath(EnGe2* this, PlayState* play) {
|
||||
if (GERUDO_PURPLE_GET_PATH(&this->picto.actor) != GERUDO_PURPLE_PATH_NONE) {
|
||||
this->path = &play->setupPathList[GERUDO_PURPLE_GET_PATH(&this->picto.actor)];
|
||||
if (this->path != NULL) {
|
||||
Path* path = this->path;
|
||||
Vec3s* points = Lib_SegmentedToVirtual(path->points);
|
||||
f32 diffX = points[0].x - this->picto.actor.world.pos.x;
|
||||
f32 diffZ = points[0].z - this->picto.actor.world.pos.z;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8C048.s")
|
||||
if ((SQ(diffX) + SQ(diffZ)) < SQ(10.0f)) {
|
||||
this->curPointIndex = 0;
|
||||
this->stateFlags &= ~GERUDO_PURPLE_STATE_PATH_REVERSE;
|
||||
} else {
|
||||
this->curPointIndex = path->count - 1;
|
||||
this->stateFlags |= GERUDO_PURPLE_STATE_PATH_REVERSE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this->path = NULL;
|
||||
this->curPointIndex = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8C0B0.s")
|
||||
void EnGe2_GetNextPath(EnGe2* this, PlayState* play) {
|
||||
Path* curPath;
|
||||
Path* nextPath;
|
||||
Vec3s* points;
|
||||
u8 unk1;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8C13C.s")
|
||||
this->curPointIndex = 0;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8C45C.s")
|
||||
if (GERUDO_PURPLE_GET_PATH(&this->picto.actor) != GERUDO_PURPLE_PATH_NONE) {
|
||||
curPath = &play->setupPathList[GERUDO_PURPLE_GET_PATH(&this->picto.actor)];
|
||||
unk1 = curPath->unk1;
|
||||
nextPath = &play->setupPathList[unk1];
|
||||
this->path = nextPath;
|
||||
points = Lib_SegmentedToVirtual(nextPath->points);
|
||||
this->picto.actor.world.pos.x = points[0].x;
|
||||
this->picto.actor.world.pos.z = points[0].z;
|
||||
} else {
|
||||
this->path = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8C59C.s")
|
||||
void EnGe2_SetupBlownAwayPath(EnGe2* this, PlayState* play) {
|
||||
s32 pad;
|
||||
Vec3s* points;
|
||||
Vec3f nextPoint;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8C644.s")
|
||||
this->curPointIndex = 0;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8C9B8.s")
|
||||
if (GERUDO_PURPLE_GET_PATH(&this->picto.actor) != GERUDO_PURPLE_PATH_NONE) {
|
||||
this->path = &play->setupPathList[GERUDO_PURPLE_GET_PATH(&this->picto.actor)];
|
||||
if (this->path != NULL) {
|
||||
points = Lib_SegmentedToVirtual(this->path->points);
|
||||
Math_Vec3s_ToVec3f(&this->picto.actor.world.pos, points);
|
||||
this->curPointIndex++;
|
||||
points++;
|
||||
Math_Vec3s_ToVec3f(&nextPoint, points);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/EnGe2_Update.s")
|
||||
this->picto.actor.world.rot.y = Math_Vec3f_Yaw(&this->picto.actor.world.pos, &nextPoint);
|
||||
this->picto.actor.world.rot.x = Math_Vec3f_Pitch(&this->picto.actor.world.pos, &nextPoint);
|
||||
this->picto.actor.speedXZ = 15.0f;
|
||||
}
|
||||
} else {
|
||||
this->path = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8CC0C.s")
|
||||
GerudoPurplePathStatus EnGe2_FollowPath(EnGe2* this) {
|
||||
Path* path = this->path;
|
||||
Vec3s* curPoint;
|
||||
f32 diffX;
|
||||
f32 diffZ;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8CCB4.s")
|
||||
if (path == NULL) {
|
||||
return GERUDO_PURPLE_PATHSTATUS_AT_POINT;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/func_80B8CCFC.s")
|
||||
curPoint = (Vec3s*)Lib_SegmentedToVirtual(path->points);
|
||||
curPoint += this->curPointIndex;
|
||||
diffX = curPoint->x - this->picto.actor.world.pos.x;
|
||||
diffZ = curPoint->z - this->picto.actor.world.pos.z;
|
||||
this->picto.actor.world.rot.y = Math_Atan2S(diffX, diffZ);
|
||||
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->picto.actor.world.rot.y, 2, 0x7D0, 0xC8);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ge2/EnGe2_Draw.s")
|
||||
if ((SQ(diffX) + SQ(diffZ)) < SQ(10.0f)) {
|
||||
if (this->stateFlags & GERUDO_PURPLE_STATE_PATH_REVERSE) {
|
||||
this->curPointIndex--;
|
||||
if (this->curPointIndex < 0) {
|
||||
return GERUDO_PURPLE_PATHSTATUS_END;
|
||||
}
|
||||
} else {
|
||||
this->curPointIndex++;
|
||||
if (this->curPointIndex >= path->count) {
|
||||
return GERUDO_PURPLE_PATHSTATUS_END;
|
||||
}
|
||||
}
|
||||
return GERUDO_PURPLE_PATHSTATUS_AT_POINT;
|
||||
}
|
||||
|
||||
return GERUDO_PURPLE_PATHSTATUS_NORMAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for Blown Away cutscene path.
|
||||
*/
|
||||
s32 EnGe2_FollowPathWithoutGravity(EnGe2* this) {
|
||||
s32 pad;
|
||||
Vec3s* curPoint;
|
||||
Path* path = this->path;
|
||||
Vec3f point;
|
||||
s16 yawTarget;
|
||||
s16 pitchTarget;
|
||||
|
||||
if (this->path == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
curPoint = Lib_SegmentedToVirtual(path->points);
|
||||
curPoint += this->curPointIndex;
|
||||
|
||||
Math_Vec3s_ToVec3f(&point, curPoint);
|
||||
yawTarget = Math_Vec3f_Yaw(&this->picto.actor.world.pos, &point);
|
||||
pitchTarget = Math_Vec3f_Pitch(&this->picto.actor.world.pos, &point);
|
||||
Math_SmoothStepToS(&this->picto.actor.world.rot.y, yawTarget, 0xA, 0x3E8, 0x64);
|
||||
Math_SmoothStepToS(&this->picto.actor.world.rot.x, pitchTarget, 6, 0x7D0, 0xC8);
|
||||
this->picto.actor.speedXZ = 15.0f;
|
||||
|
||||
Actor_MoveWithoutGravityReverse(&this->picto.actor);
|
||||
|
||||
if (Math_Vec3f_DistXYZ(&this->picto.actor.world.pos, &point) < 40.0f) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Action and helper functions */
|
||||
|
||||
void EnGe2_SpawnEffects(EnGe2* this, PlayState* play) {
|
||||
static Vec3f effectVelocity = { 0.0f, -0.05f, 0.0f };
|
||||
static Vec3f effectAccel = { 0.0f, -0.025f, 0.0f };
|
||||
static Color_RGBA8 effectPrimColor = { 255, 255, 255, 0 };
|
||||
static Color_RGBA8 effectEnvColor = { 255, 150, 0, 0 };
|
||||
s16 effectAngle = play->state.frames * 0x2800;
|
||||
Vec3f effectPos;
|
||||
|
||||
effectPos.x = (Math_CosS(effectAngle) * 5.0f) + this->picto.actor.focus.pos.x;
|
||||
effectPos.y = this->picto.actor.focus.pos.y + 10.0f;
|
||||
effectPos.z = (Math_SinS(effectAngle) * 5.0f) + this->picto.actor.focus.pos.z;
|
||||
EffectSsKirakira_SpawnDispersed(play, &effectPos, &effectVelocity, &effectAccel, &effectPrimColor, &effectEnvColor,
|
||||
1000, 16);
|
||||
}
|
||||
|
||||
void EnGe2_Scream(EnGe2* this) {
|
||||
if ((s32)Rand_ZeroFloat(2.0f) == 0) {
|
||||
Actor_PlaySfxAtPos(&this->picto.actor, NA_SE_VO_FPVO00);
|
||||
} else {
|
||||
Actor_PlaySfxAtPos(&this->picto.actor, NA_SE_VO_FPVO01);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for timer to finish, then set up the captured/thrown out transition.
|
||||
*/
|
||||
void EnGe2_ThrowPlayerOut(EnGe2* this, PlayState* play) {
|
||||
if (this->timer > 0) {
|
||||
this->timer--;
|
||||
} else if (play->nextEntrance != play->setupExitList[GERUDO_PURPLE_GET_EXIT(&this->picto.actor)]) {
|
||||
play->nextEntrance = play->setupExitList[GERUDO_PURPLE_GET_EXIT(&this->picto.actor)];
|
||||
play->transitionTrigger = TRANS_TRIGGER_START;
|
||||
play->transitionType = TRANS_TYPE_38;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used if Aveil spots Player.
|
||||
*/
|
||||
void EnGe2_TurnToPlayerFast(EnGe2* this, PlayState* play) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->picto.actor.yawTowardsPlayer, 2, 0x1000, 0x200);
|
||||
}
|
||||
|
||||
void EnGe2_CapturePlayer(EnGe2* this, PlayState* play) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->picto.actor.yawTowardsPlayer, 2, 0x400, 0x100);
|
||||
EnGe2_ThrowPlayerOut(this, play);
|
||||
}
|
||||
|
||||
void EnGe2_SetupCapturePlayer(EnGe2* this) {
|
||||
this->picto.actor.speedXZ = 0.0f;
|
||||
this->actionFunc = EnGe2_CapturePlayer;
|
||||
Animation_Change(&this->skelAnime, &gGerudoPurpleLookingAboutAnim, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame(&gGerudoPurpleLookingAboutAnim), 0, -8.0f);
|
||||
}
|
||||
|
||||
void EnGe2_Charge(EnGe2* this, PlayState* play) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->picto.actor.yawTowardsPlayer, 2, 0x400, 0x100);
|
||||
this->picto.actor.world.rot.y = this->picto.actor.shape.rot.y;
|
||||
|
||||
if (this->picto.actor.xzDistToPlayer < 50.0f) {
|
||||
EnGe2_SetupCapturePlayer(this);
|
||||
} else if (!(this->picto.actor.bgCheckFlags & 1)) {
|
||||
this->picto.actor.world.pos = this->picto.actor.prevPos;
|
||||
EnGe2_SetupCapturePlayer(this);
|
||||
}
|
||||
|
||||
if (this->timer > 0) {
|
||||
this->timer--;
|
||||
} else {
|
||||
EnGe2_ThrowPlayerOut(this, play);
|
||||
}
|
||||
|
||||
if (Animation_OnFrame(&this->skelAnime, 2.0f) || Animation_OnFrame(&this->skelAnime, 6.0f)) {
|
||||
Actor_PlaySfxAtPos(&this->picto.actor, NA_SE_EV_PIRATE_WALK);
|
||||
}
|
||||
}
|
||||
|
||||
void EnGe2_SetupCharge(EnGe2* this, PlayState* play) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->picto.actor.yawTowardsPlayer, 2, 0x400, 0x100);
|
||||
this->picto.actor.world.rot.y = this->picto.actor.shape.rot.y;
|
||||
|
||||
if (this->picto.actor.shape.rot.y == this->picto.actor.yawTowardsPlayer) {
|
||||
Animation_Change(&this->skelAnime, &gGerudoPurpleChargingAnim, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame(&gGerudoPurpleChargingAnim), 0, -8.0f);
|
||||
this->timer = 50;
|
||||
this->picto.actor.speedXZ = 4.0f;
|
||||
this->actionFunc = EnGe2_Charge;
|
||||
}
|
||||
}
|
||||
|
||||
void EnGe2_SetupLookAround(EnGe2* this) {
|
||||
Animation_Change(&this->skelAnime, &gGerudoPurpleLookingAboutAnim, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame(&gGerudoPurpleLookingAboutAnim), 0, -8.0f);
|
||||
this->timer = 60;
|
||||
this->picto.actor.speedXZ = 0.0f;
|
||||
this->actionFunc = EnGe2_LookAround;
|
||||
}
|
||||
|
||||
void EnGe2_Stunned(EnGe2* this, PlayState* play) {
|
||||
if (this->picto.actor.colorFilterTimer == 0) {
|
||||
EnGe2_SetupLookAround(this);
|
||||
this->detectedStatus = GERUDO_PURPLE_DETECTION_UNDETECTED;
|
||||
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
|
||||
this->stateFlags &= ~GERUDO_PURPLE_STATE_STUNNED;
|
||||
}
|
||||
}
|
||||
|
||||
void EnGe2_KnockedOut(EnGe2* this, PlayState* play) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
EnGe2_SpawnEffects(this, play);
|
||||
|
||||
if (this->timer > 0) {
|
||||
this->timer--;
|
||||
} else {
|
||||
EnGe2_SetupLookAround(this);
|
||||
this->detectedStatus = GERUDO_PURPLE_DETECTION_UNDETECTED;
|
||||
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
|
||||
this->stateFlags &= ~GERUDO_PURPLE_STATE_KO;
|
||||
this->picto.actor.flags |= ACTOR_FLAG_1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Carries out various patrol functions:
|
||||
* - Turning to Player if being arrested
|
||||
* - Turning to Player if spotted by Aveil
|
||||
* - Looking for Player
|
||||
* - Managing collisions and collider
|
||||
*/
|
||||
void EnGe2_PatrolDuties(EnGe2* this, PlayState* play) {
|
||||
Player* player = GET_PLAYER(play);
|
||||
f32 visionRange = gSaveContext.save.isNight ? 200.0f : 280.0f;
|
||||
|
||||
if (player->csMode == 0x1A) {
|
||||
this->picto.actor.speedXZ = 0.0f;
|
||||
this->actionFunc = EnGe2_SetupCharge;
|
||||
Animation_Change(&this->skelAnime, &gGerudoPurpleLookingAboutAnim, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame(&gGerudoPurpleLookingAboutAnim), 0, -8.0f);
|
||||
this->stateFlags |= GERUDO_PURPLE_STATE_CAPTURING;
|
||||
} else if (CHECK_WEEKEVENTREG(WEEKEVENTREG_80_08)) {
|
||||
this->picto.actor.speedXZ = 0.0f;
|
||||
this->actionFunc = EnGe2_TurnToPlayerFast;
|
||||
Animation_Change(&this->skelAnime, &gGerudoPurpleLookingAboutAnim, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame(&gGerudoPurpleLookingAboutAnim), 0, -8.0f);
|
||||
} else if (EnGe2_LookForPlayer(play, &this->picto.actor, &this->picto.actor.focus.pos,
|
||||
this->picto.actor.shape.rot.y, 0x1800, visionRange, this->verticalDetectRange)) {
|
||||
if ((GERUDO_PURPLE_GET_EXIT(&this->picto.actor) != GERUDO_PURPLE_EXIT_NONE) && !Play_InCsMode(play)) {
|
||||
this->picto.actor.speedXZ = 0.0f;
|
||||
func_800B7298(play, &this->picto.actor, 0x1A);
|
||||
func_801000A4(NA_SE_SY_FOUND);
|
||||
Message_StartTextbox(play, 0x1194, &this->picto.actor);
|
||||
this->actionFunc = EnGe2_SetupCharge;
|
||||
Animation_Change(&this->skelAnime, &gGerudoPurpleLookingAboutAnim, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame(&gGerudoPurpleLookingAboutAnim), 0, -8.0f);
|
||||
}
|
||||
} else if (this->collider.base.acFlags & AC_HIT) {
|
||||
if ((this->collider.info.acHitInfo != NULL) &&
|
||||
(this->collider.info.acHitInfo->toucher.dmgFlags & DMG_DEKU_NUT)) {
|
||||
Actor_SetColorFilter(&this->picto.actor, 0, 120, 0, 400);
|
||||
this->picto.actor.speedXZ = 0.0f;
|
||||
this->actionFunc = EnGe2_Stunned;
|
||||
this->stateFlags |= GERUDO_PURPLE_STATE_STUNNED;
|
||||
} else {
|
||||
Animation_Change(&this->skelAnime, &gGerudoPurpleFallingToGroundAnim, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame(&gGerudoPurpleFallingToGroundAnim), 2, -8.0f);
|
||||
this->timer = 200;
|
||||
this->picto.actor.speedXZ = 0.0f;
|
||||
this->actionFunc = EnGe2_KnockedOut;
|
||||
Actor_PlaySfxAtPos(&this->picto.actor, NA_SE_EN_PIRATE_DEAD);
|
||||
this->picto.actor.flags &= ~ACTOR_FLAG_1;
|
||||
this->stateFlags |= GERUDO_PURPLE_STATE_KO;
|
||||
}
|
||||
} else if (this->picto.actor.home.rot.x == 0) {
|
||||
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
|
||||
}
|
||||
}
|
||||
|
||||
void EnGe2_LookAround(EnGe2* this, PlayState* play) {
|
||||
u8 detectedStatus;
|
||||
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
|
||||
detectedStatus = EnGe2_DetectPlayer(play, this);
|
||||
if (detectedStatus != GERUDO_PURPLE_DETECTION_UNDETECTED) {
|
||||
this->timer = 100;
|
||||
this->yawTarget = this->picto.actor.yawTowardsPlayer;
|
||||
|
||||
if (this->detectedStatus < detectedStatus) {
|
||||
this->detectedStatus = detectedStatus;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->timer > 0) {
|
||||
this->timer--;
|
||||
} else {
|
||||
this->actionFunc = EnGe2_Walk;
|
||||
Animation_Change(&this->skelAnime, &gGerudoPurpleWalkingAnim, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame(&gGerudoPurpleWalkingAnim), 0, -8.0f);
|
||||
this->headRot.y = 0;
|
||||
this->detectedStatus = GERUDO_PURPLE_DETECTION_UNDETECTED;
|
||||
}
|
||||
|
||||
switch (this->detectedStatus) {
|
||||
case GERUDO_PURPLE_DETECTION_HEARD:
|
||||
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->yawTarget, 2, 0x3E8, 0x1F4);
|
||||
break;
|
||||
|
||||
case GERUDO_PURPLE_DETECTION_PROXIMITY:
|
||||
Math_SmoothStepToS(&this->picto.actor.shape.rot.y, this->yawTarget, 2, 0xBB8, 0x3E8);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
this->picto.actor.world.rot.y = this->picto.actor.shape.rot.y;
|
||||
EnGe2_PatrolDuties(this, play);
|
||||
}
|
||||
|
||||
void EnGe2_Walk(EnGe2* this, PlayState* play) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
this->picto.actor.speedXZ = 1.5f;
|
||||
|
||||
switch (EnGe2_FollowPath(this)) {
|
||||
case GERUDO_PURPLE_PATHSTATUS_END:
|
||||
EnGe2_SetupPath(this, play);
|
||||
break;
|
||||
|
||||
case GERUDO_PURPLE_PATHSTATUS_AT_POINT:
|
||||
EnGe2_SetupLookAround(this);
|
||||
this->detectedStatus = GERUDO_PURPLE_DETECTION_UNDETECTED;
|
||||
break;
|
||||
|
||||
default: // GERUDO_PURPLE_PATHSTATUS_NORMAL
|
||||
break;
|
||||
}
|
||||
|
||||
this->detectedStatus = EnGe2_DetectPlayer(play, this);
|
||||
if (this->detectedStatus != GERUDO_PURPLE_DETECTION_UNDETECTED) {
|
||||
EnGe2_SetupLookAround(this);
|
||||
this->yawTarget = this->picto.actor.yawTowardsPlayer;
|
||||
}
|
||||
EnGe2_PatrolDuties(this, play);
|
||||
}
|
||||
|
||||
void EnGe2_PerformCutsceneActions(EnGe2* this, PlayState* play) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
if (Cutscene_CheckActorAction(play, 476)) {
|
||||
s16 csAction = play->csCtx.actorActions[Cutscene_GetActorActionIndex(play, 476)]->action;
|
||||
if (this->csAction != csAction) {
|
||||
this->csAction = csAction;
|
||||
|
||||
switch (csAction) {
|
||||
case ENGE2_CSACTION_BEEHIVE_PATROL:
|
||||
Animation_Change(&this->skelAnime, &gGerudoPurpleLookingAboutAnim, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame(&gGerudoPurpleLookingAboutAnim), 0, -8.0f);
|
||||
EnGe2_GetNextPath(this, play);
|
||||
break;
|
||||
|
||||
case ENGE2_CSACTION_BEEHIVE_RUN_AWAY:
|
||||
Animation_Change(&this->skelAnime, &gGerudoPurpleRunningAwayCutsceneAnim, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame(&gGerudoPurpleRunningAwayCutsceneAnim), 0, -5.0f);
|
||||
this->screamTimer = (s32)(Rand_ZeroFloat(10.0f) + 20.0f);
|
||||
break;
|
||||
|
||||
case ENGE2_CSACTION_BEEHIVE_EXIT:
|
||||
Actor_Kill(&this->picto.actor);
|
||||
break;
|
||||
|
||||
case ENGE2_CSACTION_GBT_ENTR_STAND_STILL:
|
||||
Animation_Change(&this->skelAnime, &gGerudoPurpleGreatBayCutsceneAnim, 0.0f, 0.0f, 0.0f, 2, 0.0f);
|
||||
break;
|
||||
|
||||
case ENGE2_CSACTION_GBT_ENTR_BLOWN_AWAY:
|
||||
Animation_Change(&this->skelAnime, &gGerudoPurpleGreatBayCutsceneAnim, 0.0f, 1.0f, 1.0f, 2, 0.0f);
|
||||
EnGe2_SetupBlownAwayPath(this, play);
|
||||
this->stateFlags |= GERUDO_PURPLE_STATE_DISABLE_MOVEMENT;
|
||||
this->screamTimer = (s32)(Rand_ZeroFloat(10.0f) + 20.0f);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (this->csAction) {
|
||||
case ENGE2_CSACTION_BEEHIVE_RUN_AWAY:
|
||||
EnGe2_FollowPath(this);
|
||||
this->picto.actor.speedXZ = 5.0f;
|
||||
|
||||
if (Animation_OnFrame(&this->skelAnime, 2.0f) || Animation_OnFrame(&this->skelAnime, 6.0f)) {
|
||||
Actor_PlaySfxAtPos(&this->picto.actor, NA_SE_EV_PIRATE_WALK);
|
||||
}
|
||||
|
||||
if (this->screamTimer > 0) {
|
||||
this->screamTimer--;
|
||||
} else {
|
||||
this->screamTimer = (s32)(Rand_ZeroFloat(10.0f) + 20.0f);
|
||||
EnGe2_Scream(this);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENGE2_CSACTION_GBT_ENTR_BLOWN_AWAY:
|
||||
if ((this->curPointIndex < this->path->count) && EnGe2_FollowPathWithoutGravity(this)) {
|
||||
this->curPointIndex++;
|
||||
}
|
||||
|
||||
// Tumble in the air
|
||||
this->picto.actor.shape.rot.x += 0x3E8;
|
||||
this->picto.actor.shape.rot.y += 0x7D0;
|
||||
this->picto.actor.shape.rot.z += 0x1F4;
|
||||
|
||||
if (this->screamTimer > 0) {
|
||||
this->screamTimer--;
|
||||
} else {
|
||||
this->screamTimer = (s32)(Rand_ZeroFloat(10.0f) + 20.0f);
|
||||
EnGe2_Scream(this);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Used for those on boats
|
||||
void EnGe2_GuardStationary(EnGe2* this, PlayState* play) {
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
if (EnGe2_LookForPlayer(play, &this->picto.actor, &this->picto.actor.focus.pos, this->picto.actor.shape.rot.y,
|
||||
0x4000, 720.0f, this->verticalDetectRange)) {
|
||||
if ((GERUDO_PURPLE_GET_EXIT(&this->picto.actor) != GERUDO_PURPLE_EXIT_NONE) && !Play_InCsMode(play)) {
|
||||
func_800B7298(play, &this->picto.actor, 0x1A);
|
||||
func_801000A4(NA_SE_SY_FOUND);
|
||||
Message_StartTextbox(play, 0x1194, &this->picto.actor);
|
||||
this->timer = 50;
|
||||
EnGe2_SetupCapturePlayer(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->picto.actor.playerHeightRel < -150.0f) {
|
||||
this->picto.actor.draw = NULL;
|
||||
} else {
|
||||
this->picto.actor.draw = EnGe2_Draw;
|
||||
}
|
||||
}
|
||||
|
||||
void EnGe2_Update(Actor* thisx, PlayState* play) {
|
||||
s32 pad;
|
||||
EnGe2* this = THIS;
|
||||
|
||||
if (!(this->stateFlags & GERUDO_PURPLE_STATE_DISABLE_MOVEMENT)) {
|
||||
Actor_MoveWithGravity(&this->picto.actor);
|
||||
}
|
||||
Actor_UpdateBgCheckInfo(play, &this->picto.actor, 40.0f, 25.0f, 40.0f, 5);
|
||||
Collider_UpdateCylinder(&this->picto.actor, &this->collider);
|
||||
CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base);
|
||||
|
||||
if (Cutscene_CheckActorAction(play, 476)) {
|
||||
this->actionFunc = EnGe2_PerformCutsceneActions;
|
||||
this->stateFlags &= ~GERUDO_PURPLE_STATE_KO;
|
||||
this->stateFlags &= ~GERUDO_PURPLE_STATE_PATH_REVERSE;
|
||||
this->picto.actor.flags |= ACTOR_FLAG_20;
|
||||
this->picto.actor.speedXZ = 0.0f;
|
||||
}
|
||||
|
||||
this->actionFunc(this, play);
|
||||
|
||||
// Blinking
|
||||
if (this->stateFlags & GERUDO_PURPLE_STATE_KO) {
|
||||
this->eyeIndex = 2;
|
||||
} else if (!(this->stateFlags & GERUDO_PURPLE_STATE_STUNNED)) {
|
||||
if (DECR(this->blinkTimer) == 0) {
|
||||
this->blinkTimer = Rand_S16Offset(60, 60);
|
||||
}
|
||||
this->eyeIndex = this->blinkTimer;
|
||||
if (this->eyeIndex >= 3) {
|
||||
this->eyeIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s32 EnGe2_ValidatePictograph(PlayState* play, Actor* thisx) {
|
||||
s32 ret = Snap_ValidatePictograph(play, thisx, PICTO_VALID_PIRATE_GOOD, &thisx->focus.pos, &thisx->shape.rot, 10.0f,
|
||||
400.0f, -1);
|
||||
|
||||
ret |= Snap_ValidatePictograph(play, thisx, PICTO_VALID_PIRATE_TOO_FAR, &thisx->focus.pos, &thisx->shape.rot, 10.0f,
|
||||
1200.0f, -1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 EnGe2_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
|
||||
EnGe2* this = THIS;
|
||||
|
||||
if (limbIndex == GERUDO_PURPLE_NECK_LIMB) {
|
||||
rot->x += this->headRot.y;
|
||||
rot->z += this->headRot.x;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EnGe2_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) {
|
||||
static Vec3f sFocusOffset = { 600.0f, 700.0f, 0.0f };
|
||||
|
||||
if (limbIndex == GERUDO_PURPLE_HEAD_LIMB) {
|
||||
Matrix_MultVec3f(&sFocusOffset, &thisx->focus.pos);
|
||||
}
|
||||
}
|
||||
|
||||
void EnGe2_Draw(Actor* thisx, PlayState* play) {
|
||||
static TexturePtr sEyeTextures[] = {
|
||||
gGerudoPurpleEyeOpenTex,
|
||||
gGerudoPurpleEyeHalfTex,
|
||||
gGerudoPurpleEyeClosedTex,
|
||||
};
|
||||
s32 pad;
|
||||
EnGe2* this = THIS;
|
||||
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
func_8012C5B0(play->state.gfxCtx);
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sEyeTextures[this->eyeIndex]));
|
||||
func_800B8050(&this->picto.actor, play, 0);
|
||||
SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
|
||||
EnGe2_OverrideLimbDraw, EnGe2_PostLimbDraw, &this->picto.actor);
|
||||
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
@@ -2,14 +2,58 @@
|
||||
#define Z_EN_GE2_H
|
||||
|
||||
#include "global.h"
|
||||
#include "z64snap.h"
|
||||
#include "objects/object_gla/object_gla.h"
|
||||
|
||||
struct EnGe2;
|
||||
|
||||
typedef void (*EnGe2ActionFunc)(struct EnGe2*, PlayState*);
|
||||
|
||||
#define GERUDO_PURPLE_GET_EXIT(thisx) (((thisx)->params) & 0x1F) //!< Exit to send Player to when caught
|
||||
#define GERUDO_PURPLE_GET_TYPE(thisx) (((thisx)->params & 0xE0) >> 5)
|
||||
#define GERUDO_PURPLE_GET_PATH(thisx) ((((thisx)->params) & 0xFC00) >> 10)
|
||||
|
||||
#define GERUDO_PURPLE_PARAMS(path, type, exit) (((path) & 0x1F) | (((type) & 7) << 5) | (((exit) & 0x3F) << 10))
|
||||
|
||||
#define GERUDO_PURPLE_EXIT_NONE 0x1F
|
||||
#define GERUDO_PURPLE_PATH_NONE 0x3F
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ GERUDO_PURPLE_TYPE_CUTSCENE,
|
||||
/* 1 */ GERUDO_PURPLE_TYPE_BOAT_SENTRY, //!< on boats
|
||||
/* 2 */ GERUDO_PURPLE_TYPE_AVEIL_GUARD,
|
||||
/* 7 */ GERUDO_PURPLE_TYPE_FORTRESS = 7 //!< In both courtyard and rooms
|
||||
} GerudoPurpleType;
|
||||
|
||||
//! TODO: work out where to put this
|
||||
typedef enum {
|
||||
/* 1 */ ENGE2_CSACTION_BEEHIVE_PATROL = 1,
|
||||
/* 2 */ ENGE2_CSACTION_BEEHIVE_RUN_AWAY,
|
||||
/* 3 */ ENGE2_CSACTION_BEEHIVE_EXIT,
|
||||
/* 4 */ ENGE2_CSACTION_GBT_ENTR_STAND_STILL,
|
||||
/* 5 */ ENGE2_CSACTION_GBT_ENTR_BLOWN_AWAY
|
||||
} EnGe2CsAction;
|
||||
|
||||
typedef struct EnGe2 {
|
||||
/* 0x000 */ Actor actor;
|
||||
/* 0x144 */ char unk_144[0x1C4];
|
||||
/* 0x000 */ PictoActor picto;
|
||||
/* 0x148 */ ColliderCylinder collider;
|
||||
/* 0x194 */ SkelAnime skelAnime;
|
||||
/* 0x1D8 */ Vec3s jointTable[GERUDO_PURPLE_LIMB_MAX];
|
||||
/* 0x25C */ Vec3s morphTable[GERUDO_PURPLE_LIMB_MAX];
|
||||
/* 0x2E0 */ s16 eyeIndex;
|
||||
/* 0x2E2 */ s16 blinkTimer;
|
||||
/* 0x2E4 */ Vec3s headRot;
|
||||
/* 0x2E8 */ Vec3s torsoRot; // unused, inferred from similar usage in other actors
|
||||
/* 0x2F0 */ Path* path;
|
||||
/* 0x2F4 */ s32 curPointIndex;
|
||||
/* 0x2F8 */ u16 stateFlags;
|
||||
/* 0x2FA */ s16 yawTarget; //!< used when Player detected to fix the yaw to turn to
|
||||
/* 0x2FC */ f32 verticalDetectRange; //!< vertical range to look for the player within
|
||||
/* 0x300 */ u8 timer;
|
||||
/* 0x301 */ u8 detectedStatus;
|
||||
/* 0x302 */ s16 csAction;
|
||||
/* 0x304 */ s16 unk304; // unused
|
||||
/* 0x306 */ s16 screamTimer;
|
||||
/* 0x308 */ EnGe2ActionFunc actionFunc;
|
||||
} EnGe2; // size = 0x30C
|
||||
|
||||
|
||||
@@ -1134,7 +1134,7 @@ void func_80B43074(EnKgy* this, PlayState* play) {
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
func_8012C28C(play->state.gfxCtx);
|
||||
func_800B8050(&this->actor, play, MTXMODE_NEW);
|
||||
func_800B8050(&this->actor, play, 0);
|
||||
Matrix_Push();
|
||||
Matrix_Translate(-800.0f, 3100.0f, 8400.0f, MTXMODE_APPLY);
|
||||
Matrix_RotateXS(0x4000, MTXMODE_APPLY);
|
||||
|
||||
@@ -16,7 +16,7 @@ void ObjBoat_Destroy(Actor* thisx, PlayState* play);
|
||||
void ObjBoat_Update(Actor* thisx, PlayState* play);
|
||||
void ObjBoat_Draw(Actor* thisx, PlayState* play);
|
||||
|
||||
void func_80B9B428(Actor* thisx, PlayState* play2);
|
||||
void ObjBoat_UpdateCutscene(Actor* thisx, PlayState* play2);
|
||||
|
||||
ActorInit Obj_Boat_InitVars = {
|
||||
ACTOR_OBJ_BOAT,
|
||||
@@ -37,14 +37,21 @@ static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
s16 func_80B9AF50(ObjBoat* this, Vec3f* arg0) {
|
||||
/**
|
||||
* Get the next point on the path and the yaw to use to get there.
|
||||
*
|
||||
* @param this
|
||||
* @param nextPoint Position of next point on path
|
||||
* @return yaw to use (or opposite of yaw if reversing)
|
||||
*/
|
||||
s16 ObjBoat_GetNextPoint(ObjBoat* this, Vec3f* nextPoint) {
|
||||
s16 yaw;
|
||||
Vec3s* temp = &this->unk_164[(s32)this->unk_15C];
|
||||
Vec3s* curPoint = &this->points[(s32)this->curPointIndex];
|
||||
|
||||
Math_Vec3s_ToVec3f(arg0, &temp[this->unk_15D]);
|
||||
yaw = Math_Vec3f_Yaw(&this->dyna.actor.world.pos, arg0);
|
||||
Math_Vec3s_ToVec3f(nextPoint, &curPoint[this->direction]);
|
||||
yaw = Math_Vec3f_Yaw(&this->dyna.actor.world.pos, nextPoint);
|
||||
|
||||
return ((this->unk_15D > 0) ? yaw : (yaw + 0x8000));
|
||||
return ((this->direction > 0) ? yaw : yaw + 0x8000);
|
||||
}
|
||||
|
||||
void ObjBoat_Init(Actor* thisx, PlayState* play) {
|
||||
@@ -57,17 +64,17 @@ void ObjBoat_Init(Actor* thisx, PlayState* play) {
|
||||
DynaPolyActor_Init(&this->dyna, 3);
|
||||
DynaPolyActor_LoadMesh(play, &this->dyna, &object_kaizoku_obj_Colheader_009A88);
|
||||
if (thisx->params < 0) {
|
||||
this->dyna.actor.update = func_80B9B428;
|
||||
this->dyna.actor.update = ObjBoat_UpdateCutscene;
|
||||
} else {
|
||||
path = &play->setupPathList[OBJBOAT_GET_PATH(thisx)];
|
||||
this->unk_163 = path->count - 1;
|
||||
this->unk_164 = Lib_SegmentedToVirtual(path->points);
|
||||
this->unk_15D = 1;
|
||||
this->dyna.actor.world.pos.x = this->unk_164[this->unk_15C].x;
|
||||
this->dyna.actor.world.pos.z = this->unk_164[this->unk_15C].z;
|
||||
this->dyna.actor.shape.rot.y = func_80B9AF50(this, &sp24);
|
||||
this->maxPointIndex = path->count - 1;
|
||||
this->points = Lib_SegmentedToVirtual(path->points);
|
||||
this->direction = 1;
|
||||
this->dyna.actor.world.pos.x = this->points[this->curPointIndex].x;
|
||||
this->dyna.actor.world.pos.z = this->points[this->curPointIndex].z;
|
||||
this->dyna.actor.shape.rot.y = ObjBoat_GetNextPoint(this, &sp24);
|
||||
this->dyna.actor.world.rot.y = this->dyna.actor.shape.rot.y;
|
||||
this->unk_15D = -this->unk_15D;
|
||||
this->direction = -this->direction;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,11 +84,11 @@ void ObjBoat_Destroy(Actor* thisx, PlayState* play) {
|
||||
DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
|
||||
}
|
||||
|
||||
void func_80B9B124(ObjBoat* this) {
|
||||
this->unk_160 += 1000;
|
||||
this->dyna.actor.world.pos.y = Math_SinS(this->unk_160) + this->dyna.actor.home.pos.y;
|
||||
this->dyna.actor.shape.rot.x = Math_SinS(this->unk_160) * 100.0f;
|
||||
this->dyna.actor.shape.rot.z = Math_SinS(this->unk_160 * 2) * 50.0f;
|
||||
void ObjBoat_SetRotations(ObjBoat* this) {
|
||||
this->angle += 0x3E8;
|
||||
this->dyna.actor.world.pos.y = Math_SinS(this->angle) + this->dyna.actor.home.pos.y;
|
||||
this->dyna.actor.shape.rot.x = Math_SinS(this->angle) * 100.0f;
|
||||
this->dyna.actor.shape.rot.z = Math_SinS(this->angle * 2) * 50.0f;
|
||||
}
|
||||
|
||||
void ObjBoat_Update(Actor* thisx, PlayState* play) {
|
||||
@@ -89,93 +96,102 @@ void ObjBoat_Update(Actor* thisx, PlayState* play) {
|
||||
ObjBoat* this = THIS;
|
||||
Player* player = GET_PLAYER(play);
|
||||
s32 temp = DynaPolyActor_IsInRidingMovingState(&this->dyna);
|
||||
f32 sp3C = 0.0f;
|
||||
s16 sp3A = this->dyna.actor.shape.rot.y;
|
||||
Vec3f sp2C;
|
||||
f32 speedTarget = 0.0f;
|
||||
s16 yawTarget = this->dyna.actor.shape.rot.y;
|
||||
Vec3f nextPoint;
|
||||
|
||||
if ((temp != 0) || ((DynaPolyActor_IsInRidingFallingState(&this->dyna)))) {
|
||||
if ((this->unk_15F == 0) && (OBJBOAT_GET_4000(thisx) || ((temp != 0) && (this->unk_15C == this->unk_15E)))) {
|
||||
this->unk_15D = -this->unk_15D;
|
||||
if (this->unk_15D > 0) {
|
||||
this->unk_15E = this->unk_163;
|
||||
if (temp || ((DynaPolyActor_IsInRidingFallingState(&this->dyna)))) {
|
||||
if ((this->timer == 0) &&
|
||||
(OBJBOAT_GET_4000(thisx) || (temp && (this->curPointIndex == this->lastPointIndex)))) {
|
||||
this->direction = -this->direction;
|
||||
if (this->direction > 0) {
|
||||
this->lastPointIndex = this->maxPointIndex;
|
||||
} else {
|
||||
this->unk_15E = 0;
|
||||
this->lastPointIndex = 0;
|
||||
}
|
||||
this->unk_15F = 60;
|
||||
this->timer = 60;
|
||||
}
|
||||
} else if (this->dyna.actor.speedXZ == 0.0f) {
|
||||
if (this->unk_15F != 0) {
|
||||
this->unk_15F--;
|
||||
if (this->timer != 0) {
|
||||
this->timer--;
|
||||
}
|
||||
}
|
||||
if (this->unk_15C != this->unk_15E) {
|
||||
sp3A = func_80B9AF50(this, &sp2C);
|
||||
if (Math_Vec3f_DistXZ(&this->dyna.actor.world.pos, &sp2C) < 200.0f) {
|
||||
this->unk_15C += this->unk_15D;
|
||||
if (this->unk_15C == this->unk_15E) {
|
||||
|
||||
if (this->curPointIndex != this->lastPointIndex) {
|
||||
yawTarget = ObjBoat_GetNextPoint(this, &nextPoint);
|
||||
if (Math_Vec3f_DistXZ(&this->dyna.actor.world.pos, &nextPoint) < 200.0f) {
|
||||
this->curPointIndex += this->direction;
|
||||
if (this->curPointIndex == this->lastPointIndex) {
|
||||
if (OBJBOAT_GET_4000(thisx)) {
|
||||
this->unk_15C = 0;
|
||||
this->curPointIndex = 0;
|
||||
} else if (this->dyna.actor.speedXZ == 0.0f) {
|
||||
this->unk_15C = 0;
|
||||
this->unk_15D = -1;
|
||||
this->curPointIndex = 0;
|
||||
this->direction = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sp3C = this->unk_15D * (OBJBOAT_GET_4000(thisx) ? 5.0f : 3.0f);
|
||||
speedTarget = this->direction * (OBJBOAT_GET_4000(thisx) ? 5.0f : 3.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (player->csMode != PLAYER_CSMODE_26) {
|
||||
Math_ScaledStepToS(&this->dyna.actor.shape.rot.y, sp3A, (s16)(s32)(fabsf(this->dyna.actor.speedXZ) * 40.0f));
|
||||
Math_ScaledStepToS(&this->dyna.actor.shape.rot.y, yawTarget, (s32)(fabsf(this->dyna.actor.speedXZ) * 40.0f));
|
||||
this->dyna.actor.world.rot.y = this->dyna.actor.shape.rot.y;
|
||||
Math_StepToF(&this->dyna.actor.speedXZ, sp3C, 0.05f);
|
||||
Math_StepToF(&this->dyna.actor.speedXZ, speedTarget, 0.05f);
|
||||
Actor_MoveWithGravity(&this->dyna.actor);
|
||||
if (this->dyna.actor.speedXZ != 0.0f) {
|
||||
func_800B9010(&this->dyna.actor, NA_SE_EV_PIRATE_SHIP - SFX_FLAG);
|
||||
}
|
||||
}
|
||||
func_80B9B124(this);
|
||||
ObjBoat_SetRotations(this);
|
||||
}
|
||||
|
||||
void func_80B9B428(Actor* thisx, PlayState* play2) {
|
||||
// Update used in cutscenes
|
||||
void ObjBoat_UpdateCutscene(Actor* thisx, PlayState* play2) {
|
||||
PlayState* play = play2;
|
||||
ObjBoat* this = THIS;
|
||||
|
||||
if (Cutscene_CheckActorAction(play, 511)) {
|
||||
CsCmdActorAction* actionIndex = play->csCtx.actorActions[Cutscene_GetActorActionIndex(play, 511)];
|
||||
if (this->unk_15F != actionIndex->action) {
|
||||
if (this->csAction != actionIndex->action) {
|
||||
this->dyna.actor.shape.rot.x = actionIndex->urot.x;
|
||||
|
||||
if (actionIndex->action != 1) {
|
||||
Path* path = &play->setupPathList[OBJBOAT_GET_PATH(&this->dyna.actor)];
|
||||
|
||||
if (actionIndex->action == 3) {
|
||||
path = &play->setupPathList[path->unk1];
|
||||
}
|
||||
this->unk_163 = path->count;
|
||||
this->unk_164 = Lib_SegmentedToVirtual(path->points);
|
||||
Math_Vec3s_ToVec3f(&this->dyna.actor.world.pos, this->unk_164);
|
||||
|
||||
this->maxPointIndex = path->count;
|
||||
this->points = Lib_SegmentedToVirtual(path->points);
|
||||
Math_Vec3s_ToVec3f(&this->dyna.actor.world.pos, this->points);
|
||||
this->dyna.actor.speedXZ = actionIndex->urot.z * (45.0f / 0x2000);
|
||||
this->unk_164++;
|
||||
this->unk_15C = 1;
|
||||
this->points++;
|
||||
this->curPointIndex = 1;
|
||||
}
|
||||
this->unk_15F = actionIndex->action;
|
||||
|
||||
this->csAction = actionIndex->action;
|
||||
} else {
|
||||
if (actionIndex->action != 1) {
|
||||
Vec3f vec;
|
||||
f32 step;
|
||||
Vec3f posTarget;
|
||||
f32 distRemaining;
|
||||
|
||||
Math_Vec3s_ToVec3f(&vec, this->unk_164);
|
||||
step = Math_Vec3f_StepTo(&this->dyna.actor.world.pos, &vec, this->dyna.actor.speedXZ);
|
||||
if ((this->unk_15C < this->unk_163) && (step < this->dyna.actor.speedXZ)) {
|
||||
this->unk_164++;
|
||||
this->unk_15C++;
|
||||
Math_Vec3s_ToVec3f(&posTarget, this->points);
|
||||
distRemaining = Math_Vec3f_StepTo(&this->dyna.actor.world.pos, &posTarget, this->dyna.actor.speedXZ);
|
||||
if ((this->curPointIndex < this->maxPointIndex) && (distRemaining < this->dyna.actor.speedXZ)) {
|
||||
this->points++;
|
||||
this->curPointIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (actionIndex->action != 3) {
|
||||
func_80B9B124(this);
|
||||
ObjBoat_SetRotations(this);
|
||||
if (actionIndex->action == 2) {
|
||||
func_800B9010(&this->dyna.actor, NA_SE_EV_PIRATE_SHIP - SFX_FLAG);
|
||||
}
|
||||
} else {
|
||||
// Tumble in the air
|
||||
this->dyna.actor.shape.rot.y += 0x7D0;
|
||||
this->dyna.actor.shape.rot.x += 0x3E8;
|
||||
this->dyna.actor.shape.rot.z += 0x1F4;
|
||||
|
||||
@@ -10,14 +10,17 @@ struct ObjBoat;
|
||||
|
||||
typedef struct ObjBoat {
|
||||
/* 0x000 */ DynaPolyActor dyna;
|
||||
/* 0x15C */ u8 unk_15C;
|
||||
/* 0x15D */ s8 unk_15D;
|
||||
/* 0x15E */ u8 unk_15E;
|
||||
/* 0x15F */ u8 unk_15F;
|
||||
/* 0x160 */ s16 unk_160;
|
||||
/* 0x15C */ u8 curPointIndex;
|
||||
/* 0x15D */ s8 direction; // To follow the path
|
||||
/* 0x15E */ u8 lastPointIndex; // max point if direction is negative, first point if forwards
|
||||
/* 0x15F */ union {
|
||||
u8 timer;
|
||||
u8 csAction;
|
||||
};
|
||||
/* 0x160 */ s16 angle; // Angle used to set rotations
|
||||
/* 0x162 */ UNK_TYPE1 pad_162;
|
||||
/* 0x163 */ u8 unk_163;
|
||||
/* 0x164 */ Vec3s* unk_164;
|
||||
/* 0x163 */ u8 maxPointIndex; // point at the other end from 0
|
||||
/* 0x164 */ Vec3s* points;
|
||||
} ObjBoat; // size = 0x168
|
||||
|
||||
#endif // Z_OBJ_BOAT_H
|
||||
|
||||
@@ -135,16 +135,16 @@ void func_80AF0514(ObjLupygamelift* this) {
|
||||
}
|
||||
|
||||
void func_80AF0530(ObjLupygamelift* this, PlayState* play) {
|
||||
f32 step;
|
||||
f32 distRemaining;
|
||||
Vec3f target;
|
||||
|
||||
target.x = this->points[this->pointIndex].x;
|
||||
target.y = this->points[this->pointIndex].y;
|
||||
target.z = this->points[this->pointIndex].z;
|
||||
step = Math_Vec3f_StepTo(&this->dyna.actor.world.pos, &target, this->dyna.actor.speedXZ);
|
||||
if (step > 30.0f) {
|
||||
distRemaining = Math_Vec3f_StepTo(&this->dyna.actor.world.pos, &target, this->dyna.actor.speedXZ);
|
||||
if (distRemaining > 30.0f) {
|
||||
Math_SmoothStepToF(&this->dyna.actor.speedXZ, this->targetSpeedXZ, 0.5f, 5.0f, 0.1f);
|
||||
} else if (step > 0.0f) {
|
||||
} else if (distRemaining > 0.0f) {
|
||||
Math_SmoothStepToF(&this->dyna.actor.speedXZ, 5.0f, 0.5f, 5.0f, 1.0f);
|
||||
} else {
|
||||
if (this->pointIndex < (this->count - 1)) {
|
||||
|
||||
Reference in New Issue
Block a user