No compass while climbing. No walls while in first person. Cancel virtual actor sounds when a scene or room is left.

This commit is contained in:
Caturria 2023-08-31 01:43:49 -04:00
commit 22577029c9
3 changed files with 65 additions and 14 deletions

View file

@ -418,6 +418,7 @@ bool accessible_general_helper_init(AccessibleActor* actor) {
data->currentScene = -1;
actor->userData = data;
return true;
}
void accessible_general_helper_cleanup(AccessibleActor* actor)
@ -459,6 +460,7 @@ bool accessible_audio_compass_init(AccessibleActor* actor)
data->framesUntilChime = 0;
actor->userData = data;
return true;
}
void accessible_audio_compass_cleanup(AccessibleActor* actor)
@ -467,7 +469,7 @@ void accessible_audio_compass_cleanup(AccessibleActor* actor)
}
void accessible_audio_compass(AccessibleActor* actor) {
Player* player = GET_PLAYER(actor->play);
if (player->stateFlags1 & PLAYER_STATE1_TARGETING)
if (player->stateFlags1 & PLAYER_STATE1_TARGETING || player->stateFlags1 & PLAYER_STATE1_CLIMBING_LADDER)
return;
actor->world.pos = player->actor.world.pos;

View file

@ -69,6 +69,11 @@ class ActorAccessibility {
std::unordered_map<s16, SfxRecord> sfxMap;//Maps internal sfx to external (prerendered) resources.
std::unordered_map<std::string, SfxRecord> sampleMap;//Similar to above, but this one maps raw audio samples as opposed to SFX.
int extractSfx = 0;
s16 currentScene = -1;
s8 currentRoom = -1;
VirtualActorList* currentEverywhere = NULL;
VirtualActorList* currentSceneGlobal = NULL;
VirtualActorList* currentRoomLocal = NULL;
};
static ActorAccessibility* aa;
@ -85,6 +90,8 @@ void ActorAccessibility_OnActorInit(void* actor) {
void ActorAccessibility_OnGameFrameUpdate() {
if (gPlayState == NULL)
return;
if (!GameInteractor::IsSaveLoaded())
return;//Title screen, skip.
ActorAccessibility_RunAccessibilityForAllActors(gPlayState);
}
@ -115,9 +122,8 @@ void ActorAccessibility_OnGameStillFrozen()
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>(ActorAccessibility_OnActorInit);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorDestroy>(ActorAccessibility_OnActorDestroy);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>(ActorAccessibility_OnGameFrameUpdate);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerUpdate>(ActorAccessibility_OnGameFrameUpdate);
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameStillFrozen>(ActorAccessibility_OnGameStillFrozen);
}
void ActorAccessibility_Shutdown() {
ActorAccessibility_ShutdownAudio();
@ -341,7 +347,16 @@ int ActorAccessibility_GetRandomStartingFrameCount(int min, int max) {
actor->xyzDistToPlayer = Math_Vec3f_DistXYZ(&actor->actor->world.pos, &player->actor.world.pos);
}
void ActorAccessibility_PrepareNextAudioFrame();
void ActorAccessibility_StopAllVirtualActors(VirtualActorList* list)
{
if (list == NULL)
return;
VAList_t* val = (VAList_t*)list;
for (auto i = val->begin(); i != val->end(); i++)
ActorAccessibility_StopAllSounds((void*) &(*i));
}
void ActorAccessibility_RunAccessibilityForActor(PlayState* play, AccessibleActor* actor) {
Player* player = GET_PLAYER(play);
actor->play = play;
@ -390,13 +405,27 @@ int ActorAccessibility_GetRandomStartingFrameCount(int min, int max) {
}
void ActorAccessibility_RunAccessibilityForAllActors(PlayState* play) {
//Entirely exclude the title screen.
/*if (play->sceneNum == 81)
return;*/
Player* player = GET_PLAYER(play);
if (play->sceneNum != aa->currentScene)
{
ActorAccessibility_StopAllVirtualActors(aa->currentEverywhere);
ActorAccessibility_StopAllVirtualActors(aa->currentSceneGlobal);
ActorAccessibility_StopAllVirtualActors(aa->currentRoomLocal);
aa->currentEverywhere = ActorAccessibility_GetVirtualActorList(EVERYWHERE, 0);
aa->currentSceneGlobal = ActorAccessibility_GetVirtualActorList(play->sceneNum, -1);
aa->currentScene = play->sceneNum;
aa->currentRoomLocal = NULL;
aa->currentRoom = -1;
}
if (aa->currentRoom != play->roomCtx.curRoom.num)
{
ActorAccessibility_StopAllVirtualActors(aa->currentRoomLocal);
aa->currentRoomLocal = ActorAccessibility_GetVirtualActorList(play->sceneNum, play->roomCtx.curRoom.num);
aa->currentRoom = play->roomCtx.curRoom.num;
}
if (player->stateFlags1 & PLAYER_STATE1_IN_CUTSCENE) {
return;
}
@ -404,16 +433,16 @@ int ActorAccessibility_GetRandomStartingFrameCount(int min, int max) {
for (AccessibleActorList_t::iterator i = aa->accessibleActorList.begin(); i != aa->accessibleActorList.end(); i++)
ActorAccessibility_RunAccessibilityForActor(play, &i->second);
//Virtual actors in the "everywhere" group.
VAList_t* list = (VAList_t*)ActorAccessibility_GetVirtualActorList(EVERYWHERE, 0);
VAList_t* list = (VAList_t*)aa->currentEverywhere;
for (VAList_t::iterator i = list->begin(); i != list->end(); i++)
ActorAccessibility_RunAccessibilityForActor(play, &(*i));
//Virtual actors for the current room and scene.
list = (VAList_t*)ActorAccessibility_GetVirtualActorList(play->sceneNum, play->roomCtx.curRoom.num);
list = (VAList_t*)aa->currentRoomLocal;
for (VAList_t::iterator i = list->begin(); i != list->end(); i++)
ActorAccessibility_RunAccessibilityForActor(play, &(*i));
//Scene-global virtual actors. Most of these are automatically generated VAs from polygons, because there's no way to sort these into rooms.
list = (VAList_t*)ActorAccessibility_GetVirtualActorList(play->sceneNum, -1);
list = (VAList_t*)aa->currentSceneGlobal;
for (VAList_t::iterator i = list->begin(); i != list->end(); i++)
ActorAccessibility_RunAccessibilityForActor(play, &(*i));

View file

@ -166,12 +166,25 @@ class Decline : protected TerrainCueSound {
};
class Ledge :protected TerrainCueSound {
bool climbable;//Distinguishes between a ledge link can fall from and one he can climb up.
Vec3s probeRot;
public:
Ledge(AccessibleActor* actor, Vec3f pos, bool above = false) : TerrainCueSound(actor, pos) {
currentPitch = above? 2.0 : 0.4;
Ledge(AccessibleActor* actor, Vec3f pos, Vec3s probeRot, bool above = false) : TerrainCueSound(actor, pos) {
if (above)
currentPitch = 2.0;
climbable = above;
currentSFX = climbable ? NA_SE_EV_WOOD_BOUND : NA_SE_EV_WIND_TRAP;
shouldLoop = !climbable;
this->probeRot = probeRot;
if (!above) {
if (probeRot.y == 0)
currentPitch = 0.4;
else if (probeRot.y < 0)
currentPitch = 0.2;
else
currentPitch = 0.8;
}
play();
}
@ -421,13 +434,20 @@ class Ground : protected TerrainCueSound {
destroyCurrentSound();
new (&ledge) Ledge(actor, pos, upper);
new (&ledge) Ledge(actor, pos, relRot, upper);
currentSound = (TerrainCueSound*)&ledge;
terrainDiscovered = DISCOVERED_LEDGE;
}
// Play a sound from the position of a previously discovered wall.
void discoverWall(Vec3f pos) {
Player* player = GET_PLAYER(actor->play);
if (player->stateFlags1 & PLAYER_STATE1_FIRST_PERSON)
{
if (terrainDiscovered == DISCOVERED_WALL)
destroyCurrentSound();
return;
}
if (terrainDiscovered == DISCOVERED_WALL)
return;