From 8dfdfffd8739c641418c9f6e5e51e555a7a54d4a Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 4 Sep 2023 13:03:15 +0300 Subject: [PATCH] Use ResourcePath for audio files --- AI/Nullkiller/AIGateway.cpp | 2 +- AI/Nullkiller/AIGateway.h | 2 +- AI/VCAI/VCAI.cpp | 2 +- AI/VCAI/VCAI.h | 2 +- client/CMusicHandler.cpp | 62 +++++++++---------- client/CMusicHandler.h | 34 +++++----- client/CPlayerInterface.cpp | 19 +++--- client/CPlayerInterface.h | 2 +- client/adventureMap/CInGameConsole.cpp | 2 +- client/adventureMap/MapAudioPlayer.cpp | 8 +-- client/adventureMap/MapAudioPlayer.h | 3 +- client/adventureMap/TurnTimerWidget.cpp | 2 +- client/battle/BattleAnimationClasses.cpp | 20 +++--- client/battle/BattleAnimationClasses.h | 4 +- client/battle/BattleEffectsController.cpp | 16 ++--- client/battle/BattleEffectsController.h | 3 +- client/battle/BattleInterface.cpp | 4 +- client/battle/BattleInterfaceClasses.cpp | 8 +-- client/battle/BattleSiegeController.cpp | 2 +- client/battle/BattleStacksController.cpp | 12 ++-- client/lobby/CBonusSelection.cpp | 2 +- client/lobby/CSelectionBase.cpp | 2 +- client/mainmenu/CCampaignScreen.cpp | 6 +- client/mainmenu/CMainMenu.cpp | 2 +- client/mainmenu/CPrologEpilogVideo.cpp | 2 +- client/render/CAnimation.cpp | 2 +- include/vcmi/spells/Spell.h | 1 - lib/CCreatureHandler.cpp | 19 +++--- lib/CCreatureHandler.h | 16 ++--- lib/CGeneralTextHandler.cpp | 8 +-- lib/CTownHandler.cpp | 2 +- lib/CTownHandler.h | 2 +- lib/IGameEventsReceiver.h | 2 +- lib/JsonDetail.cpp | 4 +- lib/ObstacleHandler.h | 2 +- lib/TerrainHandler.cpp | 6 +- lib/TerrainHandler.h | 6 +- lib/battle/CObstacleInstance.cpp | 8 +-- lib/battle/CObstacleInstance.h | 6 +- lib/campaign/CampaignHandler.cpp | 8 +-- lib/campaign/CampaignHandler.h | 2 +- lib/campaign/CampaignScenarioPrologEpilog.h | 2 +- lib/campaign/CampaignState.cpp | 2 +- lib/campaign/CampaignState.h | 4 +- lib/filesystem/CFilesystemLoader.cpp | 2 +- lib/filesystem/Filesystem.cpp | 6 +- lib/filesystem/ResourcePath.cpp | 3 +- lib/filesystem/ResourcePath.h | 7 +++ .../AObjectTypeHandler.cpp | 6 +- lib/mapObjectConstructors/SObjectSounds.h | 8 ++- lib/mapObjects/CGObjectInstance.cpp | 6 +- lib/mapObjects/CGObjectInstance.h | 6 +- lib/mapping/MapFormatJson.cpp | 2 +- lib/spells/CSpellHandler.cpp | 4 +- lib/spells/CSpellHandler.h | 4 +- lib/spells/effects/Obstacle.cpp | 2 +- lib/spells/effects/Obstacle.h | 2 +- mapeditor/Animation.cpp | 2 +- test/map/CMapFormatTest.cpp | 2 +- 59 files changed, 195 insertions(+), 192 deletions(-) diff --git a/AI/Nullkiller/AIGateway.cpp b/AI/Nullkiller/AIGateway.cpp index 9ae840d4b..7257e8618 100644 --- a/AI/Nullkiller/AIGateway.cpp +++ b/AI/Nullkiller/AIGateway.cpp @@ -387,7 +387,7 @@ void AIGateway::heroCreated(const CGHeroInstance * h) NET_EVENT_HANDLER; } -void AIGateway::advmapSpellCast(const CGHeroInstance * caster, int spellID) +void AIGateway::advmapSpellCast(const CGHeroInstance * caster, SpellID spellID) { LOG_TRACE_PARAMS(logAi, "spellID '%i", spellID); NET_EVENT_HANDLER; diff --git a/AI/Nullkiller/AIGateway.h b/AI/Nullkiller/AIGateway.h index c4064f164..dd352013d 100644 --- a/AI/Nullkiller/AIGateway.h +++ b/AI/Nullkiller/AIGateway.h @@ -152,7 +152,7 @@ public: void showHillFortWindow(const CGObjectInstance * object, const CGHeroInstance * visitor) override; void playerBonusChanged(const Bonus & bonus, bool gain) override; void heroCreated(const CGHeroInstance *) override; - void advmapSpellCast(const CGHeroInstance * caster, int spellID) override; + void advmapSpellCast(const CGHeroInstance * caster, SpellID spellID) override; void showInfoDialog(EInfoWindowMode type, const std::string & text, const std::vector & components, int soundID) override; void requestRealized(PackageApplied * pa) override; void receivedResource() override; diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index 231c77cd8..3db1fa7f9 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -475,7 +475,7 @@ void VCAI::heroCreated(const CGHeroInstance * h) NET_EVENT_HANDLER; } -void VCAI::advmapSpellCast(const CGHeroInstance * caster, int spellID) +void VCAI::advmapSpellCast(const CGHeroInstance * caster, SpellID spellID) { LOG_TRACE_PARAMS(logAi, "spellID '%i", spellID); NET_EVENT_HANDLER; diff --git a/AI/VCAI/VCAI.h b/AI/VCAI/VCAI.h index ea341b4af..912f7bde2 100644 --- a/AI/VCAI/VCAI.h +++ b/AI/VCAI/VCAI.h @@ -185,7 +185,7 @@ public: void showHillFortWindow(const CGObjectInstance * object, const CGHeroInstance * visitor) override; void playerBonusChanged(const Bonus & bonus, bool gain) override; void heroCreated(const CGHeroInstance *) override; - void advmapSpellCast(const CGHeroInstance * caster, int spellID) override; + void advmapSpellCast(const CGHeroInstance * caster, SpellID spellID) override; void showInfoDialog(EInfoWindowMode type, const std::string & text, const std::vector & components, int soundID) override; void requestRealized(PackageApplied * pa) override; void receivedResource() override; diff --git a/client/CMusicHandler.cpp b/client/CMusicHandler.cpp index 0b74e73ca..65c61e933 100644 --- a/client/CMusicHandler.cpp +++ b/client/CMusicHandler.cpp @@ -119,25 +119,25 @@ void CSoundHandler::release() } // Allocate an SDL chunk and cache it. -Mix_Chunk *CSoundHandler::GetSoundChunk(std::string &sound, bool cache) +Mix_Chunk *CSoundHandler::GetSoundChunk(const AudioPath & sound, bool cache) { try { if (cache && soundChunks.find(sound) != soundChunks.end()) return soundChunks[sound].first; - auto data = CResourceHandler::get()->load(ResourcePath(std::string("SOUNDS/") + sound, EResType::SOUND))->readAll(); + auto data = CResourceHandler::get()->load(sound.addPrefix("SOUNDS/"))->readAll(); SDL_RWops *ops = SDL_RWFromMem(data.first.get(), (int)data.second); Mix_Chunk *chunk = Mix_LoadWAV_RW(ops, 1); // will free ops if (cache) - soundChunks.insert(std::pair(sound, std::make_pair (chunk, std::move (data.first)))); + soundChunks.insert({sound, std::make_pair (chunk, std::move (data.first))}); return chunk; } catch(std::exception &e) { - logGlobal->warn("Cannot get sound %s chunk: %s", sound, e.what()); + logGlobal->warn("Cannot get sound %s chunk: %s", sound.getOriginalName(), e.what()); return nullptr; } } @@ -153,7 +153,7 @@ int CSoundHandler::ambientDistToVolume(int distance) const return volume * (int)ambientConfig["volume"].Integer() / 100; } -void CSoundHandler::ambientStopSound(std::string soundId) +void CSoundHandler::ambientStopSound(const AudioPath & soundId) { stopSound(ambientChannels[soundId]); setChannelVolume(ambientChannels[soundId], volume); @@ -163,13 +163,13 @@ void CSoundHandler::ambientStopSound(std::string soundId) int CSoundHandler::playSound(soundBase::soundID soundID, int repeats) { assert(soundID < soundBase::sound_after_last); - auto sound = sounds[soundID]; - logGlobal->trace("Attempt to play sound %d with file name %s with cache", soundID, sound); + auto sound = AudioPath::builtin(sounds[soundID]); + logGlobal->trace("Attempt to play sound %d with file name %s with cache", soundID, sound.getOriginalName()); return playSound(sound, repeats, true); } -int CSoundHandler::playSound(std::string sound, int repeats, bool cache) +int CSoundHandler::playSound(const AudioPath & sound, int repeats, bool cache) { if (!initialized || sound.empty()) return -1; @@ -182,7 +182,7 @@ int CSoundHandler::playSound(std::string sound, int repeats, bool cache) channel = Mix_PlayChannel(-1, chunk, repeats); if (channel == -1) { - logGlobal->error("Unable to play sound file %s , error %s", sound, Mix_GetError()); + logGlobal->error("Unable to play sound file %s , error %s", sound.getOriginalName(), Mix_GetError()); if (!cache) Mix_FreeChunk(chunk); } @@ -290,14 +290,14 @@ int CSoundHandler::ambientGetRange() const return static_cast(ambientConfig["range"].Integer()); } -void CSoundHandler::ambientUpdateChannels(std::map soundsArg) +void CSoundHandler::ambientUpdateChannels(std::map soundsArg) { boost::mutex::scoped_lock guard(mutex); - std::vector stoppedSounds; + std::vector stoppedSounds; for(auto & pair : ambientChannels) { - const std::string & soundId = pair.first; + const auto & soundId = pair.first; const int channel = pair.second; if(!vstd::contains(soundsArg, soundId)) @@ -320,7 +320,7 @@ void CSoundHandler::ambientUpdateChannels(std::map soundsArg) for(auto & pair : soundsArg) { - const std::string & soundId = pair.first; + const auto & soundId = pair.first; const int distance = pair.second; if(!vstd::contains(ambientChannels, soundId)) @@ -372,9 +372,9 @@ CMusicHandler::CMusicHandler(): for(const ResourcePath & file : mp3files) { if(boost::algorithm::istarts_with(file.getName(), "MUSIC/Combat")) - addEntryToSet("battle", file.getName()); + addEntryToSet("battle", AudioPath::fromResource(file)); else if(boost::algorithm::istarts_with(file.getName(), "MUSIC/AITheme")) - addEntryToSet("enemy-turn", file.getName()); + addEntryToSet("enemy-turn", AudioPath::fromResource(file)); } } @@ -383,11 +383,11 @@ void CMusicHandler::loadTerrainMusicThemes() { for (const auto & terrain : CGI->terrainTypeHandler->objects) { - addEntryToSet("terrain_" + terrain->getJsonKey(), "Music/" + terrain->musicFilename); + addEntryToSet("terrain_" + terrain->getJsonKey(), terrain->musicFilename); } } -void CMusicHandler::addEntryToSet(const std::string & set, const std::string & musicURI) +void CMusicHandler::addEntryToSet(const std::string & set, const AudioPath & musicURI) { musicsSet[set].push_back(musicURI); } @@ -421,7 +421,7 @@ void CMusicHandler::release() CAudioBase::release(); } -void CMusicHandler::playMusic(const std::string & musicURI, bool loop, bool fromStart) +void CMusicHandler::playMusic(const AudioPath & musicURI, bool loop, bool fromStart) { boost::mutex::scoped_lock guard(mutex); @@ -451,7 +451,7 @@ void CMusicHandler::playMusicFromSet(const std::string & whichSet, bool loop, bo return; // in this mode - play random track from set - queueNext(this, whichSet, "", loop, fromStart); + queueNext(this, whichSet, AudioPath(), loop, fromStart); } void CMusicHandler::queueNext(std::unique_ptr queued) @@ -468,7 +468,7 @@ void CMusicHandler::queueNext(std::unique_ptr queued) } } -void CMusicHandler::queueNext(CMusicHandler *owner, const std::string & setName, const std::string & musicURI, bool looped, bool fromStart) +void CMusicHandler::queueNext(CMusicHandler *owner, const std::string & setName, const AudioPath & musicURI, bool looped, bool fromStart) { queueNext(std::make_unique(owner, setName, musicURI, looped, fromStart)); } @@ -523,7 +523,7 @@ void CMusicHandler::musicFinishedCallback() }); } -MusicEntry::MusicEntry(CMusicHandler *owner, std::string setName, std::string musicURI, bool looped, bool fromStart): +MusicEntry::MusicEntry(CMusicHandler *owner, std::string setName, const AudioPath & musicURI, bool looped, bool fromStart): owner(owner), music(nullptr), playing(false), @@ -552,16 +552,16 @@ MusicEntry::~MusicEntry() Mix_HaltMusic(); } - logGlobal->trace("Del-ing music file %s", currentName); + logGlobal->trace("Del-ing music file %s", currentName.getOriginalName()); if (music) Mix_FreeMusic(music); } -void MusicEntry::load(std::string musicURI) +void MusicEntry::load(const AudioPath & musicURI) { if (music) { - logGlobal->trace("Del-ing music file %s", currentName); + logGlobal->trace("Del-ing music file %s", currentName.getOriginalName()); Mix_FreeMusic(music); music = nullptr; } @@ -569,22 +569,22 @@ void MusicEntry::load(std::string musicURI) currentName = musicURI; music = nullptr; - logGlobal->trace("Loading music file %s", musicURI); + logGlobal->trace("Loading music file %s", musicURI.getOriginalName()); try { - auto musicFile = MakeSDLRWops(CResourceHandler::get()->load(ResourcePath(std::move(musicURI), EResType::SOUND))); + auto musicFile = MakeSDLRWops(CResourceHandler::get()->load(musicURI)); music = Mix_LoadMUS_RW(musicFile, SDL_TRUE); } catch(std::exception &e) { - logGlobal->error("Failed to load music. setName=%s\tmusicURI=%s", setName, musicURI); + logGlobal->error("Failed to load music. setName=%s\tmusicURI=%s", setName, musicURI.getOriginalName()); logGlobal->error("Exception: %s", e.what()); } if(!music) { - logGlobal->warn("Warning: Cannot open %s: %s", currentName, Mix_GetError()); + logGlobal->warn("Warning: Cannot open %s: %s", currentName.getOriginalName(), Mix_GetError()); return; } } @@ -601,7 +601,7 @@ bool MusicEntry::play() load(*iter); } - logGlobal->trace("Playing music file %s", currentName); + logGlobal->trace("Playing music file %s", currentName.getOriginalName()); if (!fromStart && owner->trackPositions.count(currentName) > 0 && owner->trackPositions[currentName] > 0) { @@ -646,7 +646,7 @@ bool MusicEntry::stop(int fade_ms) assert(startTime != uint32_t(-1)); float playDuration = (endTime - startTime + startPosition) / 1000.f; owner->trackPositions[currentName] = playDuration; - logGlobal->trace("Stopping music file %s at %f", currentName, playDuration); + logGlobal->trace("Stopping music file %s at %f", currentName.getOriginalName(), playDuration); Mix_FadeOutMusic(fade_ms); return true; @@ -664,7 +664,7 @@ bool MusicEntry::isSet(std::string set) return !setName.empty() && set == setName; } -bool MusicEntry::isTrack(std::string track) +bool MusicEntry::isTrack(const AudioPath & track) { return setName.empty() && track == currentName; } diff --git a/client/CMusicHandler.h b/client/CMusicHandler.h index a0180cd74..56e1e3d7e 100644 --- a/client/CMusicHandler.h +++ b/client/CMusicHandler.h @@ -35,15 +35,14 @@ public: class CSoundHandler: public CAudioBase { private: - //soundBase::soundID getSoundID(const std::string &fileName); //update volume on configuration change SettingsListener listener; void onVolumeChange(const JsonNode &volumeNode); using CachedChunk = std::pair>; - std::map soundChunks; + std::map soundChunks; - Mix_Chunk *GetSoundChunk(std::string &sound, bool cache); + Mix_Chunk *GetSoundChunk(const AudioPath & sound, bool cache); /// have entry for every currently active channel /// vector will be empty if callback was not set @@ -54,12 +53,12 @@ private: boost::mutex mutexCallbacks; int ambientDistToVolume(int distance) const; - void ambientStopSound(std::string soundId); + void ambientStopSound(const AudioPath & soundId); void updateChannelVolume(int channel); const JsonNode ambientConfig; - std::map ambientChannels; + std::map ambientChannels; std::map channelVolumes; void initCallback(int channel, const std::function & function); @@ -76,7 +75,7 @@ public: // Sounds int playSound(soundBase::soundID soundID, int repeats=0); - int playSound(std::string sound, int repeats=0, bool cache=false); + int playSound(const AudioPath & sound, int repeats=0, bool cache=false); int playSoundFromSet(std::vector &sound_vec); void stopSound(int handler); @@ -84,16 +83,13 @@ public: void soundFinishedCallback(int channel); int ambientGetRange() const; - void ambientUpdateChannels(std::map currentSounds); + void ambientUpdateChannels(std::map currentSounds); void ambientStopAllChannels(); // Sets std::vector battleIntroSounds; }; -// Helper //now it looks somewhat useless -#define battle_sound(creature,what_sound) creature->sounds.what_sound - class CMusicHandler; //Class for handling one music file @@ -109,16 +105,16 @@ class MusicEntry uint32_t startPosition; //if not null - set from which music will be randomly selected std::string setName; - std::string currentName; + AudioPath currentName; - void load(std::string musicURI); + void load(const AudioPath & musicURI); public: - MusicEntry(CMusicHandler *owner, std::string setName, std::string musicURI, bool looped, bool fromStart); + MusicEntry(CMusicHandler *owner, std::string setName, const AudioPath & musicURI, bool looped, bool fromStart); ~MusicEntry(); bool isSet(std::string setName); - bool isTrack(std::string trackName); + bool isTrack(const AudioPath & trackName); bool isPlaying(); bool play(); @@ -135,20 +131,20 @@ private: std::unique_ptr current; std::unique_ptr next; - void queueNext(CMusicHandler *owner, const std::string & setName, const std::string & musicURI, bool looped, bool fromStart); + void queueNext(CMusicHandler *owner, const std::string & setName, const AudioPath & musicURI, bool looped, bool fromStart); void queueNext(std::unique_ptr queued); void musicFinishedCallback(); /// map -> - std::map> musicsSet; + std::map> musicsSet; /// stored position, in seconds at which music player should resume playing this track - std::map trackPositions; + std::map trackPositions; public: CMusicHandler(); /// add entry with URI musicURI in set. Track will have ID musicID - void addEntryToSet(const std::string & set, const std::string & musicURI); + void addEntryToSet(const std::string & set, const AudioPath & musicURI); void init() override; void loadTerrainMusicThemes(); @@ -156,7 +152,7 @@ public: void setVolume(ui32 percent) override; /// play track by URI, if loop = true music will be looped - void playMusic(const std::string & musicURI, bool loop, bool fromStart); + void playMusic(const AudioPath & musicURI, bool loop, bool fromStart); /// play random track from this set void playMusicFromSet(const std::string & musicSet, bool loop, bool fromStart); /// play random track from set (musicSet, entryID) diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 8a3daf45b..e3b0c5f59 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -1657,7 +1657,7 @@ void CPlayerInterface::viewWorldMap() adventureInt->openWorldView(); } -void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellID) +void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, SpellID spellID) { EVENT_HANDLER_CALLED_BY_CLIENT; @@ -1667,8 +1667,7 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI if(spellID == SpellID::FLY || spellID == SpellID::WATER_WALK) localState->erasePath(caster); - const spells::Spell * spell = CGI->spells()->getByIndex(spellID); - auto castSoundPath = spell->getCastSound(); + auto castSoundPath = spellID.toSpell()->getCastSound(); if(!castSoundPath.empty()) CCS->soundh->playSound(castSoundPath); } @@ -1992,22 +1991,22 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path) elem.coord = h->convertFromVisitablePos(elem.coord); int soundChannel = -1; - std::string soundName; + AudioPath soundName; - auto getMovementSoundFor = [&](const CGHeroInstance * hero, int3 posPrev, int3 posNext, EPathNodeAction moveType) -> std::string + auto getMovementSoundFor = [&](const CGHeroInstance * hero, int3 posPrev, int3 posNext, EPathNodeAction moveType) -> AudioPath { if (moveType == EPathNodeAction::TELEPORT_BATTLE || moveType == EPathNodeAction::TELEPORT_BLOCKING_VISIT || moveType == EPathNodeAction::TELEPORT_NORMAL) - return ""; + return {}; if (moveType == EPathNodeAction::EMBARK || moveType == EPathNodeAction::DISEMBARK) - return ""; + return {}; if (moveType == EPathNodeAction::BLOCKING_VISIT) - return ""; + return {}; // flying movement sound if (hero->hasBonusOfType(BonusType::FLYING_MOVEMENT)) - return "HORSE10.wav"; + return AudioPath::builtin("HORSE10.wav"); auto prevTile = cb->getTile(h->convertToVisitablePos(posPrev)); auto nextTile = cb->getTile(h->convertToVisitablePos(posNext)); @@ -2073,7 +2072,7 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path) { // Start a new sound for the hero movement or let the existing one carry on. - std::string newSoundName = getMovementSoundFor(h, prevCoord, nextCoord, path.nodes[i-1].action); + AudioPath newSoundName = getMovementSoundFor(h, prevCoord, nextCoord, path.nodes[i-1].action); if(newSoundName != soundName) { diff --git a/client/CPlayerInterface.h b/client/CPlayerInterface.h index c5048637f..01cfe11af 100644 --- a/client/CPlayerInterface.h +++ b/client/CPlayerInterface.h @@ -128,7 +128,7 @@ protected: // Call-ins from server, should not be called directly, but only via void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor) override; void showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor) override; void showHillFortWindow(const CGObjectInstance *object, const CGHeroInstance *visitor) override; - void advmapSpellCast(const CGHeroInstance * caster, int spellID) override; //called when a hero casts a spell + void advmapSpellCast(const CGHeroInstance * caster, SpellID spellID) override; //called when a hero casts a spell void tileHidden(const std::unordered_set &pos) override; //called when given tiles become hidden under fog of war void tileRevealed(const std::unordered_set &pos) override; //called when fog of war disappears from given tiles void newObject(const CGObjectInstance * obj) override; diff --git a/client/adventureMap/CInGameConsole.cpp b/client/adventureMap/CInGameConsole.cpp index 8ab4aa479..8ee0145ae 100644 --- a/client/adventureMap/CInGameConsole.cpp +++ b/client/adventureMap/CInGameConsole.cpp @@ -105,7 +105,7 @@ void CInGameConsole::print(const std::string & txt) } GH.windows().totalRedraw(); // FIXME: ingame console has no parent widget set - CCS->soundh->playSound("CHAT"); + CCS->soundh->playSound(AudioPath::builtin("CHAT")); } bool CInGameConsole::captureThisKey(EShortcut key) diff --git a/client/adventureMap/MapAudioPlayer.cpp b/client/adventureMap/MapAudioPlayer.cpp index 17e8aeecb..6697d7814 100644 --- a/client/adventureMap/MapAudioPlayer.cpp +++ b/client/adventureMap/MapAudioPlayer.cpp @@ -123,9 +123,9 @@ void MapAudioPlayer::removeObject(const CGObjectInstance * obj) vstd::erase(objects[z][x][y], obj->id); } -std::vector MapAudioPlayer::getAmbientSounds(const int3 & tile) +std::vector MapAudioPlayer::getAmbientSounds(const int3 & tile) { - std::vector result; + std::vector result; for(auto & objectID : objects[tile.z][tile.x][tile.y]) { @@ -147,8 +147,8 @@ std::vector MapAudioPlayer::getAmbientSounds(const int3 & tile) void MapAudioPlayer::updateAmbientSounds() { - std::map currentSounds; - auto updateSounds = [&](const std::string& soundId, int distance) -> void + std::map currentSounds; + auto updateSounds = [&](const AudioPath& soundId, int distance) -> void { if(vstd::contains(currentSounds, soundId)) currentSounds[soundId] = std::min(currentSounds[soundId], distance); diff --git a/client/adventureMap/MapAudioPlayer.h b/client/adventureMap/MapAudioPlayer.h index 31a00e6d3..f6c752887 100644 --- a/client/adventureMap/MapAudioPlayer.h +++ b/client/adventureMap/MapAudioPlayer.h @@ -10,6 +10,7 @@ #pragma once #include "../mapView/IMapRendererObserver.h" +#include "../../lib/filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN class ObjectInstanceID; @@ -29,7 +30,7 @@ class MapAudioPlayer : public IMapObjectObserver void addObject(const CGObjectInstance * obj); void removeObject(const CGObjectInstance * obj); - std::vector getAmbientSounds(const int3 & tile); + std::vector getAmbientSounds(const int3 & tile); void updateAmbientSounds(); void updateMusic(); void update(); diff --git a/client/adventureMap/TurnTimerWidget.cpp b/client/adventureMap/TurnTimerWidget.cpp index 1530713d1..af0840755 100644 --- a/client/adventureMap/TurnTimerWidget.cpp +++ b/client/adventureMap/TurnTimerWidget.cpp @@ -77,7 +77,7 @@ void TurnTimerWidget::setTime(PlayerColor player, int time) && newTime != turnTime && notifications.count(newTime)) { - CCS->soundh->playSound(variables["notificationSound"].String()); + CCS->soundh->playSound(AudioPath::fromJson(variables["notificationSound"])); } turnTime = newTime; diff --git a/client/battle/BattleAnimationClasses.cpp b/client/battle/BattleAnimationClasses.cpp index 355b8d679..8cde61997 100644 --- a/client/battle/BattleAnimationClasses.cpp +++ b/client/battle/BattleAnimationClasses.cpp @@ -114,7 +114,7 @@ void StackActionAnimation::setGroup( ECreatureAnimType group ) currGroup = group; } -void StackActionAnimation::setSound( std::string sound ) +void StackActionAnimation::setSound( const AudioPath & sound ) { this->sound = sound; } @@ -179,7 +179,7 @@ HittedAnimation::HittedAnimation(BattleInterface & owner, const CStack * stack) : StackActionAnimation(owner, stack) { setGroup(ECreatureAnimType::HITTED); - setSound(battle_sound(stack->unitType(), wince)); + setSound(stack->unitType()->sounds.wince); logAnim->debug("Created HittedAnimation for %s", stack->getName()); } @@ -187,14 +187,14 @@ DefenceAnimation::DefenceAnimation(BattleInterface & owner, const CStack * stack : StackActionAnimation(owner, stack) { setGroup(ECreatureAnimType::DEFENCE); - setSound(battle_sound(stack->unitType(), defend)); + setSound(stack->unitType()->sounds.defend); logAnim->debug("Created DefenceAnimation for %s", stack->getName()); } DeathAnimation::DeathAnimation(BattleInterface & owner, const CStack * stack, bool ranged): StackActionAnimation(owner, stack) { - setSound(battle_sound(stack->unitType(), killed)); + setSound(stack->unitType()->sounds.killed); if(ranged && myAnim->framesInGroup(ECreatureAnimType::DEATH_RANGED) > 0) setGroup(ECreatureAnimType::DEATH_RANGED); @@ -315,7 +315,7 @@ MeleeAttackAnimation::MeleeAttackAnimation(BattleInterface & owner, const CStack : AttackAnimation(owner, attacker, _dest, _attacked) { logAnim->debug("Created MeleeAttackAnimation for %s", attacker->getName()); - setSound(battle_sound(getCreature(), attack)); + setSound(getCreature()->sounds.attack); setGroup(selectGroup(multiAttack)); } @@ -356,7 +356,7 @@ bool MovementAnimation::init() if (moveSoundHander == -1) { - moveSoundHander = CCS->soundh->playSound(battle_sound(stack->unitType(), move), -1); + moveSoundHander = CCS->soundh->playSound(stack->unitType()->sounds.move, -1); } Point begPosition = owner.stacksController->getStackPositionAtHex(prevHex, stack); @@ -453,7 +453,7 @@ bool MovementEndAnimation::init() logAnim->debug("CMovementEndAnimation::init: stack %s", stack->getName()); myAnim->pos.moveTo(owner.stacksController->getStackPositionAtHex(nextHex, stack)); - CCS->soundh->playSound(battle_sound(stack->unitType(), endMoving)); + CCS->soundh->playSound(stack->unitType()->sounds.endMoving); if(!myAnim->framesInGroup(ECreatureAnimType::MOVE_END)) { @@ -494,7 +494,7 @@ bool MovementStartAnimation::init() } logAnim->debug("CMovementStartAnimation::init: stack %s", stack->getName()); - CCS->soundh->playSound(battle_sound(stack->unitType(), startMoving)); + CCS->soundh->playSound(stack->unitType()->sounds.startMoving); if(!myAnim->framesInGroup(ECreatureAnimType::MOVE_START)) { @@ -632,7 +632,7 @@ RangedAttackAnimation::RangedAttackAnimation(BattleInterface & owner_, const CSt : AttackAnimation(owner_, attacker, dest_, defender), projectileEmitted(false) { - setSound(battle_sound(getCreature(), shoot)); + setSound(getCreature()->sounds.shoot); } bool RangedAttackAnimation::init() @@ -806,7 +806,7 @@ void CatapultAnimation::tick(uint32_t msPassed) explosionEmitted = true; Point shotTarget = owner.stacksController->getStackPositionAtHex(dest, defendingStack) + Point(225, 225) - Point(126, 105); - std::string soundFilename = (catapultDamage > 0) ? "WALLHIT" : "WALLMISS"; + auto soundFilename = AudioPath::builtin((catapultDamage > 0) ? "WALLHIT" : "WALLMISS"); AnimationPath effectFilename = AnimationPath::builtin((catapultDamage > 0) ? "SGEXPL" : "CSGRCK"); CCS->soundh->playSound( soundFilename ); diff --git a/client/battle/BattleAnimationClasses.h b/client/battle/BattleAnimationClasses.h index 93ff9c3df..11fd827a8 100644 --- a/client/battle/BattleAnimationClasses.h +++ b/client/battle/BattleAnimationClasses.h @@ -69,11 +69,11 @@ class StackActionAnimation : public BattleStackAnimation { ECreatureAnimType nextGroup; ECreatureAnimType currGroup; - std::string sound; + AudioPath sound; public: void setNextGroup( ECreatureAnimType group ); void setGroup( ECreatureAnimType group ); - void setSound( std::string sound ); + void setSound( const AudioPath & sound ); ECreatureAnimType getGroup() const; diff --git a/client/battle/BattleEffectsController.cpp b/client/battle/BattleEffectsController.cpp index 178b15196..fb64fbfc8 100644 --- a/client/battle/BattleEffectsController.cpp +++ b/client/battle/BattleEffectsController.cpp @@ -41,10 +41,10 @@ BattleEffectsController::BattleEffectsController(BattleInterface & owner): void BattleEffectsController::displayEffect(EBattleEffect effect, const BattleHex & destTile) { - displayEffect(effect, "", destTile); + displayEffect(effect, AudioPath(), destTile); } -void BattleEffectsController::displayEffect(EBattleEffect effect, std::string soundFile, const BattleHex & destTile) +void BattleEffectsController::displayEffect(EBattleEffect effect, const AudioPath & soundFile, const BattleHex & destTile) { size_t effectID = static_cast(effect); @@ -69,22 +69,22 @@ void BattleEffectsController::battleTriggerEffect(const BattleTriggerEffect & bt switch(static_cast(bte.effect)) { case BonusType::HP_REGENERATION: - displayEffect(EBattleEffect::REGENERATION, "REGENER", stack->getPosition()); + displayEffect(EBattleEffect::REGENERATION, AudioPath::builtin("REGENER"), stack->getPosition()); break; case BonusType::MANA_DRAIN: - displayEffect(EBattleEffect::MANA_DRAIN, "MANADRAI", stack->getPosition()); + displayEffect(EBattleEffect::MANA_DRAIN, AudioPath::builtin("MANADRAI"), stack->getPosition()); break; case BonusType::POISON: - displayEffect(EBattleEffect::POISON, "POISON", stack->getPosition()); + displayEffect(EBattleEffect::POISON, AudioPath::builtin("POISON"), stack->getPosition()); break; case BonusType::FEAR: - displayEffect(EBattleEffect::FEAR, "FEAR", stack->getPosition()); + displayEffect(EBattleEffect::FEAR, AudioPath::builtin("FEAR"), stack->getPosition()); break; case BonusType::MORALE: { std::string hlp = CGI->generaltexth->allTexts[33]; boost::algorithm::replace_first(hlp,"%s",(stack->getName())); - displayEffect(EBattleEffect::GOOD_MORALE, "GOODMRLE", stack->getPosition()); + displayEffect(EBattleEffect::GOOD_MORALE, AudioPath::builtin("GOODMRLE"), stack->getPosition()); owner.appendBattleLog(hlp); break; } @@ -107,7 +107,7 @@ void BattleEffectsController::startAction(const BattleAction & action) break; case EActionType::BAD_MORALE: owner.appendBattleLog(stack->formatGeneralMessage(-34)); - displayEffect(EBattleEffect::BAD_MORALE, "BADMRLE", stack->getPosition()); + displayEffect(EBattleEffect::BAD_MORALE, AudioPath::builtin("BADMRLE"), stack->getPosition()); break; } diff --git a/client/battle/BattleEffectsController.h b/client/battle/BattleEffectsController.h index 3ea1452b4..203a121fd 100644 --- a/client/battle/BattleEffectsController.h +++ b/client/battle/BattleEffectsController.h @@ -11,6 +11,7 @@ #include "../../lib/battle/BattleHex.h" #include "../../lib/Point.h" +#include "../../lib/filesystem/ResourcePath.h" #include "BattleConstants.h" VCMI_LIB_NAMESPACE_BEGIN @@ -64,7 +65,7 @@ public: //displays custom effect on the battlefield void displayEffect(EBattleEffect effect, const BattleHex & destTile); - void displayEffect(EBattleEffect effect, std::string soundFile, const BattleHex & destTile); + void displayEffect(EBattleEffect effect, const AudioPath & soundFile, const BattleHex & destTile); void battleTriggerEffect(const BattleTriggerEffect & bte); diff --git a/client/battle/BattleInterface.cpp b/client/battle/BattleInterface.cpp index 8db671a94..6729e4a1a 100644 --- a/client/battle/BattleInterface.cpp +++ b/client/battle/BattleInterface.cpp @@ -353,7 +353,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc) if(!spell) return; - const std::string & castSoundPath = spell->getCastSound(); + const AudioPath & castSoundPath = spell->getCastSound(); if (!castSoundPath.empty()) { @@ -419,7 +419,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc) if (!sc->resistedCres.empty()) { addToAnimationStage(EAnimationEvents::HIT, [=](){ - CCS->soundh->playSound("MAGICRES"); + CCS->soundh->playSound(AudioPath::builtin("MAGICRES")); }); } diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 937d6ca0e..971d94d46 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -580,7 +580,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface break; } - CCS->musich->playMusic("Music/Win Battle", false, true); + CCS->musich->playMusic(AudioPath::builtin("Music/Win Battle"), false, true); CCS->videoh->open(VideoPath::builtin("WIN3.BIK")); std::string str = CGI->generaltexth->allTexts[text]; @@ -597,19 +597,19 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface else // we lose { int text = 311; - std::string musicName = "Music/LoseCombat"; + AudioPath musicName = AudioPath::builtin("Music/LoseCombat"); VideoPath videoName = VideoPath::builtin("LBSTART.BIK"); switch(br.result) { case EBattleResult::NORMAL: break; case EBattleResult::ESCAPE: - musicName = "Music/Retreat Battle"; + musicName = AudioPath::builtin("Music/Retreat Battle"); videoName = VideoPath::builtin("RTSTART.BIK"); text = 310; break; case EBattleResult::SURRENDER: - musicName = "Music/Surrender Battle"; + musicName = AudioPath::builtin("Music/Surrender Battle"); videoName = VideoPath::builtin("SURRENDER.BIK"); text = 309; break; diff --git a/client/battle/BattleSiegeController.cpp b/client/battle/BattleSiegeController.cpp index 3b88b75f4..7bb7a908f 100644 --- a/client/battle/BattleSiegeController.cpp +++ b/client/battle/BattleSiegeController.cpp @@ -340,7 +340,7 @@ void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca) for (auto attackInfo : ca.attackedParts) positions.push_back(owner.stacksController->getStackPositionAtHex(attackInfo.destinationTile, nullptr) + Point(99, 120)); - CCS->soundh->playSound( "WALLHIT" ); + CCS->soundh->playSound( AudioPath::builtin("WALLHIT") ); owner.stacksController->addNewAnim(new EffectAnimation(owner, AnimationPath::builtin("SGEXPL.DEF"), positions)); } diff --git a/client/battle/BattleStacksController.cpp b/client/battle/BattleStacksController.cpp index 32c401612..e9c255187 100644 --- a/client/battle/BattleStacksController.cpp +++ b/client/battle/BattleStacksController.cpp @@ -462,7 +462,7 @@ void BattleStacksController::stacksAreAttacked(std::vector at addNewAnim(new HittedAnimation(owner, attackedInfo.defender)); if (attackedInfo.fireShield) - owner.effectsController->displayEffect(EBattleEffect::FIRE_SHIELD, "FIRESHIE", attackedInfo.attacker->getPosition()); + owner.effectsController->displayEffect(EBattleEffect::FIRE_SHIELD, AudioPath::builtin("FIRESHIE"), attackedInfo.attacker->getPosition()); if (attackedInfo.spellEffect != SpellID::NONE) { @@ -481,7 +481,7 @@ void BattleStacksController::stacksAreAttacked(std::vector at if (attackedInfo.rebirth) { owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [=](){ - owner.effectsController->displayEffect(EBattleEffect::RESURRECT, "RESURECT", attackedInfo.defender->getPosition()); + owner.effectsController->displayEffect(EBattleEffect::RESURRECT, AudioPath::builtin("RESURECT"), attackedInfo.defender->getPosition()); addNewAnim(new ResurrectionAnimation(owner, attackedInfo.defender)); }); } @@ -594,7 +594,7 @@ void BattleStacksController::stackAttacking( const StackAttackInfo & info ) { owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]() { owner.appendBattleLog(info.attacker->formatGeneralMessage(-45)); - owner.effectsController->displayEffect(EBattleEffect::GOOD_LUCK, "GOODLUCK", attacker->getPosition()); + owner.effectsController->displayEffect(EBattleEffect::GOOD_LUCK, AudioPath::builtin("GOODLUCK"), attacker->getPosition()); }); } @@ -602,7 +602,7 @@ void BattleStacksController::stackAttacking( const StackAttackInfo & info ) { owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]() { owner.appendBattleLog(info.attacker->formatGeneralMessage(-44)); - owner.effectsController->displayEffect(EBattleEffect::BAD_LUCK, "BADLUCK", attacker->getPosition()); + owner.effectsController->displayEffect(EBattleEffect::BAD_LUCK, AudioPath::builtin("BADLUCK"), attacker->getPosition()); }); } @@ -610,7 +610,7 @@ void BattleStacksController::stackAttacking( const StackAttackInfo & info ) { owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]() { owner.appendBattleLog(info.attacker->formatGeneralMessage(365)); - owner.effectsController->displayEffect(EBattleEffect::DEATH_BLOW, "DEATHBLO", defender->getPosition()); + owner.effectsController->displayEffect(EBattleEffect::DEATH_BLOW, AudioPath::builtin("DEATHBLO"), defender->getPosition()); }); for(auto elem : info.secondaryDefender) @@ -645,7 +645,7 @@ void BattleStacksController::stackAttacking( const StackAttackInfo & info ) { owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [=]() { - owner.effectsController->displayEffect(EBattleEffect::DRAIN_LIFE, "DRAINLIF", attacker->getPosition()); + owner.effectsController->displayEffect(EBattleEffect::DRAIN_LIFE, AudioPath::builtin("DRAINLIF"), attacker->getPosition()); }); } diff --git a/client/lobby/CBonusSelection.cpp b/client/lobby/CBonusSelection.cpp index 4fa6a65b2..526370897 100644 --- a/client/lobby/CBonusSelection.cpp +++ b/client/lobby/CBonusSelection.cpp @@ -114,7 +114,7 @@ CBonusSelection::CBonusSelection() } if (!getCampaign()->getMusic().empty()) - CCS->musich->playMusic( "Music/" + getCampaign()->getMusic(), true, false); + CCS->musich->playMusic( getCampaign()->getMusic(), true, false); } void CBonusSelection::createBonusesIcons() diff --git a/client/lobby/CSelectionBase.cpp b/client/lobby/CSelectionBase.cpp index 4c3fbbf4a..1eb555d65 100644 --- a/client/lobby/CSelectionBase.cpp +++ b/client/lobby/CSelectionBase.cpp @@ -339,7 +339,7 @@ void CChatBox::keyPressed(EShortcut key) void CChatBox::addNewMessage(const std::string & text) { - CCS->soundh->playSound("CHAT"); + CCS->soundh->playSound(AudioPath::builtin("CHAT")); chatHistory->setText(chatHistory->label->getText() + text + "\n"); if(chatHistory->slider) chatHistory->slider->scrollToMax(); diff --git a/client/mainmenu/CCampaignScreen.cpp b/client/mainmenu/CCampaignScreen.cpp index b7922003b..45708a64b 100644 --- a/client/mainmenu/CCampaignScreen.cpp +++ b/client/mainmenu/CCampaignScreen.cpp @@ -75,7 +75,7 @@ CCampaignScreen::CCampaignScreen(const JsonNode & config) void CCampaignScreen::activate() { - CCS->musich->playMusic("Music/MainMenu", true, false); + CCS->musich->playMusic(AudioPath::builtin("Music/MainMenu"), true, false); CWindowObject::activate(); } @@ -129,12 +129,12 @@ void CCampaignScreen::CCampaignButton::show(Canvas & to) // Play the campaign button video when the mouse cursor is placed over the button if(isHovered()) { - if(CCS->videoh->fname != video) + if(CCS->videoh->fname != video.addPrefix("VIDEO/")) CCS->videoh->open(video); CCS->videoh->update(pos.x, pos.y, to.getInternalSurface(), true, false); // plays sequentially frame by frame, starts at the beginning when the video is over } - else if(CCS->videoh->fname == video) // When you got out of the bounds of the button then close the video + else if(CCS->videoh->fname == video.addPrefix("VIDEO/")) // When you got out of the bounds of the button then close the video { CCS->videoh->close(); redraw(); diff --git a/client/mainmenu/CMainMenu.cpp b/client/mainmenu/CMainMenu.cpp index 6a8d226c1..0327ff4ac 100644 --- a/client/mainmenu/CMainMenu.cpp +++ b/client/mainmenu/CMainMenu.cpp @@ -114,7 +114,7 @@ void CMenuScreen::show(Canvas & to) void CMenuScreen::activate() { - CCS->musich->playMusic("Music/MainMenu", true, true); + CCS->musich->playMusic(AudioPath::builtin("Music/MainMenu"), true, true); if(!config["video"].isNull()) CCS->videoh->open(VideoPath::fromJson(config["video"]["name"])); CIntObject::activate(); diff --git a/client/mainmenu/CPrologEpilogVideo.cpp b/client/mainmenu/CPrologEpilogVideo.cpp index e4db4fc94..b8b7ab49e 100644 --- a/client/mainmenu/CPrologEpilogVideo.cpp +++ b/client/mainmenu/CPrologEpilogVideo.cpp @@ -28,7 +28,7 @@ CPrologEpilogVideo::CPrologEpilogVideo(CampaignScenarioPrologEpilog _spe, std::f updateShadow(); CCS->videoh->open(spe.prologVideo); - CCS->musich->playMusic("Music/" + spe.prologMusic, true, true); + CCS->musich->playMusic(spe.prologMusic, true, true); // MPTODO: Custom campaign crashing on this? // voiceSoundHandle = CCS->soundh->playSound(CCampaignHandler::prologVoiceName(spe.prologVideo)); diff --git a/client/render/CAnimation.cpp b/client/render/CAnimation.cpp index 6d2a20f7a..947cce37f 100644 --- a/client/render/CAnimation.cpp +++ b/client/render/CAnimation.cpp @@ -182,7 +182,7 @@ void CAnimation::init() if (vstd::contains(graphics->imageLists, name.getName())) initFromJson(graphics->imageLists[name.getName()]); - auto jsonResource = name.toType(); + auto jsonResource = name.toType(); auto configList = CResourceHandler::get()->getResourcesWithName(jsonResource); for(auto & loader : configList) diff --git a/include/vcmi/spells/Spell.h b/include/vcmi/spells/Spell.h index 38a9a247b..60e7b8023 100644 --- a/include/vcmi/spells/Spell.h +++ b/include/vcmi/spells/Spell.h @@ -45,7 +45,6 @@ public: virtual bool hasSchool(SpellSchool school) const = 0; virtual void forEachSchool(const SchoolCallback & cb) const = 0; - virtual const std::string & getCastSound() const = 0; virtual int32_t getCost(const int32_t skillLevel) const = 0; virtual int32_t getBasePower() const = 0; diff --git a/lib/CCreatureHandler.cpp b/lib/CCreatureHandler.cpp index 10b293f0a..86074a4f9 100644 --- a/lib/CCreatureHandler.cpp +++ b/lib/CCreatureHandler.cpp @@ -955,17 +955,14 @@ void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & c creature->special = config["special"].Bool() || config["disabled"].Bool(); const JsonNode & sounds = config["sound"]; - -#define GET_SOUND_VALUE(value_name) creature->sounds.value_name = sounds[#value_name].String() - GET_SOUND_VALUE(attack); - GET_SOUND_VALUE(defend); - GET_SOUND_VALUE(killed); - GET_SOUND_VALUE(move); - GET_SOUND_VALUE(shoot); - GET_SOUND_VALUE(wince); - GET_SOUND_VALUE(startMoving); - GET_SOUND_VALUE(endMoving); -#undef GET_SOUND_VALUE + creature->sounds.attack = AudioPath::fromJson(sounds["attack"]); + creature->sounds.defend = AudioPath::fromJson(sounds["defend"]); + creature->sounds.killed = AudioPath::fromJson(sounds["killed"]); + creature->sounds.move = AudioPath::fromJson(sounds["move"]); + creature->sounds.shoot = AudioPath::fromJson(sounds["shoot"]); + creature->sounds.wince = AudioPath::fromJson(sounds["wince"]); + creature->sounds.startMoving = AudioPath::fromJson(sounds["startMoving"]); + creature->sounds.endMoving = AudioPath::fromJson(sounds["endMoving"]); } void CCreatureHandler::loadStackExperience(CCreature * creature, const JsonNode & input) const diff --git a/lib/CCreatureHandler.h b/lib/CCreatureHandler.h index f1dee53ca..b6cc5b11f 100644 --- a/lib/CCreatureHandler.h +++ b/lib/CCreatureHandler.h @@ -132,14 +132,14 @@ public: //sound info struct CreatureBattleSounds { - std::string attack; - std::string defend; - std::string killed; // was killed or died - std::string move; - std::string shoot; // range attack - std::string wince; // attacked but did not die - std::string startMoving; - std::string endMoving; + AudioPath attack; + AudioPath defend; + AudioPath killed; // was killed or died + AudioPath move; + AudioPath shoot; // range attack + AudioPath wince; // attacked but did not die + AudioPath startMoving; + AudioPath endMoving; template void serialize(Handler &h, const int version) { diff --git a/lib/CGeneralTextHandler.cpp b/lib/CGeneralTextHandler.cpp index e11a3e903..3e54d7cf7 100644 --- a/lib/CGeneralTextHandler.cpp +++ b/lib/CGeneralTextHandler.cpp @@ -48,7 +48,7 @@ void CGeneralTextHandler::detectInstallParameters() "ukrainian" } }; - if(!CResourceHandler::get("core")->existsResource(ResourcePath("DATA/GENRLTXT.TXT", EResType::TEXT))) + if(!CResourceHandler::get("core")->existsResource(TextPath::builtin("DATA/GENRLTXT.TXT"))) { Settings language = settings.write["session"]["language"]; language->String() = "english"; @@ -64,7 +64,7 @@ void CGeneralTextHandler::detectInstallParameters() // load file that will be used for footprint generation // this is one of the most text-heavy files in game and consists solely from translated texts - auto resource = CResourceHandler::get("core")->load(ResourcePath("DATA/GENRLTXT.TXT", EResType::TEXT)); + auto resource = CResourceHandler::get("core")->load(TextPath::builtin("DATA/GENRLTXT.TXT")); std::array charCount{}; std::array footprint{}; @@ -429,7 +429,7 @@ CGeneralTextHandler::CGeneralTextHandler(): readToVector("core.mineevnt", "DATA/MINEEVNT.TXT" ); static const char * QE_MOD_COMMANDS = "DATA/QECOMMANDS.TXT"; - if (CResourceHandler::get()->existsResource(ResourcePath(QE_MOD_COMMANDS, EResType::TEXT))) + if (CResourceHandler::get()->existsResource(TextPath::builtin(QE_MOD_COMMANDS))) readToVector("vcmi.quickExchange", QE_MOD_COMMANDS); { @@ -574,7 +574,7 @@ CGeneralTextHandler::CGeneralTextHandler(): } if (VLC->settings()->getBoolean(EGameSettings::MODULE_COMMANDERS)) { - if(CResourceHandler::get()->existsResource(ResourcePath("DATA/ZNPC00.TXT", EResType::TEXT))) + if(CResourceHandler::get()->existsResource(TextPath::builtin("DATA/ZNPC00.TXT"))) readToVector("vcmi.znpc00", "DATA/ZNPC00.TXT" ); } } diff --git a/lib/CTownHandler.cpp b/lib/CTownHandler.cpp index 3268b20f5..b5d2fcec9 100644 --- a/lib/CTownHandler.cpp +++ b/lib/CTownHandler.cpp @@ -878,7 +878,7 @@ void CTownHandler::loadClientData(CTown &town, const JsonNode & source) const readIcon(source["icons"]["fort"]["built"], info.iconSmall[1][1], info.iconLarge[1][1]); info.hallBackground = ImagePath::fromJson(source["hallBackground"]); - info.musicTheme = source["musicTheme"].String(); + info.musicTheme = AudioPath::fromJson(source["musicTheme"]); info.townBackground = ImagePath::fromJson(source["townBackground"]); info.guildWindow = ImagePath::fromJson(source["guildWindow"]); info.buildingsIcons = AnimationPath::fromJson(source["buildingsIcons"]); diff --git a/lib/CTownHandler.h b/lib/CTownHandler.h index bb24808b9..01c8c5dbe 100644 --- a/lib/CTownHandler.h +++ b/lib/CTownHandler.h @@ -305,7 +305,7 @@ public: std::string iconSmall[2][2]; /// icon names used during loading std::string iconLarge[2][2]; VideoPath tavernVideo; - std::string musicTheme; + AudioPath musicTheme; ImagePath townBackground; ImagePath guildBackground; ImagePath guildWindow; diff --git a/lib/IGameEventsReceiver.h b/lib/IGameEventsReceiver.h index a19c9f11e..ebce9c261 100644 --- a/lib/IGameEventsReceiver.h +++ b/lib/IGameEventsReceiver.h @@ -116,7 +116,7 @@ public: virtual void showTavernWindow(const CGObjectInstance *townOrTavern){}; virtual void showThievesGuildWindow (const CGObjectInstance * obj){}; virtual void showQuestLog(){}; - virtual void advmapSpellCast(const CGHeroInstance * caster, int spellID){}; //called when a hero casts a spell + virtual void advmapSpellCast(const CGHeroInstance * caster, SpellID spellID){}; //called when a hero casts a spell virtual void tileHidden(const std::unordered_set &pos){}; virtual void tileRevealed(const std::unordered_set &pos){}; virtual void newObject(const CGObjectInstance * obj){}; //eg. ship built in shipyard diff --git a/lib/JsonDetail.cpp b/lib/JsonDetail.cpp index ce1b2a96d..a395fe4b8 100644 --- a/lib/JsonDetail.cpp +++ b/lib/JsonDetail.cpp @@ -1036,13 +1036,13 @@ namespace std::string testAnimation(const std::string & path, const std::string & scope) { TEST_FILE(scope, "Sprites/", path, EResType::ANIMATION); - TEST_FILE(scope, "Sprites/", path, EResType::TEXT); + TEST_FILE(scope, "Sprites/", path, EResType::JSON); return "Animation file \"" + path + "\" was not found"; } std::string textFile(const JsonNode & node) { - TEST_FILE(node.meta, "", node.String(), EResType::TEXT); + TEST_FILE(node.meta, "", node.String(), EResType::JSON); return "Text file \"" + node.String() + "\" was not found"; } diff --git a/lib/ObstacleHandler.h b/lib/ObstacleHandler.h index d5b2ab3f0..958e46e62 100644 --- a/lib/ObstacleHandler.h +++ b/lib/ObstacleHandler.h @@ -32,7 +32,7 @@ public: Obstacle obstacle; si32 iconIndex; std::string identifier; - std::string appearSound; + AudioPath appearSound; AnimationPath appearAnimation; AnimationPath animation; std::vector allowedTerrains; diff --git a/lib/TerrainHandler.cpp b/lib/TerrainHandler.cpp index 0c8ce487f..a6050cb40 100644 --- a/lib/TerrainHandler.cpp +++ b/lib/TerrainHandler.cpp @@ -27,10 +27,10 @@ TerrainType * TerrainTypeHandler::loadFromJson( const std::string & scope, const info->identifier = identifier; info->modScope = scope; info->moveCost = static_cast(json["moveCost"].Integer()); - info->musicFilename = json["music"].String(); + info->musicFilename = AudioPath::fromJson(json["music"]); info->tilesFilename = AnimationPath::fromJson(json["tiles"]); - info->horseSound = json["horseSound"].String(); - info->horseSoundPenalty = json["horseSoundPenalty"].String(); + info->horseSound = AudioPath::fromJson(json["horseSound"]); + info->horseSoundPenalty = AudioPath::fromJson(json["horseSoundPenalty"]); info->transitionRequired = json["transitionRequired"].Bool(); info->terrainViewPatterns = json["terrainViewPatterns"].String(); diff --git a/lib/TerrainHandler.h b/lib/TerrainHandler.h index fa7623136..7455a0cbe 100644 --- a/lib/TerrainHandler.h +++ b/lib/TerrainHandler.h @@ -67,11 +67,11 @@ public: ColorRGBA minimapBlocked; ColorRGBA minimapUnblocked; std::string shortIdentifier; - std::string musicFilename; + AudioPath musicFilename; AnimationPath tilesFilename; std::string terrainViewPatterns; - std::string horseSound; - std::string horseSoundPenalty; + AudioPath horseSound; + AudioPath horseSoundPenalty; std::vector paletteAnimation; diff --git a/lib/battle/CObstacleInstance.cpp b/lib/battle/CObstacleInstance.cpp index e1de4b984..729409727 100644 --- a/lib/battle/CObstacleInstance.cpp +++ b/lib/battle/CObstacleInstance.cpp @@ -70,7 +70,7 @@ const AnimationPath & CObstacleInstance::getAppearAnimation() const return getInfo().appearAnimation; } -const std::string & CObstacleInstance::getAppearSound() const +const AudioPath & CObstacleInstance::getAppearSound() const { return getInfo().appearSound; } @@ -118,7 +118,7 @@ void CObstacleInstance::serializeJson(JsonSerializeFormat & handler) //We need only a subset of obstacle info for correct render handler.serializeInt("position", pos); - handler.serializeString("appearSound", obstacleInfo.appearSound); + handler.serializeStruct("appearSound", obstacleInfo.appearSound); handler.serializeStruct("appearAnimation", obstacleInfo.appearAnimation); handler.serializeStruct("animation", obstacleInfo.animation); handler.serializeInt("animationYOffset", animationYOffset); @@ -213,7 +213,7 @@ void SpellCreatedObstacle::serializeJson(JsonSerializeFormat & handler) handler.serializeBool("removeOnTrigger", removeOnTrigger); handler.serializeBool("nativeVisible", nativeVisible); - handler.serializeString("appearSound", appearSound); + handler.serializeStruct("appearSound", appearSound); handler.serializeStruct("appearAnimation", appearAnimation); handler.serializeStruct("animation", animation); @@ -249,7 +249,7 @@ const AnimationPath & SpellCreatedObstacle::getAppearAnimation() const return appearAnimation; } -const std::string & SpellCreatedObstacle::getAppearSound() const +const AudioPath & SpellCreatedObstacle::getAppearSound() const { return appearSound; } diff --git a/lib/battle/CObstacleInstance.h b/lib/battle/CObstacleInstance.h index 0d74d95fd..b3759d8c4 100644 --- a/lib/battle/CObstacleInstance.h +++ b/lib/battle/CObstacleInstance.h @@ -54,7 +54,7 @@ struct DLL_LINKAGE CObstacleInstance //Client helper functions, make it easier to render animations virtual const AnimationPath & getAnimation() const; virtual const AnimationPath & getAppearAnimation() const; - virtual const std::string & getAppearSound() const; + virtual const AudioPath & getAppearSound() const; virtual int getAnimationYOffset(int imageHeight) const; @@ -88,7 +88,7 @@ struct DLL_LINKAGE SpellCreatedObstacle : CObstacleInstance bool revealed; bool nativeVisible; //Should native terrain creatures reveal obstacle - std::string appearSound; + AudioPath appearSound; AnimationPath appearAnimation; AnimationPath animation; @@ -110,7 +110,7 @@ struct DLL_LINKAGE SpellCreatedObstacle : CObstacleInstance //Client helper functions, make it easier to render animations const AnimationPath & getAnimation() const override; const AnimationPath & getAppearAnimation() const override; - const std::string & getAppearSound() const override; + const AudioPath & getAppearSound() const override; int getAnimationYOffset(int imageHeight) const override; void fromInfo(const ObstacleChanges & info); diff --git a/lib/campaign/CampaignHandler.cpp b/lib/campaign/CampaignHandler.cpp index fb6dc65da..ab2cc63c5 100644 --- a/lib/campaign/CampaignHandler.cpp +++ b/lib/campaign/CampaignHandler.cpp @@ -152,7 +152,7 @@ void CampaignHandler::readHeaderFromJson(CampaignHeader & ret, JsonNode & reader ret.name = reader["name"].String(); ret.description = reader["description"].String(); ret.difficultyChoosenByPlayer = reader["allowDifficultySelection"].Bool(); - ret.music = reader["music"].String(); + ret.music = AudioPath::fromJson(reader["music"]); ret.filename = filename; ret.modName = modName; ret.encoding = encoding; @@ -167,7 +167,7 @@ CampaignScenario CampaignHandler::readScenarioFromJson(JsonNode & reader) if(ret.hasPrologEpilog) { ret.prologVideo = VideoPath::fromJson(identifier["video"]); - ret.prologMusic = identifier["music"].String(); + ret.prologMusic = AudioPath::fromJson(identifier["music"]); ret.prologText = identifier["text"].String(); } return ret; @@ -599,10 +599,10 @@ VideoPath CampaignHandler::prologVideoName(ui8 index) return VideoPath(); } -std::string CampaignHandler::prologMusicName(ui8 index) +AudioPath CampaignHandler::prologMusicName(ui8 index) { std::vector music; - return VLC->generaltexth->translate("core.cmpmusic." + std::to_string(static_cast(index))); + return AudioPath::builtinTODO(VLC->generaltexth->translate("core.cmpmusic." + std::to_string(static_cast(index)))); } std::string CampaignHandler::prologVoiceName(ui8 index) diff --git a/lib/campaign/CampaignHandler.h b/lib/campaign/CampaignHandler.h index 5ecf6ca5c..7a6d0fd1f 100644 --- a/lib/campaign/CampaignHandler.h +++ b/lib/campaign/CampaignHandler.h @@ -34,7 +34,7 @@ class DLL_LINKAGE CampaignHandler static std::vector> getFile(std::unique_ptr file, bool headerOnly); static VideoPath prologVideoName(ui8 index); - static std::string prologMusicName(ui8 index); + static AudioPath prologMusicName(ui8 index); static std::string prologVoiceName(ui8 index); public: diff --git a/lib/campaign/CampaignScenarioPrologEpilog.h b/lib/campaign/CampaignScenarioPrologEpilog.h index 44dd1c961..00b321188 100644 --- a/lib/campaign/CampaignScenarioPrologEpilog.h +++ b/lib/campaign/CampaignScenarioPrologEpilog.h @@ -17,7 +17,7 @@ struct DLL_LINKAGE CampaignScenarioPrologEpilog { bool hasPrologEpilog = false; VideoPath prologVideo; // from CmpMovie.txt - std::string prologMusic; // from CmpMusic.txt + AudioPath prologMusic; // from CmpMusic.txt std::string prologText; template void serialize(Handler &h, const int formatVersion) diff --git a/lib/campaign/CampaignState.cpp b/lib/campaign/CampaignState.cpp index 53e8fb3ec..f8bfe0271 100644 --- a/lib/campaign/CampaignState.cpp +++ b/lib/campaign/CampaignState.cpp @@ -159,7 +159,7 @@ std::string CampaignHeader::getEncoding() const return encoding; } -std::string CampaignHeader::getMusic() const +AudioPath CampaignHeader::getMusic() const { return music; } diff --git a/lib/campaign/CampaignState.h b/lib/campaign/CampaignState.h index aa73801e3..247d86fa4 100644 --- a/lib/campaign/CampaignState.h +++ b/lib/campaign/CampaignState.h @@ -76,7 +76,7 @@ class DLL_LINKAGE CampaignHeader : public boost::noncopyable CampaignRegions campaignRegions; std::string name; std::string description; - std::string music; + AudioPath music; std::string filename; std::string modName; std::string encoding; @@ -95,7 +95,7 @@ public: std::string getFilename() const; std::string getModName() const; std::string getEncoding() const; - std::string getMusic() const; + AudioPath getMusic() const; const CampaignRegions & getRegions() const; diff --git a/lib/filesystem/CFilesystemLoader.cpp b/lib/filesystem/CFilesystemLoader.cpp index 8298ae15c..9175d0d2d 100644 --- a/lib/filesystem/CFilesystemLoader.cpp +++ b/lib/filesystem/CFilesystemLoader.cpp @@ -103,7 +103,7 @@ std::unordered_map CFilesystemLoader::lis { static const EResType initArray[] = { EResType::DIRECTORY, - EResType::TEXT, + EResType::JSON, EResType::ARCHIVE_LOD, EResType::ARCHIVE_VID, EResType::ARCHIVE_SND, diff --git a/lib/filesystem/Filesystem.cpp b/lib/filesystem/Filesystem.cpp index 726e9bb8b..84378f56b 100644 --- a/lib/filesystem/Filesystem.cpp +++ b/lib/filesystem/Filesystem.cpp @@ -113,10 +113,10 @@ void CFilesystemGenerator::loadArchive(const std::string &mountPoint, const Json void CFilesystemGenerator::loadJsonMap(const std::string &mountPoint, const JsonNode & config) { std::string URI = prefix + config["path"].String(); - auto filename = CResourceHandler::get("initial")->getResourceName(ResourcePath(URI, EResType::TEXT)); + auto filename = CResourceHandler::get("initial")->getResourceName(JsonPath::builtin(URI)); if (filename) { - auto configData = CResourceHandler::get("initial")->load(ResourcePath(URI, EResType::TEXT))->readAll(); + auto configData = CResourceHandler::get("initial")->load(JsonPath::builtin(URI))->readAll(); const JsonNode configInitial(reinterpret_cast(configData.first.get()), configData.second); filesystem->addLoader(new CMappedFileLoader(mountPoint, configInitial), false); } @@ -210,7 +210,7 @@ ISimpleResourceLoader * CResourceHandler::get(const std::string & identifier) void CResourceHandler::load(const std::string &fsConfigURI, bool extractArchives) { - auto fsConfigData = get("initial")->load(ResourcePath(fsConfigURI, EResType::TEXT))->readAll(); + auto fsConfigData = get("initial")->load(JsonPath::builtin(fsConfigURI))->readAll(); const JsonNode fsConfig(reinterpret_cast(fsConfigData.first.get()), fsConfigData.second); diff --git a/lib/filesystem/ResourcePath.cpp b/lib/filesystem/ResourcePath.cpp index 120cb5203..cba1fbb43 100644 --- a/lib/filesystem/ResourcePath.cpp +++ b/lib/filesystem/ResourcePath.cpp @@ -94,7 +94,7 @@ EResType EResTypeHelper::getTypeFromExtension(std::string extension) static const std::map stringToRes = { {".TXT", EResType::TEXT}, - {".JSON", EResType::TEXT}, + {".JSON", EResType::JSON}, {".DEF", EResType::ANIMATION}, {".MSK", EResType::MASK}, {".MSG", EResType::MASK}, @@ -148,6 +148,7 @@ std::string EResTypeHelper::getEResTypeAsString(EResType type) static const std::map stringToRes = { MAP_ENUM(TEXT) + MAP_ENUM(JSON) MAP_ENUM(ANIMATION) MAP_ENUM(MASK) MAP_ENUM(CAMPAIGN) diff --git a/lib/filesystem/ResourcePath.h b/lib/filesystem/ResourcePath.h index be2d30d20..8ed843c40 100644 --- a/lib/filesystem/ResourcePath.h +++ b/lib/filesystem/ResourcePath.h @@ -140,6 +140,12 @@ public: :ResourcePath("", Type) {} + static ResourcePathTempl fromResource(const ResourcePath & resource) + { + assert(Type == resource.getType()); + return ResourcePathTempl(resource); + } + static ResourcePathTempl builtin(const std::string & filename) { return ResourcePathTempl(filename, Type); @@ -177,6 +183,7 @@ using ImagePath = ResourcePathTempl; using TextPath = ResourcePathTempl; using JsonPath = ResourcePathTempl; using VideoPath = ResourcePathTempl; +using AudioPath = ResourcePathTempl; namespace EResTypeHelper { diff --git a/lib/mapObjectConstructors/AObjectTypeHandler.cpp b/lib/mapObjectConstructors/AObjectTypeHandler.cpp index 3b3e859ad..9766f4123 100644 --- a/lib/mapObjectConstructors/AObjectTypeHandler.cpp +++ b/lib/mapObjectConstructors/AObjectTypeHandler.cpp @@ -83,13 +83,13 @@ void AObjectTypeHandler::init(const JsonNode & input) } for(const JsonNode & node : input["sounds"]["ambient"].Vector()) - sounds.ambient.push_back(node.String()); + sounds.ambient.push_back(AudioPath::fromJson(node)); for(const JsonNode & node : input["sounds"]["visit"].Vector()) - sounds.visit.push_back(node.String()); + sounds.visit.push_back(AudioPath::fromJson(node)); for(const JsonNode & node : input["sounds"]["removal"].Vector()) - sounds.removal.push_back(node.String()); + sounds.removal.push_back(AudioPath::fromJson(node)); if(input["aiValue"].isNull()) aiValue = std::nullopt; diff --git a/lib/mapObjectConstructors/SObjectSounds.h b/lib/mapObjectConstructors/SObjectSounds.h index ca1b8fef9..8d41817c0 100644 --- a/lib/mapObjectConstructors/SObjectSounds.h +++ b/lib/mapObjectConstructors/SObjectSounds.h @@ -9,13 +9,15 @@ */ #pragma once +#include "../filesystem/ResourcePath.h" + VCMI_LIB_NAMESPACE_BEGIN struct SObjectSounds { - std::vector ambient; - std::vector visit; - std::vector removal; + std::vector ambient; + std::vector visit; + std::vector removal; template void serialize(Handler &h, const int version) { diff --git a/lib/mapObjects/CGObjectInstance.cpp b/lib/mapObjects/CGObjectInstance.cpp index 4b081c4e5..92a2c96ce 100644 --- a/lib/mapObjects/CGObjectInstance.cpp +++ b/lib/mapObjects/CGObjectInstance.cpp @@ -214,7 +214,7 @@ std::string CGObjectInstance::getObjectName() const return VLC->objtypeh->getObjectName(ID, subID); } -std::optional CGObjectInstance::getAmbientSound() const +std::optional CGObjectInstance::getAmbientSound() const { const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).ambient; if(!sounds.empty()) @@ -223,7 +223,7 @@ std::optional CGObjectInstance::getAmbientSound() const return std::nullopt; } -std::optional CGObjectInstance::getVisitSound() const +std::optional CGObjectInstance::getVisitSound() const { const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).visit; if(!sounds.empty()) @@ -232,7 +232,7 @@ std::optional CGObjectInstance::getVisitSound() const return std::nullopt; } -std::optional CGObjectInstance::getRemovalSound() const +std::optional CGObjectInstance::getRemovalSound() const { const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).removal; if(!sounds.empty()) diff --git a/lib/mapObjects/CGObjectInstance.h b/lib/mapObjects/CGObjectInstance.h index 03e27ebc9..4360e610f 100644 --- a/lib/mapObjects/CGObjectInstance.h +++ b/lib/mapObjects/CGObjectInstance.h @@ -82,9 +82,9 @@ public: virtual bool isTile2Terrain() const { return false; } - std::optional getAmbientSound() const; - std::optional getVisitSound() const; - std::optional getRemovalSound() const; + std::optional getAmbientSound() const; + std::optional getVisitSound() const; + std::optional getRemovalSound() const; /** VIRTUAL METHODS **/ diff --git a/lib/mapping/MapFormatJson.cpp b/lib/mapping/MapFormatJson.cpp index 3190ea6e8..cab269cab 100644 --- a/lib/mapping/MapFormatJson.cpp +++ b/lib/mapping/MapFormatJson.cpp @@ -904,7 +904,7 @@ std::unique_ptr CMapLoaderJson::loadMapHeader() JsonNode CMapLoaderJson::getFromArchive(const std::string & archiveFilename) { - ResourcePath resource(archiveFilename, EResType::TEXT); + JsonPath resource = JsonPath::builtin(archiveFilename); if(!loader.existsResource(resource)) throw std::runtime_error(archiveFilename+" not found"); diff --git a/lib/spells/CSpellHandler.cpp b/lib/spells/CSpellHandler.cpp index d5ac49775..7e5478212 100644 --- a/lib/spells/CSpellHandler.cpp +++ b/lib/spells/CSpellHandler.cpp @@ -310,7 +310,7 @@ const std::string & CSpell::getIconScroll() const return iconScroll; } -const std::string & CSpell::getCastSound() const +const AudioPath & CSpell::getCastSound() const { return castSound; } @@ -896,7 +896,7 @@ CSpell * CSpellHandler::loadFromJson(const std::string & scope, const JsonNode & } const JsonNode & soundsNode = json["sounds"]; - spell->castSound = soundsNode["cast"].String(); + spell->castSound = AudioPath::fromJson(soundsNode["cast"]); //load level attributes const int levelsCount = GameConstants::SPELL_SCHOOL_LEVELS; diff --git a/lib/spells/CSpellHandler.h b/lib/spells/CSpellHandler.h index 9d8bea267..ccf575518 100644 --- a/lib/spells/CSpellHandler.h +++ b/lib/spells/CSpellHandler.h @@ -262,7 +262,7 @@ public: const std::string & getIconScenarioBonus() const; const std::string & getIconScroll() const; - const std::string & getCastSound() const override; + const AudioPath & getCastSound() const; void updateFrom(const JsonNode & data); void serializeJson(JsonSerializeFormat & handler); @@ -354,7 +354,7 @@ private: std::string iconScroll; ///sound related stuff - std::string castSound; + AudioPath castSound; std::vector levels; diff --git a/lib/spells/effects/Obstacle.cpp b/lib/spells/effects/Obstacle.cpp index 428e065e3..720bc1fa0 100644 --- a/lib/spells/effects/Obstacle.cpp +++ b/lib/spells/effects/Obstacle.cpp @@ -85,7 +85,7 @@ void ObstacleSideOptions::serializeJson(JsonSerializeFormat & handler) serializeRelativeShape(handler, "shape", shape); serializeRelativeShape(handler, "range", range); - handler.serializeString("appearSound", appearSound); + handler.serializeStruct("appearSound", appearSound); handler.serializeStruct("appearAnimation", appearAnimation); handler.serializeStruct("animation", animation); diff --git a/lib/spells/effects/Obstacle.h b/lib/spells/effects/Obstacle.h index a1e9b1f56..1dd256e1a 100644 --- a/lib/spells/effects/Obstacle.h +++ b/lib/spells/effects/Obstacle.h @@ -30,7 +30,7 @@ public: RelativeShape shape; //shape of single obstacle relative to obstacle position RelativeShape range; //position of obstacles relative to effect destination - std::string appearSound; + AudioPath appearSound; AnimationPath appearAnimation; AnimationPath animation; diff --git a/mapeditor/Animation.cpp b/mapeditor/Animation.cpp index 80795d02a..412810328 100644 --- a/mapeditor/Animation.cpp +++ b/mapeditor/Animation.cpp @@ -583,7 +583,7 @@ void Animation::init() source[defEntry.first].resize(defEntry.second); } - ResourcePath resID(std::string("SPRITES/") + name, EResType::TEXT); + JsonPath resID = JsonPath::builtin("SPRITES/" + name); //if(vstd::contains(graphics->imageLists, resID.getName())) //initFromJson(graphics->imageLists[resID.getName()]); diff --git a/test/map/CMapFormatTest.cpp b/test/map/CMapFormatTest.cpp index f1b1a4d77..26082c8c9 100644 --- a/test/map/CMapFormatTest.cpp +++ b/test/map/CMapFormatTest.cpp @@ -90,7 +90,7 @@ TEST(MapFormat, Random) static JsonNode getFromArchive(CZipLoader & archive, const std::string & archiveFilename) { - ResourcePath resource(archiveFilename, EResType::TEXT); + JsonPath resource = JsonPath::builtin(archiveFilename); if(!archive.existsResource(resource)) throw std::runtime_error(archiveFilename + " not found");