1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-08-06 06:10:21 +00:00

EnFish, OK and documented (#795)

* Matching

* Some naming

* spec

* Name another function

* Name animations, clarify use of GI_MAX and GI_NONE

* Documented bottle range functions

* Simplify squared distance function in EnIceHono, actor descriptions

* Functions for dropped fish

* More naming

* Change 65535.5f to (0xFFFF + 0.5f)

* Change 65535.5f to (0xFFFF + 0.5f)

* name phases

* Named other types, Docile functions

* Naming complete

* delete asm

* format, remove outdated comment

* Fix a few DrawFlexOpa arguments

* Review changes

* Change back to original playSound

* Function comments per review
This commit is contained in:
EllipticEllipsis 2021-05-02 17:41:05 +01:00 committed by GitHub
parent 2ee1fd4668
commit ce44541d33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
63 changed files with 812 additions and 2426 deletions

View file

@ -331,8 +331,8 @@ void BgSpot08Iceblock_Init(Actor* thisx, GlobalContext* globalCtx) {
break;
}
this->bobPhaseSlow = (s32)(Rand_ZeroOne() * 65535.5f);
this->bobPhaseFast = (s32)(Rand_ZeroOne() * 65535.5f);
this->bobPhaseSlow = (s32)(Rand_ZeroOne() * (0xFFFF + 0.5f));
this->bobPhaseFast = (s32)(Rand_ZeroOne() * (0xFFFF + 0.5f));
this->surfaceNormal.y = 1.0f;
this->rotationAxis.x = 1.0f;

View file

@ -324,7 +324,8 @@ void func_808B43D0(BgSpot15Rrbox* this, GlobalContext* globalCtx) {
Actor_MoveForward(actor);
if (actor->world.pos.y <= -31990.0f) {
if (actor->world.pos.y <= BGCHECK_Y_MIN + 10.0f) {
// Lon Lon wooden crate fell too much
osSyncPrintf("Warning : ロンロン木箱落ちすぎた(%s %d)(arg_data 0x%04x)\n", "../z_bg_spot15_rrbox.c", 599,
actor->params);

View file

@ -550,7 +550,7 @@ void EnBb_Blue(EnBb* this, GlobalContext* globalCtx) {
Math_SmoothStepToF(&this->flameScaleY, 80.0f, 1.0f, 10.0f, 0.0f);
Math_SmoothStepToF(&this->flameScaleX, 100.0f, 1.0f, 10.0f, 0.0f);
if (this->actor.floorHeight > -32000.0f) {
if (this->actor.floorHeight > BGCHECK_Y_MIN) {
Math_SmoothStepToF(&this->actor.world.pos.y, this->actor.floorHeight + 50.0f + this->flyHeightMod, 1.0f, 0.5f,
0.0f);
}

View file

@ -513,7 +513,7 @@ void func_809FEC70(EnDu* this, GlobalContext* globalCtx) {
EnDu_SetupAction(this, func_809FECE4);
} else {
f32 xzRange = this->actor.xzDistToPlayer + 1.0f;
func_8002F434(&this->actor, globalCtx, 0x54, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f);
func_8002F434(&this->actor, globalCtx, GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f);
}
}

View file

@ -660,6 +660,7 @@ void func_80A0329C(EnElf* this, GlobalContext* globalCtx) {
}
if (!(this->fairyFlags & FAIRY_FLAG_BIG)) {
// GI_MAX in this case allows the player to catch the actor in a bottle
func_8002F434(&this->actor, globalCtx, GI_MAX, 80.0f, 60.0f);
}
}

View file

@ -382,30 +382,30 @@ void EnExItem_TargetPrizeApproach(EnExItem* this, GlobalContext* globalCtx) {
this->actor.world.pos.z += (tmpf3 / tmpf4) * 5.0f;
}
} else {
s32 itemId;
s32 getItemId;
this->actor.draw = NULL;
func_8002DF54(globalCtx, NULL, 7);
this->actor.parent = NULL;
if (CUR_UPG_VALUE(UPG_BULLET_BAG) == 1) {
itemId = GI_BULLET_BAG_40;
getItemId = GI_BULLET_BAG_40;
} else {
itemId = GI_BULLET_BAG_50;
getItemId = GI_BULLET_BAG_50;
}
func_8002F434(&this->actor, globalCtx, itemId, 2000.0f, 1000.0f);
func_8002F434(&this->actor, globalCtx, getItemId, 2000.0f, 1000.0f);
this->actionFunc = EnExItem_TargetPrizeGive;
}
}
void EnExItem_TargetPrizeGive(EnExItem* this, GlobalContext* globalCtx) {
s32 itemId;
s32 getItemId;
if (Actor_HasParent(&this->actor, globalCtx)) {
this->actionFunc = EnExItem_TargetPrizeFinish;
} else {
itemId = (CUR_UPG_VALUE(UPG_BULLET_BAG) == 2) ? GI_BULLET_BAG_50 : GI_BULLET_BAG_40;
getItemId = (CUR_UPG_VALUE(UPG_BULLET_BAG) == 2) ? GI_BULLET_BAG_50 : GI_BULLET_BAG_40;
func_8002F434(&this->actor, globalCtx, itemId, 2000.0f, 1000.0f);
func_8002F434(&this->actor, globalCtx, getItemId, 2000.0f, 1000.0f);
}
}

View file

@ -1,5 +1,12 @@
/*
* File: z_en_fish.c
* Overlay: ovl_En_Fish
* Description: Fish
*/
#include "z_en_fish.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "vt.h"
#define FLAGS 0x00000000
@ -10,20 +17,29 @@ void EnFish_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnFish_Update(Actor* thisx, GlobalContext* globalCtx);
void EnFish_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
const ActorInit En_Fish_InitVars = {
ACTOR_EN_FISH,
ACTORCAT_ITEMACTION,
FLAGS,
OBJECT_GAMEPLAY_KEEP,
sizeof(EnFish),
(ActorFunc)EnFish_Init,
(ActorFunc)EnFish_Destroy,
(ActorFunc)EnFish_Update,
(ActorFunc)EnFish_Draw,
};
void EnFish_Respawning_SetupSlowDown(EnFish* this);
void EnFish_Respawning_SlowDown(EnFish* this, GlobalContext* globalCtx);
void EnFish_Respawning_SetupFollowChild(EnFish* this);
void EnFish_Respawning_FollowChild(EnFish* this, GlobalContext* globalCtx);
void EnFish_Respawning_SetupFleePlayer(EnFish* this);
void EnFish_Respawning_FleePlayer(EnFish* this, GlobalContext* globalCtx);
void EnFish_Respawning_SetupApproachPlayer(EnFish* this);
void EnFish_Respawning_ApproachPlayer(EnFish* this, GlobalContext* globalCtx);
void EnFish_Dropped_SetupFall(EnFish* this);
void EnFish_Dropped_Fall(EnFish* this, GlobalContext* globalCtx);
void EnFish_Dropped_SetupFlopOnGround(EnFish* this);
void EnFish_Dropped_FlopOnGround(EnFish* this, GlobalContext* globalCtx);
void EnFish_Dropped_SetupSwimAway(EnFish* this);
void EnFish_Dropped_SwimAway(EnFish* this, GlobalContext* globalCtx);
void EnFish_Unique_SetupSwimIdle(EnFish* this);
void EnFish_Unique_SwimIdle(EnFish* this, GlobalContext* globalCtx);
static ColliderJntSphElementInit D_80A1701C[1] = {
// Used in the cutscene functions
static Actor* D_80A17010 = NULL;
static f32 D_80A17014 = 0.0f;
static f32 D_80A17018 = 0.0f;
static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
{
ELEMTYPE_UNK0,
@ -37,7 +53,7 @@ static ColliderJntSphElementInit D_80A1701C[1] = {
},
};
static ColliderJntSphInit D_80A17040 = {
static ColliderJntSphInit sJntSphInit = {
{
COLTYPE_NONE,
AT_NONE,
@ -47,73 +63,707 @@ static ColliderJntSphInit D_80A17040 = {
COLSHAPE_JNTSPH,
},
1,
D_80A1701C,
sJntSphElementsInit,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A15280.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A152AC.s")
const ActorInit En_Fish_InitVars = {
ACTOR_EN_FISH,
ACTORCAT_ITEMACTION,
FLAGS,
OBJECT_GAMEPLAY_KEEP,
sizeof(EnFish),
(ActorFunc)EnFish_Init,
(ActorFunc)EnFish_Destroy,
(ActorFunc)EnFish_Update,
(ActorFunc)EnFish_Draw,
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A15310.s")
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 900, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 40, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 700, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A15374.s")
f32 EnFish_XZDistanceSquared(Vec3f* v1, Vec3f* v2) {
return SQ(v1->x - v2->x) + SQ(v1->z - v2->z);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A153AC.s")
void EnFish_SetInWaterAnimation(EnFish* this) {
Animation_Change(&this->skelAnime, &gFishInWaterAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gFishInWaterAnim),
ANIMMODE_LOOP_INTERP, 2.0f);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A15444.s")
void EnFish_SetOutOfWaterAnimation(EnFish* this) {
Animation_Change(&this->skelAnime, &gFishOutOfWaterAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gFishOutOfWaterAnim),
ANIMMODE_LOOP_INTERP, 2.0f);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/EnFish_Init.s")
void EnFish_BeginRespawn(EnFish* this) {
this->respawnTimer = 400;
Actor_SetScale(&this->actor, 0.001f);
this->actor.draw = NULL;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/EnFish_Destroy.s")
void EnFish_SetCutsceneData(EnFish* this) {
Actor* thisx = &this->actor;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A155D0.s")
if (D_80A17010 == NULL) {
D_80A17010 = thisx;
Actor_SetScale(thisx, 0.01f);
thisx->draw = EnFish_Draw;
thisx->shape.rot.x = 0;
thisx->shape.rot.y = -0x6410;
thisx->shape.rot.z = 0x4000;
thisx->shape.yOffset = 600.0f;
D_80A17014 = 10.0f;
D_80A17018 = 0.0f;
thisx->flags |= 0x10;
EnFish_SetOutOfWaterAnimation(this);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A15688.s")
void EnFish_ClearCutsceneData(EnFish* this) {
D_80A17010 = NULL;
D_80A17014 = 0.0f;
D_80A17018 = 0.0f;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A15774.s")
void EnFish_Init(Actor* thisx, GlobalContext* globalCtx) {
EnFish* this = THIS;
s16 params = this->actor.params;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A157A4.s")
Actor_ProcessInitChain(&this->actor, sInitChain);
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gFishSkel, &gFishInWaterAnim, this->jointTable, this->morphTable,
7);
Collider_InitJntSph(globalCtx, &this->collider);
Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderItems);
this->actor.colChkInfo.mass = 50;
this->slowPhase = Rand_ZeroOne() * (0xFFFF + 0.5f);
this->fastPhase = Rand_ZeroOne() * (0xFFFF + 0.5f);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A157FC.s")
if (params == FISH_DROPPED) {
this->actor.flags |= 0x10;
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 8.0f);
EnFish_Dropped_SetupFall(this);
} else if (params == FISH_SWIMMING_UNIQUE) {
EnFish_Unique_SetupSwimIdle(this);
} else {
EnFish_Respawning_SetupSlowDown(this);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A158EC.s")
void EnFish_Destroy(Actor* thisx, GlobalContext* globalCtx2) {
GlobalContext* globalCtx = globalCtx2;
EnFish* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A15944.s")
Collider_DestroyJntSph(globalCtx, &this->collider);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A15AD4.s")
void EnFish_SetYOffset(EnFish* this) {
this->actor.shape.yOffset += (Math_SinS(this->slowPhase) * 10.0f + Math_SinS(this->fastPhase) * 5.0f);
this->actor.shape.yOffset = CLAMP(this->actor.shape.yOffset, -200.0f, 200.0f);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A15B2C.s")
s32 EnFish_InBottleRange(EnFish* this, GlobalContext* globalCtx) {
s32 pad;
Player* player = PLAYER;
Vec3f sp1C;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A15D18.s")
if (this->actor.xzDistToPlayer < 32.0f) {
sp1C.x = (Math_SinS(this->actor.yawTowardsPlayer + 0x8000) * 16.0f) + player->actor.world.pos.x;
sp1C.y = player->actor.world.pos.y;
sp1C.z = (Math_CosS(this->actor.yawTowardsPlayer + 0x8000) * 16.0f) + player->actor.world.pos.z;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A15D68.s")
//! @bug: this check is superfluous: it is automatically satisfied if the coarse check is satisfied. It may have
//! been intended to check the actor is in front of Player, but yawTowardsPlayer does not depend on Player's
//! world rotation.
if (EnFish_XZDistanceSquared(&sp1C, &this->actor.world.pos) <= SQ(20.0f)) {
return true;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A15F24.s")
return false;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A15F84.s")
s32 EnFish_CheckXZDistanceToPlayer(EnFish* this, GlobalContext* globalCtx) {
return (this->actor.xzDistToPlayer < 60.0f);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A160BC.s")
// Respawning type functions
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A16200.s")
void EnFish_Respawning_SetupSlowDown(EnFish* this) {
this->actor.gravity = 0.0f;
this->actor.minVelocityY = 0.0f;
this->timer = Rand_S16Offset(5, 35);
this->unk_250 = 0;
EnFish_SetInWaterAnimation(this);
this->actionFunc = EnFish_Respawning_SlowDown;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A163DC.s")
void EnFish_Respawning_SlowDown(EnFish* this, GlobalContext* globalCtx) {
EnFish_SetYOffset(this);
Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.05f, 0.3f, 0.0f);
this->skelAnime.playSpeed = CLAMP_MAX(this->actor.speedXZ * 1.4f + 0.8f, 2.0f);
SkelAnime_Update(&this->skelAnime);
this->actor.shape.rot.y = this->actor.world.rot.y;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A16450.s")
if (this->timer <= 0) {
EnFish_Respawning_SetupFollowChild(this);
} else if (&this->actor == this->actor.child) {
EnFish_Respawning_SetupApproachPlayer(this);
} else if (EnFish_CheckXZDistanceToPlayer(this, globalCtx)) {
EnFish_Respawning_SetupFleePlayer(this);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A16618.s")
// The three following actionfunctions also turn the yaw to home if the fish is too far from it.
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A16670.s")
void EnFish_Respawning_SetupFollowChild(EnFish* this) {
this->actor.gravity = 0.0f;
this->actor.minVelocityY = 0.0f;
this->timer = Rand_S16Offset(15, 45);
this->unk_250 = 0;
EnFish_SetInWaterAnimation(this);
this->actionFunc = EnFish_Respawning_FollowChild;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A16898.s")
void EnFish_Respawning_FollowChild(EnFish* this, GlobalContext* globalCtx) {
s32 pad;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A169C8.s")
EnFish_SetYOffset(this);
Math_SmoothStepToF(&this->actor.speedXZ, 1.8f, 0.08f, 0.4f, 0.0f);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A16A64.s")
if ((EnFish_XZDistanceSquared(&this->actor.world.pos, &this->actor.home.pos) > SQ(80.0f)) || (this->timer < 4)) {
Math_StepToAngleS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos),
3000);
} else if ((this->actor.child != NULL) && (&this->actor != this->actor.child)) {
Math_StepToAngleS(&this->actor.world.rot.y,
Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.child->world.pos), 3000);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A16C68.s")
this->actor.shape.rot.y = this->actor.world.rot.y;
this->skelAnime.playSpeed = CLAMP_MAX(this->actor.speedXZ * 1.5f + 0.8f, 4.0f);
SkelAnime_Update(&this->skelAnime);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/func_80A16DEC.s")
if (this->timer <= 0) {
EnFish_Respawning_SetupSlowDown(this);
} else if (&this->actor == this->actor.child) {
EnFish_Respawning_SetupApproachPlayer(this);
} else if (EnFish_CheckXZDistanceToPlayer(this, globalCtx)) {
EnFish_Respawning_SetupFleePlayer(this);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/EnFish_Update.s")
void EnFish_Respawning_SetupFleePlayer(EnFish* this) {
this->actor.gravity = 0.0f;
this->actor.minVelocityY = 0.0f;
this->timer = Rand_S16Offset(10, 40);
this->unk_250 = 0;
EnFish_SetInWaterAnimation(this);
this->actionFunc = EnFish_Respawning_FleePlayer;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Fish/EnFish_Draw.s")
void EnFish_Respawning_FleePlayer(EnFish* this, GlobalContext* globalCtx) {
s32 pad;
s16 pad2;
s16 frames;
s16 yaw;
s16 playerClose;
EnFish_SetYOffset(this);
playerClose = EnFish_CheckXZDistanceToPlayer(this, globalCtx);
Math_SmoothStepToF(&this->actor.speedXZ, 4.2f, 0.08f, 1.4f, 0.0f);
if (EnFish_XZDistanceSquared(&this->actor.world.pos, &this->actor.home.pos) > SQ(160.0f)) {
yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos);
Math_StepToAngleS(&this->actor.world.rot.y, yaw, 3000);
} else if ((this->actor.child != NULL) && (&this->actor != this->actor.child)) {
yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.child->world.pos);
Math_StepToAngleS(&this->actor.world.rot.y, yaw, 2000);
} else if (playerClose) {
yaw = this->actor.yawTowardsPlayer + 0x8000;
frames = globalCtx->state.frames;
if (frames & 0x10) {
if (frames & 0x20) {
yaw += 0x2000;
}
} else {
if (frames & 0x20) {
yaw -= 0x2000;
}
}
if (globalCtx) {}
Math_StepToAngleS(&this->actor.world.rot.y, yaw, 2000);
}
this->actor.shape.rot.y = this->actor.world.rot.y;
this->skelAnime.playSpeed = CLAMP_MAX(this->actor.speedXZ * 1.5f + 0.8f, 4.0f);
SkelAnime_Update(&this->skelAnime);
if ((this->timer <= 0) || !playerClose) {
EnFish_Respawning_SetupSlowDown(this);
} else if (&this->actor == this->actor.child) {
EnFish_Respawning_SetupApproachPlayer(this);
}
}
void EnFish_Respawning_SetupApproachPlayer(EnFish* this) {
this->actor.gravity = 0.0f;
this->actor.minVelocityY = 0.0f;
EnFish_SetInWaterAnimation(this);
this->timer = Rand_S16Offset(10, 40);
this->unk_250 = 0;
this->actionFunc = EnFish_Respawning_ApproachPlayer;
}
void EnFish_Respawning_ApproachPlayer(EnFish* this, GlobalContext* globalCtx) {
s32 pad;
Player* player = PLAYER;
s32 pad2;
Vec3f sp38;
s16 yaw;
s16 temp_a0_2;
EnFish_SetYOffset(this);
Math_SmoothStepToF(&this->actor.speedXZ, 1.8f, 0.1f, 0.5f, 0.0f);
if (EnFish_XZDistanceSquared(&this->actor.world.pos, &this->actor.home.pos) > SQ(80.0f)) {
yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos);
Math_StepToAngleS(&this->actor.world.rot.y, yaw, 3000);
} else {
if ((s16)globalCtx->state.frames & 0x40) {
temp_a0_2 = (this->actor.yawTowardsPlayer + 0x9000);
} else {
temp_a0_2 = (this->actor.yawTowardsPlayer + 0x7000);
}
sp38.x = player->actor.world.pos.x + (Math_SinS(temp_a0_2) * 20.0f);
sp38.y = player->actor.world.pos.y;
sp38.z = player->actor.world.pos.z + (Math_CosS(temp_a0_2) * 20.0f);
yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &sp38);
Math_StepToAngleS(&this->actor.world.rot.y, yaw, 3000);
}
this->actor.shape.rot.y = this->actor.world.rot.y;
this->skelAnime.playSpeed = CLAMP_MAX((this->actor.speedXZ * 1.5f) + 0.8f, 4.0f);
SkelAnime_Update(&this->skelAnime);
if (this->timer <= 0) {
EnFish_Respawning_SetupSlowDown(this);
}
}
// Dropped type functions
void EnFish_Dropped_SetupFall(EnFish* this) {
this->actor.gravity = -1.0f;
this->actor.minVelocityY = -10.0f;
this->actor.shape.yOffset = 0.0f;
EnFish_SetOutOfWaterAnimation(this);
this->unk_250 = 5;
this->actionFunc = EnFish_Dropped_Fall;
this->timer = 300;
}
void EnFish_Dropped_Fall(EnFish* this, GlobalContext* globalCtx) {
Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.1f, 0.1f, 0.0f);
Math_StepToAngleS(&this->actor.world.rot.x, 0x4000, 100);
Math_StepToAngleS(&this->actor.world.rot.z, -0x4000, 100);
this->actor.shape.rot.x = this->actor.world.rot.x;
this->actor.shape.rot.y = this->actor.world.rot.y;
this->actor.shape.rot.z = this->actor.world.rot.z;
SkelAnime_Update(&this->skelAnime);
if (this->actor.bgCheckFlags & 1) { // On floor
this->timer = 400;
EnFish_Dropped_SetupFlopOnGround(this);
} else if (this->actor.bgCheckFlags & 0x20) { // In water
EnFish_Dropped_SetupSwimAway(this);
} else if ((this->timer <= 0) && (this->actor.params == FISH_DROPPED) &&
(this->actor.floorHeight < BGCHECK_Y_MIN + 10.0f)) {
osSyncPrintf(VT_COL(YELLOW, BLACK));
// BG missing? Running Actor_delete
osSyncPrintf("BG 抜け? Actor_delete します(%s %d)\n", "../z_en_sakana.c", 822);
osSyncPrintf(VT_RST);
Actor_Kill(&this->actor);
}
}
/**
* If the fish is on a floor, this function is looped back to by EnFish_Dropped_FlopOnGround to set a new flopping
* height and whether the sound should play again.
*/
void EnFish_Dropped_SetupFlopOnGround(EnFish* this) {
s32 pad;
f32 randomFloat;
s32 playSound;
this->actor.gravity = -1.0f;
this->actor.minVelocityY = -10.0f;
randomFloat = Rand_ZeroOne();
if (randomFloat < 0.1f) {
this->actor.velocity.y = (Rand_ZeroOne() * 3.0f) + 2.5f;
playSound = true;
} else if (randomFloat < 0.2f) {
this->actor.velocity.y = (Rand_ZeroOne() * 1.2f) + 0.2f;
playSound = true;
} else {
this->actor.velocity.y = 0.0f;
if (Rand_ZeroOne() < 0.2f) {
playSound = true;
} else {
playSound = false;
}
}
this->actor.shape.yOffset = 300.0f;
EnFish_SetOutOfWaterAnimation(this);
this->actionFunc = EnFish_Dropped_FlopOnGround;
this->unk_250 = 5;
if (playSound && (this->actor.draw != NULL)) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_FISH_LEAP);
}
}
void EnFish_Dropped_FlopOnGround(EnFish* this, GlobalContext* globalCtx) {
s32 pad;
s16 frames = globalCtx->state.frames;
s16 targetXRot;
Math_SmoothStepToF(&this->actor.speedXZ, Rand_ZeroOne() * 0.2f, 0.1f, 0.1f, 0.0f);
targetXRot = (s16)((((frames >> 5) & 2) | ((frames >> 2) & 1)) << 0xB) * 0.3f;
if (frames & 4) {
targetXRot = -targetXRot;
}
Math_StepToAngleS(&this->actor.world.rot.x, targetXRot, 4000);
Math_StepToAngleS(&this->actor.world.rot.z, 0x4000, 1000);
this->actor.world.rot.y +=
(s16)(((Math_SinS(this->slowPhase) * 2000.0f) + (Math_SinS(this->fastPhase) * 1000.0f)) * Rand_ZeroOne());
this->actor.shape.rot = this->actor.world.rot;
SkelAnime_Update(&this->skelAnime);
if (this->timer <= 0) {
Actor_Kill(&this->actor);
return;
}
if (this->timer <= 60) {
// Blink when about to disappear
if (frames & 4) {
this->actor.draw = EnFish_Draw;
} else {
this->actor.draw = NULL;
}
} else if (this->actor.bgCheckFlags & 0x20) { // In water
EnFish_Dropped_SetupSwimAway(this);
} else if (this->actor.bgCheckFlags & 1) { // On floor
EnFish_Dropped_SetupFlopOnGround(this);
}
}
void EnFish_Dropped_SetupSwimAway(EnFish* this) {
this->actor.home.pos = this->actor.world.pos;
this->actor.flags |= 0x10;
this->timer = 200;
this->actor.gravity = 0.0f;
this->actor.minVelocityY = 0.0f;
this->actor.shape.yOffset = 0.0f;
EnFish_SetInWaterAnimation(this);
this->actionFunc = EnFish_Dropped_SwimAway;
this->unk_250 = 5;
}
void EnFish_Dropped_SwimAway(EnFish* this, GlobalContext* globalCtx) {
s32 pad;
Math_SmoothStepToF(&this->actor.speedXZ, 2.8f, 0.1f, 0.4f, 0.0f);
// If touching wall or not in water, turn back and slow down for one frame.
if ((this->actor.bgCheckFlags & 8) || !(this->actor.bgCheckFlags & 0x20)) {
this->actor.home.rot.y = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos);
this->actor.speedXZ *= 0.5f;
}
Math_StepToAngleS(&this->actor.world.rot.x, 0, 1500);
Math_StepToAngleS(&this->actor.world.rot.y, this->actor.home.rot.y, 3000);
Math_StepToAngleS(&this->actor.world.rot.z, 0, 1000);
this->actor.shape.rot = this->actor.world.rot;
// Raise if on a floor.
if (this->actor.bgCheckFlags & 1) {
Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y - 4.0f, 2.0f);
} else {
Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y - 10.0f, 2.0f);
}
// Shrink when close to disappearing.
if (this->timer < 100) {
Actor_SetScale(&this->actor, this->actor.scale.x * 0.982f);
}
this->skelAnime.playSpeed = CLAMP_MAX((this->actor.speedXZ * 1.5f) + 1.0f, 4.0f);
SkelAnime_Update(&this->skelAnime);
if (this->timer <= 0) {
Actor_Kill(&this->actor);
}
}
// Unique type functions
void EnFish_Unique_SetupSwimIdle(EnFish* this) {
this->actor.gravity = 0.0f;
this->actor.minVelocityY = 0.0f;
this->timer = Rand_S16Offset(5, 35);
this->unk_250 = 0;
EnFish_SetInWaterAnimation(this);
this->actionFunc = EnFish_Unique_SwimIdle;
}
void EnFish_Unique_SwimIdle(EnFish* this, GlobalContext* globalCtx) {
static f32 speedStopping[] = { 0.0f, 0.04f, 0.09f };
static f32 speedMoving[] = { 0.5f, 0.1f, 0.15f };
f32 playSpeed;
u32 frames = globalCtx->gameplayFrames;
f32* speed;
s32 pad2;
f32 extraPlaySpeed;
s32 pad3;
if (this->actor.xzDistToPlayer < 60.0f) {
if (this->timer < 12) {
speed = speedMoving;
} else {
speed = speedStopping;
}
} else {
if (this->timer < 4) {
speed = speedMoving;
} else {
speed = speedStopping;
}
}
EnFish_SetYOffset(this);
Math_SmoothStepToF(&this->actor.speedXZ, speed[0], speed[1], speed[2], 0.0f);
extraPlaySpeed = 0.0f;
if ((EnFish_XZDistanceSquared(&this->actor.world.pos, &this->actor.home.pos) > SQ(15.0f))) {
if (!Math_ScaledStepToS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos),
200)) {
extraPlaySpeed = 0.5f;
}
} else if ((this->timer < 4) && !Math_ScaledStepToS(&this->actor.world.rot.y, frames * 0x80, 100)) {
extraPlaySpeed = 0.5f;
}
this->actor.shape.rot.y = this->actor.world.rot.y;
playSpeed = (this->actor.speedXZ * 1.2f) + 0.2f + extraPlaySpeed;
this->skelAnime.playSpeed = CLAMP(playSpeed, 1.5f, 0.5);
SkelAnime_Update(&this->skelAnime);
if (this->timer <= 0) {
this->timer = Rand_S16Offset(5, 80);
}
}
// Cutscene functions
void EnFish_Cutscene_FlopOnGround(EnFish* this, GlobalContext* globalCtx) {
f32 sp24 = Math_SinS(this->slowPhase);
f32 sp20 = Math_SinS(this->fastPhase);
D_80A17014 += D_80A17018;
if (D_80A17014 <= 1.0f) {
D_80A17014 = 1.0f;
if (Rand_ZeroOne() < 0.1f) {
D_80A17018 = (Rand_ZeroOne() * 3.0f) + 2.0f;
Audio_PlayActorSound2(&this->actor, NA_SE_EV_FISH_LEAP);
} else {
D_80A17018 = 0.0f;
}
} else {
D_80A17018 -= 0.4f;
}
this->skelAnime.playSpeed = ((sp24 + sp20) * 0.5f) + 2.0f;
SkelAnime_Update(&this->skelAnime);
}
void EnFish_Cutscene_WiggleFlyingThroughAir(EnFish* this, GlobalContext* globalCtx) {
s32 pad;
f32 sp28 = Math_SinS(this->slowPhase);
f32 sp24 = Math_SinS(this->fastPhase);
this->actor.shape.rot.x -= 500;
this->actor.shape.rot.z += 100;
Math_StepToF(&D_80A17014, 0.0f, 1.0f);
this->skelAnime.playSpeed = ((sp28 + sp24) * 0.5f) + 2.0f;
SkelAnime_Update(&this->skelAnime);
}
void EnFish_UpdateCutscene(EnFish* this, GlobalContext* globalCtx) {
s32 pad;
s32 pad2;
CsCmdActorAction* csAction = globalCtx->csCtx.npcActions[1];
Vec3f startPos;
Vec3f endPos;
f32 progress;
s32 bgId;
if (csAction == NULL) {
// Warning : DEMO ended without dousa (action) 3 termination being called
osSyncPrintf("Warning : dousa 3 消滅 が呼ばれずにデモが終了した(%s %d)(arg_data 0x%04x)\n", "../z_en_sakana.c",
1169, this->actor.params);
EnFish_ClearCutsceneData(this);
Actor_Kill(&this->actor);
return;
}
this->slowPhase += 0x111;
this->fastPhase += 0x500;
switch (csAction->action) {
case 1:
EnFish_Cutscene_FlopOnGround(this, globalCtx);
break;
case 2:
EnFish_Cutscene_WiggleFlyingThroughAir(this, globalCtx);
break;
case 3:
// DEMO fish termination
osSyncPrintf("デモ魚消滅\n");
EnFish_ClearCutsceneData(this);
Actor_Kill(&this->actor);
return;
default:
// Improper DEMO action
osSyncPrintf("不正なデモ動作(%s %d)(arg_data 0x%04x)\n", "../z_en_sakana.c", 1200, this->actor.params);
break;
}
startPos.x = csAction->startPos.x;
startPos.y = csAction->startPos.y;
startPos.z = csAction->startPos.z;
endPos.x = csAction->endPos.x;
endPos.y = csAction->endPos.y;
endPos.z = csAction->endPos.z;
progress = func_8006F93C(csAction->endFrame, csAction->startFrame, globalCtx->csCtx.frames);
this->actor.world.pos.x = (endPos.x - startPos.x) * progress + startPos.x;
this->actor.world.pos.y = (endPos.y - startPos.y) * progress + startPos.y + D_80A17014;
this->actor.world.pos.z = (endPos.z - startPos.z) * progress + startPos.z;
this->actor.floorHeight = BgCheck_EntityRaycastFloor4(&globalCtx->colCtx, &this->actor.floorPoly, &bgId,
&this->actor, &this->actor.world.pos);
}
// Update functions and Draw
void EnFish_OrdinaryUpdate(EnFish* this, GlobalContext* globalCtx) {
if (this->timer > 0) {
this->timer--;
}
this->slowPhase += 0x111;
this->fastPhase += 0x500;
if ((this->actor.child != NULL) && (this->actor.child->update == NULL) && (&this->actor != this->actor.child)) {
this->actor.child = NULL;
}
if ((this->actionFunc == NULL) || (this->actionFunc(this, globalCtx), (this->actor.update != NULL))) {
Actor_MoveForward(&this->actor);
if (this->unk_250 != 0) {
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 17.5f, 4.0f, 0.0f, this->unk_250);
}
if (this->actor.xzDistToPlayer < 70.0f) {
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
Actor_SetFocus(&this->actor, this->actor.shape.yOffset * 0.01f);
if (Actor_HasParent(&this->actor, globalCtx)) {
this->actor.parent = NULL;
if (this->actor.params == FISH_DROPPED) {
Actor_Kill(&this->actor);
return;
}
EnFish_BeginRespawn(this);
} else if (EnFish_InBottleRange(this, globalCtx)) {
// GI_MAX in this case allows the player to catch the actor in a bottle
func_8002F434(&this->actor, globalCtx, GI_MAX, 80.0f, 20.0f);
}
}
}
void EnFish_RespawningUpdate(EnFish* this, GlobalContext* globalCtx) {
if (this->actor.params == FISH_SWIMMING_UNIQUE) {
Actor_Kill(&this->actor);
return;
}
if ((this->actor.child != NULL) && (this->actor.child->update == NULL) && (&this->actor != this->actor.child)) {
this->actor.child = NULL;
}
if ((this->actionFunc == NULL) || (this->actionFunc(this, globalCtx), (this->actor.update != NULL))) {
Actor_MoveForward(&this->actor);
if (this->respawnTimer == 20) {
this->actor.draw = EnFish_Draw;
} else if (this->respawnTimer == 0) {
Actor_SetScale(&this->actor, 0.01f);
} else if (this->respawnTimer < 20) {
Actor_SetScale(&this->actor, CLAMP_MAX(this->actor.scale.x + 0.001f, 0.01f));
}
}
}
void EnFish_Update(Actor* thisx, GlobalContext* globalCtx) {
EnFish* this = THIS;
if ((D_80A17010 == NULL) && (this->actor.params == FISH_DROPPED) && (globalCtx->csCtx.state != 0) &&
(globalCtx->csCtx.npcActions[1] != NULL)) {
EnFish_SetCutsceneData(this);
}
if ((D_80A17010 != NULL) && (&this->actor == D_80A17010)) {
EnFish_UpdateCutscene(this, globalCtx);
} else if (this->respawnTimer > 0) {
this->respawnTimer--;
EnFish_RespawningUpdate(this, globalCtx);
} else {
EnFish_OrdinaryUpdate(this, globalCtx);
}
}
void EnFish_Draw(Actor* thisx, GlobalContext* globalCtx) {
EnFish* this = THIS;
func_80093D18(globalCtx->state.gfxCtx);
SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
NULL, NULL, NULL);
Collider_UpdateSpheres(0, &this->collider);
}

View file

@ -6,11 +6,29 @@
struct EnFish;
typedef void (*EnFishActionFunc)(struct EnFish*, GlobalContext*);
typedef struct EnFish {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x108];
/* 0x014C */ ColliderJntSph collider;
/* 0x016C */ ColliderJntSphElement colliderItems[1];
/* 0x01AC */ SkelAnime skelAnime;
/* 0x01F0 */ Vec3s jointTable[7];
/* 0x021A */ Vec3s morphTable[7];
/* 0x0244 */ EnFishActionFunc actionFunc;
/* 0x0248 */ s16 timer;
/* 0x024A */ s16 respawnTimer;
/* 0x024C */ s16 slowPhase;
/* 0x024E */ s16 fastPhase;
/* 0x0250 */ s32 unk_250; // Set to 0 or 5, arg5 of Actor_UpdateBgCheckInfo
} EnFish; // size = 0x0254
typedef enum {
/* -1 */ FISH_SWIMMING_RESPAWNING = -1, // Used in Zora's Domain; code only uses not 0 or 1, runs away from Player
/* 0 */ FISH_DROPPED,
/* 1 */ FISH_SWIMMING_UNIQUE // Used in grottos
} EnFishType;
extern const ActorInit En_Fish_InitVars;
#endif

View file

@ -955,7 +955,7 @@ void func_80A40B1C(EnGo* this, GlobalContext* globalCtx) {
void EnGo_GetItem(EnGo* this, GlobalContext* globalCtx) {
f32 xzDist;
f32 yDist;
s32 getItem;
s32 getItemId;
if (Actor_HasParent(&this->actor, globalCtx)) {
this->unk_1E0.unk_00 = 2;
@ -965,24 +965,24 @@ void EnGo_GetItem(EnGo* this, GlobalContext* globalCtx) {
this->unk_20C = 0;
if ((this->actor.params & 0xF0) == 0x90) {
if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_CLAIM_CHECK) {
getItem = GI_SWORD_BGS;
getItemId = GI_SWORD_BGS;
this->unk_20C = 1;
}
if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_EYEDROPS) {
getItem = GI_CLAIM_CHECK;
getItemId = GI_CLAIM_CHECK;
}
if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_SWORD_BROKEN) {
getItem = GI_PRESCRIPTION;
getItemId = GI_PRESCRIPTION;
}
}
if ((this->actor.params & 0xF0) == 0) {
getItem = GI_TUNIC_GORON;
getItemId = GI_TUNIC_GORON;
}
yDist = fabsf(this->actor.yDistToPlayer) + 1.0f;
xzDist = this->actor.xzDistToPlayer + 1.0f;
func_8002F434(&this->actor, globalCtx, getItem, xzDist, yDist);
func_8002F434(&this->actor, globalCtx, getItemId, xzDist, yDist);
}
}

View file

@ -3209,7 +3209,7 @@ void EnHorse_UpdateBgCheckInfo(EnHorse* this, GlobalContext* globalCtx) {
obstaclePos.z += intersectDist * Math_CosS(this->actor.world.rot.y);
obstacleTop = obstaclePos;
obstacleTop.y = BgCheck_EntityRaycastFloor3(&globalCtx->colCtx, &obstacleFloor, &bgId, &obstaclePos);
if (obstacleTop.y == -32000.0f) {
if (obstacleTop.y == BGCHECK_Y_MIN) {
return;
}
obstacleHeight = obstacleTop.y - this->actor.world.pos.y;
@ -3258,7 +3258,7 @@ void EnHorse_UpdateBgCheckInfo(EnHorse* this, GlobalContext* globalCtx) {
obstacleTop = obstaclePos;
obstacleTop.y = BgCheck_EntityRaycastFloor3(&globalCtx->colCtx, &obstacleFloor, &bgId, &obstaclePos);
if (obstacleTop.y == -32000.0f) {
if (obstacleTop.y == BGCHECK_Y_MIN) {
return;
}

View file

@ -1,3 +1,9 @@
/*
* File: z_en_ice_hono.c
* Overlay: ovl_En_Ice_Hono
* Description: The various types of Blue Fire
*/
#include "z_en_ice_hono.h"
#include "objects/gameplay_keep/gameplay_keep.h"
@ -92,11 +98,8 @@ static InitChainEntry sInitChainSmallFlame[] = {
ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_STOP),
};
f32 EnIceHono_SquareDist(Vec3f* pos1, Vec3f* pos2) {
f32 dx = pos1->x - pos2->x;
f32 dz = pos1->z - pos2->z;
return SQ(dx) + SQ(dz);
f32 EnIceHono_XZDistanceSquared(Vec3f* v1, Vec3f* v2) {
return SQ(v1->x - v2->x) + SQ(v1->z - v2->z);
}
void EnIceHono_InitCapturableFlame(Actor* thisx, GlobalContext* globalCtx) {
@ -185,7 +188,7 @@ void EnIceHono_Destroy(Actor* thisx, GlobalContext* globalCtx) {
}
}
u32 EnIceHono_LinkCloseAndFacing(EnIceHono* this, GlobalContext* globalCtx) {
u32 EnIceHono_InBottleRange(EnIceHono* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
if (this->actor.xzDistToPlayer < 60.0f) {
@ -193,11 +196,15 @@ u32 EnIceHono_LinkCloseAndFacing(EnIceHono* this, GlobalContext* globalCtx) {
tempPos.x = Math_SinS(this->actor.yawTowardsPlayer + 0x8000) * 40.0f + player->actor.world.pos.x;
tempPos.y = player->actor.world.pos.y;
tempPos.z = Math_CosS(this->actor.yawTowardsPlayer + 0x8000) * 40.0f + player->actor.world.pos.z;
if (EnIceHono_SquareDist(&tempPos, &this->actor.world.pos) <= SQ(40.0f)) {
return 1;
//! @bug: this check is superfluous: it is automatically satisfied if the coarse check is satisfied. It may have
//! been intended to check the actor is in front of Player, but yawTowardsPlayer does not depend on Player's
//! world rotation.
if (EnIceHono_XZDistanceSquared(&tempPos, &this->actor.world.pos) <= SQ(40.0f)) {
return true;
}
}
return 0;
return false;
}
void EnIceHono_SetupActionCapturableFlame(EnIceHono* this) {
@ -209,8 +216,9 @@ void EnIceHono_SetupActionCapturableFlame(EnIceHono* this) {
void EnIceHono_CapturableFlame(EnIceHono* this, GlobalContext* globalCtx) {
if (Actor_HasParent(&this->actor, globalCtx)) {
this->actor.parent = NULL;
} else if (EnIceHono_LinkCloseAndFacing(this, globalCtx)) {
func_8002F434(&this->actor, globalCtx, 0x7E, 60.0f, 100.0f);
} else if (EnIceHono_InBottleRange(this, globalCtx)) {
// GI_MAX in this case allows the player to catch the actor in a bottle
func_8002F434(&this->actor, globalCtx, GI_MAX, 60.0f, 100.0f);
}
if (this->actor.xzDistToPlayer < 200.0f) {

View file

@ -1,3 +1,9 @@
/*
* File: z_en_insect.c
* Overlay: ovl_En_Insect
* Description: Bugs
*/
#include "z_en_insect.h"
#include "vt.h"
#include "objects/gameplay_keep/gameplay_keep.h"
@ -87,7 +93,7 @@ f32 EnInsect_XZDistanceSquared(Vec3f* v1, Vec3f* v2) {
return SQ(v1->x - v2->x) + SQ(v1->z - v2->z);
}
s32 func_80A7BE6C(EnInsect* this, GlobalContext* globalCtx) {
s32 EnInsect_InBottleRange(EnInsect* this, GlobalContext* globalCtx) {
s32 pad;
Player* player = PLAYER;
Vec3f pos;
@ -97,12 +103,15 @@ s32 func_80A7BE6C(EnInsect* this, GlobalContext* globalCtx) {
pos.y = player->actor.world.pos.y;
pos.z = Math_CosS(this->actor.yawTowardsPlayer + 0x8000) * 16.0f + player->actor.world.pos.z;
if (EnInsect_XZDistanceSquared(&pos, &this->actor.world.pos) <= 400.0f) {
return 1;
//! @bug: this check is superfluous: it is automatically satisfied if the coarse check is satisfied. It may have
//! been intended to check the actor is in front of Player, but yawTowardsPlayer does not depend on Player's
//! world rotation.
if (EnInsect_XZDistanceSquared(&pos, &this->actor.world.pos) <= SQ(20.0f)) {
return true;
}
}
return 0;
return false;
}
void func_80A7BF58(EnInsect* this) {
@ -143,7 +152,7 @@ s32 EnInsect_FoundNearbySoil(EnInsect* this, GlobalContext* globalCtx) {
void func_80A7C058(EnInsect* this) {
if (this->unk_31E > 0) {
this->unk_31E -= 1;
this->unk_31E--;
return;
}
@ -546,9 +555,9 @@ void func_80A7D39C(EnInsect* this) {
func_80A7BF58(this);
this->unk_31A = 100;
this->unk_324 = 1.5f;
this->unk_328 = Rand_ZeroOne() * 65535.5f;
this->unk_328 = Rand_ZeroOne() * (0xFFFF + 0.5f);
this->unk_316 = (Rand_ZeroOne() - 0.5f) * 1500.0f;
this->actor.world.rot.y = Rand_ZeroOne() * 65535.5f;
this->actor.world.rot.y = Rand_ZeroOne() * (0xFFFF + 0.5f);
Actor_SetScale(&this->actor, 0.003f);
this->actionFunc = func_80A7D460;
this->unk_314 |= 0x100;
@ -703,7 +712,7 @@ void func_80A7D460(EnInsect* this, GlobalContext* globalCtx) {
} else if (sp50 != 0) {
func_80A7C3A0(this);
} else if ((sp3A == 2 || sp3A == 3) && (this->unk_314 & 1) && this->unk_31C <= 0 && this->unk_31A <= 0 &&
this->actor.floorHeight < -31990.0f) {
this->actor.floorHeight < BGCHECK_Y_MIN + 10.0f) {
osSyncPrintf(VT_COL(YELLOW, BLACK));
// BG missing? To do Actor_delete
osSyncPrintf("BG 抜け? Actor_delete します(%s %d)\n", "../z_en_mushi.c", 1197);
@ -775,8 +784,9 @@ void EnInsect_Update(Actor* thisx, GlobalContext* globalCtx) {
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
if (!(this->unk_314 & 8) && D_80A7DEB4 < 4 && func_80A7BE6C(this, globalCtx) != 0 &&
func_8002F434(&this->actor, globalCtx, GI_MAX, 60.0f, 30.0f) != 0) {
if (!(this->unk_314 & 8) && D_80A7DEB4 < 4 && EnInsect_InBottleRange(this, globalCtx) &&
// GI_MAX in this case allows the player to catch the actor in a bottle
func_8002F434(&this->actor, globalCtx, GI_MAX, 60.0f, 30.0f)) {
D_80A7DEB4++;
}
}

View file

@ -375,10 +375,11 @@ void EnIshi_Wait(EnIshi* this, GlobalContext* globalCtx) {
if (this->actor.xzDistToPlayer < 400.0f) {
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
if (this->actor.xzDistToPlayer < 90.0f) {
// GI_NONE in these cases allows the player to lift the actor
if (type == ROCK_LARGE) {
func_8002F434(&this->actor, globalCtx, 0, 80.0f, 20.0f);
func_8002F434(&this->actor, globalCtx, GI_NONE, 80.0f, 20.0f);
} else {
func_8002F434(&this->actor, globalCtx, 0, 50.0f, 10.0f);
func_8002F434(&this->actor, globalCtx, GI_NONE, 50.0f, 10.0f);
}
}
}

View file

@ -323,7 +323,7 @@ void EnJj_Draw(Actor* thisx, GlobalContext* globalCtx2) {
Matrix_Scale(10.0f, 10.0f, 10.0f, MTXMODE_APPLY);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sEyeTextures[this->eyeIndex]));
SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
0, 0, this);
NULL, NULL, this);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_jj.c", 898);
}

View file

@ -467,7 +467,8 @@ void func_80AB6450(EnNiw* this, GlobalContext* globalCtx) {
this->actor.speedXZ = 0.0f;
this->actionFunc = func_80AB6BF8;
} else {
func_8002F434(&this->actor, globalCtx, 0, 25.0f, 10.0f);
// GI_NONE in this case allows the player to lift the actor
func_8002F434(&this->actor, globalCtx, GI_NONE, 25.0f, 10.0f);
func_80AB5BF8(this, globalCtx, 1);
}
}

View file

@ -260,7 +260,7 @@ void EnNiwGirl_Draw(Actor* thisx, GlobalContext* globalCtx) {
func_80093D18(globalCtx->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_80AB99D8[this->unk_272]));
SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
EnNiwGirlOverrideLimbDraw, 0, this);
EnNiwGirlOverrideLimbDraw, NULL, this);
func_80033C30(&this->actor.world.pos, &sp4C, 255, globalCtx);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_niw_girl.c", 592);

View file

@ -307,14 +307,14 @@ void func_80ABA654(EnNiwLady* this, GlobalContext* globalCtx) {
this->unk_26E = 0xB;
if (!(gSaveContext.itemGetInf[0] & 0x1000)) {
this->actor.parent = NULL;
this->unk_284 = 0xF;
func_8002F434(&this->actor, globalCtx, 0xF, 100.0f, 50.0f);
this->getItemId = GI_BOTTLE;
func_8002F434(&this->actor, globalCtx, GI_BOTTLE, 100.0f, 50.0f);
this->actionFunc = func_80ABAC00;
return;
}
if (this->unk_26C == 1) {
this->unk_284 = 0x55;
func_8002F434(&this->actor, globalCtx, 0x55, 100.0f, 50.0f);
this->getItemId = GI_RUPEE_PURPLE;
func_8002F434(&this->actor, globalCtx, GI_RUPEE_PURPLE, 100.0f, 50.0f);
this->actionFunc = func_80ABAC00;
}
this->actionFunc = func_80ABA244;
@ -417,7 +417,7 @@ void func_80ABAB08(EnNiwLady* this, GlobalContext* globalCtx) {
case 0:
func_80106CCC(globalCtx);
this->actor.parent = NULL;
func_8002F434(&this->actor, globalCtx, 0xE, 200.0f, 100.0f);
func_8002F434(&this->actor, globalCtx, GI_COJIRO, 200.0f, 100.0f);
this->actionFunc = func_80ABAC00;
break;
case 1:
@ -439,7 +439,7 @@ void func_80ABAC00(EnNiwLady* this, GlobalContext* globalCtx) {
if (Actor_HasParent(&this->actor, globalCtx)) {
this->actionFunc = func_80ABAC84;
} else {
getItemId = this->unk_284;
getItemId = this->getItemId;
if (LINK_IS_ADULT) {
getItemId = !(gSaveContext.itemGetInf[2] & 0x1000) ? GI_POCKET_EGG : GI_COJIRO;
}

View file

@ -37,7 +37,7 @@ typedef struct EnNiwLady {
/* 0x027E */ s16 unk_27E;
/* 0x0280 */ s8 objectAneIndex;
/* 0x0281 */ s8 objectOsAnimeIndex;
/* 0x0284 */ s32 unk_284;
/* 0x0284 */ s32 getItemId;
/* 0x0288 */ struct_80034A14_arg1 unk_288;
/* 0x02B0 */ ColliderCylinder collider;
} EnNiwLady; // size = 0x02FC

View file

@ -394,7 +394,7 @@ void EnSyatekiMan_Update(Actor* thisx, GlobalContext* globalCtx) {
func_80038290(globalCtx, &this->actor, &this->headRot, &this->bodyRot, this->actor.focus.pos);
}
s32 func_80B1148C(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) {
s32 EnSyatekiMan_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) {
EnSyatekiMan* this = THIS;
s32 turnDirection;
@ -419,7 +419,7 @@ void EnSyatekiMan_Draw(Actor* thisx, GlobalContext* globalCtx) {
func_80093D18(globalCtx->state.gfxCtx);
SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
func_80B1148C, NULL, this);
EnSyatekiMan_OverrideLimbDraw, NULL, this);
}
void EnSyatekiMan_SetBgm(void) {

View file

@ -321,7 +321,7 @@ void func_80B20768(EnToryo* this, GlobalContext* globalCtx) {
this->actor.parent = NULL;
this->unk_1E4 = 5;
} else {
func_8002F434(&this->actor, globalCtx, 0x22, 100.0f, 10.0f);
func_8002F434(&this->actor, globalCtx, GI_SWORD_BROKEN, 100.0f, 10.0f);
}
return;
}

View file

@ -572,7 +572,7 @@ void func_80B2B4A8(EnViewer* this, GlobalContext* globalCtx) {
if (params == 9) {
SkelAnime_DrawFlexOpa(globalCtx, this->skin.skelAnime.skeleton, this->skin.skelAnime.jointTable,
this->skin.skelAnime.dListCount, 0, func_80B2B364, this);
this->skin.skelAnime.dListCount, NULL, func_80B2B364, this);
} else if (params == 3) {
SkelAnime_DrawFlexOpa(globalCtx, this->skin.skelAnime.skeleton, this->skin.skelAnime.jointTable,
this->skin.skelAnime.dListCount, func_80B2B2F4, func_80B2B468, this);
@ -580,11 +580,11 @@ void func_80B2B4A8(EnViewer* this, GlobalContext* globalCtx) {
} else if ((params == 3) || (params == 5) || (params == 7) || (params == 8)) {
if ((globalCtx->csCtx.state != CS_STATE_IDLE) && (globalCtx->csCtx.npcActions[1] != NULL)) {
SkelAnime_DrawFlexOpa(globalCtx, this->skin.skelAnime.skeleton, this->skin.skelAnime.jointTable,
this->skin.skelAnime.dListCount, 0, func_80B2B468, this);
this->skin.skelAnime.dListCount, NULL, func_80B2B468, this);
func_80B2CC1C(globalCtx, this);
}
} else {
SkelAnime_DrawOpa(globalCtx, this->skin.skelAnime.skeleton, this->skin.skelAnime.jointTable, NULL, 0, this);
SkelAnime_DrawOpa(globalCtx, this->skin.skelAnime.skeleton, this->skin.skelAnime.jointTable, NULL, NULL, this);
}
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_viewer.c", 1511);
}
@ -688,7 +688,7 @@ void func_80B2C130(EnViewer* this, GlobalContext* globalCtx) {
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
gSPSegment(POLY_OPA_DISP++, 0x0C, &D_80116280[2]);
SkelAnime_DrawFlexOpa(globalCtx, this->skin.skelAnime.skeleton, this->skin.skelAnime.jointTable,
this->skin.skelAnime.dListCount, func_80B2C10C, 0, this);
this->skin.skelAnime.dListCount, func_80B2C10C, NULL, this);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_viewer.c", 1740);
}

View file

@ -575,7 +575,7 @@ void EnZl1_Update(Actor* thisx, GlobalContext* globalCtx) {
func_80B4AE18(this);
}
s32 func_80B4C340(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) {
s32 EnZl1_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) {
EnZl1* this = THIS;
if ((limbIndex == 4) || (limbIndex == 3) || (limbIndex == 6) || (limbIndex == 5)) {
@ -596,7 +596,7 @@ s32 func_80B4C340(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p
return 0;
}
void func_80B4C400(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
void EnZl1_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
Vec3f vec = { 0.0f, 0.0f, 0.0f };
EnZl1* this = THIS;
@ -616,7 +616,7 @@ void EnZl1_Draw(Actor* thisx, GlobalContext* globalCtx) {
func_80093D18(globalCtx->state.gfxCtx);
SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
func_80B4C340, func_80B4C400, this);
EnZl1_OverrideLimbDraw, EnZl1_PostLimbDraw, this);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_girlB.c", 2046);
}

View file

@ -390,7 +390,7 @@ s32 ObjOshihiki_CheckFloor(ObjOshihiki* this, GlobalContext* globalCtx) {
}
s32 ObjOshihiki_CheckGround(ObjOshihiki* this, GlobalContext* globalCtx) {
if (this->dyna.actor.world.pos.y <= -31990.0f) {
if (this->dyna.actor.world.pos.y <= BGCHECK_Y_MIN + 10.0f) {
// Warning : Push-pull block fell too much
osSyncPrintf("Warning : 押し引きブロック落ちすぎた(%s %d)(arg_data 0x%04x)\n", "../z_obj_oshihiki.c", 809,
this->dyna.actor.params);

View file

@ -266,7 +266,8 @@ void ObjTsubo_Idle(ObjTsubo* this, GlobalContext* globalCtx) {
temp_v0 = this->actor.yawTowardsPlayer - PLAYER->actor.world.rot.y;
phi_v1 = ABS(temp_v0);
if (phi_v1 >= 0x5556) {
func_8002F434(&this->actor, globalCtx, 0, 30.0f, 30.0f);
// GI_NONE in this case allows the player to lift the actor
func_8002F434(&this->actor, globalCtx, GI_NONE, 30.0f, 30.0f);
}
}
}

View file

@ -14,6 +14,7 @@
#include "overlays/actors/ovl_En_Box/z_en_box.h"
#include "overlays/actors/ovl_En_Door/z_en_door.h"
#include "overlays/actors/ovl_En_Elf/z_en_elf.h"
#include "overlays/actors/ovl_En_Fish/z_en_fish.h"
#include "overlays/actors/ovl_En_Horse/z_en_horse.h"
#include "overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.h"
#include "objects/gameplay_keep/gameplay_keep.h"
@ -12189,7 +12190,7 @@ void func_8084EED8(Player* this, GlobalContext* globalCtx) {
}
BottleDropInfo D_80854A28[] = {
{ ACTOR_EN_FISH, 0 },
{ ACTOR_EN_FISH, FISH_DROPPED },
{ ACTOR_EN_ICE_HONO, 0 },
{ ACTOR_EN_INSECT, 2 },
};