summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
authorfig02 <fig02srl@gmail.com>2021-06-21 19:51:04 -0400
committerGitHub <noreply@github.com>2021-06-22 08:51:04 +0900
commit0a35c752e7ec0a0416df96f47087338d578e2926 (patch)
tree5517e46825ebef8a4407e6b0ecc2f6dd7b349e01 /src/code
parent7984c1c5148ffb611c5e793c43070c86e0110650 (diff)
Some actor.c docs (in preparation for en_test) (#820)
* renames * format * format functions.h * clean * arg name * remove asm
Diffstat (limited to 'src/code')
-rw-r--r--src/code/z_actor.c174
-rw-r--r--src/code/z_play.c7
2 files changed, 114 insertions, 67 deletions
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index 3244c99c3..562538466 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -1063,54 +1063,79 @@ void func_8002DFA4(DynaPolyActor* dynaActor, f32 arg1, s16 arg2) {
dynaActor->unk_158 = arg2;
}
-s32 func_8002DFC8(Actor* actor, s16 arg1, GlobalContext* globalCtx) {
+/**
+ * Chcek if the player is facing the specified actor.
+ * The maximum angle difference that qualifies as "facing" is specified by `maxAngle`.
+ */
+s32 Player_IsFacingActor(Actor* actor, s16 maxAngle, GlobalContext* globalCtx) {
Player* player = PLAYER;
- s16 var = (s16)(actor->yawTowardsPlayer + 0x8000) - player->actor.shape.rot.y;
+ s16 yawDiff = (s16)(actor->yawTowardsPlayer + 0x8000) - player->actor.shape.rot.y;
- if (ABS(var) < arg1) {
+ if (ABS(yawDiff) < maxAngle) {
return true;
}
return false;
}
-s32 func_8002E020(Actor* actorA, Actor* actorB, s16 arg2) {
- s16 var = (s16)(Actor_WorldYawTowardActor(actorA, actorB) + 0x8000) - actorB->shape.rot.y;
+/**
+ * Chcek if `actorB` is facing `actorA`.
+ * The maximum angle difference that qualifies as "facing" is specified by `maxAngle`.
+ *
+ * This function is unused in the original game.
+ */
+s32 Actor_ActorBIsFacingActorA(Actor* actorA, Actor* actorB, s16 maxAngle) {
+ s16 yawDiff = (s16)(Actor_WorldYawTowardActor(actorA, actorB) + 0x8000) - actorB->shape.rot.y;
- if (ABS(var) < arg2) {
+ if (ABS(yawDiff) < maxAngle) {
return true;
}
return false;
}
-s32 func_8002E084(Actor* actor, s16 arg1) {
- s16 var = actor->yawTowardsPlayer - actor->shape.rot.y;
+/**
+ * Chcek if the specified actor is facing the player.
+ * The maximum angle difference that qualifies as "facing" is specified by `maxAngle`.
+ */
+s32 Actor_IsFacingPlayer(Actor* actor, s16 maxAngle) {
+ s16 yawDiff = actor->yawTowardsPlayer - actor->shape.rot.y;
- if (ABS(var) < arg1) {
+ if (ABS(yawDiff) < maxAngle) {
return true;
}
return false;
}
-s32 func_8002E0D0(Actor* actorA, Actor* actorB, s16 arg2) {
- s16 var = Actor_WorldYawTowardActor(actorA, actorB) - actorA->shape.rot.y;
+/**
+ * Chcek if `actorA` is facing `actorB`.
+ * The maximum angle difference that qualifies as "facing" is specified by `maxAngle`.
+ *
+ * This function is unused in the original game.
+ */
+s32 Actor_ActorAIsFacingActorB(Actor* actorA, Actor* actorB, s16 maxAngle) {
+ s16 yawDiff = Actor_WorldYawTowardActor(actorA, actorB) - actorA->shape.rot.y;
- if (ABS(var) < arg2) {
+ if (ABS(yawDiff) < maxAngle) {
return true;
}
return false;
}
-s32 func_8002E12C(Actor* actor, f32 arg1, s16 arg2) {
- s16 var = actor->yawTowardsPlayer - actor->shape.rot.y;
+/**
+ * Chcek if the specified actor is facing the player and is nearby.
+ * The maximum angle difference that qualifies as "facing" is specified by `maxAngle`.
+ * The minimum distance that qualifies as "nearby" is specified by `range`.
+ */
+s32 Actor_IsFacingAndNearPlayer(Actor* actor, f32 range, s16 maxAngle) {
+ s16 yawDiff = actor->yawTowardsPlayer - actor->shape.rot.y;
- if (ABS(var) < arg2) {
+ if (ABS(yawDiff) < maxAngle) {
f32 xyzDistanceFromLink = sqrtf(SQ(actor->xzDistToPlayer) + SQ(actor->yDistToPlayer));
- if (xyzDistanceFromLink < arg1) {
+ if (xyzDistanceFromLink < range) {
return true;
}
}
@@ -1118,11 +1143,16 @@ s32 func_8002E12C(Actor* actor, f32 arg1, s16 arg2) {
return false;
}
-s32 func_8002E1A8(Actor* actorA, Actor* actorB, f32 arg2, s16 arg3) {
- if (Actor_WorldDistXYZToActor(actorA, actorB) < arg2) {
- s16 var = Actor_WorldYawTowardActor(actorA, actorB) - actorA->shape.rot.y;
+/**
+ * Chcek if `actorA` is facing `actorB` and is nearby.
+ * The maximum angle difference that qualifies as "facing" is specified by `maxAngle`.
+ * The minimum distance that qualifies as "nearby" is specified by `range`.
+ */
+s32 Actor_ActorAIsFacingAndNearActorB(Actor* actorA, Actor* actorB, f32 range, s16 maxAngle) {
+ if (Actor_WorldDistXYZToActor(actorA, actorB) < range) {
+ s16 yawDiff = Actor_WorldYawTowardActor(actorA, actorB) - actorA->shape.rot.y;
- if (ABS(var) < arg3) {
+ if (ABS(yawDiff) < maxAngle) {
return true;
}
}
@@ -1204,7 +1234,8 @@ s32 func_8002E2AC(GlobalContext* globalCtx, Actor* actor, Vec3f* arg2, s32 arg3)
return true;
}
-void Actor_UpdateBgCheckInfo(GlobalContext* globalCtx, Actor* actor, f32 arg2, f32 arg3, f32 arg4, s32 arg5) {
+void Actor_UpdateBgCheckInfo(GlobalContext* globalCtx, Actor* actor, f32 wallCheckHeight, f32 wallCheckRadius,
+ f32 ceilingCheckHeight, s32 flags) {
f32 sp74;
s32 pad;
Vec3f sp64;
@@ -1221,11 +1252,13 @@ void Actor_UpdateBgCheckInfo(GlobalContext* globalCtx, Actor* actor, f32 arg2, f
func_800433A4(&globalCtx->colCtx, actor->floorBgId, actor);
}
- if (arg5 & 1) {
- if ((!(arg5 & 0x80) && BgCheck_EntitySphVsWall3(&globalCtx->colCtx, &sp64, &actor->world.pos, &actor->prevPos,
- arg3, &actor->wallPoly, &bgId, actor, arg2)) ||
- ((arg5 & 0x80) && BgCheck_EntitySphVsWall4(&globalCtx->colCtx, &sp64, &actor->world.pos, &actor->prevPos,
- arg3, &actor->wallPoly, &bgId, actor, arg2))) {
+ if (flags & 1) {
+ if ((!(flags & 0x80) &&
+ BgCheck_EntitySphVsWall3(&globalCtx->colCtx, &sp64, &actor->world.pos, &actor->prevPos, wallCheckRadius,
+ &actor->wallPoly, &bgId, actor, wallCheckHeight)) ||
+ ((flags & 0x80) &&
+ BgCheck_EntitySphVsWall4(&globalCtx->colCtx, &sp64, &actor->world.pos, &actor->prevPos, wallCheckRadius,
+ &actor->wallPoly, &bgId, actor, wallCheckHeight))) {
wallPoly = actor->wallPoly;
Math_Vec3f_Copy(&actor->world.pos, &sp64);
actor->wallYaw = Math_Atan2S(wallPoly->normal.z, wallPoly->normal.x);
@@ -1239,10 +1272,10 @@ void Actor_UpdateBgCheckInfo(GlobalContext* globalCtx, Actor* actor, f32 arg2, f
sp64.x = actor->world.pos.x;
sp64.z = actor->world.pos.z;
- if (arg5 & 2) {
+ if (flags & 2) {
sp64.y = actor->prevPos.y + 10.0f;
- if (BgCheck_EntityCheckCeiling(&globalCtx->colCtx, &sp58, &sp64, (arg4 + sp74) - 10.0f, &sCurCeilingPoly,
- &sCurCeilingBgId, actor)) {
+ if (BgCheck_EntityCheckCeiling(&globalCtx->colCtx, &sp58, &sp64, (ceilingCheckHeight + sp74) - 10.0f,
+ &sCurCeilingPoly, &sCurCeilingBgId, actor)) {
actor->bgCheckFlags |= 0x10;
actor->world.pos.y = (sp58 + sp74) - 10.0f;
} else {
@@ -1250,9 +1283,9 @@ void Actor_UpdateBgCheckInfo(GlobalContext* globalCtx, Actor* actor, f32 arg2, f
}
}
- if (arg5 & 4) {
+ if (flags & 4) {
sp64.y = actor->prevPos.y;
- func_8002E2AC(globalCtx, actor, &sp64, arg5);
+ func_8002E2AC(globalCtx, actor, &sp64, flags);
waterBoxYSurface = actor->world.pos.y;
if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, actor->world.pos.x, actor->world.pos.z,
&waterBoxYSurface, &waterBox)) {
@@ -1262,7 +1295,7 @@ void Actor_UpdateBgCheckInfo(GlobalContext* globalCtx, Actor* actor, f32 arg2, f
} else {
if (!(actor->bgCheckFlags & 0x20)) {
actor->bgCheckFlags |= 0x40;
- if (!(arg5 & 0x40)) {
+ if (!(flags & 0x40)) {
ripplePos.x = actor->world.pos.x;
ripplePos.y = waterBoxYSurface;
ripplePos.z = actor->world.pos.z;
@@ -2987,8 +3020,12 @@ Actor* Actor_Find(ActorContext* actorCtx, s32 actorId, s32 actorCategory) {
return NULL;
}
-void func_80032C7C(GlobalContext* globalCtx, Actor* actor) {
- globalCtx->actorCtx.unk_00 = 5;
+/**
+ * Play the death sound effect and flash the screen white for 4 frames.
+ * While the screen flashes, the game freezes.
+ */
+void Enemy_StartFinishingBlow(GlobalContext* globalCtx, Actor* actor) {
+ globalCtx->actorCtx.freezeFlashTimer = 5;
Audio_PlaySoundAtPosition(globalCtx, &actor->world.pos, 20, NA_SE_EN_LAST_DAMAGE);
}
@@ -3064,7 +3101,7 @@ void BodyBreak_SetInfo(BodyBreak* bodyBreak, s32 limbIndex, s32 minLimbIndex, s3
s16 objectId) {
GlobalContext* globalCtx = Effect_GetGlobalCtx();
- if ((globalCtx->actorCtx.unk_00 == 0) && (bodyBreak->val > 0)) {
+ if ((globalCtx->actorCtx.freezeFlashTimer == 0) && (bodyBreak->val > 0)) {
if ((limbIndex >= minLimbIndex) && (limbIndex <= maxLimbIndex) && (*dList != NULL)) {
bodyBreak->dLists[bodyBreak->val] = *dList;
Matrix_Get(&bodyBreak->matrices[bodyBreak->val]);
@@ -3130,8 +3167,8 @@ s32 BodyBreak_SpawnParts(Actor* actor, BodyBreak* bodyBreak, GlobalContext* glob
return true;
}
-void func_80033260(GlobalContext* globalCtx, Actor* actor, Vec3f* arg2, f32 arg3, s32 arg4, f32 arg5, s16 scale,
- s16 scaleStep, u8 arg8) {
+void Actor_SpawnFloorDust(GlobalContext* globalCtx, Actor* actor, Vec3f* arg2, f32 arg3, s32 arg4, f32 randAccelWeight,
+ s16 scale, s16 scaleStep, u8 arg8) {
Vec3f pos;
Vec3f velocity = { 0.0f, 0.0f, 0.0f };
Vec3f accel = { 0.0f, 0.3f, 0.0f };
@@ -3145,8 +3182,8 @@ void func_80033260(GlobalContext* globalCtx, Actor* actor, Vec3f* arg2, f32 arg3
for (i = arg4; i >= 0; i--) {
pos.x = (Math_SinF(var) * arg3) + arg2->x;
pos.z = (Math_CosF(var) * arg3) + arg2->z;
- accel.x = (Rand_ZeroOne() - 0.5f) * arg5;
- accel.z = (Rand_ZeroOne() - 0.5f) * arg5;
+ accel.x = (Rand_ZeroOne() - 0.5f) * randAccelWeight;
+ accel.z = (Rand_ZeroOne() - 0.5f) * randAccelWeight;
if (scale == 0) {
func_8002857C(globalCtx, &pos, &velocity, &accel);
@@ -3220,44 +3257,47 @@ void Actor_ChangeCategory(GlobalContext* globalCtx, ActorContext* actorCtx, Acto
Actor_AddToCategory(actorCtx, actor, actorCategory);
}
-typedef struct {
- /* 0x000 */ Actor actor;
- /* 0x14C */ char unk_14C[0xC4];
- /* 0x210 */ s16 unk_210;
-} Actor_80033780;
-
-Actor* func_80033780(GlobalContext* globalCtx, Actor* refActor, f32 arg2) {
- Actor_80033780* itemActor;
+/**
+ * Checks if a hookshot or arrow actor is going to collide with the cylinder denoted by the
+ * actor's `cylRadius` and `cylHeight`.
+ * The check is only peformed if the projectile actor is within the provided sphere radius.
+ *
+ * Returns the actor if there will be collision, NULL otherwise.
+ */
+Actor* Actor_GetProjectileActor(GlobalContext* globalCtx, Actor* refActor, f32 radius) {
+ Actor* actor;
Vec3f spA8;
f32 deltaX;
f32 deltaY;
f32 deltaZ;
Vec3f sp90;
Vec3f sp84;
- Actor* actor;
actor = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].head;
while (actor != NULL) {
if (((actor->id != ACTOR_ARMS_HOOK) && (actor->id != ACTOR_EN_ARROW)) || (actor == refActor)) {
actor = actor->next;
} else {
- itemActor = (Actor_80033780*)actor;
- if ((arg2 < Math_Vec3f_DistXYZ(&refActor->world.pos, &itemActor->actor.world.pos)) ||
- (itemActor->unk_210 == 0)) {
+ //! @bug The projectile actor gets unsafely casted to a hookshot to check its timer, even though
+ // it can also be an arrow.
+ // Luckily, the field at the same offset in the arrow actor is the x component of a vector
+ // which will rarely ever be 0. So its very unlikely for this bug to cause an issue.
+ if ((Math_Vec3f_DistXYZ(&refActor->world.pos, &actor->world.pos) > radius) ||
+ (((ArmsHook*)actor)->timer == 0)) {
actor = actor->next;
} else {
- deltaX = Math_SinS(itemActor->actor.world.rot.y) * (itemActor->actor.speedXZ * 10.0f);
- deltaY = itemActor->actor.velocity.y + (itemActor->actor.gravity * 10.0f);
- deltaZ = Math_CosS(itemActor->actor.world.rot.y) * (itemActor->actor.speedXZ * 10.0f);
+ deltaX = Math_SinS(actor->world.rot.y) * (actor->speedXZ * 10.0f);
+ deltaY = actor->velocity.y + (actor->gravity * 10.0f);
+ deltaZ = Math_CosS(actor->world.rot.y) * (actor->speedXZ * 10.0f);
- spA8.x = itemActor->actor.world.pos.x + deltaX;
- spA8.y = itemActor->actor.world.pos.y + deltaY;
- spA8.z = itemActor->actor.world.pos.z + deltaZ;
+ spA8.x = actor->world.pos.x + deltaX;
+ spA8.y = actor->world.pos.y + deltaY;
+ spA8.z = actor->world.pos.z + deltaZ;
if (CollisionCheck_CylSideVsLineSeg(refActor->colChkInfo.cylRadius, refActor->colChkInfo.cylHeight,
- 0.0f, &refActor->world.pos, &itemActor->actor.world.pos, &spA8,
- &sp90, &sp84)) {
- return &itemActor->actor;
+ 0.0f, &refActor->world.pos, &actor->world.pos, &spA8, &sp90,
+ &sp84)) {
+ return actor;
} else {
actor = actor->next;
}
@@ -3370,7 +3410,10 @@ s16 func_800339B8(Actor* actor, GlobalContext* globalCtx, f32 arg2, s16 arg3) {
return ret;
}
-s32 func_80033A84(GlobalContext* globalCtx, Actor* actor) {
+/**
+ * Returns true if the player is targeting the provided actor
+ */
+s32 Actor_IsTargeted(GlobalContext* globalCtx, Actor* actor) {
Player* player = PLAYER;
if ((player->stateFlags1 & 0x10) && actor->isTargeted) {
@@ -3380,7 +3423,10 @@ s32 func_80033A84(GlobalContext* globalCtx, Actor* actor) {
}
}
-s32 func_80033AB8(GlobalContext* globalCtx, Actor* actor) {
+/**
+ * Returns true if the player is targeting an actor other than the provided actor
+ */
+s32 Actor_OtherIsTargeted(GlobalContext* globalCtx, Actor* actor) {
Player* player = PLAYER;
if ((player->stateFlags1 & 0x10) && !actor->isTargeted) {
@@ -3987,7 +4033,7 @@ u8 Actor_ApplyDamage(Actor* actor) {
return actor->colChkInfo.health;
}
-void func_80035650(Actor* actor, ColliderInfo* colInfo, s32 freezeFlag) {
+void Actor_SetDropFlag(Actor* actor, ColliderInfo* colInfo, s32 freezeFlag) {
if (colInfo->acHitInfo == NULL) {
actor->dropFlag = 0x00;
} else if (freezeFlag && (colInfo->acHitInfo->toucher.dmgFlags & 0x10060000)) {
@@ -4015,7 +4061,7 @@ void func_80035650(Actor* actor, ColliderInfo* colInfo, s32 freezeFlag) {
}
}
-void func_8003573C(Actor* actor, ColliderJntSph* jntSph, s32 freezeFlag) {
+void Actor_SetDropFlagJntSph(Actor* actor, ColliderJntSph* jntSph, s32 freezeFlag) {
ColliderInfo* curColInfo;
s32 flag;
s32 i;
diff --git a/src/code/z_play.c b/src/code/z_play.c
index ee7567911..8e5878a14 100644
--- a/src/code/z_play.c
+++ b/src/code/z_play.c
@@ -805,9 +805,10 @@ void Gameplay_Update(GlobalContext* globalCtx) {
func_800AA178(1);
- if (globalCtx->actorCtx.unk_00 && (globalCtx->actorCtx.unk_00-- < 5)) {
- osSyncPrintf("FINISH=%d\n", globalCtx->actorCtx.unk_00);
- if ((globalCtx->actorCtx.unk_00 > 0) && ((globalCtx->actorCtx.unk_00 % 2) != 0)) {
+ if (globalCtx->actorCtx.freezeFlashTimer && (globalCtx->actorCtx.freezeFlashTimer-- < 5)) {
+ osSyncPrintf("FINISH=%d\n", globalCtx->actorCtx.freezeFlashTimer);
+ if ((globalCtx->actorCtx.freezeFlashTimer > 0) &&
+ ((globalCtx->actorCtx.freezeFlashTimer % 2) != 0)) {
globalCtx->envCtx.unk_E1 = 1;
globalCtx->envCtx.unk_E2[0] = globalCtx->envCtx.unk_E2[1] = globalCtx->envCtx.unk_E2[2] = 0x96;
globalCtx->envCtx.unk_E2[3] = 0x50;