Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion code/include/z3D/z3Dactor.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ typedef struct SkelAnime {
/* 0x14 */ char unk_14[0x14];
/* 0x28 */ struct SkeletonAnimationModel* unk_28;
/* 0x2C */ char unk_2C[0x4];
/* 0x30 */ s32 animationType;
/* 0x30 */ s32 animIndex;
/* 0x34 */ char unk_34[0x8];
/* 0x3C */ f32 curFrame;
/* 0x40 */ f32 playSpeed;
Expand Down Expand Up @@ -381,5 +381,7 @@ void Actor_UpdateBgCheckInfo(struct GlobalContext* globalCtx, Actor* actor, f32
s32 Player_InCsMode(struct GlobalContext* globalCtx);
Actor* Actor_FindNearby(struct GlobalContext* globalCtx, Actor* ref_actor, s16 actorId, u8 actor_category, f32 range);
void ActorShadow_DrawFeet(Actor* actor, void* lights, struct GlobalContext* globalCtx);
void LinkAnimation_Change(SkelAnime* skelAnime, struct GlobalContext* play, u32 animation, f32 playSpeed,
f32 startFrame, f32 endFrame, u8 mode, f32 morphFrames) __attribute__((pcs("aapcs-vfp")));

#endif
7 changes: 5 additions & 2 deletions code/oot.ld
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ SECTIONS
.patch_ArmosPushSpeed 0x10B5C4 + _LD_OFF : { *(.patch_ArmosPushSpeed) }
EnMb_ClubWaitPlayerNear = 0x10B5D0 + _LD_OFF;
.patch_ShortenRainbowBridgeCS 0x10B904 + _LD_OFF : { *(.patch_ShortenRainbowBridgeCS) }
DoorShutter_Close = 0x10D030 + _LD_OFF;
.patch_GrannyTextID 0x10DCD0 + _LD_OFF : { *(.patch_GrannyTextID) }
OceffSpot_End = 0x10FBD0 + _LD_OFF;
ObjLift_Shake = 0x110E98 + _LD_OFF;
Expand Down Expand Up @@ -490,6 +491,7 @@ SECTIONS
.patch_SkullwalltulaAttack_35F328 0x35F328 + _LD_OFF : { *(.patch_SkullwalltulaAttack_35F328) }
.patch_SkullwalltulaTargetRotation 0x35F828 + _LD_OFF : { *(.patch_SkullwalltulaTargetRotation) }
.patch_SkullwalltulaAttack_35F834 0x35F834 + _LD_OFF : { *(.patch_SkullwalltulaAttack_35F834) }
LinkAnimation_Change = 0x360190 + _LD_OFF;
LinkAnimation_PlayOnce = 0x3604F0 + _LD_OFF;
.patch_ISGCrouchStab 0x360690 + _LD_OFF : { *(.patch_ISGCrouchStab) }
.patch_ForceTrailEffectUpdate 0x362108 + _LD_OFF : { *(.patch_ForceTrailEffectUpdate) } /*EffectBlure_AddVertex*/
Expand All @@ -516,6 +518,7 @@ SECTIONS
.patch_IgnoreMaskReaction 0x36BBC4 + _LD_OFF : { *(.patch_IgnoreMaskReaction) }
Flags_UnsetSwitch = 0x36BEAC + _LD_OFF;
Matrix_Multiply = 0x36C174 + _LD_OFF;
.patch_SetupDoorShutter 0x36C3BC + _LD_OFF : { *(.patch_SetupDoorShutter) }
Flags_GetClear = 0x36CF6C + _LD_OFF;
Math_Vec3f_DistXZ = 0x36D260 + _LD_OFF;
Math_SmoothStepToF = 0x36E168 + _LD_OFF;
Expand Down Expand Up @@ -661,7 +664,7 @@ SECTIONS
EnDoor_Open = 0x3EC04C + _LD_OFF;
.patch_CowItemOverride 0x3EE378 + _LD_OFF : { *(.patch_CowItemOverride) }
DoorGerudo_Unlocking = 0x3EEE38 + _LD_OFF;
DoorShutter_SlidingDoor_Open = 0x3EEE7C + _LD_OFF;
DoorShutter_Open = 0x3EEE7C + _LD_OFF;
.patch_CowBottleCheck 0x3F065C + _LD_OFF : { *(.patch_CowBottleCheck) }
.patch_CarpetSalesmanCheckFlagOne 0x3F0A18 + _LD_OFF : { *(.patch_CarpetSalesmanCheckFlagOne) }
.patch_CarpetSalesmanCheckFlagTwo 0x3F0A64 + _LD_OFF : { *(.patch_CarpetSalesmanCheckFlagTwo) }
Expand All @@ -675,7 +678,7 @@ SECTIONS
.patch_FireArrowCheckChestFlagTwo 0x3F2448 + _LD_OFF : { *(.patch_FireArrowCheckChestFlagTwo) }
.patch_LinkReflection 0x3F2F0C + _LD_OFF : { *(.patch_LinkReflection) }
DoorGerudo_Idle = 0x3F3FA0 + _LD_OFF;
DoorShutter_SlidingDoor_Idle = 0x3F4A3C + _LD_OFF;
DoorShutter_Idle = 0x3F4A3C + _LD_OFF;
.patch_SlidingDoorDestroyCustomModels 0x3F4A70 + _LD_OFF : { *(.patch_SlidingDoorDestroyCustomModels) }
.patch_ChildBlueWarpOverride 0x3F5774 + _LD_OFF : { *(.patch_ChildBlueWarpOverride) }
BgIceShelter_Melt = 0x3F5F00 + _LD_OFF;
Expand Down
11 changes: 11 additions & 0 deletions code/src/actors/dark_link.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ void EnTorch2_Update(Actor* thisx, GlobalContext* globalCtx);

u8 sPlayerWeaponClanked = FALSE;

#define IDLE_STANDING_ANIM_IDX 0x58

void EnTorch2_rInit(Actor* thisx, GlobalContext* globalCtx) {
EnTorch2_Init(thisx, globalCtx);

Expand Down Expand Up @@ -58,6 +60,15 @@ void EnTorch2_rUpdate(Actor* thisx, GlobalContext* globalCtx) {
case ENTORCH2_WAIT:
// Avoid triggering fall damage effect when spawning in certain locations.
this->darkPlayer.fallStartHeight = thisx->world.pos.y;

// Sometimes during the first update cycle the animation changes to the falling one, so we need to
// restore it. Check water level in case it can raise and submerge Dark Link while idle.
if (this->darkPlayer.skelAnime.animIndex != IDLE_STANDING_ANIM_IDX &&
this->darkPlayer.actor.depthInWater <= 0) {
LinkAnimation_Change(&this->darkPlayer.skelAnime, globalCtx, IDLE_STANDING_ANIM_IDX, 1.0, 0.0, 0.0,
0, 0.0);
}

break;
case ENTORCH2_ATTACK:
CollisionPoly floorPoly;
Expand Down
44 changes: 30 additions & 14 deletions code/src/actors/door.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "models.h"
#include "settings.h"
#include "enemizer.h"
#include "enemy_souls.h"
#include "multiplayer.h"

// Certain doors can cause a crash depending on a freestanding
Expand Down Expand Up @@ -80,14 +81,16 @@ void DoorShutter_rInit(Actor* thisx, GlobalContext* globalCtx) {

void DoorShutter_Update(Actor* thisx, GlobalContext* globalCtx);

void DoorShutter_SlidingDoor_Idle(DoorShutter* this, GlobalContext* globalCtx);
void DoorShutter_SlidingDoor_Open(DoorShutter* this, GlobalContext* globalCtx);
void DoorShutter_Idle(DoorShutter* this, GlobalContext* globalCtx);
void DoorShutter_Open(DoorShutter* this, GlobalContext* globalCtx);
void DoorShutter_Close(DoorShutter* this, GlobalContext* globalCtx);

void DoorShutter_Unlocking(DoorShutter* this, GlobalContext* globalCtx);

void DoorShutter_rUpdate(Actor* thisx, GlobalContext* globalCtx) {
DoorShutter* this = (DoorShutter*)thisx;

DoorShutterActionFunc prev_action_fn = this->action_fn;
DoorShutterActionFunc prevActionFunc = this->actionFunc;

DoorShutter_Update(thisx, globalCtx);

Expand All @@ -96,32 +99,45 @@ void DoorShutter_rUpdate(Actor* thisx, GlobalContext* globalCtx) {
return;
}

if (this->lock_timer != 0 && prev_action_fn == DoorShutter_SlidingDoor_Idle &&
this->action_fn == DoorShutter_SlidingDoor_Open) {
if (this->door_type_maybe != 5) {
if (this->unlockTimer != 0 && prevActionFunc == DoorShutter_Idle && this->actionFunc == DoorShutter_Open) {
if (this->doorType != 5) {
Multiplayer_Send_UnlockedDoor(thisx->params & 0x3F);
}
Multiplayer_Send_ActorUpdate(thisx, NULL, 0);
}
}

void DoorShutter_Unlock(DoorShutter* this) {
if (this->action_fn != DoorShutter_SlidingDoor_Idle) {
if (this->actionFunc != DoorShutter_Idle) {
return;
}
this->action_fn = &DoorShutter_Unlocking;
this->actionFunc = DoorShutter_Unlocking;

u32 sfx_id = this->door_type_maybe != 5 ? NA_SE_EV_CHAIN_KEY_UNLOCK : NA_SE_EV_CHAIN_KEY_UNLOCK_B;
Audio_PlaySfxGeneral(sfx_id, &this->base.world.pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultReverb);
u32 sfx_id = this->doorType != 5 ? NA_SE_EV_CHAIN_KEY_UNLOCK : NA_SE_EV_CHAIN_KEY_UNLOCK_B;
Audio_PlaySfxGeneral(sfx_id, &this->dyna.actor.world.pos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
}

void DoorShutter_Unlocking(DoorShutter* this, GlobalContext* globalCtx) {
if (this->lock_timer > 0) {
this->lock_timer--;
if (this->unlockTimer > 0) {
this->unlockTimer--;
return;
}
this->action_fn = DoorShutter_SlidingDoor_Idle;
this->actionFunc = DoorShutter_Idle;
}

u8 DoorShutter_CheckSoullessEnemies(DoorShutter* this) {
if (gSettingsContext.shuffleEnemySouls == SHUFFLEENEMYSOULS_ALL &&
(this->actionFunc == DoorShutter_Close || this->actionFunc == DoorShutter_Open)) {
Actor* enemy = gGlobalContext->actorCtx.actorList[ACTORTYPE_ENEMY].first;
for (; enemy != NULL; enemy = enemy->next) {
Comment thread
HylianFreddy marked this conversation as resolved.
if (enemy->room == gGlobalContext->roomNum && !EnemySouls_CheckSoulForActor(enemy)) {
this->barsClosedAmount = 0.0;
return TRUE;
}
}
}
return FALSE;
}

/*------------------------------
Expand Down
18 changes: 10 additions & 8 deletions code/src/actors/door.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@ struct DoorShutter;
typedef void (*DoorShutterActionFunc)(struct DoorShutter* this, GlobalContext* globalCtx);

typedef struct DoorShutter {
Actor base;
char dyna[24];
char unk_1BC[6];
s8 door_type_maybe;
char unk_1C3[3];
s8 lock_timer;
char unk_1C7[9];
DoorShutterActionFunc action_fn;
/* 0x000 */ DynaPolyActor dyna;
/* 0x1BC */ char unk_1BC[0x06];
/* 0x1C2 */ s8 doorType;
/* 0x1C3 */ char unk_1C3[0x03];
/* 0x1C6 */ s8 unlockTimer;
/* 0x1C7 */ char unk_1C7[0x05];
/* 0x1CC */ f32 barsClosedAmount;
/* 0x1D0 */ DoorShutterActionFunc actionFunc;
/* 0x1D4 */ char unk_1D4[0x4C];
} DoorShutter;
_Static_assert(sizeof(DoorShutter) == 0x220, "DoorShutter size");

void DoorShutter_rInit(Actor* thisx, GlobalContext* globalCtx);
void DoorShutter_rUpdate(Actor* thisx, GlobalContext* globalCtx);
Expand Down
8 changes: 8 additions & 0 deletions code/src/asm/hooks.s
Original file line number Diff line number Diff line change
Expand Up @@ -2192,3 +2192,11 @@ HOOK BusinessScrubCheckFlags
addgt lr,lr,#0x10 @ 1: kill actor
cmplt r1,#0x2 @ -1: resume vanilla checks
bx lr

HOOK SetupDoorShutter
push {r0-r12, lr}
cpy r0,r4 @ actor
bl DoorShutter_CheckSoullessEnemies
cmp r0,#0x0
pop {r0-r12, lr}
bx lr
3 changes: 3 additions & 0 deletions code/src/asm/patches.s
Original file line number Diff line number Diff line change
Expand Up @@ -1622,3 +1622,6 @@ PATCH GanonFinalBlow

PATCH PlayerBonk
bl hook_PlayerBonk

PATCH SetupDoorShutter
bleq hook_SetupDoorShutter
3 changes: 2 additions & 1 deletion code/src/enemy_souls.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ void EnemySouls_SetSoulFlag(EnemySoulId soulId) {
u8 EnemySouls_CheckSoulForActor(Actor* actor) {
if ((gSettingsContext.shuffleEnemySouls == SHUFFLEENEMYSOULS_OFF) ||
(gSettingsContext.shuffleEnemySouls == SHUFFLEENEMYSOULS_BOSSES && !Actor_IsBoss(actor)) ||
(actor->id == 0x054 && ((EnAm*)actor)->textureBlend == 0 /* Armos, statue or asleep */)) {
(actor->id == ACTOR_ARMOS && ((EnAm*)actor)->textureBlend == 0 /* Statue or asleep enemy */) ||
(actor->id == ACTOR_DEAD_HAND && actor->shape.yOffset <= -15000.0 /* Waiting underground */)) {
return TRUE;
}

Expand Down