diff --git a/soh/soh/Enhancements/accessible-actors/AccessibleActorList.cpp b/soh/soh/Enhancements/accessible-actors/AccessibleActorList.cpp index d4dd662d0..df27fef97 100644 --- a/soh/soh/Enhancements/accessible-actors/AccessibleActorList.cpp +++ b/soh/soh/Enhancements/accessible-actors/AccessibleActorList.cpp @@ -107,12 +107,12 @@ void accessible_switch(AccessibleActor* actor) { } } else if ((actor->actor->params & 7) == OBJSWITCH_TYPE_EYE) { if (sw->eyeTexIndex == 0) { - actor->policy.aimAssist.isProvider = true; + actor->policy.aimAssist.isProvider = AIM_SHOOT; actor->policy.ydist = 1000; ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_FOOT_SWITCH); } } else if (actor->xyzDistToPlayer < 1000) { - actor->policy.aimAssist.isProvider = true; + actor->policy.aimAssist.isProvider = AIM_ALL; actor->policy.ydist = 1000; ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_DIAMOND_SWITCH); } @@ -479,7 +479,7 @@ void ActorAccessibility_InitActors() { }); policy.distance = 2000; policy.n = 1; - policy.aimAssist.isProvider = true; + policy.aimAssist.isProvider = AIM_HOOK; ActorAccessibility_AddSupportedActor(ACTOR_EN_KAKASI2, policy); ActorAccessibility_InitPolicy(&policy, "Chest", [](AccessibleActor* actor) { Player* player = GET_PLAYER(actor->play); @@ -584,7 +584,7 @@ void ActorAccessibility_InitActors() { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_FLUTTER_FLAG); } }); - policy.aimAssist.isProvider = true; + policy.aimAssist.isProvider = AIM_HOOK; policy.distance = 1000; policy.volume = 1.5; policy.n = 1; @@ -654,7 +654,7 @@ void ActorAccessibility_InitActors() { ActorAccessibility_InitPolicy(&policy, "Jabu Switch", [](AccessibleActor* actor) { int type = actor->actor->params & 0xFF; if (type == YELLOW_TALL_1 || type == YELLOW_TALL_2) { - actor->policy.aimAssist.isProvider = true; + actor->policy.aimAssist.isProvider = AIM_ALL; } if ((actor->frameCount & 31) == 0) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EV_DIAMOND_SWITCH); @@ -730,7 +730,7 @@ void ActorAccessibility_InitActors() { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EN_PO_CRY); } }); - policy.aimAssist.isProvider = true; + policy.aimAssist.isProvider = AIM_BOW; policy.aimAssist.tolerance = 50.0f; policy.n = 1; policy.ydist = 1000; @@ -738,15 +738,15 @@ void ActorAccessibility_InitActors() { ActorAccessibility_AddSupportedActor(ACTOR_BG_PO_EVENT, policy); ActorAccessibility_InitPolicy(&policy, "Poe Sister", [](AccessibleActor* actor) { if (actor->actor->category == ACTORCAT_PROP) { - actor->policy.aimAssist.isProvider = false; + actor->policy.aimAssist.isProvider = 0; } }); - policy.aimAssist.isProvider = true; + policy.aimAssist.isProvider = AIM_ALL; policy.aimAssist.tolerance = 20.0f; policy.n = 1; ActorAccessibility_AddSupportedActor(ACTOR_EN_PO_SISTERS, policy); ActorAccessibility_InitPolicy(&policy, "Lake Hylia Object", nullptr); - policy.aimAssist.isProvider = true; + policy.aimAssist.isProvider = AIM_HOOK; policy.n = 1; policy.ydist = 600; policy.distance = 600; @@ -804,7 +804,7 @@ void ActorAccessibility_InitActors() { ActorAccessibility_InitPolicy(&policy, "Statue Eye", [](AccessibleActor* actor) { actor->policy.aimAssist.isProvider = - ABS((s16)(actor->actor->yawTowardsPlayer - actor->actor->shape.rot.y)) < 0x2000; + ABS((s16)(actor->actor->yawTowardsPlayer - actor->actor->shape.rot.y)) < 0x2000 ? AIM_BOW : 0; }); policy.n = 1; policy.ydist = 500; @@ -822,7 +822,7 @@ void ActorAccessibility_InitActors() { ActorAccessibility_InitPolicy(&policy, "gold skulltula token", NA_SE_EN_NUTS_DAMAGE); ActorAccessibility_AddSupportedActor(ACTOR_EN_SI, policy); ActorAccessibility_InitPolicy(&policy, "Gold and Wall skulltulas", nullptr); - policy.aimAssist.isProvider = true; + policy.aimAssist.isProvider = AIM_ALL | AIM_CUP; policy.n = 1; policy.ydist = 500; policy.distance = 750; @@ -837,7 +837,7 @@ void ActorAccessibility_InitActors() { }); policy.ydist = 100; ActorAccessibility_AddSupportedActor(ACTOR_EN_ST, policy); - ActorAccessibility_InitPolicy(&policy, "goma larva egg", [](AccessibleActor* actor) { + ActorAccessibility_InitPolicy(&policy, "goma larva egg", [](AccessibleActor* actor) { if (actor->actor->bgCheckFlags == 0) { ActorAccessibility_PlaySoundForActor(actor, 0, NA_SE_EN_GOMA_BJR_EGG1); } @@ -890,7 +890,7 @@ void ActorAccessibility_InitActors() { } }); policy.n = 20; - policy.aimAssist.isProvider = true; + policy.aimAssist.isProvider = AIM_ALL; ActorAccessibility_AddSupportedActor(ACTOR_EN_FZ, policy); ActorAccessibility_InitPolicy(&policy, "Iron Knuckle", [](AccessibleActor* actor) { EnIk* ik = (EnIk*)actor->actor; @@ -949,7 +949,7 @@ void ActorAccessibility_InitActors() { } } }); - policy.aimAssist.isProvider = true; + policy.aimAssist.isProvider = AIM_SHOOT | AIM_CUP; policy.distance = 1000; policy.n = 1; ActorAccessibility_AddSupportedActor(ACTOR_EN_G_SWITCH, policy); @@ -1007,7 +1007,7 @@ void ActorAccessibility_InitActors() { list = ActorAccessibility_GetVirtualActorList(SCENE_LOST_WOODS, 1); temp = ActorAccessibility_AddVirtualActor(list, VA_MARKER, { 1348, 25, -25 }); - temp->policy.aimAssist.isProvider = true; + temp->policy.aimAssist.isProvider = AIM_SLING; temp->policy.distance = 700; temp->policy.n = 1; @@ -1191,8 +1191,8 @@ void ActorAccessibility_InitActors() { actor->pos = { 0, 0, 0 }; actor->sceneIndex = 0; actor->managedSoundSlots = 0; - actor->aimAssist.framesSinceAimAssist = 0; - actor->aimAssist.frequency = 10; + actor->aimFramesSinceAimAssist = 0; + actor->aimFrequency = 10; actor->policy = policy; ActorAccessibility_AddTerrainCues(actor); } diff --git a/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp b/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp index 16ae91feb..24053c037 100644 --- a/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp +++ b/soh/soh/Enhancements/accessible-actors/ActorAccessibility.cpp @@ -67,10 +67,10 @@ class AudioGlossaryData { AccessibleActorList_t accessibleActorList; AccessibleActorList_t::iterator current = accessibleActorList.begin(); bool GlossaryStarted = false; - int cooldown = 0; - int frameCount = 0; + u16 frameCount = 0; s16 currentScene = -1; s8 currentRoom = -1; + s8 cooldown = 0; }; class ActorAccessibility { @@ -85,12 +85,12 @@ class ActorAccessibility { SceneList_t sceneList; AccessibleAudioEngine* audioEngine; SfxExtractor sfxExtractor; - // Maps internal sfx to external (prerendered) resources. + // Maps internal sfx to external (prerendered) resources std::unordered_map sfxMap; - int framesUntilChime = 0; s16 currentScene = -1; s8 currentRoom = -1; bool currentRoomClear = false; + u8 framesUntilChime = 0; Vec3f prevPos = { 0, 0, 0 }; s16 prevYaw = 0; bool extractSfx = false; @@ -162,7 +162,7 @@ void ActorAccessibility_InitPolicy(ActorAccessibilityPolicy* policy, const char* policy->runsAlways = false; policy->volume = 1.0; policy->pitchModifier = 0.1; - policy->aimAssist.isProvider = false; + policy->aimAssist.isProvider = 0; policy->aimAssist.sfx = NA_SE_SY_HITPOINT_ALARM; policy->aimAssist.tolerance = 0.0; } @@ -219,8 +219,8 @@ void ActorAccessibility_TrackNewActor(Actor* actor) { accessibleActor.currentVolume = accessibleActor.policy.volume; accessibleActor.sceneIndex = 0; accessibleActor.managedSoundSlots = 0; - accessibleActor.aimAssist.framesSinceAimAssist = 32768; - accessibleActor.aimAssist.frequency = 10; + accessibleActor.aimFramesSinceAimAssist = 255; + accessibleActor.aimFrequency = 10; aa->trackedActors[actor] = accessibleActor.instanceID; aa->accessibleActorList[accessibleActor.instanceID] = accessibleActor; @@ -377,18 +377,46 @@ void ActorAccessibility_RunAccessibilityForActor(PlayState* play, AccessibleActo if (actor->policy.aimAssist.isProvider) { Player* player = GET_PLAYER(play); if ((player->stateFlags1 & PLAYER_STATE1_FIRST_PERSON) && - (player->stateFlags1 & (PLAYER_STATE1_USING_BOOMERANG | PLAYER_STATE1_ITEM_IN_HAND))) { - auto aimAssistProps = ActorAccessibility_ProvideAimAssistForActor(actor); - if (++actor->aimAssist.framesSinceAimAssist >= actor->aimAssist.frequency) { - actor->aimAssist.framesSinceAimAssist = 0; - ActorAccessibility_PlaySoundForActor(actor, 7, actor->policy.aimAssist.sfx); + ((actor->policy.aimAssist.isProvider & AIM_CUP) || + (player->stateFlags1 & (PLAYER_STATE1_USING_BOOMERANG | PLAYER_STATE1_ITEM_IN_HAND)))) { + bool aim = false; + switch (player->heldItemAction) { + case PLAYER_IA_BOW: + case PLAYER_IA_BOW_FIRE: + case PLAYER_IA_BOW_ICE: + case PLAYER_IA_BOW_LIGHT: + case PLAYER_IA_BOW_0C: + case PLAYER_IA_BOW_0D: + case PLAYER_IA_BOW_0E: + aim = actor->policy.aimAssist.isProvider & AIM_BOW; + break; + case PLAYER_IA_SLINGSHOT: + aim = actor->policy.aimAssist.isProvider & AIM_SLING; + break; + case PLAYER_IA_HOOKSHOT: + case PLAYER_IA_LONGSHOT: + aim = actor->policy.aimAssist.isProvider & AIM_HOOK; + break; + case PLAYER_IA_BOOMERANG: + aim = actor->policy.aimAssist.isProvider & AIM_BOOM; + break; + case PLAYER_IA_NONE: + aim = actor->policy.aimAssist.isProvider & AIM_CUP; + break; + } + if (aim) { + auto aimAssistProps = ActorAccessibility_ProvideAimAssistForActor(actor); + if (++actor->aimFramesSinceAimAssist >= actor->aimFrequency) { + actor->aimFramesSinceAimAssist = 0; + ActorAccessibility_PlaySoundForActor(actor, 7, actor->policy.aimAssist.sfx); + } + ActorAccessibility_SetSoundPitch(actor, 7, aimAssistProps.pitch); + ActorAccessibility_SetSoundVolume(actor, 7, aimAssistProps.volume); + ActorAccessibility_SetSoundPan(actor, 7, aimAssistProps.pan); } - ActorAccessibility_SetSoundPitch(actor, 7, aimAssistProps.pitch); - ActorAccessibility_SetSoundVolume(actor, 7, aimAssistProps.volume); - ActorAccessibility_SetSoundPan(actor, 7, aimAssistProps.pan); } else { // Make sure there's no delay the next time you draw your bow or whatever. - actor->aimAssist.framesSinceAimAssist = 32768; + actor->aimFramesSinceAimAssist = 255; } } @@ -472,7 +500,8 @@ void ActorAccessibility_GeneralHelper(PlayState* play) { ActorAccessibility_AnnounceRoomNumber(play); } - if (player->actor.wallPoly && player->actor.speedXZ > 0 && (player->yDistToLedge == 0 || player->yDistToLedge >= 79.0f)) { + if (player->actor.wallPoly && player->actor.speedXZ > 0 && + (player->yDistToLedge == 0 || player->yDistToLedge >= 79.0f)) { f32 movedsq = SQ(aa->prevPos.x - player->actor.world.pos.x) + SQ(aa->prevPos.z - player->actor.world.pos.z); if (movedsq < 0.125) { ActorAccessibility_PlaySound(nullptr, 3, NA_SE_IT_WALL_HIT_SOFT); @@ -623,8 +652,8 @@ AccessibleActor* ActorAccessibility_AddVirtualActor(VirtualActorList* list, VIRT actor.pos = where; actor.sceneIndex = 0; actor.managedSoundSlots = 0; - actor.aimAssist.framesSinceAimAssist = 0; - actor.aimAssist.frequency = 10; + actor.aimFramesSinceAimAssist = 0; + actor.aimFrequency = 10; actor.policy = *policy; VAList_t* l = (VAList_t*)list; @@ -710,9 +739,9 @@ AimAssistProps ActorAccessibility_ProvideAimAssistForActor(AccessibleActor* acto yDiff = std::max(yDiff - correction, 0); } if (yDiff > 300) { - actor->aimAssist.frequency = 30; + actor->aimFrequency = 30; } else { - actor->aimAssist.frequency = 1 + (uint8_t)(yDiff / 5); + actor->aimFrequency = 1 + (uint8_t)(yDiff / 5); } s16 yawdiff = player->yaw - Math_Atan2S(actor->pos.z - player->actor.world.pos.z, actor->pos.x - player->actor.world.pos.x); @@ -741,7 +770,7 @@ bool ActorAccessibility_InitAudio() { void ActorAccessibility_ShutdownAudio() { if (aa->isOn) { delete aa->audioEngine; - if (aa->terrainCues) { + if (aa->terrainCues) { DeleteTerrainCueState(aa->terrainCues); } aa->isOn = false; diff --git a/soh/soh/Enhancements/accessible-actors/ActorAccessibility.h b/soh/soh/Enhancements/accessible-actors/ActorAccessibility.h index b8424739a..d4a8e8569 100644 --- a/soh/soh/Enhancements/accessible-actors/ActorAccessibility.h +++ b/soh/soh/Enhancements/accessible-actors/ActorAccessibility.h @@ -8,12 +8,20 @@ typedef void (*ActorAccessibilityCallback)(AccessibleActor*); struct VirtualActorList; +#define AIM_ALL 0x0F +#define AIM_BOW 0x01 +#define AIM_SLING 0x02 +#define AIM_SHOOT 0x03 +#define AIM_HOOK 0x04 +#define AIM_BOOM 0x08 +#define AIM_CUP 0x10 + struct ActorAccessibilityPolicy { const char* englishName; - - ActorAccessibilityCallback callback; // If set, it will be called once every n frames. If null, then sfx will be - // played once every n frames. + ActorAccessibilityCallback callback; // If set, it will be called once every n frames. + // If null, then sfx will be played once every n frames. s16 sound; // The ID of a sound to play. Ignored if the callback is set. + bool runsAlways; // If set, then the distance policy is ignored. int n; // How often to run the callback in frames. f32 distance; // Maximum xz distance from player before the actor should be considered out of range. @@ -21,13 +29,11 @@ struct ActorAccessibilityPolicy { f32 pitch; f32 volume; f32 pitchModifier; - bool runsAlways; // If set, then the distance policy is ignored. // Aim assist settings. struct { - bool isProvider; // determines whether or not this actor supports aim assist. - s16 sfx; // The sound to play when this actor provides aim assist. Uses sound slot 9. - f32 tolerance; // How close to the center of the actor does Link have to aim for aim assist to consider - // it lined up. + u8 isProvider; // determines whether or not this actor supports aim assist. + s16 sfx; // The sound to play when this actor provides aim assist. Uses sound slot 9. + f32 tolerance; // How close to center of actor does Link have to aim to consider it lined up. } aimAssist; }; @@ -40,8 +46,8 @@ struct AccessibleActor { uint64_t instanceID; Actor* actor; // null for virtual actors - s16 id; // For real actors, copy actor ID. For virtual actors we have our own table of values which - // are out of range for real actors. + s16 id; // For real actors, copy actor ID. For virtual actors we have our own table of values which + // are out of range for real actors. f32 yDistToPlayer; f32 xzDistToPlayer; f32 xyzDistToPlayer; @@ -60,14 +66,9 @@ struct AccessibleActor { s16 sceneIndex; // If this actor represents a scene transition, then this will contain the destination scene index. // Zero otherwise. u8 managedSoundSlots; // These have their attenuation and panning parameters updated every frame automatically. - struct { - u16 framesSinceAimAssist; // Allows rate-based vertical aim assist. Incremented every frame for aim assist - // actors. Manually reset by aim assist provider. - u8 frequency; // How often the sound will be played. Lower frequencies indicate that Link's vertical aim is - // closer to the actor. - } aimAssist; + u8 aimFramesSinceAimAssist; // Used for rate-based vertical aim assist. + u8 aimFrequency; // How often the sound will be played. Lower frequencies indicate vertical aim is getting closer. - // Add more state as needed. ActorAccessibilityPolicy policy; // A copy, so it can be customized on a per-actor basis if needed. }; diff --git a/soh/soh/Enhancements/accessible-actors/accessibility_cues.cpp b/soh/soh/Enhancements/accessible-actors/accessibility_cues.cpp index 7e6023d8c..ed1ce973e 100644 --- a/soh/soh/Enhancements/accessible-actors/accessibility_cues.cpp +++ b/soh/soh/Enhancements/accessible-actors/accessibility_cues.cpp @@ -1364,11 +1364,13 @@ struct TerrainCueState { AccessibleActor* actor; TerrainCueDirection directions[3]; // Directly ahead of Link, 90 degrees to his left and 90 degrees to his right - TerrainCueState(AccessibleActor* actor) : actor(actor), directions{ - { actor, { 0, 0, 0 } }, - { actor, { 0, 16384, 0 } }, - { actor, { 0, -16384, 0 } }, - } {} + TerrainCueState(AccessibleActor* actor) + : actor(actor), directions{ + { actor, { 0, 0, 0 } }, + { actor, { 0, 16384, 0 } }, + { actor, { 0, -16384, 0 } }, + } { + } ~TerrainCueState() { delete actor;