Browse Source

Add proximity audio cues for potions, scrolls, and stairs

access
mojsior 2 months ago
parent
commit
0afda1e9bf
  1. 4
      Source/engine/sound_pool.hpp
  2. 62
      Source/utils/proximity_audio.cpp

4
Source/engine/sound_pool.hpp

@ -16,8 +16,11 @@ public:
WeaponItem,
ArmorItem,
GoldItem,
PotionItem,
ScrollItem,
Chest,
Door,
Stairs,
Monster,
Interact,
COUNT,
@ -55,4 +58,3 @@ private:
};
} // namespace devilution

62
Source/utils/proximity_audio.cpp

@ -25,6 +25,8 @@
#include "monster.h"
#include "objects.h"
#include "player.h"
#include "levels/trigs.h"
#include "utils/is_of.hpp"
#include "utils/screen_reader.hpp"
namespace devilution {
@ -66,6 +68,7 @@ enum class EmitterType : uint8_t {
Item = 1,
Object = 2,
Monster = 3,
Trigger = 4,
};
[[nodiscard]] constexpr uint32_t MakeEmitterId(EmitterType type, uint32_t id)
@ -73,6 +76,32 @@ enum class EmitterType : uint8_t {
return (static_cast<uint32_t>(type) << 24) | (id & 0x00FFFFFF);
}
[[nodiscard]] constexpr bool IsPotion(const Item &item)
{
switch (item._iMiscId) {
case IMISC_FULLHEAL:
case IMISC_HEAL:
case IMISC_MANA:
case IMISC_FULLMANA:
case IMISC_REJUV:
case IMISC_FULLREJUV:
case IMISC_ELIXSTR:
case IMISC_ELIXMAG:
case IMISC_ELIXDEX:
case IMISC_ELIXVIT:
case IMISC_SPECELIX:
case IMISC_ARENAPOT:
return true;
default:
return false;
}
}
[[nodiscard]] constexpr bool IsScroll(const Item &item)
{
return item._iMiscId == IMISC_SCROLL || item._iMiscId == IMISC_SCROLLT;
}
[[nodiscard]] uint32_t IntervalMsForDistance(int distance, int maxDistance, uint32_t minIntervalMs, uint32_t maxIntervalMs)
{
if (maxDistance <= 0)
@ -229,9 +258,12 @@ void EnsureNavigationSoundsLoaded(SoundPool &pool)
(void)pool.EnsureLoaded(SoundPool::SoundId::WeaponItem, { "audio\\weapon.ogg", "..\\audio\\weapon.ogg", "audio\\weapon.wav", "..\\audio\\weapon.wav", "audio\\weapon.mp3", "..\\audio\\weapon.mp3" });
(void)pool.EnsureLoaded(SoundPool::SoundId::ArmorItem, { "audio\\armor.ogg", "..\\audio\\armor.ogg", "audio\\armor.wav", "..\\audio\\armor.wav", "audio\\armor.mp3", "..\\audio\\armor.mp3" });
(void)pool.EnsureLoaded(SoundPool::SoundId::GoldItem, { "audio\\coin.ogg", "..\\audio\\coin.ogg", "audio\\coin.wav", "..\\audio\\coin.wav", "audio\\coin.mp3", "..\\audio\\coin.mp3" });
(void)pool.EnsureLoaded(SoundPool::SoundId::PotionItem, { "audio\\potion.ogg", "..\\audio\\potion.ogg", "audio\\potion.wav", "..\\audio\\potion.wav", "audio\\Potion.wav", "..\\audio\\Potion.wav", "audio\\potion.mp3", "..\\audio\\potion.mp3" });
(void)pool.EnsureLoaded(SoundPool::SoundId::ScrollItem, { "audio\\scroll.ogg", "..\\audio\\scroll.ogg", "audio\\scroll.wav", "..\\audio\\scroll.wav", "audio\\Scroll.wav", "..\\audio\\Scroll.wav", "audio\\scroll.mp3", "..\\audio\\scroll.mp3" });
(void)pool.EnsureLoaded(SoundPool::SoundId::Chest, { "audio\\chest.ogg", "..\\audio\\chest.ogg", "audio\\chest.wav", "..\\audio\\chest.wav", "audio\\chest.mp3", "..\\audio\\chest.mp3" });
(void)pool.EnsureLoaded(SoundPool::SoundId::Door, { "audio\\door.ogg", "..\\audio\\door.ogg", "audio\\door.wav", "..\\audio\\door.wav", "audio\\Door.wav", "..\\audio\\Door.wav", "audio\\door.mp3", "..\\audio\\door.mp3" });
(void)pool.EnsureLoaded(SoundPool::SoundId::Stairs, { "audio\\stairs.ogg", "..\\audio\\stairs.ogg", "audio\\stairs.wav", "..\\audio\\stairs.wav", "audio\\Stairs.wav", "..\\audio\\Stairs.wav", "audio\\stairs.mp3", "..\\audio\\stairs.mp3" });
(void)pool.EnsureLoaded(SoundPool::SoundId::Monster, { "audio\\monster.ogg", "..\\audio\\monster.ogg", "audio\\monster.wav", "..\\audio\\monster.wav", "audio\\monster.mp3", "..\\audio\\monster.mp3" });
@ -323,6 +355,15 @@ void UpdateProximityAudioCues()
case ICLASS_GOLD:
soundId = SoundPool::SoundId::GoldItem;
break;
case ICLASS_MISC:
if (IsPotion(item)) {
soundId = SoundPool::SoundId::PotionItem;
} else if (IsScroll(item)) {
soundId = SoundPool::SoundId::ScrollItem;
} else {
continue;
}
break;
default:
continue;
}
@ -374,6 +415,27 @@ void UpdateProximityAudioCues()
});
}
for (int i = 0; i < numtrigs; ++i) {
if (!IsAnyOf(trigs[i]._tmsg, WM_DIABNEXTLVL, WM_DIABPREVLVL))
continue;
if (!pool.IsLoaded(SoundPool::SoundId::Stairs))
continue;
const Point triggerPosition { trigs[i].position.x, trigs[i].position.y };
const int distance = playerPosition.ApproxDistance(triggerPosition);
if (distance > MaxCueDistanceTiles)
continue;
ConsiderCandidate(best, CandidateEmitter {
.emitterId = MakeEmitterId(EmitterType::Trigger, static_cast<uint32_t>(i)),
.sound = SoundPool::SoundId::Stairs,
.position = triggerPosition,
.distance = distance,
.intervalMs = IntervalMsForDistance(distance, MaxCueDistanceTiles, MinIntervalMs, MaxIntervalMs),
});
}
for (size_t i = 0; i < ActiveMonsterCount; i++) {
const int monsterId = static_cast<int>(ActiveMonsters[i]);
const Monster &monster = Monsters[monsterId];

Loading…
Cancel
Save