Document Hookshot Attachment (#1745)

* hookshot attachment

* period
This commit is contained in:
engineer124
2024-11-26 11:26:55 +11:00
committed by GitHub
parent a448168d37
commit ba693efb08
15 changed files with 79 additions and 65 deletions
+36 -29
View File
@@ -68,8 +68,8 @@ void ArmsHook_Init(Actor* thisx, PlayState* play) {
void ArmsHook_Destroy(Actor* thisx, PlayState* play) {
ArmsHook* this = THIS;
if (this->grabbed != NULL) {
this->grabbed->flags &= ~ACTOR_FLAG_2000;
if (this->attachedActor != NULL) {
this->attachedActor->flags &= ~ACTOR_FLAG_HOOKSHOT_ATTACHED;
}
Collider_DestroyQuad(play, &this->collider);
}
@@ -98,10 +98,10 @@ s32 ArmsHook_AttachToPlayer(ArmsHook* this, Player* player) {
return 0;
}
void ArmsHook_DetachHookFromActor(ArmsHook* this) {
if (this->grabbed != NULL) {
this->grabbed->flags &= ~ACTOR_FLAG_2000;
this->grabbed = NULL;
void ArmsHook_DetachFromActor(ArmsHook* this) {
if (this->attachedActor != NULL) {
this->attachedActor->flags &= ~ACTOR_FLAG_HOOKSHOT_ATTACHED;
this->attachedActor = NULL;
}
}
@@ -112,7 +112,7 @@ s32 ArmsHook_CheckForCancel(ArmsHook* this) {
if ((player->itemAction != player->heldItemAction) || (player->actor.flags & ACTOR_FLAG_TALK) ||
(player->stateFlags1 & (PLAYER_STATE1_DEAD | PLAYER_STATE1_4000000))) {
this->timer = 0;
ArmsHook_DetachHookFromActor(this);
ArmsHook_DetachFromActor(this);
Math_Vec3f_Copy(&this->actor.world.pos, &player->rightHandWorld.pos);
return 1;
}
@@ -120,17 +120,17 @@ s32 ArmsHook_CheckForCancel(ArmsHook* this) {
return 0;
}
void ArmsHook_AttachHookToActor(ArmsHook* this, Actor* actor) {
actor->flags |= ACTOR_FLAG_2000;
this->grabbed = actor;
Math_Vec3f_Diff(&actor->world.pos, &this->actor.world.pos, &this->unk1FC);
void ArmsHook_AttachToActor(ArmsHook* this, Actor* actor) {
actor->flags |= ACTOR_FLAG_HOOKSHOT_ATTACHED;
this->attachedActor = actor;
Math_Vec3f_Diff(&actor->world.pos, &this->actor.world.pos, &this->attachPointOffset);
}
void ArmsHook_Shoot(ArmsHook* this, PlayState* play) {
Player* player = GET_PLAYER(play);
if ((this->actor.parent == NULL) || !Player_IsHoldingHookshot(player)) {
ArmsHook_DetachHookFromActor(this);
ArmsHook_DetachFromActor(this);
Actor_Kill(&this->actor);
return;
}
@@ -144,7 +144,7 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) {
if ((touchedActor->update != NULL) && (touchedActor->flags & (ACTOR_FLAG_200 | ACTOR_FLAG_400))) {
if (this->collider.elem.atHitElem->acElemFlags & ACELEM_HOOKABLE) {
ArmsHook_AttachHookToActor(this, touchedActor);
ArmsHook_AttachToActor(this, touchedActor);
if (CHECK_FLAG_ALL(touchedActor->flags, ACTOR_FLAG_400)) {
func_808C1154(this);
}
@@ -157,25 +157,31 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) {
}
if (DECR(this->timer) == 0) {
Actor* grabbed = this->grabbed;
Actor* attachedActor = this->attachedActor;
Vec3f bodyDistDiffVec;
Vec3f newPos;
f32 bodyDistDiff;
f32 phi_f16;
s32 pad;
if (grabbed != NULL) {
if ((grabbed->update == NULL) || !CHECK_FLAG_ALL(grabbed->flags, ACTOR_FLAG_2000)) {
grabbed = NULL;
this->grabbed = NULL;
if (attachedActor != NULL) {
if ((attachedActor->update == NULL) ||
!CHECK_FLAG_ALL(attachedActor->flags, ACTOR_FLAG_HOOKSHOT_ATTACHED)) {
attachedActor = NULL;
this->attachedActor = NULL;
} else if (this->actor.child != NULL) {
f32 sp94 = Actor_WorldDistXYZToActor(&this->actor, grabbed);
f32 sp90 = sqrtf(SQXYZ(this->unk1FC));
f32 curActorOffsetXYZ = Actor_WorldDistXYZToActor(&this->actor, attachedActor);
f32 attachPointOffsetXYZ = sqrtf(SQXYZ(this->attachPointOffset));
Math_Vec3f_Diff(&grabbed->world.pos, &this->unk1FC, &this->actor.world.pos);
if (50.0f < (sp94 - sp90)) {
ArmsHook_DetachHookFromActor(this);
grabbed = NULL;
// Keep the hookshot actor at the same relative offset as the initial attachment even if the actor moves
Math_Vec3f_Diff(&attachedActor->world.pos, &this->attachPointOffset, &this->actor.world.pos);
// If the actor the hookshot is attached to is moving, the hookshot's current relative
// position will be different than the initial attachment position.
// If the distance between those two points is larger than 50 units, detach the hookshot.
if ((curActorOffsetXYZ - attachPointOffsetXYZ) > 50.0f) {
ArmsHook_DetachFromActor(this);
attachedActor = NULL;
}
}
}
@@ -185,13 +191,14 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) {
bodyDistDiff =
Math_Vec3f_DistXYZAndStoreDiff(&player->rightHandWorld.pos, &this->actor.world.pos, &bodyDistDiffVec);
if (bodyDistDiff < 30.0f) {
velocity = 0.0f;
phi_f16 = 0.0f;
} else {
if (this->actor.child != NULL) {
velocity = 30.0f;
} else if (grabbed != NULL) {
} else if (attachedActor != NULL) {
velocity = 50.0f;
} else {
velocity = 200.0f;
@@ -210,15 +217,15 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) {
if (this->actor.child == NULL) {
Math_Vec3f_Sum(&player->rightHandWorld.pos, &newPos, &this->actor.world.pos);
if (grabbed != NULL) {
Math_Vec3f_Sum(&this->actor.world.pos, &this->unk1FC, &grabbed->world.pos);
if (attachedActor != NULL) {
Math_Vec3f_Sum(&this->actor.world.pos, &this->attachPointOffset, &attachedActor->world.pos);
}
} else {
Math_Vec3f_Diff(&bodyDistDiffVec, &newPos, &player->actor.velocity);
player->actor.world.rot.x = Math_Atan2S_XY(sqrtf(SQXZ(bodyDistDiffVec)), -bodyDistDiffVec.y);
}
if (phi_f16 < 50.0f) {
ArmsHook_DetachHookFromActor(this);
ArmsHook_DetachFromActor(this);
if (phi_f16 == 0.0f) {
ArmsHook_SetupAction(this, ArmsHook_Wait);
if (ArmsHook_AttachToPlayer(this, player)) {
@@ -259,7 +266,7 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) {
if (bgId != BGCHECK_SCENE) {
dynaPolyActor = DynaPoly_GetActor(&play->colCtx, bgId);
if (dynaPolyActor != NULL) {
ArmsHook_AttachHookToActor(this, &dynaPolyActor->actor);
ArmsHook_AttachToActor(this, &dynaPolyActor->actor);
}
}
func_808C1154(this);
@@ -13,8 +13,8 @@ typedef struct ArmsHook {
/* 0x1C4 */ WeaponInfo weaponInfo;
/* 0x1E0 */ Vec3f unk1E0;
/* 0x1EC */ Vec3f unk1EC;
/* 0x1F8 */ Actor* grabbed;
/* 0x1FC */ Vec3f unk1FC;
/* 0x1F8 */ Actor* attachedActor;
/* 0x1FC */ Vec3f attachPointOffset; // Distance from the hookshot attach point to world pos of `attachedActor`
/* 0x208 */ s8 unk_208;
/* 0x20A */ s16 timer;
/* 0x20C */ ArmsHookActionFunc actionFunc;
@@ -1159,7 +1159,7 @@ void EnBigpo_Update(Actor* thisx, PlayState* play) {
s32 pad;
ColliderCylinder* thisCollider;
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) {
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED)) {
this->hoverHeightCycleTimer = 0;
this->savedHeight = this->actor.world.pos.y;
}
@@ -2179,8 +2179,8 @@ void EnBigslime_SetupDamageGekko(EnBigslime* this, s32 isNotFrozen) {
}
EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_DAMAGE);
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) {
this->actor.flags &= ~ACTOR_FLAG_2000;
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED)) {
this->actor.flags &= ~ACTOR_FLAG_HOOKSHOT_ATTACHED;
}
this->actionFunc = EnBigslime_DamageGekko;
+2 -2
View File
@@ -221,7 +221,7 @@ void func_808A2918(EnBoom* this, PlayState* play) {
(this->collider.base.at->id == ACTOR_EN_SI))) {
this->unk_1C8 = this->collider.base.at;
if (this->collider.base.at->id == ACTOR_EN_SI) {
this->collider.base.at->flags |= ACTOR_FLAG_2000;
this->collider.base.at->flags |= ACTOR_FLAG_HOOKSHOT_ATTACHED;
}
}
@@ -266,7 +266,7 @@ void func_808A2918(EnBoom* this, PlayState* play) {
targetActor->gravity = -0.9f;
targetActor->bgCheckFlags &= ~(BGCHECKFLAG_GROUND | BGCHECKFLAG_GROUND_TOUCH);
} else {
targetActor->flags &= ~ACTOR_FLAG_2000;
targetActor->flags &= ~ACTOR_FLAG_HOOKSHOT_ATTACHED;
}
}
Actor_Kill(&this->actor);
+1 -1
View File
@@ -363,7 +363,7 @@ void EnFg_Destroy(Actor* thisx, PlayState* play) {
void EnFg_Update(Actor* thisx, PlayState* play) {
EnFg* this = THIS;
if ((CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000) == 0) &&
if ((CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED) == 0) &&
(CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_ATTACHED_TO_ARROW) == 0)) {
this->actionFunc(this, play);
Actor_UpdateBgCheckInfo(play, &this->actor, sREG(0), sREG(1), 0.0f,
@@ -1604,7 +1604,8 @@ void func_80B89280(EnKaizoku* this, PlayState* play) {
}
}
if ((this->unk_2B6 == 0) && (this->unk_2B8 == 0) && !CHECK_FLAG_ALL(this->picto.actor.flags, ACTOR_FLAG_2000) &&
if ((this->unk_2B6 == 0) && (this->unk_2B8 == 0) &&
!CHECK_FLAG_ALL(this->picto.actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED) &&
(this->picto.actor.bgCheckFlags & BGCHECKFLAG_GROUND)) {
this->unk_2D8 = 0;
func_80B85A00(this, play, true);
@@ -500,8 +500,8 @@ void EnMinislime_SetupMoveToBigslime(EnMinislime* this) {
}
this->frozenAlpha = 0;
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) {
this->actor.flags &= ~ACTOR_FLAG_2000;
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED)) {
this->actor.flags &= ~ACTOR_FLAG_HOOKSHOT_ATTACHED;
}
this->actionFunc = EnMinislime_MoveToBigslime;
}
@@ -556,8 +556,8 @@ void EnMinislime_SetupDefeatIdle(EnMinislime* this) {
}
this->frozenAlpha = 0;
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) {
this->actor.flags &= ~ACTOR_FLAG_2000;
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED)) {
this->actor.flags &= ~ACTOR_FLAG_HOOKSHOT_ATTACHED;
}
this->actor.shape.rot.x = 0;
@@ -625,8 +625,8 @@ void EnMinislime_SetupMoveToGekko(EnMinislime* this) {
this->actor.velocity.y = 0.0f;
this->collider.base.acFlags &= ~AC_ON;
this->collider.base.ocFlags1 &= ~OC1_ON;
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) {
this->actor.flags &= ~ACTOR_FLAG_2000;
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED)) {
this->actor.flags &= ~ACTOR_FLAG_HOOKSHOT_ATTACHED;
}
this->actionFunc = EnMinislime_MoveToGekko;
@@ -715,7 +715,7 @@ void EnMinislime_Update(Actor* thisx, PlayState* play) {
} else if ((this->actor.params == MINISLIME_FORM_BIGSLIME) && (this->actionFunc != EnMinislime_MoveToBigslime)) {
EnMinislime_SetupMoveToBigslime(this);
} else {
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) {
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED)) {
this->collider.base.acFlags &= ~AC_HIT;
return;
}
+1 -1
View File
@@ -1121,7 +1121,7 @@ void EnPp_Mask_SetupDetach(EnPp* this, PlayState* play) {
* Moves the mask through the air and eventually makes it burst into flames.
*/
void EnPp_Mask_Detach(EnPp* this, PlayState* play) {
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000) || (this->action == EN_PP_ACTION_MASK_DEAD)) {
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED) || (this->action == EN_PP_ACTION_MASK_DEAD)) {
switch (this->actionVar.maskDetachState) {
case EN_PP_MASK_DETACH_STATE_START:
this->action = EN_PP_ACTION_MASK_DEAD;
+1 -1
View File
@@ -835,7 +835,7 @@ void EnRat_Update(Actor* thisx, PlayState* play) {
if (this->damageReaction.hookedState == EN_RAT_HOOK_STARTED) {
// The player just hit the Real Bombchu with the Hookshot.
this->damageReaction.hookedState = EN_RAT_HOOKED;
} else if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) {
} else if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED)) {
// The player has hooked the Real Bombchu for more than one frame, but
// the actor flag indicating that the Hookshot is attached is *not* set.
EnRat_Explode(this, play);
+2 -2
View File
@@ -114,7 +114,7 @@ void EnSi_GiveToken(EnSi* this, PlayState* play) {
}
void EnSi_Wait(EnSi* this, PlayState* play) {
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) {
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED)) {
this->actionFunc = EnSi_DraggedByHookshot;
} else if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) {
EnSi_GiveToken(this, play);
@@ -125,7 +125,7 @@ void EnSi_Wait(EnSi* this, PlayState* play) {
}
void EnSi_DraggedByHookshot(EnSi* this, PlayState* play) {
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) {
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED)) {
EnSi_GiveToken(this, play);
Actor_Kill(&this->actor);
}
@@ -559,8 +559,8 @@ void EnTanron2_Update(Actor* thisx, PlayState* play) {
}
}
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000) && (this->actor.xzDistToPlayer < 80.0f)) {
this->actor.flags &= ~ACTOR_FLAG_2000;
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED) && (this->actor.xzDistToPlayer < 80.0f)) {
this->actor.flags &= ~ACTOR_FLAG_HOOKSHOT_ATTACHED;
this->unk_15A = 25;
this->unk_159 = 1;
}
@@ -368,7 +368,7 @@ void EnWallmas_ReturnToCeiling(EnWallmas* this, PlayState* play) {
if (this->skelAnime.curFrame > 20.0f) {
this->actor.world.pos.y += 30.0f;
this->timer += 9;
this->actor.flags &= ~ACTOR_FLAG_2000;
this->actor.flags &= ~ACTOR_FLAG_HOOKSHOT_ATTACHED;
}
if (Animation_OnFrame(&this->skelAnime, 20.0f)) {