mirror of https://github.com/zeldaret/mm.git
parent
a448168d37
commit
ba693efb08
|
@ -502,8 +502,14 @@ typedef enum DoorLockType {
|
|||
|
||||
// Actor will not shake when a quake occurs
|
||||
#define ACTOR_FLAG_IGNORE_QUAKE (1 << 12)
|
||||
|
||||
// The hookshot is currently attached to this actor.
|
||||
// The behavior that occurs after attachment is determined by `ACTOR_FLAG_200` and `ACTOR_FLAG_400`.
|
||||
// If neither of those flags are set attachment cannot occur, and the hookshot will simply act as a damage source.
|
||||
//
|
||||
#define ACTOR_FLAG_2000 (1 << 13)
|
||||
// This flag is also reused to indicate that an actor is attached to the Zora boomerang.
|
||||
// This only has an effect for Gold Skulltula Tokens (EN_SI) which has overlapping behavior for hookshot and boomerang.
|
||||
#define ACTOR_FLAG_HOOKSHOT_ATTACHED (1 << 13)
|
||||
|
||||
// When hit by an arrow, the actor will be able to attach to the arrow and fly with it in the air
|
||||
#define ACTOR_FLAG_CAN_ATTACH_TO_ARROW (1 << 14)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -6105,9 +6105,9 @@
|
|||
0x808C10F8:("ArmsHook_Wait",),
|
||||
0x808C1154:("func_808C1154",),
|
||||
0x808C1168:("ArmsHook_AttachToPlayer",),
|
||||
0x808C1198:("ArmsHook_DetachHookFromActor",),
|
||||
0x808C1198:("ArmsHook_DetachFromActor",),
|
||||
0x808C11C0:("ArmsHook_CheckForCancel",),
|
||||
0x808C125C:("ArmsHook_AttachHookToActor",),
|
||||
0x808C125C:("ArmsHook_AttachToActor",),
|
||||
0x808C12A4:("ArmsHook_Shoot",),
|
||||
0x808C18D8:("ArmsHook_Update",),
|
||||
0x808C1918:("ArmsHook_Draw",),
|
||||
|
|
Loading…
Reference in New Issue