mirror of
https://github.com/vcmi/vcmi.git
synced 2026-06-19 22:57:37 +02:00
Use ResourcePath for audio files
This commit is contained in:
@@ -387,7 +387,7 @@ void AIGateway::heroCreated(const CGHeroInstance * h)
|
|||||||
NET_EVENT_HANDLER;
|
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);
|
LOG_TRACE_PARAMS(logAi, "spellID '%i", spellID);
|
||||||
NET_EVENT_HANDLER;
|
NET_EVENT_HANDLER;
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ public:
|
|||||||
void showHillFortWindow(const CGObjectInstance * object, const CGHeroInstance * visitor) override;
|
void showHillFortWindow(const CGObjectInstance * object, const CGHeroInstance * visitor) override;
|
||||||
void playerBonusChanged(const Bonus & bonus, bool gain) override;
|
void playerBonusChanged(const Bonus & bonus, bool gain) override;
|
||||||
void heroCreated(const CGHeroInstance *) 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<Component> & components, int soundID) override;
|
void showInfoDialog(EInfoWindowMode type, const std::string & text, const std::vector<Component> & components, int soundID) override;
|
||||||
void requestRealized(PackageApplied * pa) override;
|
void requestRealized(PackageApplied * pa) override;
|
||||||
void receivedResource() override;
|
void receivedResource() override;
|
||||||
|
|||||||
+1
-1
@@ -475,7 +475,7 @@ void VCAI::heroCreated(const CGHeroInstance * h)
|
|||||||
NET_EVENT_HANDLER;
|
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);
|
LOG_TRACE_PARAMS(logAi, "spellID '%i", spellID);
|
||||||
NET_EVENT_HANDLER;
|
NET_EVENT_HANDLER;
|
||||||
|
|||||||
+1
-1
@@ -185,7 +185,7 @@ public:
|
|||||||
void showHillFortWindow(const CGObjectInstance * object, const CGHeroInstance * visitor) override;
|
void showHillFortWindow(const CGObjectInstance * object, const CGHeroInstance * visitor) override;
|
||||||
void playerBonusChanged(const Bonus & bonus, bool gain) override;
|
void playerBonusChanged(const Bonus & bonus, bool gain) override;
|
||||||
void heroCreated(const CGHeroInstance *) 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<Component> & components, int soundID) override;
|
void showInfoDialog(EInfoWindowMode type, const std::string & text, const std::vector<Component> & components, int soundID) override;
|
||||||
void requestRealized(PackageApplied * pa) override;
|
void requestRealized(PackageApplied * pa) override;
|
||||||
void receivedResource() override;
|
void receivedResource() override;
|
||||||
|
|||||||
+31
-31
@@ -119,25 +119,25 @@ void CSoundHandler::release()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allocate an SDL chunk and cache it.
|
// 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
|
try
|
||||||
{
|
{
|
||||||
if (cache && soundChunks.find(sound) != soundChunks.end())
|
if (cache && soundChunks.find(sound) != soundChunks.end())
|
||||||
return soundChunks[sound].first;
|
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);
|
SDL_RWops *ops = SDL_RWFromMem(data.first.get(), (int)data.second);
|
||||||
Mix_Chunk *chunk = Mix_LoadWAV_RW(ops, 1); // will free ops
|
Mix_Chunk *chunk = Mix_LoadWAV_RW(ops, 1); // will free ops
|
||||||
|
|
||||||
if (cache)
|
if (cache)
|
||||||
soundChunks.insert(std::pair<std::string, CachedChunk>(sound, std::make_pair (chunk, std::move (data.first))));
|
soundChunks.insert({sound, std::make_pair (chunk, std::move (data.first))});
|
||||||
|
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,7 +153,7 @@ int CSoundHandler::ambientDistToVolume(int distance) const
|
|||||||
return volume * (int)ambientConfig["volume"].Integer() / 100;
|
return volume * (int)ambientConfig["volume"].Integer() / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSoundHandler::ambientStopSound(std::string soundId)
|
void CSoundHandler::ambientStopSound(const AudioPath & soundId)
|
||||||
{
|
{
|
||||||
stopSound(ambientChannels[soundId]);
|
stopSound(ambientChannels[soundId]);
|
||||||
setChannelVolume(ambientChannels[soundId], volume);
|
setChannelVolume(ambientChannels[soundId], volume);
|
||||||
@@ -163,13 +163,13 @@ void CSoundHandler::ambientStopSound(std::string soundId)
|
|||||||
int CSoundHandler::playSound(soundBase::soundID soundID, int repeats)
|
int CSoundHandler::playSound(soundBase::soundID soundID, int repeats)
|
||||||
{
|
{
|
||||||
assert(soundID < soundBase::sound_after_last);
|
assert(soundID < soundBase::sound_after_last);
|
||||||
auto sound = sounds[soundID];
|
auto sound = AudioPath::builtin(sounds[soundID]);
|
||||||
logGlobal->trace("Attempt to play sound %d with file name %s with cache", soundID, sound);
|
logGlobal->trace("Attempt to play sound %d with file name %s with cache", soundID, sound.getOriginalName());
|
||||||
|
|
||||||
return playSound(sound, repeats, true);
|
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())
|
if (!initialized || sound.empty())
|
||||||
return -1;
|
return -1;
|
||||||
@@ -182,7 +182,7 @@ int CSoundHandler::playSound(std::string sound, int repeats, bool cache)
|
|||||||
channel = Mix_PlayChannel(-1, chunk, repeats);
|
channel = Mix_PlayChannel(-1, chunk, repeats);
|
||||||
if (channel == -1)
|
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)
|
if (!cache)
|
||||||
Mix_FreeChunk(chunk);
|
Mix_FreeChunk(chunk);
|
||||||
}
|
}
|
||||||
@@ -290,14 +290,14 @@ int CSoundHandler::ambientGetRange() const
|
|||||||
return static_cast<int>(ambientConfig["range"].Integer());
|
return static_cast<int>(ambientConfig["range"].Integer());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSoundHandler::ambientUpdateChannels(std::map<std::string, int> soundsArg)
|
void CSoundHandler::ambientUpdateChannels(std::map<AudioPath, int> soundsArg)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock guard(mutex);
|
boost::mutex::scoped_lock guard(mutex);
|
||||||
|
|
||||||
std::vector<std::string> stoppedSounds;
|
std::vector<AudioPath> stoppedSounds;
|
||||||
for(auto & pair : ambientChannels)
|
for(auto & pair : ambientChannels)
|
||||||
{
|
{
|
||||||
const std::string & soundId = pair.first;
|
const auto & soundId = pair.first;
|
||||||
const int channel = pair.second;
|
const int channel = pair.second;
|
||||||
|
|
||||||
if(!vstd::contains(soundsArg, soundId))
|
if(!vstd::contains(soundsArg, soundId))
|
||||||
@@ -320,7 +320,7 @@ void CSoundHandler::ambientUpdateChannels(std::map<std::string, int> soundsArg)
|
|||||||
|
|
||||||
for(auto & pair : soundsArg)
|
for(auto & pair : soundsArg)
|
||||||
{
|
{
|
||||||
const std::string & soundId = pair.first;
|
const auto & soundId = pair.first;
|
||||||
const int distance = pair.second;
|
const int distance = pair.second;
|
||||||
|
|
||||||
if(!vstd::contains(ambientChannels, soundId))
|
if(!vstd::contains(ambientChannels, soundId))
|
||||||
@@ -372,9 +372,9 @@ CMusicHandler::CMusicHandler():
|
|||||||
for(const ResourcePath & file : mp3files)
|
for(const ResourcePath & file : mp3files)
|
||||||
{
|
{
|
||||||
if(boost::algorithm::istarts_with(file.getName(), "MUSIC/Combat"))
|
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"))
|
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)
|
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);
|
musicsSet[set].push_back(musicURI);
|
||||||
}
|
}
|
||||||
@@ -421,7 +421,7 @@ void CMusicHandler::release()
|
|||||||
CAudioBase::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);
|
boost::mutex::scoped_lock guard(mutex);
|
||||||
|
|
||||||
@@ -451,7 +451,7 @@ void CMusicHandler::playMusicFromSet(const std::string & whichSet, bool loop, bo
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// in this mode - play random track from set
|
// 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<MusicEntry> queued)
|
void CMusicHandler::queueNext(std::unique_ptr<MusicEntry> queued)
|
||||||
@@ -468,7 +468,7 @@ void CMusicHandler::queueNext(std::unique_ptr<MusicEntry> 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<MusicEntry>(owner, setName, musicURI, looped, fromStart));
|
queueNext(std::make_unique<MusicEntry>(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),
|
owner(owner),
|
||||||
music(nullptr),
|
music(nullptr),
|
||||||
playing(false),
|
playing(false),
|
||||||
@@ -552,16 +552,16 @@ MusicEntry::~MusicEntry()
|
|||||||
Mix_HaltMusic();
|
Mix_HaltMusic();
|
||||||
}
|
}
|
||||||
|
|
||||||
logGlobal->trace("Del-ing music file %s", currentName);
|
logGlobal->trace("Del-ing music file %s", currentName.getOriginalName());
|
||||||
if (music)
|
if (music)
|
||||||
Mix_FreeMusic(music);
|
Mix_FreeMusic(music);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MusicEntry::load(std::string musicURI)
|
void MusicEntry::load(const AudioPath & musicURI)
|
||||||
{
|
{
|
||||||
if (music)
|
if (music)
|
||||||
{
|
{
|
||||||
logGlobal->trace("Del-ing music file %s", currentName);
|
logGlobal->trace("Del-ing music file %s", currentName.getOriginalName());
|
||||||
Mix_FreeMusic(music);
|
Mix_FreeMusic(music);
|
||||||
music = nullptr;
|
music = nullptr;
|
||||||
}
|
}
|
||||||
@@ -569,22 +569,22 @@ void MusicEntry::load(std::string musicURI)
|
|||||||
currentName = musicURI;
|
currentName = musicURI;
|
||||||
music = nullptr;
|
music = nullptr;
|
||||||
|
|
||||||
logGlobal->trace("Loading music file %s", musicURI);
|
logGlobal->trace("Loading music file %s", musicURI.getOriginalName());
|
||||||
|
|
||||||
try
|
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);
|
music = Mix_LoadMUS_RW(musicFile, SDL_TRUE);
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
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());
|
logGlobal->error("Exception: %s", e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!music)
|
if(!music)
|
||||||
{
|
{
|
||||||
logGlobal->warn("Warning: Cannot open %s: %s", currentName, Mix_GetError());
|
logGlobal->warn("Warning: Cannot open %s: %s", currentName.getOriginalName(), Mix_GetError());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -601,7 +601,7 @@ bool MusicEntry::play()
|
|||||||
load(*iter);
|
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)
|
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));
|
assert(startTime != uint32_t(-1));
|
||||||
float playDuration = (endTime - startTime + startPosition) / 1000.f;
|
float playDuration = (endTime - startTime + startPosition) / 1000.f;
|
||||||
owner->trackPositions[currentName] = playDuration;
|
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);
|
Mix_FadeOutMusic(fade_ms);
|
||||||
return true;
|
return true;
|
||||||
@@ -664,7 +664,7 @@ bool MusicEntry::isSet(std::string set)
|
|||||||
return !setName.empty() && set == setName;
|
return !setName.empty() && set == setName;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MusicEntry::isTrack(std::string track)
|
bool MusicEntry::isTrack(const AudioPath & track)
|
||||||
{
|
{
|
||||||
return setName.empty() && track == currentName;
|
return setName.empty() && track == currentName;
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-19
@@ -35,15 +35,14 @@ public:
|
|||||||
class CSoundHandler: public CAudioBase
|
class CSoundHandler: public CAudioBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
//soundBase::soundID getSoundID(const std::string &fileName);
|
|
||||||
//update volume on configuration change
|
//update volume on configuration change
|
||||||
SettingsListener listener;
|
SettingsListener listener;
|
||||||
void onVolumeChange(const JsonNode &volumeNode);
|
void onVolumeChange(const JsonNode &volumeNode);
|
||||||
|
|
||||||
using CachedChunk = std::pair<Mix_Chunk *, std::unique_ptr<ui8[]>>;
|
using CachedChunk = std::pair<Mix_Chunk *, std::unique_ptr<ui8[]>>;
|
||||||
std::map<std::string, CachedChunk> soundChunks;
|
std::map<AudioPath, CachedChunk> soundChunks;
|
||||||
|
|
||||||
Mix_Chunk *GetSoundChunk(std::string &sound, bool cache);
|
Mix_Chunk *GetSoundChunk(const AudioPath & sound, bool cache);
|
||||||
|
|
||||||
/// have entry for every currently active channel
|
/// have entry for every currently active channel
|
||||||
/// vector will be empty if callback was not set
|
/// vector will be empty if callback was not set
|
||||||
@@ -54,12 +53,12 @@ private:
|
|||||||
boost::mutex mutexCallbacks;
|
boost::mutex mutexCallbacks;
|
||||||
|
|
||||||
int ambientDistToVolume(int distance) const;
|
int ambientDistToVolume(int distance) const;
|
||||||
void ambientStopSound(std::string soundId);
|
void ambientStopSound(const AudioPath & soundId);
|
||||||
void updateChannelVolume(int channel);
|
void updateChannelVolume(int channel);
|
||||||
|
|
||||||
const JsonNode ambientConfig;
|
const JsonNode ambientConfig;
|
||||||
|
|
||||||
std::map<std::string, int> ambientChannels;
|
std::map<AudioPath, int> ambientChannels;
|
||||||
std::map<int, int> channelVolumes;
|
std::map<int, int> channelVolumes;
|
||||||
|
|
||||||
void initCallback(int channel, const std::function<void()> & function);
|
void initCallback(int channel, const std::function<void()> & function);
|
||||||
@@ -76,7 +75,7 @@ public:
|
|||||||
|
|
||||||
// Sounds
|
// Sounds
|
||||||
int playSound(soundBase::soundID soundID, int repeats=0);
|
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<soundBase::soundID> &sound_vec);
|
int playSoundFromSet(std::vector<soundBase::soundID> &sound_vec);
|
||||||
void stopSound(int handler);
|
void stopSound(int handler);
|
||||||
|
|
||||||
@@ -84,16 +83,13 @@ public:
|
|||||||
void soundFinishedCallback(int channel);
|
void soundFinishedCallback(int channel);
|
||||||
|
|
||||||
int ambientGetRange() const;
|
int ambientGetRange() const;
|
||||||
void ambientUpdateChannels(std::map<std::string, int> currentSounds);
|
void ambientUpdateChannels(std::map<AudioPath, int> currentSounds);
|
||||||
void ambientStopAllChannels();
|
void ambientStopAllChannels();
|
||||||
|
|
||||||
// Sets
|
// Sets
|
||||||
std::vector<soundBase::soundID> battleIntroSounds;
|
std::vector<soundBase::soundID> battleIntroSounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper //now it looks somewhat useless
|
|
||||||
#define battle_sound(creature,what_sound) creature->sounds.what_sound
|
|
||||||
|
|
||||||
class CMusicHandler;
|
class CMusicHandler;
|
||||||
|
|
||||||
//Class for handling one music file
|
//Class for handling one music file
|
||||||
@@ -109,16 +105,16 @@ class MusicEntry
|
|||||||
uint32_t startPosition;
|
uint32_t startPosition;
|
||||||
//if not null - set from which music will be randomly selected
|
//if not null - set from which music will be randomly selected
|
||||||
std::string setName;
|
std::string setName;
|
||||||
std::string currentName;
|
AudioPath currentName;
|
||||||
|
|
||||||
void load(std::string musicURI);
|
void load(const AudioPath & musicURI);
|
||||||
|
|
||||||
public:
|
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();
|
~MusicEntry();
|
||||||
|
|
||||||
bool isSet(std::string setName);
|
bool isSet(std::string setName);
|
||||||
bool isTrack(std::string trackName);
|
bool isTrack(const AudioPath & trackName);
|
||||||
bool isPlaying();
|
bool isPlaying();
|
||||||
|
|
||||||
bool play();
|
bool play();
|
||||||
@@ -135,20 +131,20 @@ private:
|
|||||||
std::unique_ptr<MusicEntry> current;
|
std::unique_ptr<MusicEntry> current;
|
||||||
std::unique_ptr<MusicEntry> next;
|
std::unique_ptr<MusicEntry> 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<MusicEntry> queued);
|
void queueNext(std::unique_ptr<MusicEntry> queued);
|
||||||
void musicFinishedCallback();
|
void musicFinishedCallback();
|
||||||
|
|
||||||
/// map <set name> -> <list of URI's to tracks belonging to the said set>
|
/// map <set name> -> <list of URI's to tracks belonging to the said set>
|
||||||
std::map<std::string, std::vector<std::string>> musicsSet;
|
std::map<std::string, std::vector<AudioPath>> musicsSet;
|
||||||
/// stored position, in seconds at which music player should resume playing this track
|
/// stored position, in seconds at which music player should resume playing this track
|
||||||
std::map<std::string, float> trackPositions;
|
std::map<AudioPath, float> trackPositions;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CMusicHandler();
|
CMusicHandler();
|
||||||
|
|
||||||
/// add entry with URI musicURI in set. Track will have ID musicID
|
/// 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 init() override;
|
||||||
void loadTerrainMusicThemes();
|
void loadTerrainMusicThemes();
|
||||||
@@ -156,7 +152,7 @@ public:
|
|||||||
void setVolume(ui32 percent) override;
|
void setVolume(ui32 percent) override;
|
||||||
|
|
||||||
/// play track by URI, if loop = true music will be looped
|
/// 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
|
/// play random track from this set
|
||||||
void playMusicFromSet(const std::string & musicSet, bool loop, bool fromStart);
|
void playMusicFromSet(const std::string & musicSet, bool loop, bool fromStart);
|
||||||
/// play random track from set (musicSet, entryID)
|
/// play random track from set (musicSet, entryID)
|
||||||
|
|||||||
@@ -1657,7 +1657,7 @@ void CPlayerInterface::viewWorldMap()
|
|||||||
adventureInt->openWorldView();
|
adventureInt->openWorldView();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellID)
|
void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, SpellID spellID)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
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)
|
if(spellID == SpellID::FLY || spellID == SpellID::WATER_WALK)
|
||||||
localState->erasePath(caster);
|
localState->erasePath(caster);
|
||||||
|
|
||||||
const spells::Spell * spell = CGI->spells()->getByIndex(spellID);
|
auto castSoundPath = spellID.toSpell()->getCastSound();
|
||||||
auto castSoundPath = spell->getCastSound();
|
|
||||||
if(!castSoundPath.empty())
|
if(!castSoundPath.empty())
|
||||||
CCS->soundh->playSound(castSoundPath);
|
CCS->soundh->playSound(castSoundPath);
|
||||||
}
|
}
|
||||||
@@ -1992,22 +1991,22 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
|
|||||||
elem.coord = h->convertFromVisitablePos(elem.coord);
|
elem.coord = h->convertFromVisitablePos(elem.coord);
|
||||||
|
|
||||||
int soundChannel = -1;
|
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)
|
if (moveType == EPathNodeAction::TELEPORT_BATTLE || moveType == EPathNodeAction::TELEPORT_BLOCKING_VISIT || moveType == EPathNodeAction::TELEPORT_NORMAL)
|
||||||
return "";
|
return {};
|
||||||
|
|
||||||
if (moveType == EPathNodeAction::EMBARK || moveType == EPathNodeAction::DISEMBARK)
|
if (moveType == EPathNodeAction::EMBARK || moveType == EPathNodeAction::DISEMBARK)
|
||||||
return "";
|
return {};
|
||||||
|
|
||||||
if (moveType == EPathNodeAction::BLOCKING_VISIT)
|
if (moveType == EPathNodeAction::BLOCKING_VISIT)
|
||||||
return "";
|
return {};
|
||||||
|
|
||||||
// flying movement sound
|
// flying movement sound
|
||||||
if (hero->hasBonusOfType(BonusType::FLYING_MOVEMENT))
|
if (hero->hasBonusOfType(BonusType::FLYING_MOVEMENT))
|
||||||
return "HORSE10.wav";
|
return AudioPath::builtin("HORSE10.wav");
|
||||||
|
|
||||||
auto prevTile = cb->getTile(h->convertToVisitablePos(posPrev));
|
auto prevTile = cb->getTile(h->convertToVisitablePos(posPrev));
|
||||||
auto nextTile = cb->getTile(h->convertToVisitablePos(posNext));
|
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.
|
// 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)
|
if(newSoundName != soundName)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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 showMarketWindow(const IMarket *market, const CGHeroInstance *visitor) override;
|
||||||
void showUniversityWindow(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 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<int3> &pos) override; //called when given tiles become hidden under fog of war
|
void tileHidden(const std::unordered_set<int3> &pos) override; //called when given tiles become hidden under fog of war
|
||||||
void tileRevealed(const std::unordered_set<int3> &pos) override; //called when fog of war disappears from given tiles
|
void tileRevealed(const std::unordered_set<int3> &pos) override; //called when fog of war disappears from given tiles
|
||||||
void newObject(const CGObjectInstance * obj) override;
|
void newObject(const CGObjectInstance * obj) override;
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ void CInGameConsole::print(const std::string & txt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GH.windows().totalRedraw(); // FIXME: ingame console has no parent widget set
|
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)
|
bool CInGameConsole::captureThisKey(EShortcut key)
|
||||||
|
|||||||
@@ -123,9 +123,9 @@ void MapAudioPlayer::removeObject(const CGObjectInstance * obj)
|
|||||||
vstd::erase(objects[z][x][y], obj->id);
|
vstd::erase(objects[z][x][y], obj->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> MapAudioPlayer::getAmbientSounds(const int3 & tile)
|
std::vector<AudioPath> MapAudioPlayer::getAmbientSounds(const int3 & tile)
|
||||||
{
|
{
|
||||||
std::vector<std::string> result;
|
std::vector<AudioPath> result;
|
||||||
|
|
||||||
for(auto & objectID : objects[tile.z][tile.x][tile.y])
|
for(auto & objectID : objects[tile.z][tile.x][tile.y])
|
||||||
{
|
{
|
||||||
@@ -147,8 +147,8 @@ std::vector<std::string> MapAudioPlayer::getAmbientSounds(const int3 & tile)
|
|||||||
|
|
||||||
void MapAudioPlayer::updateAmbientSounds()
|
void MapAudioPlayer::updateAmbientSounds()
|
||||||
{
|
{
|
||||||
std::map<std::string, int> currentSounds;
|
std::map<AudioPath, int> currentSounds;
|
||||||
auto updateSounds = [&](const std::string& soundId, int distance) -> void
|
auto updateSounds = [&](const AudioPath& soundId, int distance) -> void
|
||||||
{
|
{
|
||||||
if(vstd::contains(currentSounds, soundId))
|
if(vstd::contains(currentSounds, soundId))
|
||||||
currentSounds[soundId] = std::min(currentSounds[soundId], distance);
|
currentSounds[soundId] = std::min(currentSounds[soundId], distance);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../mapView/IMapRendererObserver.h"
|
#include "../mapView/IMapRendererObserver.h"
|
||||||
|
#include "../../lib/filesystem/ResourcePath.h"
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
class ObjectInstanceID;
|
class ObjectInstanceID;
|
||||||
@@ -29,7 +30,7 @@ class MapAudioPlayer : public IMapObjectObserver
|
|||||||
void addObject(const CGObjectInstance * obj);
|
void addObject(const CGObjectInstance * obj);
|
||||||
void removeObject(const CGObjectInstance * obj);
|
void removeObject(const CGObjectInstance * obj);
|
||||||
|
|
||||||
std::vector<std::string> getAmbientSounds(const int3 & tile);
|
std::vector<AudioPath> getAmbientSounds(const int3 & tile);
|
||||||
void updateAmbientSounds();
|
void updateAmbientSounds();
|
||||||
void updateMusic();
|
void updateMusic();
|
||||||
void update();
|
void update();
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ void TurnTimerWidget::setTime(PlayerColor player, int time)
|
|||||||
&& newTime != turnTime
|
&& newTime != turnTime
|
||||||
&& notifications.count(newTime))
|
&& notifications.count(newTime))
|
||||||
{
|
{
|
||||||
CCS->soundh->playSound(variables["notificationSound"].String());
|
CCS->soundh->playSound(AudioPath::fromJson(variables["notificationSound"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
turnTime = newTime;
|
turnTime = newTime;
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ void StackActionAnimation::setGroup( ECreatureAnimType group )
|
|||||||
currGroup = group;
|
currGroup = group;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StackActionAnimation::setSound( std::string sound )
|
void StackActionAnimation::setSound( const AudioPath & sound )
|
||||||
{
|
{
|
||||||
this->sound = sound;
|
this->sound = sound;
|
||||||
}
|
}
|
||||||
@@ -179,7 +179,7 @@ HittedAnimation::HittedAnimation(BattleInterface & owner, const CStack * stack)
|
|||||||
: StackActionAnimation(owner, stack)
|
: StackActionAnimation(owner, stack)
|
||||||
{
|
{
|
||||||
setGroup(ECreatureAnimType::HITTED);
|
setGroup(ECreatureAnimType::HITTED);
|
||||||
setSound(battle_sound(stack->unitType(), wince));
|
setSound(stack->unitType()->sounds.wince);
|
||||||
logAnim->debug("Created HittedAnimation for %s", stack->getName());
|
logAnim->debug("Created HittedAnimation for %s", stack->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,14 +187,14 @@ DefenceAnimation::DefenceAnimation(BattleInterface & owner, const CStack * stack
|
|||||||
: StackActionAnimation(owner, stack)
|
: StackActionAnimation(owner, stack)
|
||||||
{
|
{
|
||||||
setGroup(ECreatureAnimType::DEFENCE);
|
setGroup(ECreatureAnimType::DEFENCE);
|
||||||
setSound(battle_sound(stack->unitType(), defend));
|
setSound(stack->unitType()->sounds.defend);
|
||||||
logAnim->debug("Created DefenceAnimation for %s", stack->getName());
|
logAnim->debug("Created DefenceAnimation for %s", stack->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
DeathAnimation::DeathAnimation(BattleInterface & owner, const CStack * stack, bool ranged):
|
DeathAnimation::DeathAnimation(BattleInterface & owner, const CStack * stack, bool ranged):
|
||||||
StackActionAnimation(owner, stack)
|
StackActionAnimation(owner, stack)
|
||||||
{
|
{
|
||||||
setSound(battle_sound(stack->unitType(), killed));
|
setSound(stack->unitType()->sounds.killed);
|
||||||
|
|
||||||
if(ranged && myAnim->framesInGroup(ECreatureAnimType::DEATH_RANGED) > 0)
|
if(ranged && myAnim->framesInGroup(ECreatureAnimType::DEATH_RANGED) > 0)
|
||||||
setGroup(ECreatureAnimType::DEATH_RANGED);
|
setGroup(ECreatureAnimType::DEATH_RANGED);
|
||||||
@@ -315,7 +315,7 @@ MeleeAttackAnimation::MeleeAttackAnimation(BattleInterface & owner, const CStack
|
|||||||
: AttackAnimation(owner, attacker, _dest, _attacked)
|
: AttackAnimation(owner, attacker, _dest, _attacked)
|
||||||
{
|
{
|
||||||
logAnim->debug("Created MeleeAttackAnimation for %s", attacker->getName());
|
logAnim->debug("Created MeleeAttackAnimation for %s", attacker->getName());
|
||||||
setSound(battle_sound(getCreature(), attack));
|
setSound(getCreature()->sounds.attack);
|
||||||
setGroup(selectGroup(multiAttack));
|
setGroup(selectGroup(multiAttack));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,7 +356,7 @@ bool MovementAnimation::init()
|
|||||||
|
|
||||||
if (moveSoundHander == -1)
|
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);
|
Point begPosition = owner.stacksController->getStackPositionAtHex(prevHex, stack);
|
||||||
@@ -453,7 +453,7 @@ bool MovementEndAnimation::init()
|
|||||||
logAnim->debug("CMovementEndAnimation::init: stack %s", stack->getName());
|
logAnim->debug("CMovementEndAnimation::init: stack %s", stack->getName());
|
||||||
myAnim->pos.moveTo(owner.stacksController->getStackPositionAtHex(nextHex, stack));
|
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))
|
if(!myAnim->framesInGroup(ECreatureAnimType::MOVE_END))
|
||||||
{
|
{
|
||||||
@@ -494,7 +494,7 @@ bool MovementStartAnimation::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
logAnim->debug("CMovementStartAnimation::init: stack %s", stack->getName());
|
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))
|
if(!myAnim->framesInGroup(ECreatureAnimType::MOVE_START))
|
||||||
{
|
{
|
||||||
@@ -632,7 +632,7 @@ RangedAttackAnimation::RangedAttackAnimation(BattleInterface & owner_, const CSt
|
|||||||
: AttackAnimation(owner_, attacker, dest_, defender),
|
: AttackAnimation(owner_, attacker, dest_, defender),
|
||||||
projectileEmitted(false)
|
projectileEmitted(false)
|
||||||
{
|
{
|
||||||
setSound(battle_sound(getCreature(), shoot));
|
setSound(getCreature()->sounds.shoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RangedAttackAnimation::init()
|
bool RangedAttackAnimation::init()
|
||||||
@@ -806,7 +806,7 @@ void CatapultAnimation::tick(uint32_t msPassed)
|
|||||||
explosionEmitted = true;
|
explosionEmitted = true;
|
||||||
Point shotTarget = owner.stacksController->getStackPositionAtHex(dest, defendingStack) + Point(225, 225) - Point(126, 105);
|
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");
|
AnimationPath effectFilename = AnimationPath::builtin((catapultDamage > 0) ? "SGEXPL" : "CSGRCK");
|
||||||
|
|
||||||
CCS->soundh->playSound( soundFilename );
|
CCS->soundh->playSound( soundFilename );
|
||||||
|
|||||||
@@ -69,11 +69,11 @@ class StackActionAnimation : public BattleStackAnimation
|
|||||||
{
|
{
|
||||||
ECreatureAnimType nextGroup;
|
ECreatureAnimType nextGroup;
|
||||||
ECreatureAnimType currGroup;
|
ECreatureAnimType currGroup;
|
||||||
std::string sound;
|
AudioPath sound;
|
||||||
public:
|
public:
|
||||||
void setNextGroup( ECreatureAnimType group );
|
void setNextGroup( ECreatureAnimType group );
|
||||||
void setGroup( ECreatureAnimType group );
|
void setGroup( ECreatureAnimType group );
|
||||||
void setSound( std::string sound );
|
void setSound( const AudioPath & sound );
|
||||||
|
|
||||||
ECreatureAnimType getGroup() const;
|
ECreatureAnimType getGroup() const;
|
||||||
|
|
||||||
|
|||||||
@@ -41,10 +41,10 @@ BattleEffectsController::BattleEffectsController(BattleInterface & owner):
|
|||||||
|
|
||||||
void BattleEffectsController::displayEffect(EBattleEffect effect, const BattleHex & destTile)
|
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<size_t>(effect);
|
size_t effectID = static_cast<size_t>(effect);
|
||||||
|
|
||||||
@@ -69,22 +69,22 @@ void BattleEffectsController::battleTriggerEffect(const BattleTriggerEffect & bt
|
|||||||
switch(static_cast<BonusType>(bte.effect))
|
switch(static_cast<BonusType>(bte.effect))
|
||||||
{
|
{
|
||||||
case BonusType::HP_REGENERATION:
|
case BonusType::HP_REGENERATION:
|
||||||
displayEffect(EBattleEffect::REGENERATION, "REGENER", stack->getPosition());
|
displayEffect(EBattleEffect::REGENERATION, AudioPath::builtin("REGENER"), stack->getPosition());
|
||||||
break;
|
break;
|
||||||
case BonusType::MANA_DRAIN:
|
case BonusType::MANA_DRAIN:
|
||||||
displayEffect(EBattleEffect::MANA_DRAIN, "MANADRAI", stack->getPosition());
|
displayEffect(EBattleEffect::MANA_DRAIN, AudioPath::builtin("MANADRAI"), stack->getPosition());
|
||||||
break;
|
break;
|
||||||
case BonusType::POISON:
|
case BonusType::POISON:
|
||||||
displayEffect(EBattleEffect::POISON, "POISON", stack->getPosition());
|
displayEffect(EBattleEffect::POISON, AudioPath::builtin("POISON"), stack->getPosition());
|
||||||
break;
|
break;
|
||||||
case BonusType::FEAR:
|
case BonusType::FEAR:
|
||||||
displayEffect(EBattleEffect::FEAR, "FEAR", stack->getPosition());
|
displayEffect(EBattleEffect::FEAR, AudioPath::builtin("FEAR"), stack->getPosition());
|
||||||
break;
|
break;
|
||||||
case BonusType::MORALE:
|
case BonusType::MORALE:
|
||||||
{
|
{
|
||||||
std::string hlp = CGI->generaltexth->allTexts[33];
|
std::string hlp = CGI->generaltexth->allTexts[33];
|
||||||
boost::algorithm::replace_first(hlp,"%s",(stack->getName()));
|
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);
|
owner.appendBattleLog(hlp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ void BattleEffectsController::startAction(const BattleAction & action)
|
|||||||
break;
|
break;
|
||||||
case EActionType::BAD_MORALE:
|
case EActionType::BAD_MORALE:
|
||||||
owner.appendBattleLog(stack->formatGeneralMessage(-34));
|
owner.appendBattleLog(stack->formatGeneralMessage(-34));
|
||||||
displayEffect(EBattleEffect::BAD_MORALE, "BADMRLE", stack->getPosition());
|
displayEffect(EBattleEffect::BAD_MORALE, AudioPath::builtin("BADMRLE"), stack->getPosition());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "../../lib/battle/BattleHex.h"
|
#include "../../lib/battle/BattleHex.h"
|
||||||
#include "../../lib/Point.h"
|
#include "../../lib/Point.h"
|
||||||
|
#include "../../lib/filesystem/ResourcePath.h"
|
||||||
#include "BattleConstants.h"
|
#include "BattleConstants.h"
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
@@ -64,7 +65,7 @@ public:
|
|||||||
|
|
||||||
//displays custom effect on the battlefield
|
//displays custom effect on the battlefield
|
||||||
void displayEffect(EBattleEffect effect, const BattleHex & destTile);
|
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);
|
void battleTriggerEffect(const BattleTriggerEffect & bte);
|
||||||
|
|
||||||
|
|||||||
@@ -353,7 +353,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
|
|||||||
if(!spell)
|
if(!spell)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const std::string & castSoundPath = spell->getCastSound();
|
const AudioPath & castSoundPath = spell->getCastSound();
|
||||||
|
|
||||||
if (!castSoundPath.empty())
|
if (!castSoundPath.empty())
|
||||||
{
|
{
|
||||||
@@ -419,7 +419,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
|
|||||||
if (!sc->resistedCres.empty())
|
if (!sc->resistedCres.empty())
|
||||||
{
|
{
|
||||||
addToAnimationStage(EAnimationEvents::HIT, [=](){
|
addToAnimationStage(EAnimationEvents::HIT, [=](){
|
||||||
CCS->soundh->playSound("MAGICRES");
|
CCS->soundh->playSound(AudioPath::builtin("MAGICRES"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -580,7 +580,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
|
|||||||
break;
|
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"));
|
CCS->videoh->open(VideoPath::builtin("WIN3.BIK"));
|
||||||
std::string str = CGI->generaltexth->allTexts[text];
|
std::string str = CGI->generaltexth->allTexts[text];
|
||||||
|
|
||||||
@@ -597,19 +597,19 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
|
|||||||
else // we lose
|
else // we lose
|
||||||
{
|
{
|
||||||
int text = 311;
|
int text = 311;
|
||||||
std::string musicName = "Music/LoseCombat";
|
AudioPath musicName = AudioPath::builtin("Music/LoseCombat");
|
||||||
VideoPath videoName = VideoPath::builtin("LBSTART.BIK");
|
VideoPath videoName = VideoPath::builtin("LBSTART.BIK");
|
||||||
switch(br.result)
|
switch(br.result)
|
||||||
{
|
{
|
||||||
case EBattleResult::NORMAL:
|
case EBattleResult::NORMAL:
|
||||||
break;
|
break;
|
||||||
case EBattleResult::ESCAPE:
|
case EBattleResult::ESCAPE:
|
||||||
musicName = "Music/Retreat Battle";
|
musicName = AudioPath::builtin("Music/Retreat Battle");
|
||||||
videoName = VideoPath::builtin("RTSTART.BIK");
|
videoName = VideoPath::builtin("RTSTART.BIK");
|
||||||
text = 310;
|
text = 310;
|
||||||
break;
|
break;
|
||||||
case EBattleResult::SURRENDER:
|
case EBattleResult::SURRENDER:
|
||||||
musicName = "Music/Surrender Battle";
|
musicName = AudioPath::builtin("Music/Surrender Battle");
|
||||||
videoName = VideoPath::builtin("SURRENDER.BIK");
|
videoName = VideoPath::builtin("SURRENDER.BIK");
|
||||||
text = 309;
|
text = 309;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -340,7 +340,7 @@ void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca)
|
|||||||
for (auto attackInfo : ca.attackedParts)
|
for (auto attackInfo : ca.attackedParts)
|
||||||
positions.push_back(owner.stacksController->getStackPositionAtHex(attackInfo.destinationTile, nullptr) + Point(99, 120));
|
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));
|
owner.stacksController->addNewAnim(new EffectAnimation(owner, AnimationPath::builtin("SGEXPL.DEF"), positions));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -462,7 +462,7 @@ void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> at
|
|||||||
addNewAnim(new HittedAnimation(owner, attackedInfo.defender));
|
addNewAnim(new HittedAnimation(owner, attackedInfo.defender));
|
||||||
|
|
||||||
if (attackedInfo.fireShield)
|
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)
|
if (attackedInfo.spellEffect != SpellID::NONE)
|
||||||
{
|
{
|
||||||
@@ -481,7 +481,7 @@ void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> at
|
|||||||
if (attackedInfo.rebirth)
|
if (attackedInfo.rebirth)
|
||||||
{
|
{
|
||||||
owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [=](){
|
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));
|
addNewAnim(new ResurrectionAnimation(owner, attackedInfo.defender));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -594,7 +594,7 @@ void BattleStacksController::stackAttacking( const StackAttackInfo & info )
|
|||||||
{
|
{
|
||||||
owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]() {
|
owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]() {
|
||||||
owner.appendBattleLog(info.attacker->formatGeneralMessage(-45));
|
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.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]() {
|
||||||
owner.appendBattleLog(info.attacker->formatGeneralMessage(-44));
|
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.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]() {
|
||||||
owner.appendBattleLog(info.attacker->formatGeneralMessage(365));
|
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)
|
for(auto elem : info.secondaryDefender)
|
||||||
@@ -645,7 +645,7 @@ void BattleStacksController::stackAttacking( const StackAttackInfo & info )
|
|||||||
{
|
{
|
||||||
owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [=]()
|
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());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ CBonusSelection::CBonusSelection()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!getCampaign()->getMusic().empty())
|
if (!getCampaign()->getMusic().empty())
|
||||||
CCS->musich->playMusic( "Music/" + getCampaign()->getMusic(), true, false);
|
CCS->musich->playMusic( getCampaign()->getMusic(), true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBonusSelection::createBonusesIcons()
|
void CBonusSelection::createBonusesIcons()
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ void CChatBox::keyPressed(EShortcut key)
|
|||||||
|
|
||||||
void CChatBox::addNewMessage(const std::string & text)
|
void CChatBox::addNewMessage(const std::string & text)
|
||||||
{
|
{
|
||||||
CCS->soundh->playSound("CHAT");
|
CCS->soundh->playSound(AudioPath::builtin("CHAT"));
|
||||||
chatHistory->setText(chatHistory->label->getText() + text + "\n");
|
chatHistory->setText(chatHistory->label->getText() + text + "\n");
|
||||||
if(chatHistory->slider)
|
if(chatHistory->slider)
|
||||||
chatHistory->slider->scrollToMax();
|
chatHistory->slider->scrollToMax();
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ CCampaignScreen::CCampaignScreen(const JsonNode & config)
|
|||||||
|
|
||||||
void CCampaignScreen::activate()
|
void CCampaignScreen::activate()
|
||||||
{
|
{
|
||||||
CCS->musich->playMusic("Music/MainMenu", true, false);
|
CCS->musich->playMusic(AudioPath::builtin("Music/MainMenu"), true, false);
|
||||||
|
|
||||||
CWindowObject::activate();
|
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
|
// Play the campaign button video when the mouse cursor is placed over the button
|
||||||
if(isHovered())
|
if(isHovered())
|
||||||
{
|
{
|
||||||
if(CCS->videoh->fname != video)
|
if(CCS->videoh->fname != video.addPrefix("VIDEO/"))
|
||||||
CCS->videoh->open(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
|
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();
|
CCS->videoh->close();
|
||||||
redraw();
|
redraw();
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ void CMenuScreen::show(Canvas & to)
|
|||||||
|
|
||||||
void CMenuScreen::activate()
|
void CMenuScreen::activate()
|
||||||
{
|
{
|
||||||
CCS->musich->playMusic("Music/MainMenu", true, true);
|
CCS->musich->playMusic(AudioPath::builtin("Music/MainMenu"), true, true);
|
||||||
if(!config["video"].isNull())
|
if(!config["video"].isNull())
|
||||||
CCS->videoh->open(VideoPath::fromJson(config["video"]["name"]));
|
CCS->videoh->open(VideoPath::fromJson(config["video"]["name"]));
|
||||||
CIntObject::activate();
|
CIntObject::activate();
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ CPrologEpilogVideo::CPrologEpilogVideo(CampaignScenarioPrologEpilog _spe, std::f
|
|||||||
updateShadow();
|
updateShadow();
|
||||||
|
|
||||||
CCS->videoh->open(spe.prologVideo);
|
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?
|
// MPTODO: Custom campaign crashing on this?
|
||||||
// voiceSoundHandle = CCS->soundh->playSound(CCampaignHandler::prologVoiceName(spe.prologVideo));
|
// voiceSoundHandle = CCS->soundh->playSound(CCampaignHandler::prologVoiceName(spe.prologVideo));
|
||||||
|
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ void CAnimation::init()
|
|||||||
if (vstd::contains(graphics->imageLists, name.getName()))
|
if (vstd::contains(graphics->imageLists, name.getName()))
|
||||||
initFromJson(graphics->imageLists[name.getName()]);
|
initFromJson(graphics->imageLists[name.getName()]);
|
||||||
|
|
||||||
auto jsonResource = name.toType<EResType::TEXT>();
|
auto jsonResource = name.toType<EResType::JSON>();
|
||||||
auto configList = CResourceHandler::get()->getResourcesWithName(jsonResource);
|
auto configList = CResourceHandler::get()->getResourcesWithName(jsonResource);
|
||||||
|
|
||||||
for(auto & loader : configList)
|
for(auto & loader : configList)
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ public:
|
|||||||
|
|
||||||
virtual bool hasSchool(SpellSchool school) const = 0;
|
virtual bool hasSchool(SpellSchool school) const = 0;
|
||||||
virtual void forEachSchool(const SchoolCallback & cb) 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 getCost(const int32_t skillLevel) const = 0;
|
||||||
|
|
||||||
virtual int32_t getBasePower() const = 0;
|
virtual int32_t getBasePower() const = 0;
|
||||||
|
|||||||
@@ -955,17 +955,14 @@ void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & c
|
|||||||
creature->special = config["special"].Bool() || config["disabled"].Bool();
|
creature->special = config["special"].Bool() || config["disabled"].Bool();
|
||||||
|
|
||||||
const JsonNode & sounds = config["sound"];
|
const JsonNode & sounds = config["sound"];
|
||||||
|
creature->sounds.attack = AudioPath::fromJson(sounds["attack"]);
|
||||||
#define GET_SOUND_VALUE(value_name) creature->sounds.value_name = sounds[#value_name].String()
|
creature->sounds.defend = AudioPath::fromJson(sounds["defend"]);
|
||||||
GET_SOUND_VALUE(attack);
|
creature->sounds.killed = AudioPath::fromJson(sounds["killed"]);
|
||||||
GET_SOUND_VALUE(defend);
|
creature->sounds.move = AudioPath::fromJson(sounds["move"]);
|
||||||
GET_SOUND_VALUE(killed);
|
creature->sounds.shoot = AudioPath::fromJson(sounds["shoot"]);
|
||||||
GET_SOUND_VALUE(move);
|
creature->sounds.wince = AudioPath::fromJson(sounds["wince"]);
|
||||||
GET_SOUND_VALUE(shoot);
|
creature->sounds.startMoving = AudioPath::fromJson(sounds["startMoving"]);
|
||||||
GET_SOUND_VALUE(wince);
|
creature->sounds.endMoving = AudioPath::fromJson(sounds["endMoving"]);
|
||||||
GET_SOUND_VALUE(startMoving);
|
|
||||||
GET_SOUND_VALUE(endMoving);
|
|
||||||
#undef GET_SOUND_VALUE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCreatureHandler::loadStackExperience(CCreature * creature, const JsonNode & input) const
|
void CCreatureHandler::loadStackExperience(CCreature * creature, const JsonNode & input) const
|
||||||
|
|||||||
@@ -132,14 +132,14 @@ public:
|
|||||||
//sound info
|
//sound info
|
||||||
struct CreatureBattleSounds
|
struct CreatureBattleSounds
|
||||||
{
|
{
|
||||||
std::string attack;
|
AudioPath attack;
|
||||||
std::string defend;
|
AudioPath defend;
|
||||||
std::string killed; // was killed or died
|
AudioPath killed; // was killed or died
|
||||||
std::string move;
|
AudioPath move;
|
||||||
std::string shoot; // range attack
|
AudioPath shoot; // range attack
|
||||||
std::string wince; // attacked but did not die
|
AudioPath wince; // attacked but did not die
|
||||||
std::string startMoving;
|
AudioPath startMoving;
|
||||||
std::string endMoving;
|
AudioPath endMoving;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ void CGeneralTextHandler::detectInstallParameters()
|
|||||||
"ukrainian"
|
"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"];
|
Settings language = settings.write["session"]["language"];
|
||||||
language->String() = "english";
|
language->String() = "english";
|
||||||
@@ -64,7 +64,7 @@ void CGeneralTextHandler::detectInstallParameters()
|
|||||||
|
|
||||||
// load file that will be used for footprint generation
|
// 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
|
// 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<size_t, 256> charCount{};
|
std::array<size_t, 256> charCount{};
|
||||||
std::array<double, 16> footprint{};
|
std::array<double, 16> footprint{};
|
||||||
@@ -429,7 +429,7 @@ CGeneralTextHandler::CGeneralTextHandler():
|
|||||||
readToVector("core.mineevnt", "DATA/MINEEVNT.TXT" );
|
readToVector("core.mineevnt", "DATA/MINEEVNT.TXT" );
|
||||||
|
|
||||||
static const char * QE_MOD_COMMANDS = "DATA/QECOMMANDS.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);
|
readToVector("vcmi.quickExchange", QE_MOD_COMMANDS);
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -574,7 +574,7 @@ CGeneralTextHandler::CGeneralTextHandler():
|
|||||||
}
|
}
|
||||||
if (VLC->settings()->getBoolean(EGameSettings::MODULE_COMMANDERS))
|
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" );
|
readToVector("vcmi.znpc00", "DATA/ZNPC00.TXT" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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]);
|
readIcon(source["icons"]["fort"]["built"], info.iconSmall[1][1], info.iconLarge[1][1]);
|
||||||
|
|
||||||
info.hallBackground = ImagePath::fromJson(source["hallBackground"]);
|
info.hallBackground = ImagePath::fromJson(source["hallBackground"]);
|
||||||
info.musicTheme = source["musicTheme"].String();
|
info.musicTheme = AudioPath::fromJson(source["musicTheme"]);
|
||||||
info.townBackground = ImagePath::fromJson(source["townBackground"]);
|
info.townBackground = ImagePath::fromJson(source["townBackground"]);
|
||||||
info.guildWindow = ImagePath::fromJson(source["guildWindow"]);
|
info.guildWindow = ImagePath::fromJson(source["guildWindow"]);
|
||||||
info.buildingsIcons = AnimationPath::fromJson(source["buildingsIcons"]);
|
info.buildingsIcons = AnimationPath::fromJson(source["buildingsIcons"]);
|
||||||
|
|||||||
+1
-1
@@ -305,7 +305,7 @@ public:
|
|||||||
std::string iconSmall[2][2]; /// icon names used during loading
|
std::string iconSmall[2][2]; /// icon names used during loading
|
||||||
std::string iconLarge[2][2];
|
std::string iconLarge[2][2];
|
||||||
VideoPath tavernVideo;
|
VideoPath tavernVideo;
|
||||||
std::string musicTheme;
|
AudioPath musicTheme;
|
||||||
ImagePath townBackground;
|
ImagePath townBackground;
|
||||||
ImagePath guildBackground;
|
ImagePath guildBackground;
|
||||||
ImagePath guildWindow;
|
ImagePath guildWindow;
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ public:
|
|||||||
virtual void showTavernWindow(const CGObjectInstance *townOrTavern){};
|
virtual void showTavernWindow(const CGObjectInstance *townOrTavern){};
|
||||||
virtual void showThievesGuildWindow (const CGObjectInstance * obj){};
|
virtual void showThievesGuildWindow (const CGObjectInstance * obj){};
|
||||||
virtual void showQuestLog(){};
|
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<int3> &pos){};
|
virtual void tileHidden(const std::unordered_set<int3> &pos){};
|
||||||
virtual void tileRevealed(const std::unordered_set<int3> &pos){};
|
virtual void tileRevealed(const std::unordered_set<int3> &pos){};
|
||||||
virtual void newObject(const CGObjectInstance * obj){}; //eg. ship built in shipyard
|
virtual void newObject(const CGObjectInstance * obj){}; //eg. ship built in shipyard
|
||||||
|
|||||||
+2
-2
@@ -1036,13 +1036,13 @@ namespace
|
|||||||
std::string testAnimation(const std::string & path, const std::string & scope)
|
std::string testAnimation(const std::string & path, const std::string & scope)
|
||||||
{
|
{
|
||||||
TEST_FILE(scope, "Sprites/", path, EResType::ANIMATION);
|
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";
|
return "Animation file \"" + path + "\" was not found";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string textFile(const JsonNode & node)
|
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";
|
return "Text file \"" + node.String() + "\" was not found";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public:
|
|||||||
Obstacle obstacle;
|
Obstacle obstacle;
|
||||||
si32 iconIndex;
|
si32 iconIndex;
|
||||||
std::string identifier;
|
std::string identifier;
|
||||||
std::string appearSound;
|
AudioPath appearSound;
|
||||||
AnimationPath appearAnimation;
|
AnimationPath appearAnimation;
|
||||||
AnimationPath animation;
|
AnimationPath animation;
|
||||||
std::vector<TerrainId> allowedTerrains;
|
std::vector<TerrainId> allowedTerrains;
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ TerrainType * TerrainTypeHandler::loadFromJson( const std::string & scope, const
|
|||||||
info->identifier = identifier;
|
info->identifier = identifier;
|
||||||
info->modScope = scope;
|
info->modScope = scope;
|
||||||
info->moveCost = static_cast<int>(json["moveCost"].Integer());
|
info->moveCost = static_cast<int>(json["moveCost"].Integer());
|
||||||
info->musicFilename = json["music"].String();
|
info->musicFilename = AudioPath::fromJson(json["music"]);
|
||||||
info->tilesFilename = AnimationPath::fromJson(json["tiles"]);
|
info->tilesFilename = AnimationPath::fromJson(json["tiles"]);
|
||||||
info->horseSound = json["horseSound"].String();
|
info->horseSound = AudioPath::fromJson(json["horseSound"]);
|
||||||
info->horseSoundPenalty = json["horseSoundPenalty"].String();
|
info->horseSoundPenalty = AudioPath::fromJson(json["horseSoundPenalty"]);
|
||||||
info->transitionRequired = json["transitionRequired"].Bool();
|
info->transitionRequired = json["transitionRequired"].Bool();
|
||||||
info->terrainViewPatterns = json["terrainViewPatterns"].String();
|
info->terrainViewPatterns = json["terrainViewPatterns"].String();
|
||||||
|
|
||||||
|
|||||||
@@ -67,11 +67,11 @@ public:
|
|||||||
ColorRGBA minimapBlocked;
|
ColorRGBA minimapBlocked;
|
||||||
ColorRGBA minimapUnblocked;
|
ColorRGBA minimapUnblocked;
|
||||||
std::string shortIdentifier;
|
std::string shortIdentifier;
|
||||||
std::string musicFilename;
|
AudioPath musicFilename;
|
||||||
AnimationPath tilesFilename;
|
AnimationPath tilesFilename;
|
||||||
std::string terrainViewPatterns;
|
std::string terrainViewPatterns;
|
||||||
std::string horseSound;
|
AudioPath horseSound;
|
||||||
std::string horseSoundPenalty;
|
AudioPath horseSoundPenalty;
|
||||||
|
|
||||||
std::vector<TerrainPaletteAnimation> paletteAnimation;
|
std::vector<TerrainPaletteAnimation> paletteAnimation;
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ const AnimationPath & CObstacleInstance::getAppearAnimation() const
|
|||||||
return getInfo().appearAnimation;
|
return getInfo().appearAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string & CObstacleInstance::getAppearSound() const
|
const AudioPath & CObstacleInstance::getAppearSound() const
|
||||||
{
|
{
|
||||||
return getInfo().appearSound;
|
return getInfo().appearSound;
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ void CObstacleInstance::serializeJson(JsonSerializeFormat & handler)
|
|||||||
|
|
||||||
//We need only a subset of obstacle info for correct render
|
//We need only a subset of obstacle info for correct render
|
||||||
handler.serializeInt("position", pos);
|
handler.serializeInt("position", pos);
|
||||||
handler.serializeString("appearSound", obstacleInfo.appearSound);
|
handler.serializeStruct("appearSound", obstacleInfo.appearSound);
|
||||||
handler.serializeStruct("appearAnimation", obstacleInfo.appearAnimation);
|
handler.serializeStruct("appearAnimation", obstacleInfo.appearAnimation);
|
||||||
handler.serializeStruct("animation", obstacleInfo.animation);
|
handler.serializeStruct("animation", obstacleInfo.animation);
|
||||||
handler.serializeInt("animationYOffset", animationYOffset);
|
handler.serializeInt("animationYOffset", animationYOffset);
|
||||||
@@ -213,7 +213,7 @@ void SpellCreatedObstacle::serializeJson(JsonSerializeFormat & handler)
|
|||||||
handler.serializeBool("removeOnTrigger", removeOnTrigger);
|
handler.serializeBool("removeOnTrigger", removeOnTrigger);
|
||||||
handler.serializeBool("nativeVisible", nativeVisible);
|
handler.serializeBool("nativeVisible", nativeVisible);
|
||||||
|
|
||||||
handler.serializeString("appearSound", appearSound);
|
handler.serializeStruct("appearSound", appearSound);
|
||||||
handler.serializeStruct("appearAnimation", appearAnimation);
|
handler.serializeStruct("appearAnimation", appearAnimation);
|
||||||
handler.serializeStruct("animation", animation);
|
handler.serializeStruct("animation", animation);
|
||||||
|
|
||||||
@@ -249,7 +249,7 @@ const AnimationPath & SpellCreatedObstacle::getAppearAnimation() const
|
|||||||
return appearAnimation;
|
return appearAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string & SpellCreatedObstacle::getAppearSound() const
|
const AudioPath & SpellCreatedObstacle::getAppearSound() const
|
||||||
{
|
{
|
||||||
return appearSound;
|
return appearSound;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ struct DLL_LINKAGE CObstacleInstance
|
|||||||
//Client helper functions, make it easier to render animations
|
//Client helper functions, make it easier to render animations
|
||||||
virtual const AnimationPath & getAnimation() const;
|
virtual const AnimationPath & getAnimation() const;
|
||||||
virtual const AnimationPath & getAppearAnimation() const;
|
virtual const AnimationPath & getAppearAnimation() const;
|
||||||
virtual const std::string & getAppearSound() const;
|
virtual const AudioPath & getAppearSound() const;
|
||||||
|
|
||||||
virtual int getAnimationYOffset(int imageHeight) const;
|
virtual int getAnimationYOffset(int imageHeight) const;
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ struct DLL_LINKAGE SpellCreatedObstacle : CObstacleInstance
|
|||||||
bool revealed;
|
bool revealed;
|
||||||
bool nativeVisible; //Should native terrain creatures reveal obstacle
|
bool nativeVisible; //Should native terrain creatures reveal obstacle
|
||||||
|
|
||||||
std::string appearSound;
|
AudioPath appearSound;
|
||||||
AnimationPath appearAnimation;
|
AnimationPath appearAnimation;
|
||||||
AnimationPath animation;
|
AnimationPath animation;
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ struct DLL_LINKAGE SpellCreatedObstacle : CObstacleInstance
|
|||||||
//Client helper functions, make it easier to render animations
|
//Client helper functions, make it easier to render animations
|
||||||
const AnimationPath & getAnimation() const override;
|
const AnimationPath & getAnimation() const override;
|
||||||
const AnimationPath & getAppearAnimation() const override;
|
const AnimationPath & getAppearAnimation() const override;
|
||||||
const std::string & getAppearSound() const override;
|
const AudioPath & getAppearSound() const override;
|
||||||
int getAnimationYOffset(int imageHeight) const override;
|
int getAnimationYOffset(int imageHeight) const override;
|
||||||
|
|
||||||
void fromInfo(const ObstacleChanges & info);
|
void fromInfo(const ObstacleChanges & info);
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ void CampaignHandler::readHeaderFromJson(CampaignHeader & ret, JsonNode & reader
|
|||||||
ret.name = reader["name"].String();
|
ret.name = reader["name"].String();
|
||||||
ret.description = reader["description"].String();
|
ret.description = reader["description"].String();
|
||||||
ret.difficultyChoosenByPlayer = reader["allowDifficultySelection"].Bool();
|
ret.difficultyChoosenByPlayer = reader["allowDifficultySelection"].Bool();
|
||||||
ret.music = reader["music"].String();
|
ret.music = AudioPath::fromJson(reader["music"]);
|
||||||
ret.filename = filename;
|
ret.filename = filename;
|
||||||
ret.modName = modName;
|
ret.modName = modName;
|
||||||
ret.encoding = encoding;
|
ret.encoding = encoding;
|
||||||
@@ -167,7 +167,7 @@ CampaignScenario CampaignHandler::readScenarioFromJson(JsonNode & reader)
|
|||||||
if(ret.hasPrologEpilog)
|
if(ret.hasPrologEpilog)
|
||||||
{
|
{
|
||||||
ret.prologVideo = VideoPath::fromJson(identifier["video"]);
|
ret.prologVideo = VideoPath::fromJson(identifier["video"]);
|
||||||
ret.prologMusic = identifier["music"].String();
|
ret.prologMusic = AudioPath::fromJson(identifier["music"]);
|
||||||
ret.prologText = identifier["text"].String();
|
ret.prologText = identifier["text"].String();
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -599,10 +599,10 @@ VideoPath CampaignHandler::prologVideoName(ui8 index)
|
|||||||
return VideoPath();
|
return VideoPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CampaignHandler::prologMusicName(ui8 index)
|
AudioPath CampaignHandler::prologMusicName(ui8 index)
|
||||||
{
|
{
|
||||||
std::vector<std::string> music;
|
std::vector<std::string> music;
|
||||||
return VLC->generaltexth->translate("core.cmpmusic." + std::to_string(static_cast<int>(index)));
|
return AudioPath::builtinTODO(VLC->generaltexth->translate("core.cmpmusic." + std::to_string(static_cast<int>(index))));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CampaignHandler::prologVoiceName(ui8 index)
|
std::string CampaignHandler::prologVoiceName(ui8 index)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class DLL_LINKAGE CampaignHandler
|
|||||||
static std::vector<std::vector<ui8>> getFile(std::unique_ptr<CInputStream> file, bool headerOnly);
|
static std::vector<std::vector<ui8>> getFile(std::unique_ptr<CInputStream> file, bool headerOnly);
|
||||||
|
|
||||||
static VideoPath prologVideoName(ui8 index);
|
static VideoPath prologVideoName(ui8 index);
|
||||||
static std::string prologMusicName(ui8 index);
|
static AudioPath prologMusicName(ui8 index);
|
||||||
static std::string prologVoiceName(ui8 index);
|
static std::string prologVoiceName(ui8 index);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ struct DLL_LINKAGE CampaignScenarioPrologEpilog
|
|||||||
{
|
{
|
||||||
bool hasPrologEpilog = false;
|
bool hasPrologEpilog = false;
|
||||||
VideoPath prologVideo; // from CmpMovie.txt
|
VideoPath prologVideo; // from CmpMovie.txt
|
||||||
std::string prologMusic; // from CmpMusic.txt
|
AudioPath prologMusic; // from CmpMusic.txt
|
||||||
std::string prologText;
|
std::string prologText;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int formatVersion)
|
template <typename Handler> void serialize(Handler &h, const int formatVersion)
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ std::string CampaignHeader::getEncoding() const
|
|||||||
return encoding;
|
return encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CampaignHeader::getMusic() const
|
AudioPath CampaignHeader::getMusic() const
|
||||||
{
|
{
|
||||||
return music;
|
return music;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class DLL_LINKAGE CampaignHeader : public boost::noncopyable
|
|||||||
CampaignRegions campaignRegions;
|
CampaignRegions campaignRegions;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string description;
|
std::string description;
|
||||||
std::string music;
|
AudioPath music;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
std::string modName;
|
std::string modName;
|
||||||
std::string encoding;
|
std::string encoding;
|
||||||
@@ -95,7 +95,7 @@ public:
|
|||||||
std::string getFilename() const;
|
std::string getFilename() const;
|
||||||
std::string getModName() const;
|
std::string getModName() const;
|
||||||
std::string getEncoding() const;
|
std::string getEncoding() const;
|
||||||
std::string getMusic() const;
|
AudioPath getMusic() const;
|
||||||
|
|
||||||
const CampaignRegions & getRegions() const;
|
const CampaignRegions & getRegions() const;
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ std::unordered_map<ResourcePath, boost::filesystem::path> CFilesystemLoader::lis
|
|||||||
{
|
{
|
||||||
static const EResType initArray[] = {
|
static const EResType initArray[] = {
|
||||||
EResType::DIRECTORY,
|
EResType::DIRECTORY,
|
||||||
EResType::TEXT,
|
EResType::JSON,
|
||||||
EResType::ARCHIVE_LOD,
|
EResType::ARCHIVE_LOD,
|
||||||
EResType::ARCHIVE_VID,
|
EResType::ARCHIVE_VID,
|
||||||
EResType::ARCHIVE_SND,
|
EResType::ARCHIVE_SND,
|
||||||
|
|||||||
@@ -113,10 +113,10 @@ void CFilesystemGenerator::loadArchive(const std::string &mountPoint, const Json
|
|||||||
void CFilesystemGenerator::loadJsonMap(const std::string &mountPoint, const JsonNode & config)
|
void CFilesystemGenerator::loadJsonMap(const std::string &mountPoint, const JsonNode & config)
|
||||||
{
|
{
|
||||||
std::string URI = prefix + config["path"].String();
|
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)
|
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<char *>(configData.first.get()), configData.second);
|
const JsonNode configInitial(reinterpret_cast<char *>(configData.first.get()), configData.second);
|
||||||
filesystem->addLoader(new CMappedFileLoader(mountPoint, configInitial), false);
|
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)
|
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<char *>(fsConfigData.first.get()), fsConfigData.second);
|
const JsonNode fsConfig(reinterpret_cast<char *>(fsConfigData.first.get()), fsConfigData.second);
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ EResType EResTypeHelper::getTypeFromExtension(std::string extension)
|
|||||||
static const std::map<std::string, EResType> stringToRes =
|
static const std::map<std::string, EResType> stringToRes =
|
||||||
{
|
{
|
||||||
{".TXT", EResType::TEXT},
|
{".TXT", EResType::TEXT},
|
||||||
{".JSON", EResType::TEXT},
|
{".JSON", EResType::JSON},
|
||||||
{".DEF", EResType::ANIMATION},
|
{".DEF", EResType::ANIMATION},
|
||||||
{".MSK", EResType::MASK},
|
{".MSK", EResType::MASK},
|
||||||
{".MSG", EResType::MASK},
|
{".MSG", EResType::MASK},
|
||||||
@@ -148,6 +148,7 @@ std::string EResTypeHelper::getEResTypeAsString(EResType type)
|
|||||||
static const std::map<EResType, std::string> stringToRes =
|
static const std::map<EResType, std::string> stringToRes =
|
||||||
{
|
{
|
||||||
MAP_ENUM(TEXT)
|
MAP_ENUM(TEXT)
|
||||||
|
MAP_ENUM(JSON)
|
||||||
MAP_ENUM(ANIMATION)
|
MAP_ENUM(ANIMATION)
|
||||||
MAP_ENUM(MASK)
|
MAP_ENUM(MASK)
|
||||||
MAP_ENUM(CAMPAIGN)
|
MAP_ENUM(CAMPAIGN)
|
||||||
|
|||||||
@@ -140,6 +140,12 @@ public:
|
|||||||
:ResourcePath("", Type)
|
:ResourcePath("", Type)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
static ResourcePathTempl fromResource(const ResourcePath & resource)
|
||||||
|
{
|
||||||
|
assert(Type == resource.getType());
|
||||||
|
return ResourcePathTempl(resource);
|
||||||
|
}
|
||||||
|
|
||||||
static ResourcePathTempl builtin(const std::string & filename)
|
static ResourcePathTempl builtin(const std::string & filename)
|
||||||
{
|
{
|
||||||
return ResourcePathTempl(filename, Type);
|
return ResourcePathTempl(filename, Type);
|
||||||
@@ -177,6 +183,7 @@ using ImagePath = ResourcePathTempl<EResType::IMAGE>;
|
|||||||
using TextPath = ResourcePathTempl<EResType::TEXT>;
|
using TextPath = ResourcePathTempl<EResType::TEXT>;
|
||||||
using JsonPath = ResourcePathTempl<EResType::JSON>;
|
using JsonPath = ResourcePathTempl<EResType::JSON>;
|
||||||
using VideoPath = ResourcePathTempl<EResType::VIDEO>;
|
using VideoPath = ResourcePathTempl<EResType::VIDEO>;
|
||||||
|
using AudioPath = ResourcePathTempl<EResType::SOUND>;
|
||||||
|
|
||||||
namespace EResTypeHelper
|
namespace EResTypeHelper
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -83,13 +83,13 @@ void AObjectTypeHandler::init(const JsonNode & input)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(const JsonNode & node : input["sounds"]["ambient"].Vector())
|
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())
|
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())
|
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())
|
if(input["aiValue"].isNull())
|
||||||
aiValue = std::nullopt;
|
aiValue = std::nullopt;
|
||||||
|
|||||||
@@ -9,13 +9,15 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../filesystem/ResourcePath.h"
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct SObjectSounds
|
struct SObjectSounds
|
||||||
{
|
{
|
||||||
std::vector<std::string> ambient;
|
std::vector<AudioPath> ambient;
|
||||||
std::vector<std::string> visit;
|
std::vector<AudioPath> visit;
|
||||||
std::vector<std::string> removal;
|
std::vector<AudioPath> removal;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ std::string CGObjectInstance::getObjectName() const
|
|||||||
return VLC->objtypeh->getObjectName(ID, subID);
|
return VLC->objtypeh->getObjectName(ID, subID);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> CGObjectInstance::getAmbientSound() const
|
std::optional<AudioPath> CGObjectInstance::getAmbientSound() const
|
||||||
{
|
{
|
||||||
const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).ambient;
|
const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).ambient;
|
||||||
if(!sounds.empty())
|
if(!sounds.empty())
|
||||||
@@ -223,7 +223,7 @@ std::optional<std::string> CGObjectInstance::getAmbientSound() const
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> CGObjectInstance::getVisitSound() const
|
std::optional<AudioPath> CGObjectInstance::getVisitSound() const
|
||||||
{
|
{
|
||||||
const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).visit;
|
const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).visit;
|
||||||
if(!sounds.empty())
|
if(!sounds.empty())
|
||||||
@@ -232,7 +232,7 @@ std::optional<std::string> CGObjectInstance::getVisitSound() const
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> CGObjectInstance::getRemovalSound() const
|
std::optional<AudioPath> CGObjectInstance::getRemovalSound() const
|
||||||
{
|
{
|
||||||
const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).removal;
|
const auto & sounds = VLC->objtypeh->getObjectSounds(ID, subID).removal;
|
||||||
if(!sounds.empty())
|
if(!sounds.empty())
|
||||||
|
|||||||
@@ -82,9 +82,9 @@ public:
|
|||||||
|
|
||||||
virtual bool isTile2Terrain() const { return false; }
|
virtual bool isTile2Terrain() const { return false; }
|
||||||
|
|
||||||
std::optional<std::string> getAmbientSound() const;
|
std::optional<AudioPath> getAmbientSound() const;
|
||||||
std::optional<std::string> getVisitSound() const;
|
std::optional<AudioPath> getVisitSound() const;
|
||||||
std::optional<std::string> getRemovalSound() const;
|
std::optional<AudioPath> getRemovalSound() const;
|
||||||
|
|
||||||
/** VIRTUAL METHODS **/
|
/** VIRTUAL METHODS **/
|
||||||
|
|
||||||
|
|||||||
@@ -904,7 +904,7 @@ std::unique_ptr<CMapHeader> CMapLoaderJson::loadMapHeader()
|
|||||||
|
|
||||||
JsonNode CMapLoaderJson::getFromArchive(const std::string & archiveFilename)
|
JsonNode CMapLoaderJson::getFromArchive(const std::string & archiveFilename)
|
||||||
{
|
{
|
||||||
ResourcePath resource(archiveFilename, EResType::TEXT);
|
JsonPath resource = JsonPath::builtin(archiveFilename);
|
||||||
|
|
||||||
if(!loader.existsResource(resource))
|
if(!loader.existsResource(resource))
|
||||||
throw std::runtime_error(archiveFilename+" not found");
|
throw std::runtime_error(archiveFilename+" not found");
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ const std::string & CSpell::getIconScroll() const
|
|||||||
return iconScroll;
|
return iconScroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string & CSpell::getCastSound() const
|
const AudioPath & CSpell::getCastSound() const
|
||||||
{
|
{
|
||||||
return castSound;
|
return castSound;
|
||||||
}
|
}
|
||||||
@@ -896,7 +896,7 @@ CSpell * CSpellHandler::loadFromJson(const std::string & scope, const JsonNode &
|
|||||||
}
|
}
|
||||||
|
|
||||||
const JsonNode & soundsNode = json["sounds"];
|
const JsonNode & soundsNode = json["sounds"];
|
||||||
spell->castSound = soundsNode["cast"].String();
|
spell->castSound = AudioPath::fromJson(soundsNode["cast"]);
|
||||||
|
|
||||||
//load level attributes
|
//load level attributes
|
||||||
const int levelsCount = GameConstants::SPELL_SCHOOL_LEVELS;
|
const int levelsCount = GameConstants::SPELL_SCHOOL_LEVELS;
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ public:
|
|||||||
const std::string & getIconScenarioBonus() const;
|
const std::string & getIconScenarioBonus() const;
|
||||||
const std::string & getIconScroll() const;
|
const std::string & getIconScroll() const;
|
||||||
|
|
||||||
const std::string & getCastSound() const override;
|
const AudioPath & getCastSound() const;
|
||||||
|
|
||||||
void updateFrom(const JsonNode & data);
|
void updateFrom(const JsonNode & data);
|
||||||
void serializeJson(JsonSerializeFormat & handler);
|
void serializeJson(JsonSerializeFormat & handler);
|
||||||
@@ -354,7 +354,7 @@ private:
|
|||||||
std::string iconScroll;
|
std::string iconScroll;
|
||||||
|
|
||||||
///sound related stuff
|
///sound related stuff
|
||||||
std::string castSound;
|
AudioPath castSound;
|
||||||
|
|
||||||
std::vector<LevelInfo> levels;
|
std::vector<LevelInfo> levels;
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ void ObstacleSideOptions::serializeJson(JsonSerializeFormat & handler)
|
|||||||
serializeRelativeShape(handler, "shape", shape);
|
serializeRelativeShape(handler, "shape", shape);
|
||||||
serializeRelativeShape(handler, "range", range);
|
serializeRelativeShape(handler, "range", range);
|
||||||
|
|
||||||
handler.serializeString("appearSound", appearSound);
|
handler.serializeStruct("appearSound", appearSound);
|
||||||
handler.serializeStruct("appearAnimation", appearAnimation);
|
handler.serializeStruct("appearAnimation", appearAnimation);
|
||||||
handler.serializeStruct("animation", animation);
|
handler.serializeStruct("animation", animation);
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public:
|
|||||||
RelativeShape shape; //shape of single obstacle relative to obstacle position
|
RelativeShape shape; //shape of single obstacle relative to obstacle position
|
||||||
RelativeShape range; //position of obstacles relative to effect destination
|
RelativeShape range; //position of obstacles relative to effect destination
|
||||||
|
|
||||||
std::string appearSound;
|
AudioPath appearSound;
|
||||||
AnimationPath appearAnimation;
|
AnimationPath appearAnimation;
|
||||||
AnimationPath animation;
|
AnimationPath animation;
|
||||||
|
|
||||||
|
|||||||
@@ -583,7 +583,7 @@ void Animation::init()
|
|||||||
source[defEntry.first].resize(defEntry.second);
|
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()))
|
//if(vstd::contains(graphics->imageLists, resID.getName()))
|
||||||
//initFromJson(graphics->imageLists[resID.getName()]);
|
//initFromJson(graphics->imageLists[resID.getName()]);
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ TEST(MapFormat, Random)
|
|||||||
|
|
||||||
static JsonNode getFromArchive(CZipLoader & archive, const std::string & archiveFilename)
|
static JsonNode getFromArchive(CZipLoader & archive, const std::string & archiveFilename)
|
||||||
{
|
{
|
||||||
ResourcePath resource(archiveFilename, EResType::TEXT);
|
JsonPath resource = JsonPath::builtin(archiveFilename);
|
||||||
|
|
||||||
if(!archive.existsResource(resource))
|
if(!archive.existsResource(resource))
|
||||||
throw std::runtime_error(archiveFilename + " not found");
|
throw std::runtime_error(archiveFilename + " not found");
|
||||||
|
|||||||
Reference in New Issue
Block a user