diff --git a/AI/Nullkiller/Engine/PriorityEvaluator.cpp b/AI/Nullkiller/Engine/PriorityEvaluator.cpp index 7b0b40086..202644db3 100644 --- a/AI/Nullkiller/Engine/PriorityEvaluator.cpp +++ b/AI/Nullkiller/Engine/PriorityEvaluator.cpp @@ -68,7 +68,7 @@ PriorityEvaluator::~PriorityEvaluator() void PriorityEvaluator::initVisitTile() { - auto file = CResourceHandler::get()->load(ResourceID("config/ai/object-priorities.txt"))->readAll(); + auto file = CResourceHandler::get()->load(ResourcePath("config/ai/object-priorities.txt"))->readAll(); std::string str = std::string((char *)file.first.get(), file.second); engine = fl::FllImporter().fromString(str); armyLossPersentageVariable = engine->getInputVariable("armyLoss"); diff --git a/client/CMT.cpp b/client/CMT.cpp index aebf3a916..4c0d97a76 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -251,7 +251,7 @@ int main(int argc, char * argv[]) // Some basic data validation to produce better error messages in cases of incorrect install auto testFile = [](std::string filename, std::string message) { - if (!CResourceHandler::get()->existsResource(ResourceID(filename))) + if (!CResourceHandler::get()->existsResource(ResourcePath(filename))) handleFatalError(message, false); }; diff --git a/client/CMusicHandler.cpp b/client/CMusicHandler.cpp index 6c527c2e7..57a3c5aad 100644 --- a/client/CMusicHandler.cpp +++ b/client/CMusicHandler.cpp @@ -75,7 +75,7 @@ void CSoundHandler::onVolumeChange(const JsonNode &volumeNode) CSoundHandler::CSoundHandler(): listener(settings.listen["general"]["sound"]), - ambientConfig(JsonNode(ResourceID("config/ambientSounds.json"))) + ambientConfig(JsonNode(ResourcePath("config/ambientSounds.json"))) { listener(std::bind(&CSoundHandler::onVolumeChange, this, _1)); @@ -126,7 +126,7 @@ Mix_Chunk *CSoundHandler::GetSoundChunk(std::string &sound, bool cache) if (cache && soundChunks.find(sound) != soundChunks.end()) return soundChunks[sound].first; - auto data = CResourceHandler::get()->load(ResourceID(std::string("SOUNDS/") + sound, EResType::SOUND))->readAll(); + auto data = CResourceHandler::get()->load(ResourcePath(std::string("SOUNDS/") + sound, EResType::SOUND))->readAll(); SDL_RWops *ops = SDL_RWFromMem(data.first.get(), (int)data.second); Mix_Chunk *chunk = Mix_LoadWAV_RW(ops, 1); // will free ops @@ -357,7 +357,7 @@ CMusicHandler::CMusicHandler(): { listener(std::bind(&CMusicHandler::onVolumeChange, this, _1)); - auto mp3files = CResourceHandler::get()->getFilteredFiles([](const ResourceID & id) -> bool + auto mp3files = CResourceHandler::get()->getFilteredFiles([](const ResourcePath & id) -> bool { if(id.getType() != EResType::SOUND) return false; @@ -369,7 +369,7 @@ CMusicHandler::CMusicHandler(): return true; }); - for(const ResourceID & file : mp3files) + for(const ResourcePath & file : mp3files) { if(boost::algorithm::istarts_with(file.getName(), "MUSIC/Combat")) addEntryToSet("battle", file.getName()); @@ -573,7 +573,7 @@ void MusicEntry::load(std::string musicURI) try { - auto musicFile = MakeSDLRWops(CResourceHandler::get()->load(ResourceID(std::move(musicURI), EResType::SOUND))); + auto musicFile = MakeSDLRWops(CResourceHandler::get()->load(ResourcePath(std::move(musicURI), EResType::SOUND))); music = Mix_LoadMUS_RW(musicFile, SDL_TRUE); } catch(std::exception &e) diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 2240cd638..8a3daf45b 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -1112,11 +1112,11 @@ void CPlayerInterface::showBlockingDialog( const std::string &text, const std::v for (auto & component : components) intComps.push_back(std::make_shared(component)); //will be deleted by CSelWindow::close - std::vector > > pom; - pom.push_back(std::pair >("IOKAY.DEF",0)); + std::vector > > pom; + pom.push_back({ AnimationPath::builtin("IOKAY.DEF"),0}); if (cancel) { - pom.push_back(std::pair >("ICANCEL.DEF",0)); + pom.push_back({AnimationPath::builtin("ICANCEL.DEF"),0}); } int charperline = 35; diff --git a/client/CServerHandler.cpp b/client/CServerHandler.cpp index ddf40406d..780ea9097 100644 --- a/client/CServerHandler.cpp +++ b/client/CServerHandler.cpp @@ -748,7 +748,7 @@ void CServerHandler::debugStartTest(std::string filename, bool save) if(save) { resetStateForLobby(StartInfo::LOAD_GAME); - mapInfo->saveInit(ResourceID(filename, EResType::SAVEGAME)); + mapInfo->saveInit(ResourcePath(filename, EResType::SAVEGAME)); screenType = ESelectionScreen::loadGame; } else diff --git a/client/CVideoHandler.cpp b/client/CVideoHandler.cpp index f6a88cb54..c685ff422 100644 --- a/client/CVideoHandler.cpp +++ b/client/CVideoHandler.cpp @@ -85,7 +85,7 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay, bool scal doLoop = loop; frameTime = 0; - ResourceID resource(std::string("Video/") + fname, EResType::VIDEO); + ResourcePath resource(std::string("Video/") + fname, EResType::VIDEO); if (!CResourceHandler::get()->existsResource(resource)) { diff --git a/client/Client.cpp b/client/Client.cpp index b1d89cfa4..c5087bdbc 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -222,7 +222,7 @@ void CClient::loadGame(CGameState * initializedGameState) // try to deserialize client data including sleepingHeroes try { - boost::filesystem::path clientSaveName = *CResourceHandler::get()->getResourceName(ResourceID(CSH->si->mapname, EResType::CLIENT_SAVEGAME)); + boost::filesystem::path clientSaveName = *CResourceHandler::get()->getResourceName(ResourcePath(CSH->si->mapname, EResType::CLIENT_SAVEGAME)); if(clientSaveName.empty()) throw std::runtime_error("Cannot open client part of " + CSH->si->mapname); diff --git a/client/ClientCommandManager.cpp b/client/ClientCommandManager.cpp index 5a4c2f8cf..43b98723d 100644 --- a/client/ClientCommandManager.cpp +++ b/client/ClientCommandManager.cpp @@ -182,12 +182,12 @@ void ClientCommandManager::handleNotDialogCommand() void ClientCommandManager::handleConvertTextCommand() { logGlobal->info("Searching for available maps"); - std::unordered_set mapList = CResourceHandler::get()->getFilteredFiles([&](const ResourceID & ident) + std::unordered_set mapList = CResourceHandler::get()->getFilteredFiles([&](const ResourcePath & ident) { return ident.getType() == EResType::MAP; }); - std::unordered_set campaignList = CResourceHandler::get()->getFilteredFiles([&](const ResourceID & ident) + std::unordered_set campaignList = CResourceHandler::get()->getFilteredFiles([&](const ResourcePath & ident) { return ident.getType() == EResType::CAMPAIGN; }); @@ -292,7 +292,7 @@ void ClientCommandManager::handleGetTextCommand() VCMIDirs::get().userExtractedPath(); auto list = - CResourceHandler::get()->getFilteredFiles([](const ResourceID & ident) + CResourceHandler::get()->getFilteredFiles([](const ResourcePath & ident) { return ident.getType() == EResType::TEXT && boost::algorithm::starts_with(ident.getName(), "DATA/"); }); @@ -317,7 +317,7 @@ void ClientCommandManager::handleDef2bmpCommand(std::istringstream& singleWordBu { std::string URI; singleWordBuffer >> URI; - std::unique_ptr anim = std::make_unique(URI); + std::unique_ptr anim = std::make_unique(AnimationPath::builtin(URI)); anim->preload(); anim->exportBitmaps(VCMIDirs::get().userExtractedPath()); } @@ -327,11 +327,11 @@ void ClientCommandManager::handleExtractCommand(std::istringstream& singleWordBu std::string URI; singleWordBuffer >> URI; - if(CResourceHandler::get()->existsResource(ResourceID(URI))) + if(CResourceHandler::get()->existsResource(ResourcePath(URI))) { const boost::filesystem::path outPath = VCMIDirs::get().userExtractedPath() / URI; - auto data = CResourceHandler::get()->load(ResourceID(URI))->readAll(); + auto data = CResourceHandler::get()->load(ResourcePath(URI))->readAll(); boost::filesystem::create_directories(outPath.parent_path()); std::ofstream outFile(outPath.c_str(), std::ofstream::binary); diff --git a/client/adventureMap/AdventureMapWidget.cpp b/client/adventureMap/AdventureMapWidget.cpp index 7ee69da42..1af8cdb8d 100644 --- a/client/adventureMap/AdventureMapWidget.cpp +++ b/client/adventureMap/AdventureMapWidget.cpp @@ -30,7 +30,7 @@ #include "../PlayerLocalState.h" #include "../../lib/constants/StringConstants.h" -#include "../../lib/filesystem/ResourceID.h" +#include "../../lib/filesystem/ResourcePath.h" AdventureMapWidget::AdventureMapWidget( std::shared_ptr shortcuts ) : shortcuts(shortcuts) @@ -56,11 +56,11 @@ AdventureMapWidget::AdventureMapWidget( std::shared_ptr s for (const auto & entry : shortcuts->getShortcuts()) addShortcut(entry.shortcut, entry.callback); - const JsonNode config(ResourceID("config/widgets/adventureMap.json")); + const JsonNode config(ResourcePath("config/widgets/adventureMap.json")); for(const auto & entry : config["options"]["imagesPlayerColored"].Vector()) { - ResourceID resourceName(entry.String(), EResType::IMAGE); + ResourcePath resourceName(entry.String(), EResType::IMAGE); playerColorerImages.push_back(resourceName.getName()); } @@ -127,22 +127,22 @@ Rect AdventureMapWidget::readArea(const JsonNode & source, const Rect & bounding return Rect(topLeft + boundingBox.topLeft(), dimensions); } -std::shared_ptr AdventureMapWidget::loadImage(const std::string & name) +std::shared_ptr AdventureMapWidget::loadImage(const JsonNode & name) { - ResourceID resource(name, EResType::IMAGE); + ImagePath resource = ImagePath::fromJson(name); if(images.count(resource.getName()) == 0) - images[resource.getName()] = IImage::createFromFile(resource.getName()); + images[resource.getName()] = IImage::createFromFile(resource); return images[resource.getName()]; } -std::shared_ptr AdventureMapWidget::loadAnimation(const std::string & name) +std::shared_ptr AdventureMapWidget::loadAnimation(const JsonNode & name) { - ResourceID resource(name, EResType::ANIMATION); + AnimationPath resource = AnimationPath::fromJson(name); if(animations.count(resource.getName()) == 0) - animations[resource.getName()] = std::make_shared(resource.getName()); + animations[resource.getName()] = std::make_shared(resource); return animations[resource.getName()]; } @@ -158,15 +158,14 @@ std::shared_ptr AdventureMapWidget::buildMapImage(const JsonNode & i { Rect targetArea = readTargetArea(input["area"]); Rect sourceArea = readSourceArea(input["sourceArea"], input["area"]); - std::string image = input["image"].String(); - return std::make_shared(loadImage(image), targetArea, sourceArea); + return std::make_shared(loadImage(input["image"]), targetArea, sourceArea); } std::shared_ptr AdventureMapWidget::buildMapButton(const JsonNode & input) { auto position = readTargetArea(input["area"]); - auto image = input["image"].String(); + auto image = AnimationPath::fromJson(input["image"]); auto help = readHintText(input["help"]); bool playerColored = input["playerColored"].Bool(); @@ -259,9 +258,8 @@ std::shared_ptr AdventureMapWidget::buildMapIcon(const JsonNode & in Rect area = readTargetArea(input["area"]); size_t index = input["index"].Integer(); size_t perPlayer = input["perPlayer"].Integer(); - std::string image = input["image"].String(); - return std::make_shared(area.topLeft(), loadAnimation(image), index, perPlayer); + return std::make_shared(area.topLeft(), loadAnimation(input["image"]), index, perPlayer); } std::shared_ptr AdventureMapWidget::buildMapTownList(const JsonNode & input) @@ -298,7 +296,7 @@ std::shared_ptr AdventureMapWidget::buildMinimap(const JsonNode & in std::shared_ptr AdventureMapWidget::buildResourceDateBar(const JsonNode & input) { Rect area = readTargetArea(input["area"]); - std::string image = input["image"].String(); + auto image = ImagePath::fromJson(input["image"]); auto result = std::make_shared(image, area.topLeft()); @@ -320,7 +318,7 @@ std::shared_ptr AdventureMapWidget::buildResourceDateBar(const JsonN std::shared_ptr AdventureMapWidget::buildStatusBar(const JsonNode & input) { Rect area = readTargetArea(input["area"]); - std::string image = input["image"].String(); + auto image = ImagePath::fromJson(input["image"]); auto background = std::make_shared(image, area); @@ -330,7 +328,7 @@ std::shared_ptr AdventureMapWidget::buildStatusBar(const JsonNode & std::shared_ptr AdventureMapWidget::buildTexturePlayerColored(const JsonNode & input) { logGlobal->debug("Building widget CFilledTexture"); - auto image = input["image"].String(); + auto image = ImagePath::fromJson(input["image"]); Rect area = readTargetArea(input["area"]); return std::make_shared(image, area); } diff --git a/client/adventureMap/AdventureMapWidget.h b/client/adventureMap/AdventureMapWidget.h index bf02f7c46..185440397 100644 --- a/client/adventureMap/AdventureMapWidget.h +++ b/client/adventureMap/AdventureMapWidget.h @@ -48,8 +48,8 @@ class AdventureMapWidget : public InterfaceObjectConfigurable Rect readSourceArea(const JsonNode & source, const JsonNode & sourceCommon); Rect readArea(const JsonNode & source, const Rect & boundingBox); - std::shared_ptr loadImage(const std::string & name); - std::shared_ptr loadAnimation(const std::string & name); + std::shared_ptr loadImage(const JsonNode & name); + std::shared_ptr loadAnimation(const JsonNode & name); std::shared_ptr buildInfobox(const JsonNode & input); std::shared_ptr buildMapImage(const JsonNode & input); diff --git a/client/adventureMap/AdventureOptions.cpp b/client/adventureMap/AdventureOptions.cpp index 5f9dc7b67..328baedeb 100644 --- a/client/adventureMap/AdventureOptions.cpp +++ b/client/adventureMap/AdventureOptions.cpp @@ -25,22 +25,22 @@ #include "../../lib/StartInfo.h" AdventureOptions::AdventureOptions() - : CWindowObject(PLAYER_COLORED, "ADVOPTS") + : CWindowObject(PLAYER_COLORED, ImagePath::builtin("ADVOPTS")) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - viewWorld = std::make_shared(Point(24, 23), "ADVVIEW.DEF", CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_VIEW_WORLD); + viewWorld = std::make_shared(Point(24, 23), AnimationPath::builtin("ADVVIEW.DEF"), CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_VIEW_WORLD); viewWorld->addCallback( [] { LOCPLINT->viewWorldMap(); }); - exit = std::make_shared(Point(204, 313), "IOK6432.DEF", CButton::tooltip(), std::bind(&AdventureOptions::close, this), EShortcut::GLOBAL_RETURN); + exit = std::make_shared(Point(204, 313), AnimationPath::builtin("IOK6432.DEF"), CButton::tooltip(), std::bind(&AdventureOptions::close, this), EShortcut::GLOBAL_RETURN); - scenInfo = std::make_shared(Point(24, 198), "ADVINFO.DEF", CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_VIEW_SCENARIO); + scenInfo = std::make_shared(Point(24, 198), AnimationPath::builtin("ADVINFO.DEF"), CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_VIEW_SCENARIO); scenInfo->addCallback(AdventureOptions::showScenarioInfo); - puzzle = std::make_shared(Point(24, 81), "ADVPUZ.DEF", CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_VIEW_PUZZLE); + puzzle = std::make_shared(Point(24, 81), AnimationPath::builtin("ADVPUZ.DEF"), CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_VIEW_PUZZLE); puzzle->addCallback(std::bind(&CPlayerInterface::showPuzzleMap, LOCPLINT)); - dig = std::make_shared(Point(24, 139), "ADVDIG.DEF", CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_DIG_GRAIL); + dig = std::make_shared(Point(24, 139), AnimationPath::builtin("ADVDIG.DEF"), CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_DIG_GRAIL); if(const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero()) dig->addCallback(std::bind(&CPlayerInterface::tryDigging, LOCPLINT, h)); else diff --git a/client/adventureMap/CInfoBar.cpp b/client/adventureMap/CInfoBar.cpp index 7f5226d46..cbfd5e835 100644 --- a/client/adventureMap/CInfoBar.cpp +++ b/client/adventureMap/CInfoBar.cpp @@ -51,7 +51,7 @@ CInfoBar::EmptyVisibleInfo::EmptyVisibleInfo() CInfoBar::VisibleHeroInfo::VisibleHeroInfo(const CGHeroInstance * hero) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - background = std::make_shared("ADSTATHR"); + background = std::make_shared(ImagePath::builtin("ADSTATHR")); if(settings["gameTweaks"]["infoBarCreatureManagement"].Bool()) heroTooltip = std::make_shared(Point(0,0), hero); @@ -62,7 +62,7 @@ CInfoBar::VisibleHeroInfo::VisibleHeroInfo(const CGHeroInstance * hero) CInfoBar::VisibleTownInfo::VisibleTownInfo(const CGTownInstance * town) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - background = std::make_shared("ADSTATCS"); + background = std::make_shared(ImagePath::builtin("ADSTATCS")); if(settings["gameTweaks"]["infoBarCreatureManagement"].Bool()) townTooltip = std::make_shared(Point(0,0), town); @@ -88,36 +88,36 @@ CInfoBar::VisibleDateInfo::VisibleDateInfo() forceRefresh.push_back(label); } -std::string CInfoBar::VisibleDateInfo::getNewDayName() +AnimationPath CInfoBar::VisibleDateInfo::getNewDayName() { if(LOCPLINT->cb->getDate(Date::DAY) == 1) - return "NEWDAY"; + return AnimationPath::builtin("NEWDAY"); if(LOCPLINT->cb->getDate(Date::DAY_OF_WEEK) != 1) - return "NEWDAY"; + return AnimationPath("NEWDAY"); switch(LOCPLINT->cb->getDate(Date::WEEK)) { case 1: - return "NEWWEEK1"; + return AnimationPath("NEWWEEK1"); case 2: - return "NEWWEEK2"; + return AnimationPath("NEWWEEK2"); case 3: - return "NEWWEEK3"; + return AnimationPath("NEWWEEK3"); case 4: - return "NEWWEEK4"; + return AnimationPath("NEWWEEK4"); default: - return ""; + return AnimationPath(); } } CInfoBar::VisibleEnemyTurnInfo::VisibleEnemyTurnInfo(PlayerColor player) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - background = std::make_shared("ADSTATNX"); - banner = std::make_shared("CREST58", player.getNum(), 0, 20, 51); - sand = std::make_shared(99, 51, "HOURSAND", 0, 100); // H3 uses around 100 ms per frame - glass = std::make_shared(99, 51, "HOURGLAS", CShowableAnim::PLAY_ONCE, 1000); // H3 scales this nicely for AI turn duration, don't have anything like that in vcmi + background = std::make_shared(ImagePath::builtin("ADSTATNX")); + banner = std::make_shared(AnimationPath::builtin("CREST58"), player.getNum(), 0, 20, 51); + sand = std::make_shared(99, 51, AnimationPath::builtin("HOURSAND"), 0, 100); // H3 uses around 100 ms per frame + glass = std::make_shared(99, 51, AnimationPath::builtin("HOURGLAS"), CShowableAnim::PLAY_ONCE, 1000); // H3 scales this nicely for AI turn duration, don't have anything like that in vcmi } CInfoBar::VisibleGameStatusInfo::VisibleGameStatusInfo() @@ -148,14 +148,14 @@ CInfoBar::VisibleGameStatusInfo::VisibleGameStatusInfo() } //generate widgets - background = std::make_shared("ADSTATIN"); + background = std::make_shared(ImagePath::builtin("ADSTATIN")); allyLabel = std::make_shared(10, 106, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[390] + ":"); enemyLabel = std::make_shared(10, 136, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[391] + ":"); int posx = allyLabel->pos.w + allyLabel->pos.x - pos.x + 4; for(PlayerColor & player : allies) { - auto image = std::make_shared("ITGFLAGS", player.getNum(), 0, posx, 102); + auto image = std::make_shared(AnimationPath::builtin("ITGFLAGS"), player.getNum(), 0, posx, 102); posx += image->pos.w; flags.push_back(image); } @@ -163,14 +163,14 @@ CInfoBar::VisibleGameStatusInfo::VisibleGameStatusInfo() posx = enemyLabel->pos.w + enemyLabel->pos.x - pos.x + 4; for(PlayerColor & player : enemies) { - auto image = std::make_shared("ITGFLAGS", player.getNum(), 0, posx, 132); + auto image = std::make_shared(AnimationPath::builtin("ITGFLAGS"), player.getNum(), 0, posx, 132); posx += image->pos.w; flags.push_back(image); } for(size_t i=0; i("itmtl", i, 0, 6 + 42 * (int)i , 11)); + hallIcons.push_back(std::make_shared(AnimationPath::builtin("itmtl"), i, 0, 6 + 42 * (int)i , 11)); if(halls[i]) hallLabels.push_back(std::make_shared( 26 + 42 * (int)i, 64, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, std::to_string(halls[i]))); } @@ -180,7 +180,7 @@ CInfoBar::VisibleComponentInfo::VisibleComponentInfo(const std::vector("ADSTATOT", 1, 0); + background = std::make_shared(ImagePath::builtin("ADSTATOT"), 1, 0); auto fullRect = Rect(CInfoBar::offset, CInfoBar::offset, data_width - 2 * CInfoBar::offset, data_height - 2 * CInfoBar::offset); auto textRect = fullRect; auto imageRect = fullRect; diff --git a/client/adventureMap/CInfoBar.h b/client/adventureMap/CInfoBar.h index c69fed1f0..8dc8c88cb 100644 --- a/client/adventureMap/CInfoBar.h +++ b/client/adventureMap/CInfoBar.h @@ -11,6 +11,7 @@ #include "../gui/CIntObject.h" #include "CConfigHandler.h" +#include "../../lib/filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -86,7 +87,7 @@ private: std::shared_ptr animation; std::shared_ptr label; - std::string getNewDayName(); + AnimationPath getNewDayName(); public: VisibleDateInfo(); }; diff --git a/client/adventureMap/CList.cpp b/client/adventureMap/CList.cpp index 4758dac6b..cd84d4348 100644 --- a/client/adventureMap/CList.cpp +++ b/client/adventureMap/CList.cpp @@ -206,9 +206,9 @@ void CList::selectPrev() CHeroList::CEmptyHeroItem::CEmptyHeroItem() { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - movement = std::make_shared("IMOBIL", 0, 0, 0, 1); - portrait = std::make_shared("HPSXXX", movement->pos.w + 1, 0); - mana = std::make_shared("IMANA", 0, 0, movement->pos.w + portrait->pos.w + 2, 1 ); + movement = std::make_shared(AnimationPath::builtin("IMOBIL"), 0, 0, 0, 1); + portrait = std::make_shared(ImagePath::builtin("HPSXXX"), movement->pos.w + 1, 0); + mana = std::make_shared(AnimationPath::builtin("IMANA"), 0, 0, movement->pos.w + portrait->pos.w + 2, 1 ); pos.w = mana->pos.w + mana->pos.x - pos.x; pos.h = std::max(std::max(movement->pos.h + 1, mana->pos.h + 1), portrait->pos.h); @@ -219,9 +219,9 @@ CHeroList::CHeroItem::CHeroItem(CHeroList *parent, const CGHeroInstance * Hero) hero(Hero) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - movement = std::make_shared("IMOBIL", 0, 0, 0, 1); - portrait = std::make_shared("PortraitsSmall", hero->portrait, 0, movement->pos.w + 1); - mana = std::make_shared("IMANA", 0, 0, movement->pos.w + portrait->pos.w + 2, 1); + movement = std::make_shared(AnimationPath::builtin("IMOBIL"), 0, 0, 0, 1); + portrait = std::make_shared(AnimationPath::builtin("PortraitsSmall"), hero->portrait, 0, movement->pos.w + 1); + mana = std::make_shared(AnimationPath::builtin("IMANA"), 0, 0, movement->pos.w + portrait->pos.w + 2, 1); pos.w = mana->pos.w + mana->pos.x - pos.x; pos.h = std::max(std::max(movement->pos.h + 1, mana->pos.h + 1), portrait->pos.h); @@ -238,7 +238,7 @@ void CHeroList::CHeroItem::update() std::shared_ptr CHeroList::CHeroItem::genSelection() { - return std::make_shared("HPSYYY", movement->pos.w + 1, 0); + return std::make_shared(ImagePath::builtin("HPSYYY"), movement->pos.w + 1, 0); } void CHeroList::CHeroItem::select(bool on) @@ -319,7 +319,7 @@ std::shared_ptr CTownList::createItem(size_t index) { if (LOCPLINT->localState->getOwnedTowns().size() > index) return std::make_shared(this, LOCPLINT->localState->getOwnedTown(index)); - return std::make_shared("ITPA", 0); + return std::make_shared(AnimationPath::builtin("ITPA"), 0); } CTownList::CTownItem::CTownItem(CTownList *parent, const CGTownInstance *Town): @@ -327,14 +327,14 @@ CTownList::CTownItem::CTownItem(CTownList *parent, const CGTownInstance *Town): town(Town) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - picture = std::make_shared("ITPA", 0); + picture = std::make_shared(AnimationPath::builtin("ITPA"), 0); pos = picture->pos; update(); } std::shared_ptr CTownList::CTownItem::genSelection() { - return std::make_shared("ITPA", 1); + return std::make_shared(AnimationPath::builtin("ITPA"), 1); } void CTownList::CTownItem::update() diff --git a/client/adventureMap/CMinimap.cpp b/client/adventureMap/CMinimap.cpp index 7165b9e6e..358cd6de4 100644 --- a/client/adventureMap/CMinimap.cpp +++ b/client/adventureMap/CMinimap.cpp @@ -94,7 +94,7 @@ CMinimap::CMinimap(const Rect & position) pos.w = position.w; pos.h = position.h; - aiShield = std::make_shared("AIShield"); + aiShield = std::make_shared(ImagePath::builtin("AIShield")); aiShield->disable(); } diff --git a/client/adventureMap/CResDataBar.cpp b/client/adventureMap/CResDataBar.cpp index afea62a38..ea7914ecf 100644 --- a/client/adventureMap/CResDataBar.cpp +++ b/client/adventureMap/CResDataBar.cpp @@ -24,7 +24,7 @@ #include "../../lib/CGeneralTextHandler.h" #include "../../lib/ResourceSet.h" -CResDataBar::CResDataBar(const std::string & imageName, const Point & position) +CResDataBar::CResDataBar(const ImagePath & imageName, const Point & position) { pos.x += position.x; pos.y += position.y; @@ -37,7 +37,7 @@ CResDataBar::CResDataBar(const std::string & imageName, const Point & position) pos.h = background->pos.h; } -CResDataBar::CResDataBar(const std::string & defname, int x, int y, int offx, int offy, int resdist, int datedist): +CResDataBar::CResDataBar(const ImagePath & defname, int x, int y, int offx, int offy, int resdist, int datedist): CResDataBar(defname, Point(x,y)) { for (int i = 0; i < 7 ; i++) diff --git a/client/adventureMap/CResDataBar.h b/client/adventureMap/CResDataBar.h index c9bc01286..b37abeacf 100644 --- a/client/adventureMap/CResDataBar.h +++ b/client/adventureMap/CResDataBar.h @@ -10,6 +10,7 @@ #pragma once #include "../gui/CIntObject.h" +#include "../../lib/filesystem/ResourcePath.h" /// Resources bar which shows information about how many gold, crystals,... you have /// Current date is displayed too @@ -25,10 +26,10 @@ class CResDataBar : public CIntObject public: /// For dynamically-sized UI windows, e.g. adventure map interface - CResDataBar(const std::string & imageName, const Point & position); + CResDataBar(const ImagePath & imageName, const Point & position); /// For fixed-size UI windows, e.g. CastleInterface - CResDataBar(const std::string &defname, int x, int y, int offx, int offy, int resdist, int datedist); + CResDataBar(const ImagePath & defname, int x, int y, int offx, int offy, int resdist, int datedist); void setDatePosition(const Point & position); void setResourcePosition(const GameResID & resource, const Point & position); diff --git a/client/adventureMap/TurnTimerWidget.cpp b/client/adventureMap/TurnTimerWidget.cpp index b47d111da..2550ef23d 100644 --- a/client/adventureMap/TurnTimerWidget.cpp +++ b/client/adventureMap/TurnTimerWidget.cpp @@ -25,7 +25,7 @@ #include "../../CCallback.h" #include "../../lib/CStack.h" #include "../../lib/CPlayerState.h" -#include "../../lib/filesystem/ResourceID.h" +#include "../../lib/filesystem/ResourcePath.h" TurnTimerWidget::DrawRect::DrawRect(const Rect & r, const ColorRGBA & c): CIntObject(), rect(r), color(c) @@ -47,7 +47,7 @@ TurnTimerWidget::TurnTimerWidget(): recActions &= ~DEACTIVATE; - const JsonNode config(ResourceID("config/widgets/turnTimer.json")); + const JsonNode config(ResourcePath("config/widgets/turnTimer.json")); build(config); diff --git a/client/battle/BattleAnimationClasses.cpp b/client/battle/BattleAnimationClasses.cpp index 3a89b0661..355b8d679 100644 --- a/client/battle/BattleAnimationClasses.cpp +++ b/client/battle/BattleAnimationClasses.cpp @@ -807,7 +807,7 @@ void CatapultAnimation::tick(uint32_t msPassed) Point shotTarget = owner.stacksController->getStackPositionAtHex(dest, defendingStack) + Point(225, 225) - Point(126, 105); std::string soundFilename = (catapultDamage > 0) ? "WALLHIT" : "WALLMISS"; - std::string effectFilename = (catapultDamage > 0) ? "SGEXPL" : "CSGRCK"; + AnimationPath effectFilename = AnimationPath::builtin((catapultDamage > 0) ? "SGEXPL" : "CSGRCK"); CCS->soundh->playSound( soundFilename ); owner.stacksController->addNewAnim( new EffectAnimation(owner, effectFilename, shotTarget)); @@ -879,42 +879,42 @@ uint32_t CastAnimation::getAttackClimaxFrame() const return maxFrames / 2; } -EffectAnimation::EffectAnimation(BattleInterface & owner, std::string animationName, int effects, bool reversed): +EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, int effects, bool reversed): BattleAnimation(owner), animation(std::make_shared(animationName)), effectFlags(effects), effectFinished(false), reversed(reversed) { - logAnim->debug("CPointEffectAnimation::init: effect %s", animationName); + logAnim->debug("CPointEffectAnimation::init: effect %s", animationName.getName()); } -EffectAnimation::EffectAnimation(BattleInterface & owner, std::string animationName, std::vector hex, int effects, bool reversed): +EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, std::vector hex, int effects, bool reversed): EffectAnimation(owner, animationName, effects, reversed) { battlehexes = hex; } -EffectAnimation::EffectAnimation(BattleInterface & owner, std::string animationName, BattleHex hex, int effects, bool reversed): +EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, BattleHex hex, int effects, bool reversed): EffectAnimation(owner, animationName, effects, reversed) { assert(hex.isValid()); battlehexes.push_back(hex); } -EffectAnimation::EffectAnimation(BattleInterface & owner, std::string animationName, std::vector pos, int effects, bool reversed): +EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, std::vector pos, int effects, bool reversed): EffectAnimation(owner, animationName, effects, reversed) { positions = pos; } -EffectAnimation::EffectAnimation(BattleInterface & owner, std::string animationName, Point pos, int effects, bool reversed): +EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, Point pos, int effects, bool reversed): EffectAnimation(owner, animationName, effects, reversed) { positions.push_back(pos); } -EffectAnimation::EffectAnimation(BattleInterface & owner, std::string animationName, Point pos, BattleHex hex, int effects, bool reversed): +EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, Point pos, BattleHex hex, int effects, bool reversed): EffectAnimation(owner, animationName, effects, reversed) { assert(hex.isValid()); diff --git a/client/battle/BattleAnimationClasses.h b/client/battle/BattleAnimationClasses.h index f47f8ce9c..93ff9c3df 100644 --- a/client/battle/BattleAnimationClasses.h +++ b/client/battle/BattleAnimationClasses.h @@ -10,6 +10,7 @@ #pragma once #include "../../lib/battle/BattleHex.h" +#include "../../lib/filesystem/ResourcePath.h" #include "BattleConstants.h" VCMI_LIB_NAMESPACE_BEGIN @@ -334,17 +335,17 @@ public: }; /// Create animation with screen-wide effect - EffectAnimation(BattleInterface & owner, std::string animationName, int effects = 0, bool reversed = false); + EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, int effects = 0, bool reversed = false); /// Create animation positioned at point(s). Note that positions must be are absolute, including battleint position offset - EffectAnimation(BattleInterface & owner, std::string animationName, Point pos , int effects = 0, bool reversed = false); - EffectAnimation(BattleInterface & owner, std::string animationName, std::vector pos , int effects = 0, bool reversed = false); + EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, Point pos , int effects = 0, bool reversed = false); + EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, std::vector pos , int effects = 0, bool reversed = false); /// Create animation positioned at certain hex(es) - EffectAnimation(BattleInterface & owner, std::string animationName, BattleHex hex , int effects = 0, bool reversed = false); - EffectAnimation(BattleInterface & owner, std::string animationName, std::vector hex, int effects = 0, bool reversed = false); + EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, BattleHex hex , int effects = 0, bool reversed = false); + EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, std::vector hex, int effects = 0, bool reversed = false); - EffectAnimation(BattleInterface & owner, std::string animationName, Point pos, BattleHex hex, int effects = 0, bool reversed = false); + EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, Point pos, BattleHex hex, int effects = 0, bool reversed = false); ~EffectAnimation(); bool init() override; diff --git a/client/battle/BattleEffectsController.cpp b/client/battle/BattleEffectsController.cpp index bdaba92af..eb3d2e419 100644 --- a/client/battle/BattleEffectsController.cpp +++ b/client/battle/BattleEffectsController.cpp @@ -27,7 +27,7 @@ #include "../../CCallback.h" #include "../../lib/battle/BattleAction.h" -#include "../../lib/filesystem/ResourceID.h" +#include "../../lib/filesystem/ResourcePath.h" #include "../../lib/NetPacks.h" #include "../../lib/CStack.h" #include "../../lib/IGameEventsReceiver.h" @@ -48,7 +48,7 @@ void BattleEffectsController::displayEffect(EBattleEffect effect, std::string so { size_t effectID = static_cast(effect); - std::string customAnim = graphics->battleACToDef[effectID][0]; + AnimationPath customAnim = AnimationPath::builtinTODO(graphics->battleACToDef[effectID][0]); CCS->soundh->playSound( soundFile ); @@ -132,7 +132,7 @@ void BattleEffectsController::collectRenderableObjects(BattleRenderer & renderer void BattleEffectsController::loadColorMuxers() { - const JsonNode config(ResourceID("config/battleEffects.json")); + const JsonNode config(ResourcePath("config/battleEffects.json")); for(auto & muxer : config["colorMuxers"].Struct()) { diff --git a/client/battle/BattleFieldController.cpp b/client/battle/BattleFieldController.cpp index 8eda33038..a53e5d8c2 100644 --- a/client/battle/BattleFieldController.cpp +++ b/client/battle/BattleFieldController.cpp @@ -120,20 +120,20 @@ BattleFieldController::BattleFieldController(BattleInterface & owner): OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; //preparing cells and hexes - cellBorder = IImage::createFromFile("CCELLGRD.BMP", EImageBlitMode::COLORKEY); - cellShade = IImage::createFromFile("CCELLSHD.BMP"); - cellUnitMovementHighlight = IImage::createFromFile("UnitMovementHighlight.PNG", EImageBlitMode::COLORKEY); - cellUnitMaxMovementHighlight = IImage::createFromFile("UnitMaxMovementHighlight.PNG", EImageBlitMode::COLORKEY); + cellBorder = IImage::createFromFile(ImagePath::builtin("CCELLGRD.BMP"), EImageBlitMode::COLORKEY); + cellShade = IImage::createFromFile(ImagePath::builtin("CCELLSHD.BMP")); + cellUnitMovementHighlight = IImage::createFromFile(ImagePath::builtin("UnitMovementHighlight.PNG"), EImageBlitMode::COLORKEY); + cellUnitMaxMovementHighlight = IImage::createFromFile(ImagePath::builtin("UnitMaxMovementHighlight.PNG"), EImageBlitMode::COLORKEY); - attackCursors = std::make_shared("CRCOMBAT"); + attackCursors = std::make_shared(AnimationPath::builtin("CRCOMBAT")); attackCursors->preload(); initializeHexEdgeMaskToFrameIndex(); - rangedFullDamageLimitImages = std::make_shared("battle/rangeHighlights/rangeHighlightsGreen.json"); + rangedFullDamageLimitImages = std::make_shared(AnimationPath::builtin("battle/rangeHighlights/rangeHighlightsGreen.json")); rangedFullDamageLimitImages->preload(); - shootingRangeLimitImages = std::make_shared("battle/rangeHighlights/rangeHighlightsRed.json"); + shootingRangeLimitImages = std::make_shared(AnimationPath::builtin("battle/rangeHighlights/rangeHighlightsRed.json")); shootingRangeLimitImages->preload(); flipRangeLimitImagesIntoPositions(rangedFullDamageLimitImages); @@ -150,7 +150,7 @@ BattleFieldController::BattleFieldController(BattleInterface & owner): } else { - std::string backgroundName = owner.siegeController->getBattleBackgroundName(); + auto backgroundName = owner.siegeController->getBattleBackgroundName(); background = IImage::createFromFile(backgroundName, EImageBlitMode::OPAQUE); } diff --git a/client/battle/BattleInterface.cpp b/client/battle/BattleInterface.cpp index deb640985..8db671a94 100644 --- a/client/battle/BattleInterface.cpp +++ b/client/battle/BattleInterface.cpp @@ -440,8 +440,8 @@ void BattleInterface::spellCast(const BattleSpellCast * sc) bool side = sc->side; addToAnimationStage(EAnimationEvents::AFTER_HIT, [=](){ - stacksController->addNewAnim(new EffectAnimation(*this, side ? "SP07_A.DEF" : "SP07_B.DEF", leftHero)); - stacksController->addNewAnim(new EffectAnimation(*this, side ? "SP07_B.DEF" : "SP07_A.DEF", rightHero)); + stacksController->addNewAnim(new EffectAnimation(*this, AnimationPath::builtin(side ? "SP07_A.DEF" : "SP07_B.DEF"), leftHero)); + stacksController->addNewAnim(new EffectAnimation(*this, AnimationPath::builtin(side ? "SP07_B.DEF" : "SP07_A.DEF"), rightHero)); }); } diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 94ea31b38..4557d6cff 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -342,7 +342,7 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her currentFrame(0.f), flagCurrentFrame(0.f) { - std::string animationPath; + AnimationPath animationPath; if(!hero->type->battleImage.empty()) animationPath = hero->type->battleImage; @@ -364,9 +364,9 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her animation->verticalFlip(); if(defender) - flagAnimation = std::make_shared("CMFLAGR"); + flagAnimation = std::make_shared(AnimationPath::builtin("CMFLAGR")); else - flagAnimation = std::make_shared("CMFLAGL"); + flagAnimation = std::make_shared(AnimationPath::builtin("CMFLAGL")); flagAnimation->preload(); flagAnimation->playerColored(hero->tempOwner); @@ -386,7 +386,7 @@ HeroInfoBasicPanel::HeroInfoBasicPanel(const InfoAboutHero & hero, Point * posit if(initializeBackground) { - background = std::make_shared("CHRPOP"); + background = std::make_shared(ImagePath::builtin("CHRPOP")); background->getSurface()->setBlitMode(EImageBlitMode::OPAQUE); background->colorize(hero.owner); } @@ -406,7 +406,7 @@ void HeroInfoBasicPanel::initializeData(const InfoAboutHero & hero) auto currentSpellPoints = hero.details->mana; auto maxSpellPoints = hero.details->manaLimit; - icons.push_back(std::make_shared("PortraitsLarge", hero.portrait, 0, 10, 6)); + icons.push_back(std::make_shared(AnimationPath::builtin("PortraitsLarge"), hero.portrait, 0, 10, 6)); //primary stats labels.push_back(std::make_shared(9, 75, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[380] + ":")); @@ -423,8 +423,8 @@ void HeroInfoBasicPanel::initializeData(const InfoAboutHero & hero) labels.push_back(std::make_shared(9, 131, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[384] + ":")); labels.push_back(std::make_shared(9, 143, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[385] + ":")); - icons.push_back(std::make_shared("IMRL22", morale + 3, 0, 47, 131)); - icons.push_back(std::make_shared("ILCK22", luck + 3, 0, 47, 143)); + icons.push_back(std::make_shared(AnimationPath::builtin("IMRL22"), morale + 3, 0, 47, 131)); + icons.push_back(std::make_shared(AnimationPath::builtin("ILCK22"), luck + 3, 0, 47, 143)); //spell points labels.push_back(std::make_shared(39, 174, EFonts::FONT_TINY, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[387])); @@ -446,7 +446,7 @@ void HeroInfoBasicPanel::show(Canvas & to) } HeroInfoWindow::HeroInfoWindow(const InfoAboutHero & hero, Point * position) - : CWindowObject(RCLICK_POPUP | SHADOW_DISABLED, "CHRPOP") + : CWindowObject(RCLICK_POPUP | SHADOW_DISABLED, ImagePath::builtin("CHRPOP")) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); if (position != nullptr) @@ -462,16 +462,16 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - background = std::make_shared("CPRESULT"); + background = std::make_shared(ImagePath::builtin("CPRESULT")); background->colorize(owner.playerID); pos = center(background->pos); - exit = std::make_shared(Point(384, 505), "iok6432.def", std::make_pair("", ""), [&](){ bExitf();}, EShortcut::GLOBAL_ACCEPT); + exit = std::make_shared(Point(384, 505), AnimationPath::builtin("iok6432.def"), std::make_pair("", ""), [&](){ bExitf();}, EShortcut::GLOBAL_ACCEPT); exit->setBorderColor(Colors::METALLIC_GOLD); if(allowReplay) { - repeat = std::make_shared(Point(24, 505), "icn6432.def", std::make_pair("", ""), [&](){ bRepeatf();}, EShortcut::GLOBAL_CANCEL); + repeat = std::make_shared(Point(24, 505), AnimationPath::builtin("icn6432.def"), std::make_pair("", ""), [&](){ bRepeatf();}, EShortcut::GLOBAL_CANCEL); repeat->setBorderColor(Colors::METALLIC_GOLD); labels.push_back(std::make_shared(232, 520, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->translate("vcmi.battleResultsWindow.applyResultsLabel"))); } @@ -507,7 +507,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface if(heroInfo.portrait >= 0) //attacking hero { - icons.push_back(std::make_shared("PortraitsLarge", heroInfo.portrait, 0, xs[i], 38)); + icons.push_back(std::make_shared(AnimationPath::builtin("PortraitsLarge"), heroInfo.portrait, 0, xs[i], 38)); sideNames[i] = heroInfo.name; } else @@ -525,7 +525,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface if(best != stacks.end()) //should be always but to be safe... { - icons.push_back(std::make_shared("TWCRPORT", (*best)->unitType()->getIconIndex(), 0, xs[i], 38)); + icons.push_back(std::make_shared(AnimationPath::builtin("TWCRPORT"), (*best)->unitType()->getIconIndex(), 0, xs[i], 38)); sideNames[i] = (*best)->unitType()->getNamePluralTranslated(); } } @@ -552,7 +552,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface if (creature->getId() == CreatureID::ARROW_TOWERS ) continue; // do not show destroyed towers in battle results - icons.push_back(std::make_shared("CPRSMALL", creature->getIconIndex(), 0, xPos, yPos)); + icons.push_back(std::make_shared(AnimationPath::builtin("CPRSMALL"), creature->getIconIndex(), 0, xPos, yPos)); std::ostringstream amount; amount<(xPos + 16, yPos + 42, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, amount.str())); @@ -676,8 +676,8 @@ StackQueue::StackQueue(bool Embedded, BattleInterface & owner) pos.x += parent->pos.w/2 - pos.w/2; pos.y += 10; - icons = std::make_shared("CPRSMALL"); - stateIcons = std::make_shared("VCMI/BATTLEQUEUE/STATESSMALL"); + icons = std::make_shared(AnimationPath::builtin("CPRSMALL")); + stateIcons = std::make_shared(AnimationPath::builtin("VCMI/BATTLEQUEUE/STATESSMALL")); } else { @@ -686,10 +686,10 @@ StackQueue::StackQueue(bool Embedded, BattleInterface & owner) pos.x += 0; pos.y -= pos.h; - background = std::make_shared("DIBOXBCK", Rect(0, 0, pos.w, pos.h)); + background = std::make_shared(ImagePath::builtin("DIBOXBCK"), Rect(0, 0, pos.w, pos.h)); - icons = std::make_shared("TWCRPORT"); - stateIcons = std::make_shared("VCMI/BATTLEQUEUE/STATESSMALL"); + icons = std::make_shared(AnimationPath::builtin("TWCRPORT")); + stateIcons = std::make_shared(AnimationPath::builtin("VCMI/BATTLEQUEUE/STATESSMALL")); //TODO: where use big icons? //stateIcons = std::make_shared("VCMI/BATTLEQUEUE/STATESBIG"); } @@ -750,7 +750,7 @@ StackQueue::StackBox::StackBox(StackQueue * owner): CIntObject(SHOW_POPUP | HOVER), owner(owner) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - background = std::make_shared(owner->embedded ? "StackQueueSmall" : "StackQueueLarge"); + background = std::make_shared(ImagePath::builtin(owner->embedded ? "StackQueueSmall" : "StackQueueLarge")); pos.w = background->pos.w; pos.h = background->pos.h; diff --git a/client/battle/BattleObstacleController.cpp b/client/battle/BattleObstacleController.cpp index d41b09a66..a2acf75ee 100644 --- a/client/battle/BattleObstacleController.cpp +++ b/client/battle/BattleObstacleController.cpp @@ -42,7 +42,7 @@ BattleObstacleController::BattleObstacleController(BattleInterface & owner): void BattleObstacleController::loadObstacleImage(const CObstacleInstance & oi) { - std::string animationName = oi.getAnimation(); + AnimationPath animationName = oi.getAnimation(); if (animationsCache.count(animationName) == 0) { @@ -50,7 +50,7 @@ void BattleObstacleController::loadObstacleImage(const CObstacleInstance & oi) { // obstacle uses single bitmap image for animations auto animation = std::make_shared(); - animation->setCustom(animationName, 0, 0); + animation->setCustom(animationName.getName(), 0, 0); animationsCache[animationName] = animation; animation->preload(); } @@ -76,7 +76,7 @@ void BattleObstacleController::obstacleRemoved(const std::vector(obstacle["appearAnimation"].String()); + auto animation = std::make_shared(AnimationPath::fromJson(obstacle["appearAnimation"])); animation->preload(); auto first = animation->getImage(0, 0); @@ -87,7 +87,7 @@ void BattleObstacleController::obstacleRemoved(const std::vector if we know how to blit obstacle, let's blit the effect in the same place Point whereTo = getObstaclePosition(first, obstacle); //AFAIK, in H3 there is no sound of obstacle removal - owner.stacksController->addNewAnim(new EffectAnimation(owner, obstacle["appearAnimation"].String(), whereTo, obstacle["position"].Integer(), 0, true)); + owner.stacksController->addNewAnim(new EffectAnimation(owner, AnimationPath::fromJson(obstacle["appearAnimation"]), whereTo, obstacle["position"].Integer(), 0, true)); obstacleAnimations.erase(oi.id); //so when multiple obstacles are removed, they show up one after another diff --git a/client/battle/BattleObstacleController.h b/client/battle/BattleObstacleController.h index 0f33626f9..b05ded9a6 100644 --- a/client/battle/BattleObstacleController.h +++ b/client/battle/BattleObstacleController.h @@ -9,6 +9,8 @@ */ #pragma once +#include "../../lib/filesystem/ResourcePath.h" + VCMI_LIB_NAMESPACE_BEGIN struct BattleHex; @@ -35,7 +37,7 @@ class BattleObstacleController float timePassed; /// cached animations of all obstacles in current battle - std::map> animationsCache; + std::map> animationsCache; /// list of all obstacles that are currently being rendered std::map> obstacleAnimations; diff --git a/client/battle/BattleProjectileController.cpp b/client/battle/BattleProjectileController.cpp index c2b2715e0..71fac3f52 100644 --- a/client/battle/BattleProjectileController.cpp +++ b/client/battle/BattleProjectileController.cpp @@ -188,7 +188,7 @@ void BattleProjectileController::initStackProjectile(const CStack * stack) projectilesCache[creature.animation.projectileImageName] = createProjectileImage(creature.animation.projectileImageName); } -std::shared_ptr BattleProjectileController::createProjectileImage(const std::string & path ) +std::shared_ptr BattleProjectileController::createProjectileImage(const AnimationPath & path ) { std::shared_ptr projectile = std::make_shared(path); projectile->preload(); @@ -204,7 +204,7 @@ std::shared_ptr BattleProjectileController::createProjectileImage(co std::shared_ptr BattleProjectileController::getProjectileImage(const CStack * stack) { const CCreature & creature = getShooter(stack); - std::string imageName = creature.animation.projectileImageName; + AnimationPath imageName = creature.animation.projectileImageName; if (!projectilesCache.count(imageName)) initStackProjectile(stack); @@ -361,7 +361,7 @@ void BattleProjectileController::createProjectile(const CStack * shooter, Point void BattleProjectileController::createSpellProjectile(const CStack * shooter, Point from, Point dest, const CSpell * spell) { double projectileAngle = std::abs(atan2(dest.x - from.x, dest.y - from.y)); - std::string animToDisplay = spell->animationInfo.selectProjectile(projectileAngle); + AnimationPath animToDisplay = spell->animationInfo.selectProjectile(projectileAngle); assert(!animToDisplay.empty()); diff --git a/client/battle/BattleProjectileController.h b/client/battle/BattleProjectileController.h index a9622c230..b54a5bca1 100644 --- a/client/battle/BattleProjectileController.h +++ b/client/battle/BattleProjectileController.h @@ -11,6 +11,7 @@ #include "../../lib/CCreatureHandler.h" #include "../../lib/Point.h" +#include "../../lib/filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -83,13 +84,13 @@ class BattleProjectileController BattleInterface & owner; /// all projectiles loaded during current battle - std::map> projectilesCache; + std::map> projectilesCache; /// projectiles currently flying on battlefield std::vector> projectiles; std::shared_ptr getProjectileImage(const CStack * stack); - std::shared_ptr createProjectileImage(const std::string & path ); + std::shared_ptr createProjectileImage(const AnimationPath & path ); void initStackProjectile(const CStack * stack); bool stackUsesRayProjectile(const CStack * stack) const; diff --git a/client/battle/BattleSiegeController.cpp b/client/battle/BattleSiegeController.cpp index 63c8cab10..3b88b75f4 100644 --- a/client/battle/BattleSiegeController.cpp +++ b/client/battle/BattleSiegeController.cpp @@ -28,7 +28,7 @@ #include "../../lib/CStack.h" #include "../../lib/mapObjects/CGTownInstance.h" -std::string BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisual what, EWallState state) const +ImagePath BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisual what, EWallState state) const { auto getImageIndex = [&]() -> int { @@ -68,44 +68,44 @@ std::string BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisua auto faction = town->town->faction->getIndex(); if (faction == ETownType::RAMPART || faction == ETownType::NECROPOLIS || faction == ETownType::DUNGEON || faction == ETownType::STRONGHOLD) - return prefix + "TPW1.BMP"; + return ImagePath::builtinTODO(prefix + "TPW1.BMP"); else - return prefix + "TPWL.BMP"; + return ImagePath::builtinTODO(prefix + "TPWL.BMP"); } case EWallVisual::KEEP: - return prefix + "MAN" + addit + ".BMP"; + return ImagePath::builtinTODO(prefix + "MAN" + addit + ".BMP"); case EWallVisual::BOTTOM_TOWER: - return prefix + "TW1" + addit + ".BMP"; + return ImagePath::builtinTODO(prefix + "TW1" + addit + ".BMP"); case EWallVisual::BOTTOM_WALL: - return prefix + "WA1" + addit + ".BMP"; + return ImagePath::builtinTODO(prefix + "WA1" + addit + ".BMP"); case EWallVisual::WALL_BELLOW_GATE: - return prefix + "WA3" + addit + ".BMP"; + return ImagePath::builtinTODO(prefix + "WA3" + addit + ".BMP"); case EWallVisual::WALL_OVER_GATE: - return prefix + "WA4" + addit + ".BMP"; + return ImagePath::builtinTODO(prefix + "WA4" + addit + ".BMP"); case EWallVisual::UPPER_WALL: - return prefix + "WA6" + addit + ".BMP"; + return ImagePath::builtinTODO(prefix + "WA6" + addit + ".BMP"); case EWallVisual::UPPER_TOWER: - return prefix + "TW2" + addit + ".BMP"; + return ImagePath::builtinTODO(prefix + "TW2" + addit + ".BMP"); case EWallVisual::GATE: - return prefix + "DRW" + addit + ".BMP"; + return ImagePath::builtinTODO(prefix + "DRW" + addit + ".BMP"); case EWallVisual::GATE_ARCH: - return prefix + "ARCH.BMP"; + return ImagePath::builtinTODO(prefix + "ARCH.BMP"); case EWallVisual::BOTTOM_STATIC_WALL: - return prefix + "WA2.BMP"; + return ImagePath::builtinTODO(prefix + "WA2.BMP"); case EWallVisual::UPPER_STATIC_WALL: - return prefix + "WA5.BMP"; + return ImagePath::builtinTODO(prefix + "WA5.BMP"); case EWallVisual::MOAT: - return prefix + "MOAT.BMP"; + return ImagePath::builtinTODO(prefix + "MOAT.BMP"); case EWallVisual::MOAT_BANK: - return prefix + "MLIP.BMP"; + return ImagePath::builtinTODO(prefix + "MLIP.BMP"); case EWallVisual::KEEP_BATTLEMENT: - return prefix + "MANC.BMP"; + return ImagePath::builtinTODO(prefix + "MANC.BMP"); case EWallVisual::BOTTOM_BATTLEMENT: - return prefix + "TW1C.BMP"; + return ImagePath::builtinTODO(prefix + "TW1C.BMP"); case EWallVisual::UPPER_BATTLEMENT: - return prefix + "TW2C.BMP"; + return ImagePath::builtinTODO(prefix + "TW2C.BMP"); default: - return ""; + return ImagePath(); } } @@ -118,10 +118,10 @@ void BattleSiegeController::showWallPiece(Canvas & canvas, EWallVisual::EWallVis canvas.draw(wallPieceImages[what], Point(pos.x, pos.y)); } -std::string BattleSiegeController::getBattleBackgroundName() const +ImagePath BattleSiegeController::getBattleBackgroundName() const { const std::string & prefix = town->town->clientInfo.siegePrefix; - return prefix + "BACK.BMP"; + return ImagePath::builtinTODO(prefix + "BACK.BMP"); } bool BattleSiegeController::getWallPieceExistance(EWallVisual::EWallVisual what) const @@ -341,7 +341,7 @@ void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca) positions.push_back(owner.stacksController->getStackPositionAtHex(attackInfo.destinationTile, nullptr) + Point(99, 120)); CCS->soundh->playSound( "WALLHIT" ); - owner.stacksController->addNewAnim(new EffectAnimation(owner, "SGEXPL.DEF", positions)); + owner.stacksController->addNewAnim(new EffectAnimation(owner, AnimationPath::builtin("SGEXPL.DEF"), positions)); } owner.waitForAnimations(); diff --git a/client/battle/BattleSiegeController.h b/client/battle/BattleSiegeController.h index 262b78b76..7acb38f13 100644 --- a/client/battle/BattleSiegeController.h +++ b/client/battle/BattleSiegeController.h @@ -11,6 +11,7 @@ #include "../../lib/GameConstants.h" #include "../../lib/battle/BattleHex.h" +#include "../../lib/filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -76,7 +77,7 @@ class BattleSiegeController std::array, EWallVisual::WALL_LAST + 1> wallPieceImages; /// return URI for image for a wall piece - std::string getWallPieceImageName(EWallVisual::EWallVisual what, EWallState state) const; + ImagePath getWallPieceImageName(EWallVisual::EWallVisual what, EWallState state) const; /// returns BattleHex to which chosen wall piece is bound BattleHex getWallPiecePosition(EWallVisual::EWallVisual what) const; @@ -102,7 +103,7 @@ public: /// queries from other battle controllers bool isAttackableByCatapult(BattleHex hex) const; - std::string getBattleBackgroundName() const; + ImagePath getBattleBackgroundName() const; const CCreature *getTurretCreature() const; Point getTurretCreaturePosition( BattleHex position ) const; diff --git a/client/battle/BattleStacksController.cpp b/client/battle/BattleStacksController.cpp index f83e97782..32c401612 100644 --- a/client/battle/BattleStacksController.cpp +++ b/client/battle/BattleStacksController.cpp @@ -76,10 +76,10 @@ BattleStacksController::BattleStacksController(BattleInterface & owner): animIDhelper(0) { //preparing graphics for displaying amounts of creatures - amountNormal = IImage::createFromFile("CMNUMWIN.BMP", EImageBlitMode::COLORKEY); - amountPositive = IImage::createFromFile("CMNUMWIN.BMP", EImageBlitMode::COLORKEY); - amountNegative = IImage::createFromFile("CMNUMWIN.BMP", EImageBlitMode::COLORKEY); - amountEffNeutral = IImage::createFromFile("CMNUMWIN.BMP", EImageBlitMode::COLORKEY); + amountNormal = IImage::createFromFile(ImagePath::builtin("CMNUMWIN.BMP"), EImageBlitMode::COLORKEY); + amountPositive = IImage::createFromFile(ImagePath::builtin("CMNUMWIN.BMP"), EImageBlitMode::COLORKEY); + amountNegative = IImage::createFromFile(ImagePath::builtin("CMNUMWIN.BMP"), EImageBlitMode::COLORKEY); + amountEffNeutral = IImage::createFromFile(ImagePath::builtin("CMNUMWIN.BMP"), EImageBlitMode::COLORKEY); static const auto shifterNormal = ColorFilter::genRangeShifter( 0.f, 0.f, 0.f, 0.6f, 0.2f, 1.0f ); static const auto shifterPositive = ColorFilter::genRangeShifter( 0.f, 0.f, 0.f, 0.2f, 1.0f, 0.2f ); diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index 79f558932..4e62ea056 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -37,7 +37,7 @@ #include "../../lib/mapObjects/CGHeroInstance.h" #include "../../lib/CStack.h" #include "../../lib/CConfigHandler.h" -#include "../../lib/filesystem/ResourceID.h" +#include "../../lib/filesystem/ResourcePath.h" #include "../windows/settings/SettingsMainWindow.h" BattleWindow::BattleWindow(BattleInterface & owner): @@ -51,7 +51,7 @@ BattleWindow::BattleWindow(BattleInterface & owner): REGISTER_BUILDER("battleConsole", &BattleWindow::buildBattleConsole); - const JsonNode config(ResourceID("config/widgets/BattleWindow2.json")); + const JsonNode config(ResourcePath("config/widgets/BattleWindow2.json")); addShortcut(EShortcut::GLOBAL_OPTIONS, std::bind(&BattleWindow::bOptionsf, this)); addShortcut(EShortcut::BATTLE_SURRENDER, std::bind(&BattleWindow::bSurrenderf, this)); @@ -436,23 +436,23 @@ void BattleWindow::showAlternativeActionIcon(PossiblePlayerBattleAction action) if(!w) return; - std::string iconName = variables["actionIconDefault"].String(); + AnimationPath iconName = AnimationPath::fromJson(variables["actionIconDefault"]); switch(action.get()) { case PossiblePlayerBattleAction::ATTACK: - iconName = variables["actionIconAttack"].String(); + iconName = AnimationPath::fromJson(variables["actionIconAttack"]); break; case PossiblePlayerBattleAction::SHOOT: - iconName = variables["actionIconShoot"].String(); + iconName = AnimationPath::fromJson(variables["actionIconShoot"]); break; case PossiblePlayerBattleAction::AIMED_SPELL_CREATURE: - iconName = variables["actionIconSpell"].String(); + iconName = AnimationPath::fromJson(variables["actionIconSpell"]); break; case PossiblePlayerBattleAction::ANY_LOCATION: - iconName = variables["actionIconSpell"].String(); + iconName = AnimationPath::fromJson(variables["actionIconSpell"]); break; //TODO: figure out purpose of this icon @@ -461,11 +461,11 @@ void BattleWindow::showAlternativeActionIcon(PossiblePlayerBattleAction action) //break; case PossiblePlayerBattleAction::ATTACK_AND_RETURN: - iconName = variables["actionIconReturn"].String(); + iconName = AnimationPath::fromJson(variables["actionIconReturn"]); break; case PossiblePlayerBattleAction::WALK_AND_ATTACK: - iconName = variables["actionIconNoReturn"].String(); + iconName = AnimationPath::fromJson(variables["actionIconNoReturn"]); break; } diff --git a/client/battle/CreatureAnimation.cpp b/client/battle/CreatureAnimation.cpp index 64397ec04..ee0106f0b 100644 --- a/client/battle/CreatureAnimation.cpp +++ b/client/battle/CreatureAnimation.cpp @@ -185,7 +185,7 @@ void CreatureAnimation::setType(ECreatureAnimType type) speed = speedController(this, type); } -CreatureAnimation::CreatureAnimation(const std::string & name_, TSpeedController controller) +CreatureAnimation::CreatureAnimation(const AnimationPath & name_, TSpeedController controller) : name(name_), speed(0.1f), shadowAlpha(128), diff --git a/client/battle/CreatureAnimation.h b/client/battle/CreatureAnimation.h index d98c12085..66ad3f285 100644 --- a/client/battle/CreatureAnimation.h +++ b/client/battle/CreatureAnimation.h @@ -70,7 +70,7 @@ public: using TSpeedController = std::function; private: - std::string name; + AnimationPath name; /// animation for rendering stack in default orientation - facing right std::shared_ptr forward; @@ -122,7 +122,7 @@ public: /// name - path to .def file, relative to SPRITES/ directory /// controller - function that will return for how long *each* frame /// in specified group of animation should be played, measured in seconds - CreatureAnimation(const std::string & name_, TSpeedController speedController); + CreatureAnimation(const AnimationPath & name_, TSpeedController speedController); /// sets type of animation and resets framecount void setType(ECreatureAnimType type); diff --git a/client/gui/CursorHandler.cpp b/client/gui/CursorHandler.cpp index f51ab4310..dbdf7853e 100644 --- a/client/gui/CursorHandler.cpp +++ b/client/gui/CursorHandler.cpp @@ -46,10 +46,10 @@ CursorHandler::CursorHandler() cursors = { - std::make_unique("CRADVNTR"), - std::make_unique("CRCOMBAT"), - std::make_unique("CRDEFLT"), - std::make_unique("CRSPELL") + std::make_unique(AnimationPath::builtin("CRADVNTR")), + std::make_unique(AnimationPath::builtin("CRCOMBAT")), + std::make_unique(AnimationPath::builtin("CRDEFLT")), + std::make_unique(AnimationPath::builtin("CRSPELL")) }; for (auto & cursor : cursors) @@ -100,7 +100,7 @@ void CursorHandler::dragAndDropCursor(std::shared_ptr image) cursor->setImage(getCurrentImage(), getPivotOffset()); } -void CursorHandler::dragAndDropCursor (std::string path, size_t index) +void CursorHandler::dragAndDropCursor (const AnimationPath & path, size_t index) { CAnimation anim(path); anim.load(index); diff --git a/client/gui/CursorHandler.h b/client/gui/CursorHandler.h index 531594b3a..b17686b93 100644 --- a/client/gui/CursorHandler.h +++ b/client/gui/CursorHandler.h @@ -10,6 +10,7 @@ #pragma once #include "../../lib/Point.h" +#include "../../lib/filesystem/ResourcePath.h" class ICursor; class IImage; @@ -143,7 +144,7 @@ public: /// @param image Image to replace cursor with or nullptr to use the normal cursor. void dragAndDropCursor(std::shared_ptr image); - void dragAndDropCursor(std::string path, size_t index); + void dragAndDropCursor(const AnimationPath & path, size_t index); /// Changes cursor to specified index void set(Cursor::Default index); diff --git a/client/gui/InterfaceObjectConfigurable.cpp b/client/gui/InterfaceObjectConfigurable.cpp index dc97aba1a..e3d9a8a34 100644 --- a/client/gui/InterfaceObjectConfigurable.cpp +++ b/client/gui/InterfaceObjectConfigurable.cpp @@ -31,7 +31,7 @@ #include "../../lib//constants/StringConstants.h" #include "../../lib/CGeneralTextHandler.h" -#include "../../lib/filesystem/ResourceID.h" +#include "../../lib/filesystem/ResourcePath.h" InterfaceObjectConfigurable::InterfaceObjectConfigurable(const JsonNode & config, int used, Point offset): InterfaceObjectConfigurable(used, offset) @@ -110,7 +110,7 @@ void InterfaceObjectConfigurable::build(const JsonNode &config) { if (!config["library"].isNull()) { - const JsonNode library(ResourceID(config["library"].String())); + const JsonNode library(ResourcePath(config["library"].String())); loadCustomBuilders(library); } @@ -305,7 +305,7 @@ EShortcut InterfaceObjectConfigurable::readHotkey(const JsonNode & config) const std::shared_ptr InterfaceObjectConfigurable::buildPicture(const JsonNode & config) const { logGlobal->debug("Building widget CPicture"); - auto image = config["image"].String(); + auto image = ImagePath::fromJson(config["image"]); auto position = readPosition(config["position"]); auto pic = std::make_shared(image, position.x, position.y); if(!config["visible"].isNull()) @@ -369,7 +369,7 @@ std::shared_ptr InterfaceObjectConfigurable::buildToggleButton(co { logGlobal->debug("Building widget CToggleButton"); auto position = readPosition(config["position"]); - auto image = config["image"].String(); + auto image = AnimationPath::fromJson(config["image"]); auto help = readHintText(config["help"]); auto button = std::make_shared(position, image, help); if(!config["items"].isNull()) @@ -395,7 +395,7 @@ std::shared_ptr InterfaceObjectConfigurable::buildButton(const JsonNode { logGlobal->debug("Building widget CButton"); auto position = readPosition(config["position"]); - auto image = config["image"].String(); + auto image = AnimationPath::fromJson(config["image"]); auto help = readHintText(config["help"]); auto button = std::make_shared(position, image, help); if(!config["items"].isNull()) @@ -522,7 +522,7 @@ std::shared_ptr InterfaceObjectConfigurable::buildImage(const JsonNo { logGlobal->debug("Building widget CAnimImage"); auto position = readPosition(config["position"]); - auto image = config["image"].String(); + auto image = AnimationPath::fromJson(config["image"]); int group = config["group"].isNull() ? 0 : config["group"].Integer(); int frame = config["frame"].isNull() ? 0 : config["frame"].Integer(); return std::make_shared(image, frame, group, position.x, position.y); @@ -531,7 +531,7 @@ std::shared_ptr InterfaceObjectConfigurable::buildImage(const JsonNo std::shared_ptr InterfaceObjectConfigurable::buildTexture(const JsonNode & config) const { logGlobal->debug("Building widget CFilledTexture"); - auto image = config["image"].String(); + auto image = ImagePath::fromJson(config["image"]); auto rect = readRect(config["rect"]); auto playerColor = readPlayerColor(config["color"]); if(playerColor.isValidPlayer()) @@ -546,7 +546,7 @@ std::shared_ptr InterfaceObjectConfigurable::buildComboBox(const JsonN { logGlobal->debug("Building widget ComboBox"); auto position = readPosition(config["position"]); - auto image = config["image"].String(); + auto image = AnimationPath::fromJson(config["image"]); auto help = readHintText(config["help"]); auto result = std::make_shared(position, image, help, config["dropDown"]); if(!config["items"].isNull()) @@ -573,7 +573,7 @@ std::shared_ptr InterfaceObjectConfigurable::buildTextInput(const Js logGlobal->debug("Building widget CTextInput"); auto rect = readRect(config["rect"]); auto offset = readPosition(config["backgroundOffset"]); - auto bgName = config["background"].String(); + auto bgName = ImagePath::fromJson(config["background"]); auto result = std::make_shared(rect, offset, bgName, 0); if(!config["alignment"].isNull()) result->alignment = readTextAlignment(config["alignment"]); @@ -664,7 +664,7 @@ std::shared_ptr InterfaceObjectConfigurable::buildAnimation(const { logGlobal->debug("Building widget CShowableAnim"); auto position = readPosition(config["position"]); - auto image = config["image"].String(); + auto image = AnimationPath::fromJson(config["image"]); ui8 flags = 0; if(!config["repeat"].Bool()) flags |= CShowableAnim::EFlags::PLAY_ONCE; diff --git a/client/lobby/CBonusSelection.cpp b/client/lobby/CBonusSelection.cpp index 2bd79577b..4fa6a65b2 100644 --- a/client/lobby/CBonusSelection.cpp +++ b/client/lobby/CBonusSelection.cpp @@ -65,18 +65,17 @@ CBonusSelection::CBonusSelection() { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - std::string bgName = getCampaign()->getRegions().getBackgroundName(); - setBackground(bgName); + setBackground(getCampaign()->getRegions().getBackgroundName()); - panelBackground = std::make_shared("CAMPBRF.BMP", 456, 6); + panelBackground = std::make_shared(ImagePath::builtin("CAMPBRF.BMP"), 456, 6); - buttonStart = std::make_shared(Point(475, 536), "CBBEGIB.DEF", CButton::tooltip(), std::bind(&CBonusSelection::startMap, this), EShortcut::GLOBAL_ACCEPT); - buttonRestart = std::make_shared(Point(475, 536), "CBRESTB.DEF", CButton::tooltip(), std::bind(&CBonusSelection::restartMap, this), EShortcut::GLOBAL_ACCEPT); - buttonBack = std::make_shared(Point(624, 536), "CBCANCB.DEF", CButton::tooltip(), std::bind(&CBonusSelection::goBack, this), EShortcut::GLOBAL_CANCEL); + buttonStart = std::make_shared(Point(475, 536), AnimationPath::builtin("CBBEGIB.DEF"), CButton::tooltip(), std::bind(&CBonusSelection::startMap, this), EShortcut::GLOBAL_ACCEPT); + buttonRestart = std::make_shared(Point(475, 536), AnimationPath::builtin("CBRESTB.DEF"), CButton::tooltip(), std::bind(&CBonusSelection::restartMap, this), EShortcut::GLOBAL_ACCEPT); + buttonBack = std::make_shared(Point(624, 536), AnimationPath::builtin("CBCANCB.DEF"), CButton::tooltip(), std::bind(&CBonusSelection::goBack, this), EShortcut::GLOBAL_CANCEL); campaignName = std::make_shared(481, 28, FONT_BIG, ETextAlignment::TOPLEFT, Colors::YELLOW, CSH->si->getCampaignName()); - iconsMapSizes = std::make_shared("SCNRMPSZ", 4, 0, 735, 26); + iconsMapSizes = std::make_shared(AnimationPath::builtin("SCNRMPSZ"), 4, 0, 735, 26); labelCampaignDescription = std::make_shared(481, 63, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::YELLOW, CGI->generaltexth->allTexts[38]); campaignDescription = std::make_shared(getCampaign()->getDescription(), Rect(480, 86, 286, 117), 1); @@ -97,13 +96,13 @@ CBonusSelection::CBonusSelection() for(size_t b = 0; b < difficultyIcons.size(); ++b) { - difficultyIcons[b] = std::make_shared("GSPBUT" + std::to_string(b + 3) + ".DEF", 0, 0, 709, 455); + difficultyIcons[b] = std::make_shared(AnimationPath::builtinTODO("GSPBUT" + std::to_string(b + 3) + ".DEF"), 0, 0, 709, 455); } if(getCampaign()->playerSelectedDifficulty()) { - buttonDifficultyLeft = std::make_shared(Point(694, 508), "SCNRBLF.DEF", CButton::tooltip(), std::bind(&CBonusSelection::decreaseDifficulty, this)); - buttonDifficultyRight = std::make_shared(Point(738, 508), "SCNRBRT.DEF", CButton::tooltip(), std::bind(&CBonusSelection::increaseDifficulty, this)); + buttonDifficultyLeft = std::make_shared(Point(694, 508), AnimationPath::builtin("SCNRBLF.DEF"), CButton::tooltip(), std::bind(&CBonusSelection::decreaseDifficulty, this)); + buttonDifficultyRight = std::make_shared(Point(738, 508), AnimationPath::builtin("SCNRBRT.DEF"), CButton::tooltip(), std::bind(&CBonusSelection::increaseDifficulty, this)); } for(auto scenarioID : getCampaign()->allScenarios()) @@ -302,7 +301,7 @@ void CBonusSelection::createBonusesIcons() break; } - std::shared_ptr bonusButton = std::make_shared(Point(475 + i * 68, 455), "", CButton::tooltip(desc, desc)); + std::shared_ptr bonusButton = std::make_shared(Point(475 + i * 68, 455), AnimationPath(), CButton::tooltip(desc, desc)); if(picNumber != -1) picName += ":" + std::to_string(picNumber); diff --git a/client/lobby/CLobbyScreen.cpp b/client/lobby/CLobbyScreen.cpp index b523d50c2..25d845b70 100644 --- a/client/lobby/CLobbyScreen.cpp +++ b/client/lobby/CLobbyScreen.cpp @@ -43,17 +43,17 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType) { tabSel->callOnSelect = std::bind(&IServerAPI::setMapInfo, CSH, _1, nullptr); - buttonSelect = std::make_shared(Point(411, 80), "GSPBUTT.DEF", CGI->generaltexth->zelp[45], 0, EShortcut::LOBBY_SELECT_SCENARIO); + buttonSelect = std::make_shared(Point(411, 80), AnimationPath::builtin("GSPBUTT.DEF"), CGI->generaltexth->zelp[45], 0, EShortcut::LOBBY_SELECT_SCENARIO); buttonSelect->addCallback([&]() { toggleTab(tabSel); CSH->setMapInfo(tabSel->getSelectedMapInfo()); }); - buttonOptions = std::make_shared(Point(411, 510), "GSPBUTT.DEF", CGI->generaltexth->zelp[46], std::bind(&CLobbyScreen::toggleTab, this, tabOpt), EShortcut::LOBBY_ADDITIONAL_OPTIONS); + buttonOptions = std::make_shared(Point(411, 510), AnimationPath::builtin("GSPBUTT.DEF"), CGI->generaltexth->zelp[46], std::bind(&CLobbyScreen::toggleTab, this, tabOpt), EShortcut::LOBBY_ADDITIONAL_OPTIONS); }; - buttonChat = std::make_shared(Point(619, 80), "GSPBUT2.DEF", CGI->generaltexth->zelp[48], std::bind(&CLobbyScreen::toggleChat, this), EShortcut::LOBBY_HIDE_CHAT); + buttonChat = std::make_shared(Point(619, 80), AnimationPath::builtin("GSPBUT2.DEF"), CGI->generaltexth->zelp[48], std::bind(&CLobbyScreen::toggleChat, this), EShortcut::LOBBY_HIDE_CHAT); buttonChat->addTextOverlay(CGI->generaltexth->allTexts[532], FONT_SMALL, Colors::WHITE); switch(screenType) @@ -63,7 +63,7 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType) tabOpt = std::make_shared(); tabRand = std::make_shared(); tabRand->mapInfoChanged += std::bind(&IServerAPI::setMapInfo, CSH, _1, _2); - buttonRMG = std::make_shared(Point(411, 105), "GSPBUTT.DEF", CGI->generaltexth->zelp[47], 0, EShortcut::LOBBY_RANDOM_MAP); + buttonRMG = std::make_shared(Point(411, 105), AnimationPath::builtin("GSPBUTT.DEF"), CGI->generaltexth->zelp[47], 0, EShortcut::LOBBY_RANDOM_MAP); buttonRMG->addCallback([&]() { toggleTab(tabRand); @@ -72,24 +72,24 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType) card->iconDifficulty->addCallback(std::bind(&IServerAPI::setDifficulty, CSH, _1)); - buttonStart = std::make_shared(Point(411, 535), "SCNRBEG.DEF", CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, true), EShortcut::LOBBY_BEGIN_GAME); + buttonStart = std::make_shared(Point(411, 535), AnimationPath::builtin("SCNRBEG.DEF"), CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, true), EShortcut::LOBBY_BEGIN_GAME); initLobby(); break; } case ESelectionScreen::loadGame: { tabOpt = std::make_shared(); - buttonStart = std::make_shared(Point(411, 535), "SCNRLOD.DEF", CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, true), EShortcut::LOBBY_LOAD_GAME); + buttonStart = std::make_shared(Point(411, 535), AnimationPath::builtin("SCNRLOD.DEF"), CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, true), EShortcut::LOBBY_LOAD_GAME); initLobby(); break; } case ESelectionScreen::campaignList: tabSel->callOnSelect = std::bind(&IServerAPI::setMapInfo, CSH, _1, nullptr); - buttonStart = std::make_shared(Point(411, 535), "SCNRLOD.DEF", CButton::tooltip(), std::bind(&CLobbyScreen::startCampaign, this), EShortcut::LOBBY_BEGIN_GAME); + buttonStart = std::make_shared(Point(411, 535), AnimationPath::builtin("SCNRLOD.DEF"), CButton::tooltip(), std::bind(&CLobbyScreen::startCampaign, this), EShortcut::LOBBY_BEGIN_GAME); break; } - buttonBack = std::make_shared(Point(581, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], [&]() + buttonBack = std::make_shared(Point(581, 535), AnimationPath::builtin("SCNRBACK.DEF"), CGI->generaltexth->zelp[105], [&]() { CSH->sendClientDisconnecting(); close(); diff --git a/client/lobby/CSavingScreen.cpp b/client/lobby/CSavingScreen.cpp index 1126fb444..5a43f2fc3 100644 --- a/client/lobby/CSavingScreen.cpp +++ b/client/lobby/CSavingScreen.cpp @@ -40,7 +40,7 @@ CSavingScreen::CSavingScreen() tabSel->toggleMode(); curTab = tabSel; - buttonStart = std::make_shared(Point(411, 535), "SCNRSAV.DEF", CGI->generaltexth->zelp[103], std::bind(&CSavingScreen::saveGame, this), EShortcut::LOBBY_SAVE_GAME); + buttonStart = std::make_shared(Point(411, 535), AnimationPath::builtin("SCNRSAV.DEF"), CGI->generaltexth->zelp[103], std::bind(&CSavingScreen::saveGame, this), EShortcut::LOBBY_SAVE_GAME); } const CMapInfo * CSavingScreen::getMapInfo() @@ -80,7 +80,7 @@ void CSavingScreen::saveGame() close(); }; - if(CResourceHandler::get("local")->existsResource(ResourceID(path, EResType::SAVEGAME))) + if(CResourceHandler::get("local")->existsResource(ResourcePath(path, EResType::SAVEGAME))) { std::string hlp = CGI->generaltexth->allTexts[493]; //%s exists. Overwrite? boost::algorithm::replace_first(hlp, "%s", tabSel->inputName->getText()); diff --git a/client/lobby/CScenarioInfoScreen.cpp b/client/lobby/CScenarioInfoScreen.cpp index acccf2da4..51a6f242a 100644 --- a/client/lobby/CScenarioInfoScreen.cpp +++ b/client/lobby/CScenarioInfoScreen.cpp @@ -45,7 +45,7 @@ CScenarioInfoScreen::CScenarioInfoScreen() card->changeSelection(); card->iconDifficulty->setSelected(getCurrentDifficulty()); - buttonBack = std::make_shared(Point(584, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], [=](){ close();}, EShortcut::GLOBAL_CANCEL); + buttonBack = std::make_shared(Point(584, 535), AnimationPath::builtin("SCNRBACK.DEF"), CGI->generaltexth->zelp[105], [=](){ close();}, EShortcut::GLOBAL_CANCEL); } CScenarioInfoScreen::~CScenarioInfoScreen() diff --git a/client/lobby/CSelectionBase.cpp b/client/lobby/CSelectionBase.cpp index 5701a17bc..4c3fbbf4a 100644 --- a/client/lobby/CSelectionBase.cpp +++ b/client/lobby/CSelectionBase.cpp @@ -80,16 +80,16 @@ CSelectionBase::CSelectionBase(ESelectionScreen type) pos.h = 584; if(screenType == ESelectionScreen::campaignList) { - setBackground("CamCust.bmp"); + setBackground(ImagePath::builtin("CamCust.bmp")); } else { const JsonVector & bgNames = CMainMenuConfig::get().getConfig()["game-select"].Vector(); - setBackground(RandomGeneratorUtil::nextItem(bgNames, CRandomGenerator::getDefault())->String()); + setBackground(ImagePath::fromJson(*RandomGeneratorUtil::nextItem(bgNames, CRandomGenerator::getDefault()))); } pos = background->center(); card = std::make_shared(); - buttonBack = std::make_shared(Point(581, 535), "SCNRBACK.DEF", CGI->generaltexth->zelp[105], [=](){ close();}, EShortcut::GLOBAL_CANCEL); + buttonBack = std::make_shared(Point(581, 535), AnimationPath::builtin("SCNRBACK.DEF"), CGI->generaltexth->zelp[105], [=](){ close();}, EShortcut::GLOBAL_CANCEL); } void CSelectionBase::toggleTab(std::shared_ptr tab) @@ -125,7 +125,7 @@ InfoCard::InfoCard() mapName = std::make_shared(26, 39, FONT_BIG, ETextAlignment::TOPLEFT, Colors::YELLOW); Rect descriptionRect(26, 149, 320, 115); mapDescription = std::make_shared("", descriptionRect, 1); - playerListBg = std::make_shared("CHATPLUG.bmp", 16, 276); + playerListBg = std::make_shared(ImagePath::builtin("CHATPLUG.bmp"), 16, 276); chat = std::make_shared(Rect(26, 132, 340, 132)); if(SEL->screenType == ESelectionScreen::campaignList) @@ -134,14 +134,14 @@ InfoCard::InfoCard() } else { - background = std::make_shared("GSELPOP1.bmp", 0, 0); + background = std::make_shared(ImagePath::builtin("GSELPOP1.bmp"), 0, 0); parent->addChild(background.get()); auto it = vstd::find(parent->children, this); //our position among parent children parent->children.insert(it, background.get()); //put BG before us parent->children.pop_back(); pos.w = background->pos.w; pos.h = background->pos.h; - iconsMapSizes = std::make_shared("SCNRMPSZ", 4, 0, 318, 22); //let it be custom size (frame 4) by default + iconsMapSizes = std::make_shared(AnimationPath::builtin("SCNRMPSZ"), 4, 0, 318, 22); //let it be custom size (frame 4) by default iconDifficulty = std::make_shared(0); { @@ -149,7 +149,7 @@ InfoCard::InfoCard() for(int i = 0; i < 5; i++) { - auto button = std::make_shared(Point(110 + i * 32, 450), difButns[i], CGI->generaltexth->zelp[24 + i]); + auto button = std::make_shared(Point(110 + i * 32, 450), AnimationPath::builtin(difButns[i]), CGI->generaltexth->zelp[24 + i]); iconDifficulty->addToggle(i, button); if(SEL->screenType != ESelectionScreen::newGame) @@ -165,8 +165,8 @@ InfoCard::InfoCard() labelScenarioDescription = std::make_shared(26, 132, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::YELLOW, CGI->generaltexth->allTexts[496]); labelVictoryCondition = std::make_shared(26, 283, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::YELLOW, CGI->generaltexth->allTexts[497]); labelLossCondition = std::make_shared(26, 339, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::YELLOW, CGI->generaltexth->allTexts[498]); - iconsVictoryCondition = std::make_shared("SCNRVICT", 0, 0, 24, 302); - iconsLossCondition = std::make_shared("SCNRLOSS", 0, 0, 24, 359); + iconsVictoryCondition = std::make_shared(AnimationPath::builtin("SCNRVICT"), 0, 0, 24, 302); + iconsLossCondition = std::make_shared(AnimationPath::builtin("SCNRLOSS"), 0, 0, 24, 359); labelVictoryConditionText = std::make_shared(60, 307, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE); labelLossConditionText = std::make_shared(60, 366, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE); @@ -356,7 +356,7 @@ CFlagBox::CFlagBox(const Rect & rect) labelAllies = std::make_shared(0, 0, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[390] + ":"); labelEnemies = std::make_shared(133, 0, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[391] + ":"); - iconsTeamFlags = std::make_shared("ITGFLAGS.DEF"); + iconsTeamFlags = std::make_shared(AnimationPath::builtin("ITGFLAGS.DEF")); iconsTeamFlags->preload(); } @@ -390,7 +390,7 @@ void CFlagBox::showPopupWindow(const Point & cursorPosition) } CFlagBox::CFlagBoxTooltipBox::CFlagBoxTooltipBox(std::shared_ptr icons) - : CWindowObject(BORDERED | RCLICK_POPUP | SHADOW_DISABLED, "DIBOXBCK") + : CWindowObject(BORDERED | RCLICK_POPUP | SHADOW_DISABLED, ImagePath::builtin("DIBOXBCK")) { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; diff --git a/client/lobby/OptionsTab.cpp b/client/lobby/OptionsTab.cpp index f9de0b3f3..48f675425 100644 --- a/client/lobby/OptionsTab.cpp +++ b/client/lobby/OptionsTab.cpp @@ -137,7 +137,7 @@ OptionsTab::OptionsTab() : humanPlayers(0) } }); - const JsonNode config(ResourceID("config/widgets/optionsTab.json")); + const JsonNode config(ResourcePath("config/widgets/optionsTab.json")); build(config); //set timers combo box callbacks @@ -343,18 +343,18 @@ size_t OptionsTab::CPlayerSettingsHelper::getImageIndex(bool big) return 0; } -std::string OptionsTab::CPlayerSettingsHelper::getImageName(bool big) +AnimationPath OptionsTab::CPlayerSettingsHelper::getImageName(bool big) { switch(type) { case OptionsTab::TOWN: - return big ? "ITPt": "ITPA"; + return AnimationPath::builtin(big ? "ITPt": "ITPA"); case OptionsTab::HERO: - return big ? "PortraitsLarge": "PortraitsSmall"; + return AnimationPath::builtin(big ? "PortraitsLarge": "PortraitsSmall"); case OptionsTab::BONUS: - return "SCNRSTAR"; + return AnimationPath::builtin("SCNRSTAR"); } - return ""; + return {}; } std::string OptionsTab::CPlayerSettingsHelper::getName() @@ -553,7 +553,7 @@ OptionsTab::CPlayerOptionTooltipBox::CPlayerOptionTooltipBox(CPlayerSettingsHelp void OptionsTab::CPlayerOptionTooltipBox::genHeader() { - backgroundTexture = std::make_shared("DIBOXBCK", pos); + backgroundTexture = std::make_shared(ImagePath::builtin("DIBOXBCK"), pos); updateShadow(); labelTitle = std::make_shared(pos.w / 2 + 8, 21, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, getTitle()); @@ -585,7 +585,7 @@ void OptionsTab::CPlayerOptionTooltipBox::genHeroWindow() labelHeroSpeciality = std::make_shared(pos.w / 2 + 4, 117, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[78]); auto heroIndex = settings.hero.getNum() >= CGI->heroh->size() ? 0 : settings.hero.getNum(); - imageSpeciality = std::make_shared("UN44", (*CGI->heroh)[heroIndex]->imageIndex, 0, pos.w / 2 - 22, 134); + imageSpeciality = std::make_shared(AnimationPath::builtin("UN44"), (*CGI->heroh)[heroIndex]->imageIndex, 0, pos.w / 2 - 22, 134); labelSpecialityName = std::make_shared(pos.w / 2, 188, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, (*CGI->heroh)[heroIndex]->getSpecialtyNameTranslated()); } @@ -717,7 +717,7 @@ void OptionsTab::SelectionWindow::recreate() pos = Rect(0, 0, x, y); - backgroundTexture = std::make_shared("DiBoxBck", pos); + backgroundTexture = std::make_shared(ImagePath::builtin("DiBoxBck"), pos); backgroundTexture->playerColored(PlayerColor(1)); updateShadow(); @@ -747,7 +747,7 @@ void OptionsTab::SelectionWindow::genContentGrid(int lines) { for(int x = 0; x < elementsPerLine; x++) { - components.push_back(std::make_shared("lobby/townBorderBig", x * (ICON_BIG_WIDTH-1), y * (ICON_BIG_HEIGHT-1))); + components.push_back(std::make_shared(ImagePath::builtin("lobby/townBorderBig"), x * (ICON_BIG_WIDTH-1), y * (ICON_BIG_HEIGHT-1))); } } } @@ -763,7 +763,7 @@ void OptionsTab::SelectionWindow::genContentFactions() components.push_back(std::make_shared(helper.getImageName(), helper.getImageIndex(), 0, 6, (ICON_SMALL_HEIGHT/2))); drawOutlinedText(TEXT_POS_X, TEXT_POS_Y, (selectedFaction.getNum() == PlayerSettings::RANDOM) ? Colors::YELLOW : Colors::WHITE, helper.getName()); if(selectedFaction.getNum() == PlayerSettings::RANDOM) - components.push_back(std::make_shared("lobby/townBorderSmallActivated", 6, (ICON_SMALL_HEIGHT/2))); + components.push_back(std::make_shared(ImagePath::builtin("lobby/townBorderSmallActivated"), 6, (ICON_SMALL_HEIGHT/2))); for(auto & elem : allowedFactions) { @@ -776,7 +776,7 @@ void OptionsTab::SelectionWindow::genContentFactions() CPlayerSettingsHelper helper = CPlayerSettingsHelper(set, SelType::TOWN); components.push_back(std::make_shared(helper.getImageName(true), helper.getImageIndex(true), 0, x * (ICON_BIG_WIDTH-1), y * (ICON_BIG_HEIGHT-1))); - components.push_back(std::make_shared(selectedFaction == elem ? "lobby/townBorderBigActivated" : "lobby/townBorderBig", x * (ICON_BIG_WIDTH-1), y * (ICON_BIG_HEIGHT-1))); + components.push_back(std::make_shared(ImagePath::builtin(selectedFaction == elem ? "lobby/townBorderBigActivated" : "lobby/townBorderBig"), x * (ICON_BIG_WIDTH-1), y * (ICON_BIG_HEIGHT-1))); drawOutlinedText(x * (ICON_BIG_WIDTH-1) + TEXT_POS_X, y * (ICON_BIG_HEIGHT-1) + TEXT_POS_Y, (selectedFaction == elem) ? Colors::YELLOW : Colors::WHITE, helper.getName()); factions.push_back(elem); @@ -795,7 +795,7 @@ void OptionsTab::SelectionWindow::genContentHeroes() components.push_back(std::make_shared(helper.getImageName(), helper.getImageIndex(), 0, 6, (ICON_SMALL_HEIGHT/2))); drawOutlinedText(TEXT_POS_X, TEXT_POS_Y, (selectedHero.getNum() == PlayerSettings::RANDOM) ? Colors::YELLOW : Colors::WHITE, helper.getName()); if(selectedHero.getNum() == PlayerSettings::RANDOM) - components.push_back(std::make_shared("lobby/townBorderSmallActivated", 6, (ICON_SMALL_HEIGHT/2))); + components.push_back(std::make_shared(ImagePath::builtin("lobby/townBorderSmallActivated"), 6, (ICON_SMALL_HEIGHT/2))); for(auto & elem : allowedHeroes) { @@ -814,11 +814,11 @@ void OptionsTab::SelectionWindow::genContentHeroes() components.push_back(std::make_shared(helper.getImageName(true), helper.getImageIndex(true), 0, x * (ICON_BIG_WIDTH-1), y * (ICON_BIG_HEIGHT-1))); drawOutlinedText(x * (ICON_BIG_WIDTH-1) + TEXT_POS_X, y * (ICON_BIG_HEIGHT-1) + TEXT_POS_Y, (selectedHero == elem) ? Colors::YELLOW : Colors::WHITE, helper.getName()); - std::string image = "lobby/townBorderBig"; + ImagePath image = ImagePath::builtin("lobby/townBorderBig"); if(selectedHero == elem) - image = "lobby/townBorderBigActivated"; + image = ImagePath::builtin("lobby/townBorderBigActivated"); if(unusableHeroes.count(elem)) - image = "lobby/townBorderBigGrayedOut"; + image = ImagePath::builtin("lobby/townBorderBigGrayedOut"); components.push_back(std::make_shared(image, x * (ICON_BIG_WIDTH-1), y * (ICON_BIG_HEIGHT-1))); heroes.push_back(elem); @@ -843,7 +843,7 @@ void OptionsTab::SelectionWindow::genContentBonus() drawOutlinedText(x * (ICON_BIG_WIDTH-1) + TEXT_POS_X, y * (ICON_BIG_HEIGHT-1) + TEXT_POS_Y, Colors::WHITE , helper.getName()); if(selectedBonus == elem) { - components.push_back(std::make_shared("lobby/townBorderSmallActivated", x * (ICON_BIG_WIDTH-1) + 6, y * (ICON_BIG_HEIGHT-1) + (ICON_SMALL_HEIGHT/2))); + components.push_back(std::make_shared(ImagePath::builtin("lobby/townBorderSmallActivated"), x * (ICON_BIG_WIDTH-1) + 6, y * (ICON_BIG_HEIGHT-1) + (ICON_SMALL_HEIGHT/2))); drawOutlinedText(x * (ICON_BIG_WIDTH-1) + TEXT_POS_X, y * (ICON_BIG_HEIGHT-1) + TEXT_POS_Y, Colors::YELLOW , helper.getName()); } @@ -1075,18 +1075,18 @@ OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry(const PlayerSettings & S, con "ADOPOPNL.bmp", "ADOPPPNL.bmp", "ADOPTPNL.bmp", "ADOPSPNL.bmp" }}; - background = std::make_shared(bgs[s->color.getNum()], 0, 0); + background = std::make_shared(ImagePath::builtin(bgs[s->color.getNum()]), 0, 0); labelPlayerName = std::make_shared(55, 10, EFonts::FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, s->name); labelWhoCanPlay = std::make_shared(Rect(6, 23, 45, (int)graphics->fonts[EFonts::FONT_TINY]->getLineHeight()*2), EFonts::FONT_TINY, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->arraytxt[206 + whoCanPlay]); if(SEL->screenType == ESelectionScreen::newGame) { - buttonTownLeft = std::make_shared(Point(107, 5), "ADOPLFA.DEF", CGI->generaltexth->zelp[132], std::bind(&IServerAPI::setPlayerOption, CSH, LobbyChangePlayerOption::TOWN, -1, s->color)); - buttonTownRight = std::make_shared(Point(168, 5), "ADOPRTA.DEF", CGI->generaltexth->zelp[133], std::bind(&IServerAPI::setPlayerOption, CSH, LobbyChangePlayerOption::TOWN, +1, s->color)); - buttonHeroLeft = std::make_shared(Point(183, 5), "ADOPLFA.DEF", CGI->generaltexth->zelp[148], std::bind(&IServerAPI::setPlayerOption, CSH, LobbyChangePlayerOption::HERO, -1, s->color)); - buttonHeroRight = std::make_shared(Point(244, 5), "ADOPRTA.DEF", CGI->generaltexth->zelp[149], std::bind(&IServerAPI::setPlayerOption, CSH, LobbyChangePlayerOption::HERO, +1, s->color)); - buttonBonusLeft = std::make_shared(Point(259, 5), "ADOPLFA.DEF", CGI->generaltexth->zelp[164], std::bind(&IServerAPI::setPlayerOption, CSH, LobbyChangePlayerOption::BONUS, -1, s->color)); - buttonBonusRight = std::make_shared(Point(320, 5), "ADOPRTA.DEF", CGI->generaltexth->zelp[165], std::bind(&IServerAPI::setPlayerOption, CSH, LobbyChangePlayerOption::BONUS, +1, s->color)); + buttonTownLeft = std::make_shared(Point(107, 5), AnimationPath::builtin("ADOPLFA.DEF"), CGI->generaltexth->zelp[132], std::bind(&IServerAPI::setPlayerOption, CSH, LobbyChangePlayerOption::TOWN, -1, s->color)); + buttonTownRight = std::make_shared(Point(168, 5), AnimationPath::builtin("ADOPRTA.DEF"), CGI->generaltexth->zelp[133], std::bind(&IServerAPI::setPlayerOption, CSH, LobbyChangePlayerOption::TOWN, +1, s->color)); + buttonHeroLeft = std::make_shared(Point(183, 5), AnimationPath::builtin("ADOPLFA.DEF"), CGI->generaltexth->zelp[148], std::bind(&IServerAPI::setPlayerOption, CSH, LobbyChangePlayerOption::HERO, -1, s->color)); + buttonHeroRight = std::make_shared(Point(244, 5), AnimationPath::builtin("ADOPRTA.DEF"), CGI->generaltexth->zelp[149], std::bind(&IServerAPI::setPlayerOption, CSH, LobbyChangePlayerOption::HERO, +1, s->color)); + buttonBonusLeft = std::make_shared(Point(259, 5), AnimationPath::builtin("ADOPLFA.DEF"), CGI->generaltexth->zelp[164], std::bind(&IServerAPI::setPlayerOption, CSH, LobbyChangePlayerOption::BONUS, -1, s->color)); + buttonBonusRight = std::make_shared(Point(320, 5), AnimationPath::builtin("ADOPRTA.DEF"), CGI->generaltexth->zelp[165], std::bind(&IServerAPI::setPlayerOption, CSH, LobbyChangePlayerOption::BONUS, +1, s->color)); } hideUnavailableButtons(); @@ -1095,7 +1095,7 @@ OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry(const PlayerSettings & S, con { flag = std::make_shared( Point(-43, 2), - flags[s->color.getNum()], + AnimationPath::builtin(flags[s->color.getNum()]), CGI->generaltexth->zelp[180], std::bind(&OptionsTab::onSetPlayerClicked, &parentTab, *s) ); diff --git a/client/lobby/OptionsTab.h b/client/lobby/OptionsTab.h index b3d9f7e9a..042b84bea 100644 --- a/client/lobby/OptionsTab.h +++ b/client/lobby/OptionsTab.h @@ -62,7 +62,7 @@ private: /// visible image settings size_t getImageIndex(bool big = false); - std::string getImageName(bool big = false); + AnimationPath getImageName(bool big = false); std::string getName(); /// name visible in options dialog std::string getTitle(); /// title in popup box diff --git a/client/lobby/RandomMapTab.cpp b/client/lobby/RandomMapTab.cpp index fad8a28eb..f116104bc 100644 --- a/client/lobby/RandomMapTab.cpp +++ b/client/lobby/RandomMapTab.cpp @@ -118,7 +118,7 @@ RandomMapTab::RandomMapTab(): }); } - const JsonNode config(ResourceID("config/widgets/randomMapTab.json")); + const JsonNode config(ResourcePath("config/widgets/randomMapTab.json")); build(config); //set combo box callbacks @@ -388,7 +388,7 @@ std::vector RandomMapTab::getPossibleMapSizes() TeamAlignmentsWidget::TeamAlignmentsWidget(RandomMapTab & randomMapTab): InterfaceObjectConfigurable() { - const JsonNode config(ResourceID("config/widgets/randomMapTeamsWidget.json")); + const JsonNode config(ResourcePath("config/widgets/randomMapTeamsWidget.json")); variables = config["variables"]; int humanPlayers = randomMapTab.obtainMapGenOptions().getPlayerCount(); diff --git a/client/lobby/SelectionTab.cpp b/client/lobby/SelectionTab.cpp index e2514cb8f..7200fc690 100644 --- a/client/lobby/SelectionTab.cpp +++ b/client/lobby/SelectionTab.cpp @@ -158,16 +158,16 @@ SelectionTab::SelectionTab(ESelectionScreen Type) if(tabType != ESelectionScreen::campaignList) { sortingBy = _format; - background = std::make_shared("SCSELBCK.bmp", 0, 6); + background = std::make_shared(ImagePath::builtin("SCSELBCK.bmp"), 0, 6); pos = background->pos; - inputName = std::make_shared(inputNameRect, Point(-32, -25), "GSSTRIP.bmp", 0); + inputName = std::make_shared(inputNameRect, Point(-32, -25), ImagePath::builtin("GSSTRIP.bmp"), 0); inputName->filters += CTextInput::filenameFilter; labelMapSizes = std::make_shared(87, 62, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[510]); int sizes[] = {36, 72, 108, 144, 0}; const char * filterIconNmes[] = {"SCSMBUT.DEF", "SCMDBUT.DEF", "SCLGBUT.DEF", "SCXLBUT.DEF", "SCALBUT.DEF"}; for(int i = 0; i < 5; i++) - buttonsSortBy.push_back(std::make_shared(Point(158 + 47 * i, 46), filterIconNmes[i], CGI->generaltexth->zelp[54 + i], std::bind(&SelectionTab::filter, this, sizes[i], true))); + buttonsSortBy.push_back(std::make_shared(Point(158 + 47 * i, 46), AnimationPath::builtin(filterIconNmes[i]), CGI->generaltexth->zelp[54 + i], std::bind(&SelectionTab::filter, this, sizes[i], true))); int xpos[] = {23, 55, 88, 121, 306, 339}; const char * sortIconNames[] = {"SCBUTT1.DEF", "SCBUTT2.DEF", "SCBUTCP.DEF", "SCBUTT3.DEF", "SCBUTT4.DEF", "SCBUTT5.DEF"}; @@ -177,7 +177,7 @@ SelectionTab::SelectionTab(ESelectionScreen Type) if(criteria == _name) criteria = generalSortingBy; - buttonsSortBy.push_back(std::make_shared(Point(xpos[i], 86), sortIconNames[i], CGI->generaltexth->zelp[107 + i], std::bind(&SelectionTab::sortBy, this, criteria))); + buttonsSortBy.push_back(std::make_shared(Point(xpos[i], 86), AnimationPath::builtin(sortIconNames[i]), CGI->generaltexth->zelp[107 + i], std::bind(&SelectionTab::sortBy, this, criteria))); } } @@ -203,17 +203,17 @@ SelectionTab::SelectionTab(ESelectionScreen Type) pos.x += 3; pos.y += 6; - buttonsSortBy.push_back(std::make_shared(Point(23, 86), "CamCusM.DEF", CButton::tooltip(), std::bind(&SelectionTab::sortBy, this, _numOfMaps))); - buttonsSortBy.push_back(std::make_shared(Point(55, 86), "CamCusL.DEF", CButton::tooltip(), std::bind(&SelectionTab::sortBy, this, _name))); + buttonsSortBy.push_back(std::make_shared(Point(23, 86), AnimationPath::builtin("CamCusM.DEF"), CButton::tooltip(), std::bind(&SelectionTab::sortBy, this, _numOfMaps))); + buttonsSortBy.push_back(std::make_shared(Point(55, 86), AnimationPath::builtin("CamCusL.DEF"), CButton::tooltip(), std::bind(&SelectionTab::sortBy, this, _name))); break; default: assert(0); break; } - iconsMapFormats = std::make_shared("SCSELC.DEF"); - iconsVictoryCondition = std::make_shared("SCNRVICT.DEF"); - iconsLossCondition = std::make_shared("SCNRLOSS.DEF"); + iconsMapFormats = std::make_shared(AnimationPath::builtin("SCSELC.DEF")); + iconsVictoryCondition = std::make_shared(AnimationPath::builtin("SCNRVICT.DEF")); + iconsLossCondition = std::make_shared(AnimationPath::builtin("SCNRLOSS.DEF")); for(int i = 0; i < positionsToShow; i++) listItems.push_back(std::make_shared(Point(30, 129 + i * 25), iconsMapFormats, iconsVictoryCondition, iconsLossCondition)); @@ -244,7 +244,7 @@ void SelectionTab::toggleMode() { inputName->disable(); auto files = getFiles("Maps/", EResType::MAP); - files.erase(ResourceID("Maps/Tutorial.tut", EResType::MAP)); + files.erase(ResourcePath("Maps/Tutorial.tut", EResType::MAP)); parseMaps(files); break; } @@ -367,7 +367,7 @@ void SelectionTab::showPopupWindow(const Point & cursorPosition) if(curItems[py]->date != "") text += boost::str(boost::format("\r\n\r\n%1%:\r\n%2%") % CGI->generaltexth->translate("vcmi.lobby.creationDate") % curItems[py]->date); - GH.windows().createAndPushWindow(text, ResourceID(curItems[py]->fileURI), tabType); + GH.windows().createAndPushWindow(text, ResourcePath(curItems[py]->fileURI), tabType); } } @@ -556,7 +556,7 @@ void SelectionTab::select(int position) if(inputName && inputName->isActive()) { - auto filename = *CResourceHandler::get()->getResourceName(ResourceID(curItems[py]->fileURI, EResType::SAVEGAME)); + auto filename = *CResourceHandler::get()->getResourceName(ResourcePath(curItems[py]->fileURI, EResType::SAVEGAME)); inputName->setText(filename.stem().string()); } @@ -723,7 +723,7 @@ bool SelectionTab::isMapSupported(const CMapInfo & info) return false; } -void SelectionTab::parseMaps(const std::unordered_set & files) +void SelectionTab::parseMaps(const std::unordered_set & files) { logGlobal->debug("Parsing %d maps", files.size()); allItems.clear(); @@ -744,7 +744,7 @@ void SelectionTab::parseMaps(const std::unordered_set & files) } } -void SelectionTab::parseSaves(const std::unordered_set & files) +void SelectionTab::parseSaves(const std::unordered_set & files) { for(auto & file : files) { @@ -786,7 +786,7 @@ void SelectionTab::parseSaves(const std::unordered_set & files) } } -void SelectionTab::parseCampaigns(const std::unordered_set & files) +void SelectionTab::parseCampaigns(const std::unordered_set & files) { allItems.reserve(files.size()); for(auto & file : files) @@ -800,7 +800,7 @@ void SelectionTab::parseCampaigns(const std::unordered_set & files) } } -std::unordered_set SelectionTab::getFiles(std::string dirURI, int resType) +std::unordered_set SelectionTab::getFiles(std::string dirURI, EResType resType) { boost::to_upper(dirURI); CResourceHandler::get()->updateFilteredFiles([&](const std::string & mount) @@ -808,7 +808,7 @@ std::unordered_set SelectionTab::getFiles(std::string dirURI, int re return boost::algorithm::starts_with(mount, dirURI); }); - std::unordered_set ret = CResourceHandler::get()->getFilteredFiles([&](const ResourceID & ident) + std::unordered_set ret = CResourceHandler::get()->getFilteredFiles([&](const ResourcePath & ident) { return ident.getType() == resType && boost::algorithm::starts_with(ident.getName(), dirURI); }); @@ -816,7 +816,7 @@ std::unordered_set SelectionTab::getFiles(std::string dirURI, int re return ret; } -SelectionTab::CMapInfoTooltipBox::CMapInfoTooltipBox(std::string text, ResourceID resource, ESelectionScreen tabType) +SelectionTab::CMapInfoTooltipBox::CMapInfoTooltipBox(std::string text, ResourcePath resource, ESelectionScreen tabType) : CWindowObject(BORDERED | RCLICK_POPUP) { drawPlayerElements = tabType == ESelectionScreen::newGame; @@ -826,7 +826,7 @@ SelectionTab::CMapInfoTooltipBox::CMapInfoTooltipBox(std::string text, ResourceI std::vector> mapLayerImages; if(renderImage) - mapLayerImages = createMinimaps(ResourceID(resource.getName(), EResType::MAP), IMAGE_SIZE); + mapLayerImages = createMinimaps(ResourcePath(resource.getName(), EResType::MAP), IMAGE_SIZE); if(mapLayerImages.size() == 0) renderImage = false; @@ -844,7 +844,7 @@ SelectionTab::CMapInfoTooltipBox::CMapInfoTooltipBox(std::string text, ResourceI pos.h = BORDER + textHeight + BORDER; if(renderImage) pos.h += IMAGE_SIZE + BORDER; - backgroundTexture = std::make_shared("DIBOXBCK", pos); + backgroundTexture = std::make_shared(ImagePath::builtin("DIBOXBCK"), pos); updateShadow(); drawLabel(); @@ -903,7 +903,7 @@ Canvas SelectionTab::CMapInfoTooltipBox::createMinimapForLayer(std::unique_ptr> SelectionTab::CMapInfoTooltipBox::createMinimaps(ResourceID resource, int size) +std::vector> SelectionTab::CMapInfoTooltipBox::createMinimaps(ResourcePath resource, int size) { std::vector> ret = std::vector>(); @@ -935,7 +935,7 @@ SelectionTab::ListItem::ListItem(Point position, std::shared_ptr ico : CIntObject(LCLICK, position) { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - pictureEmptyLine = std::make_shared(IImage::createFromFile("camcust"), Rect(25, 121, 349, 26), -8, -14); + pictureEmptyLine = std::make_shared(IImage::createFromFile(ImagePath::builtin("camcust")), Rect(25, 121, 349, 26), -8, -14); labelName = std::make_shared(184, 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); labelName->setAutoRedraw(false); labelAmountOfPlayers = std::make_shared(8, 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); @@ -945,7 +945,7 @@ SelectionTab::ListItem::ListItem(Point position, std::shared_ptr ico labelMapSizeLetter = std::make_shared(41, 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); labelMapSizeLetter->setAutoRedraw(false); // FIXME: This -12 should not be needed, but for some reason CAnimImage displaced otherwise - iconFolder = std::make_shared("lobby/iconFolder.png", -8, -12); + iconFolder = std::make_shared(ImagePath::builtin("lobby/iconFolder.png"), -8, -12); iconFormat = std::make_shared(iconsFormats, 0, 0, 59, -12); iconVictoryCondition = std::make_shared(iconsVictory, 0, 0, 277, -12); iconLossCondition = std::make_shared(iconsLoss, 0, 0, 310, -12); diff --git a/client/lobby/SelectionTab.h b/client/lobby/SelectionTab.h index 50426b78d..e4d67ef83 100644 --- a/client/lobby/SelectionTab.h +++ b/client/lobby/SelectionTab.h @@ -14,6 +14,7 @@ VCMI_LIB_NAMESPACE_BEGIN class CMap; VCMI_LIB_NAMESPACE_END #include "../../lib/mapping/CMapInfo.h" +#include "../../lib/filesystem/ResourcePath.h" class CSlider; class CLabel; @@ -81,9 +82,9 @@ class SelectionTab : public CIntObject std::shared_ptr image2; Canvas createMinimapForLayer(std::unique_ptr & map, int layer); - std::vector> createMinimaps(ResourceID resource, int size); + std::vector> createMinimaps(ResourcePath resource, int size); public: - CMapInfoTooltipBox(std::string text, ResourceID resource, ESelectionScreen tabType); + CMapInfoTooltipBox(std::string text, ResourcePath resource, ESelectionScreen tabType); }; public: std::vector> allItems; @@ -134,8 +135,8 @@ private: auto checkSubfolder(std::string path); bool isMapSupported(const CMapInfo & info); - void parseMaps(const std::unordered_set & files); - void parseSaves(const std::unordered_set & files); - void parseCampaigns(const std::unordered_set & files); - std::unordered_set getFiles(std::string dirURI, int resType); + void parseMaps(const std::unordered_set & files); + void parseSaves(const std::unordered_set & files); + void parseCampaigns(const std::unordered_set & files); + std::unordered_set getFiles(std::string dirURI, EResType resType); }; diff --git a/client/mainmenu/CCampaignScreen.cpp b/client/mainmenu/CCampaignScreen.cpp index d1c9fd328..c8d695aee 100644 --- a/client/mainmenu/CCampaignScreen.cpp +++ b/client/mainmenu/CCampaignScreen.cpp @@ -86,7 +86,7 @@ std::shared_ptr CCampaignScreen::createExitButton(const JsonNode & butt if(!button["help"].isNull() && button["help"].Float() > 0) help = CGI->generaltexth->zelp[(size_t)button["help"].Float()]; - return std::make_shared(Point((int)button["x"].Float(), (int)button["y"].Float()), button["name"].String(), help, [=](){ close();}, EShortcut::GLOBAL_CANCEL); + return std::make_shared(Point((int)button["x"].Float(), (int)button["y"].Float()), AnimationPath::fromJson(button["name"]), help, [=](){ close();}, EShortcut::GLOBAL_CANCEL); } CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode & config) @@ -109,14 +109,14 @@ CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode & config) if(status != CCampaignScreen::DISABLED) { addUsedEvents(LCLICK | HOVER); - graphicsImage = std::make_shared(config["image"].String()); + graphicsImage = std::make_shared(ImagePath::fromJson(config["image"])); hoverLabel = std::make_shared(pos.w / 2, pos.h + 20, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, ""); parent->addChild(hoverLabel.get()); } if(status == CCampaignScreen::COMPLETED) - graphicsCompleted = std::make_shared("CAMPCHK"); + graphicsCompleted = std::make_shared(ImagePath::builtin("CAMPCHK")); } void CCampaignScreen::CCampaignButton::show(Canvas & to) diff --git a/client/mainmenu/CMainMenu.cpp b/client/mainmenu/CMainMenu.cpp index 9580d91c8..bd6edd96a 100644 --- a/client/mainmenu/CMainMenu.cpp +++ b/client/mainmenu/CMainMenu.cpp @@ -78,7 +78,7 @@ CMenuScreen::CMenuScreen(const JsonNode & configNode) { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - background = std::make_shared(config["background"].String()); + background = std::make_shared(ImagePath::fromJson(config["background"])); if(config["scalable"].Bool()) background->scaleTo(GH.screenDimensions()); @@ -237,7 +237,7 @@ std::shared_ptr CMenuEntry::createButton(CMenuScreen * parent, const Js EShortcut shortcut = GH.shortcuts().findShortcut(button["shortcut"].String()); - auto result = std::make_shared(Point(posx, posy), button["name"].String(), help, command, shortcut); + auto result = std::make_shared(Point(posx, posy), AnimationPath::fromJson(button["name"]), help, command, shortcut); if (button["center"].Bool()) result->moveBy(Point(-result->pos.w/2, -result->pos.h/2)); @@ -262,7 +262,7 @@ CMenuEntry::CMenuEntry(CMenuScreen * parent, const JsonNode & config) } CMainMenuConfig::CMainMenuConfig() - : campaignSets(JsonNode(ResourceID("config/campaignSets.json"))), config(JsonNode(ResourceID("config/mainmenu.json"))) + : campaignSets(JsonNode(ResourcePath("config/campaignSets.json"))), config(JsonNode(ResourcePath("config/mainmenu.json"))) { } @@ -291,7 +291,7 @@ CMainMenu::CMainMenu() GH.defActionsDef = 63; menu = std::make_shared(CMainMenuConfig::get().getConfig()["window"]); OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - backgroundAroundMenu = std::make_shared("DIBOXBCK", pos); + backgroundAroundMenu = std::make_shared(ImagePath::builtin("DIBOXBCK"), pos); } CMainMenu::~CMainMenu() @@ -374,7 +374,7 @@ void CMainMenu::openCampaignScreen(std::string name) void CMainMenu::startTutorial() { - ResourceID tutorialMap("Maps/Tutorial.tut", EResType::MAP); + ResourcePath tutorialMap("Maps/Tutorial.tut", EResType::MAP); if(!CResourceHandler::get()->existsResource(tutorialMap)) { CInfoWindow::showInfoDialog(CGI->generaltexth->translate("core.genrltxt.742"), std::vector>(), PlayerColor(1)); @@ -397,7 +397,7 @@ std::shared_ptr CMainMenu::create() std::shared_ptr CMainMenu::createPicture(const JsonNode & config) { - return std::make_shared(config["name"].String(), (int)config["x"].Float(), (int)config["y"].Float()); + return std::make_shared(ImagePath::fromJson(config["name"]), (int)config["x"].Float(), (int)config["y"].Float()); } CMultiMode::CMultiMode(ESelectionScreen ScreenType) @@ -405,20 +405,20 @@ CMultiMode::CMultiMode(ESelectionScreen ScreenType) { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - background = std::make_shared("MUPOPUP.bmp"); + background = std::make_shared(ImagePath::builtin("MUPOPUP.bmp")); pos = background->center(); //center, window has size of bg graphic - picture = std::make_shared("MUMAP.bmp", 16, 77); + picture = std::make_shared(ImagePath::builtin("MUMAP.bmp"), 16, 77); statusBar = CGStatusBar::create(std::make_shared(background->getSurface(), Rect(7, 465, 440, 18), 7, 465)); playerName = std::make_shared(Rect(19, 436, 334, 16), background->getSurface()); playerName->setText(getPlayerName()); playerName->cb += std::bind(&CMultiMode::onNameChange, this, _1); - buttonHotseat = std::make_shared(Point(373, 78), "MUBHOT.DEF", CGI->generaltexth->zelp[266], std::bind(&CMultiMode::hostTCP, this)); - buttonHost = std::make_shared(Point(373, 78 + 57 * 1), "MUBHOST.DEF", CButton::tooltip(CGI->generaltexth->translate("vcmi.mainMenu.hostTCP"), ""), std::bind(&CMultiMode::hostTCP, this)); - buttonJoin = std::make_shared(Point(373, 78 + 57 * 2), "MUBJOIN.DEF", CButton::tooltip(CGI->generaltexth->translate("vcmi.mainMenu.joinTCP"), ""), std::bind(&CMultiMode::joinTCP, this)); - buttonCancel = std::make_shared(Point(373, 424), "MUBCANC.DEF", CGI->generaltexth->zelp[288], [=](){ close();}, EShortcut::GLOBAL_CANCEL); + buttonHotseat = std::make_shared(Point(373, 78), AnimationPath::builtin("MUBHOT.DEF"), CGI->generaltexth->zelp[266], std::bind(&CMultiMode::hostTCP, this)); + buttonHost = std::make_shared(Point(373, 78 + 57 * 1), AnimationPath::builtin("MUBHOST.DEF"), CButton::tooltip(CGI->generaltexth->translate("vcmi.mainMenu.hostTCP"), ""), std::bind(&CMultiMode::hostTCP, this)); + buttonJoin = std::make_shared(Point(373, 78 + 57 * 2), AnimationPath::builtin("MUBJOIN.DEF"), CButton::tooltip(CGI->generaltexth->translate("vcmi.mainMenu.joinTCP"), ""), std::bind(&CMultiMode::joinTCP, this)); + buttonCancel = std::make_shared(Point(373, 424), AnimationPath::builtin("MUBCANC.DEF"), CGI->generaltexth->zelp[288], [=](){ close();}, EShortcut::GLOBAL_CANCEL); } void CMultiMode::hostTCP() @@ -453,7 +453,7 @@ CMultiPlayers::CMultiPlayers(const std::string & firstPlayer, ESelectionScreen S : loadMode(LoadMode), screenType(ScreenType), host(Host) { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - background = std::make_shared("MUHOTSEA.bmp"); + background = std::make_shared(ImagePath::builtin("MUHOTSEA.bmp")); pos = background->center(); //center, window has size of bg graphic std::string text = CGI->generaltexth->allTexts[446]; @@ -466,8 +466,8 @@ CMultiPlayers::CMultiPlayers(const std::string & firstPlayer, ESelectionScreen S inputNames[i]->cb += std::bind(&CMultiPlayers::onChange, this, _1); } - buttonOk = std::make_shared(Point(95, 338), "MUBCHCK.DEF", CGI->generaltexth->zelp[560], std::bind(&CMultiPlayers::enterSelectionScreen, this), EShortcut::GLOBAL_ACCEPT); - buttonCancel = std::make_shared(Point(205, 338), "MUBCANC.DEF", CGI->generaltexth->zelp[561], [=](){ close();}, EShortcut::GLOBAL_CANCEL); + buttonOk = std::make_shared(Point(95, 338), AnimationPath::builtin("MUBCHCK.DEF"), CGI->generaltexth->zelp[560], std::bind(&CMultiPlayers::enterSelectionScreen, this), EShortcut::GLOBAL_ACCEPT); + buttonCancel = std::make_shared(Point(205, 338), AnimationPath::builtin("MUBCANC.DEF"), CGI->generaltexth->zelp[561], [=](){ close();}, EShortcut::GLOBAL_CANCEL); statusBar = CGStatusBar::create(std::make_shared(background->getSurface(), Rect(7, 381, 348, 18), 7, 381)); inputNames[0]->setText(firstPlayer, true); @@ -498,7 +498,7 @@ void CMultiPlayers::enterSelectionScreen() CSimpleJoinScreen::CSimpleJoinScreen(bool host) { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - background = std::make_shared("MUDIALOG.bmp"); // address background + background = std::make_shared(ImagePath::builtin("MUDIALOG.bmp")); // address background pos = background->center(); //center, window has size of bg graphic (x,y = 396,278 w=232 h=212) textTitle = std::make_shared("", Rect(20, 20, 205, 50), 0, FONT_BIG, ETextAlignment::CENTER, Colors::WHITE); @@ -515,14 +515,14 @@ CSimpleJoinScreen::CSimpleJoinScreen(bool host) inputAddress->cb += std::bind(&CSimpleJoinScreen::onChange, this, _1); inputPort->cb += std::bind(&CSimpleJoinScreen::onChange, this, _1); inputPort->filters += std::bind(&CTextInput::numberFilter, _1, _2, 0, 65535); - buttonOk = std::make_shared(Point(26, 142), "MUBCHCK.DEF", CGI->generaltexth->zelp[560], std::bind(&CSimpleJoinScreen::connectToServer, this), EShortcut::GLOBAL_ACCEPT); + buttonOk = std::make_shared(Point(26, 142), AnimationPath::builtin("MUBCHCK.DEF"), CGI->generaltexth->zelp[560], std::bind(&CSimpleJoinScreen::connectToServer, this), EShortcut::GLOBAL_ACCEPT); inputAddress->giveFocus(); } inputAddress->setText(host ? CServerHandler::localhostAddress : CSH->getHostAddress(), true); inputPort->setText(std::to_string(CSH->getHostPort()), true); - buttonCancel = std::make_shared(Point(142, 142), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CSimpleJoinScreen::leaveScreen, this), EShortcut::GLOBAL_CANCEL); + buttonCancel = std::make_shared(Point(142, 142), AnimationPath::builtin("MUBCANC.DEF"), CGI->generaltexth->zelp[561], std::bind(&CSimpleJoinScreen::leaveScreen, this), EShortcut::GLOBAL_CANCEL); statusBar = CGStatusBar::create(std::make_shared(background->getSurface(), Rect(7, 186, 218, 18), 7, 186)); } @@ -601,7 +601,7 @@ CLoadingScreen::CLoadingScreen() for(int i = 0; i < blocksAmount; ++i) { - progressBlocks.push_back(std::make_shared(conf["name"].String(), i, 0, posx + i * blockSize, posy)); + progressBlocks.push_back(std::make_shared(AnimationPath::fromJson(conf["name"]), i, 0, posx + i * blockSize, posy)); progressBlocks.back()->deactivate(); progressBlocks.back()->visible = false; } @@ -626,24 +626,24 @@ void CLoadingScreen::tick(uint32_t msPassed) } } -std::string CLoadingScreen::getBackground() +ImagePath CLoadingScreen::getBackground() { - std::string fname = "loadbar"; + ImagePath fname = ImagePath::builtin("loadbar"); const auto & conf = CMainMenuConfig::get().getConfig()["loading"]; if(conf.isStruct()) { if(conf["background"].isVector()) - return RandomGeneratorUtil::nextItem(conf["background"].Vector(), CRandomGenerator::getDefault())->String(); + return ImagePath::fromJson(*RandomGeneratorUtil::nextItem(conf["background"].Vector(), CRandomGenerator::getDefault())); if(conf["background"].isString()) - return conf["background"].String(); + return ImagePath::fromJson(conf["background"]); return fname; } if(conf.isVector() && !conf.Vector().empty()) - return RandomGeneratorUtil::nextItem(conf.Vector(), CRandomGenerator::getDefault())->String(); + return ImagePath::fromJson(*RandomGeneratorUtil::nextItem(conf.Vector(), CRandomGenerator::getDefault())); return fname; } diff --git a/client/mainmenu/CMainMenu.h b/client/mainmenu/CMainMenu.h index 7e632fe6f..327fdb908 100644 --- a/client/mainmenu/CMainMenu.h +++ b/client/mainmenu/CMainMenu.h @@ -185,7 +185,7 @@ class CLoadingScreen : virtual public CWindowObject, virtual public Load::Progre { std::vector> progressBlocks; - std::string getBackground(); + ImagePath getBackground(); public: CLoadingScreen(); diff --git a/client/mainmenu/CreditsScreen.cpp b/client/mainmenu/CreditsScreen.cpp index dd8aae62c..8848ec407 100644 --- a/client/mainmenu/CreditsScreen.cpp +++ b/client/mainmenu/CreditsScreen.cpp @@ -26,7 +26,7 @@ CreditsScreen::CreditsScreen(Rect rect) pos.h = rect.h; setRedrawParent(true); OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - auto textFile = CResourceHandler::get()->load(ResourceID("DATA/CREDITS.TXT"))->readAll(); + auto textFile = CResourceHandler::get()->load(ResourcePath("DATA/CREDITS.TXT"))->readAll(); std::string text((char *)textFile.first.get(), textFile.second); size_t firstQuote = text.find('\"') + 1; text = text.substr(firstQuote, text.find('\"', firstQuote) - firstQuote); diff --git a/client/mapView/MapRenderer.cpp b/client/mapView/MapRenderer.cpp index 0b073177a..be14e7dcf 100644 --- a/client/mapView/MapRenderer.cpp +++ b/client/mapView/MapRenderer.cpp @@ -94,7 +94,7 @@ MapTileStorage::MapTileStorage(size_t capacity) { } -void MapTileStorage::load(size_t index, const std::string & filename, EImageBlitMode blitMode) +void MapTileStorage::load(size_t index, const AnimationPath & filename, EImageBlitMode blitMode) { auto & terrainAnimations = animations[index]; @@ -247,7 +247,7 @@ uint8_t MapRendererRoad::checksum(IMapRendererContext & context, const int3 & co MapRendererBorder::MapRendererBorder() { emptyFill = std::make_unique(Point(32,32)); - animation = std::make_unique("EDG"); + animation = std::make_unique(AnimationPath::builtin("EDG")); animation->preload(); } @@ -309,9 +309,9 @@ uint8_t MapRendererBorder::checksum(IMapRendererContext & context, const int3 & MapRendererFow::MapRendererFow() { - fogOfWarFullHide = std::make_unique("TSHRC"); + fogOfWarFullHide = std::make_unique(AnimationPath::builtin("TSHRC")); fogOfWarFullHide->preload(); - fogOfWarPartialHide = std::make_unique("TSHRE"); + fogOfWarPartialHide = std::make_unique(AnimationPath::builtin("TSHRE")); fogOfWarPartialHide->preload(); for(size_t i = 0; i < fogOfWarFullHide->size(); ++i) @@ -387,7 +387,7 @@ std::shared_ptr MapRendererObjects::getBaseAnimation(const CGObjectI return getAnimation(info->animationFile, generateMovementGroups); } -std::shared_ptr MapRendererObjects::getAnimation(const std::string & filename, bool generateMovementGroups) +std::shared_ptr MapRendererObjects::getAnimation(const AnimationPath & filename, bool generateMovementGroups) { auto it = animations.find(filename); @@ -422,7 +422,7 @@ std::shared_ptr MapRendererObjects::getFlagAnimation(const CGObjectI { assert(dynamic_cast(obj) != nullptr); assert(obj->tempOwner.isValidPlayer()); - return getAnimation(heroFlags[obj->tempOwner.getNum()], true); + return getAnimation(AnimationPath::builtin(heroFlags[obj->tempOwner.getNum()]), true); } if(obj->ID == Obj::BOAT) @@ -557,10 +557,10 @@ uint8_t MapRendererObjects::checksum(IMapRendererContext & context, const int3 & } MapRendererOverlay::MapRendererOverlay() - : imageGrid(IImage::createFromFile("debug/grid", EImageBlitMode::ALPHA)) - , imageBlocked(IImage::createFromFile("debug/blocked", EImageBlitMode::ALPHA)) - , imageVisitable(IImage::createFromFile("debug/visitable", EImageBlitMode::ALPHA)) - , imageSpellRange(IImage::createFromFile("debug/spellRange", EImageBlitMode::ALPHA)) + : imageGrid(IImage::createFromFile(ImagePath::builtin("debug/grid"), EImageBlitMode::ALPHA)) + , imageBlocked(IImage::createFromFile(ImagePath::builtin("debug/blocked"), EImageBlitMode::ALPHA)) + , imageVisitable(IImage::createFromFile(ImagePath::builtin("debug/visitable"), EImageBlitMode::ALPHA)) + , imageSpellRange(IImage::createFromFile(ImagePath::builtin("debug/spellRange"), EImageBlitMode::ALPHA)) { } @@ -616,7 +616,7 @@ uint8_t MapRendererOverlay::checksum(IMapRendererContext & context, const int3 & } MapRendererPath::MapRendererPath() - : pathNodes(new CAnimation("ADAG")) + : pathNodes(new CAnimation(AnimationPath::builtin("ADAG"))) { pathNodes->preload(); } diff --git a/client/mapView/MapRenderer.h b/client/mapView/MapRenderer.h index 2ee036f88..6fc1ccce7 100644 --- a/client/mapView/MapRenderer.h +++ b/client/mapView/MapRenderer.h @@ -9,6 +9,8 @@ */ #pragma once +#include "../../lib/filesystem/ResourcePath.h" + VCMI_LIB_NAMESPACE_BEGIN class int3; @@ -30,7 +32,7 @@ class MapTileStorage public: explicit MapTileStorage(size_t capacity); - void load(size_t index, const std::string & filename, EImageBlitMode blitMode); + void load(size_t index, const AnimationPath & filename, EImageBlitMode blitMode); std::shared_ptr find(size_t fileIndex, size_t rotationIndex, size_t imageIndex); }; @@ -69,13 +71,13 @@ public: class MapRendererObjects { - std::unordered_map> animations; + std::map> animations; std::shared_ptr getBaseAnimation(const CGObjectInstance * obj); std::shared_ptr getFlagAnimation(const CGObjectInstance * obj); std::shared_ptr getOverlayAnimation(const CGObjectInstance * obj); - std::shared_ptr getAnimation(const std::string & filename, bool generateMovementGroups); + std::shared_ptr getAnimation(const AnimationPath & filename, bool generateMovementGroups); std::shared_ptr getImage(IMapRendererContext & context, const CGObjectInstance * obj, const std::shared_ptr & animation) const; diff --git a/client/mapView/MapViewCache.cpp b/client/mapView/MapViewCache.cpp index 18ed65208..528ba5b39 100644 --- a/client/mapView/MapViewCache.cpp +++ b/client/mapView/MapViewCache.cpp @@ -28,7 +28,7 @@ MapViewCache::MapViewCache(const std::shared_ptr & model) : model(model) , cachedLevel(0) , mapRenderer(new MapRenderer()) - , iconsStorage(new CAnimation("VwSymbol")) + , iconsStorage(new CAnimation(AnimationPath::builtin("VwSymbol"))) , intermediate(new Canvas(Point(32, 32))) , terrain(new Canvas(model->getCacheDimensionsPixels())) , terrainTransition(new Canvas(model->getPixelsVisibleDimensions())) diff --git a/client/render/CAnimation.cpp b/client/render/CAnimation.cpp index 40cf03681..6d2a20f7a 100644 --- a/client/render/CAnimation.cpp +++ b/client/render/CAnimation.cpp @@ -22,7 +22,7 @@ std::shared_ptr CAnimation::getFromExtraDef(std::string filename) size_t pos = filename.find(':'); if (pos == -1) return nullptr; - CAnimation anim(filename.substr(0, pos)); + CAnimation anim(AnimationPath::builtinTODO(filename.substr(0, pos))); pos++; size_t frame = atoi(filename.c_str()+pos); size_t group = 0; @@ -144,7 +144,7 @@ void CAnimation::exportBitmaps(const boost::filesystem::path& path) const return; } - boost::filesystem::path actualPath = path / "SPRITES" / name; + boost::filesystem::path actualPath = path / "SPRITES" / name.getName(); boost::filesystem::create_directories(actualPath); size_t counter = 0; @@ -179,16 +179,15 @@ void CAnimation::init() source[defEntry.first].resize(defEntry.second); } - ResourceID resID(std::string("SPRITES/") + name, EResType::TEXT); + if (vstd::contains(graphics->imageLists, name.getName())) + initFromJson(graphics->imageLists[name.getName()]); - if (vstd::contains(graphics->imageLists, resID.getName())) - initFromJson(graphics->imageLists[resID.getName()]); - - auto configList = CResourceHandler::get()->getResourcesWithName(resID); + auto jsonResource = name.toType(); + auto configList = CResourceHandler::get()->getResourcesWithName(jsonResource); for(auto & loader : configList) { - auto stream = loader->load(resID); + auto stream = loader->load(jsonResource); std::unique_ptr textData(new ui8[stream->getSize()]); stream->read(textData.get(), stream->getSize()); @@ -200,28 +199,21 @@ void CAnimation::init() void CAnimation::printError(size_t frame, size_t group, std::string type) const { - logGlobal->error("%s error: Request for frame not present in CAnimation! File name: %s, Group: %d, Frame: %d", type, name, group, frame); + logGlobal->error("%s error: Request for frame not present in CAnimation! File name: %s, Group: %d, Frame: %d", type, name.getOriginalName(), group, frame); } -CAnimation::CAnimation(std::string Name): - name(Name), +CAnimation::CAnimation(const AnimationPath & Name): + name(boost::starts_with(Name.getName(), "SPRITES") ? Name : Name.addPrefix("SPRITES/")), preloaded(false), defFile() { - size_t dotPos = name.find_last_of('.'); - if ( dotPos!=-1 ) - name.erase(dotPos); - std::transform(name.begin(), name.end(), name.begin(), toupper); - - ResourceID resource(std::string("SPRITES/") + name, EResType::ANIMATION); - - if(CResourceHandler::get()->existsResource(resource)) + if(CResourceHandler::get()->existsResource(name)) defFile = std::make_shared(name); init(); if(source.empty()) - logAnim->error("Animation %s failed to load", Name); + logAnim->error("Animation %s failed to load", Name.getOriginalName()); } CAnimation::CAnimation(): @@ -238,13 +230,13 @@ void CAnimation::duplicateImage(const size_t sourceGroup, const size_t sourceFra { if(!source.count(sourceGroup)) { - logAnim->error("Group %d missing in %s", sourceGroup, name); + logAnim->error("Group %d missing in %s", sourceGroup, name.getName()); return; } if(source[sourceGroup].size() <= sourceFrame) { - logAnim->error("Frame [%d %d] missing in %s", sourceGroup, sourceFrame, name); + logAnim->error("Frame [%d %d] missing in %s", sourceGroup, sourceFrame, name.getName()); return; } @@ -253,7 +245,7 @@ void CAnimation::duplicateImage(const size_t sourceGroup, const size_t sourceFra if(clone.getType() == JsonNode::JsonType::DATA_NULL) { - std::string temp = name+":"+std::to_string(sourceGroup)+":"+std::to_string(sourceFrame); + std::string temp = name.getName()+":"+std::to_string(sourceGroup)+":"+std::to_string(sourceFrame); clone["file"].String() = temp; } diff --git a/client/render/CAnimation.h b/client/render/CAnimation.h index 7e26d13cd..b39bfe401 100644 --- a/client/render/CAnimation.h +++ b/client/render/CAnimation.h @@ -10,6 +10,7 @@ #pragma once #include "../../lib/GameConstants.h" +#include "../../lib/filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN class JsonNode; @@ -29,7 +30,7 @@ private: std::map > > images; //animation file name - std::string name; + AnimationPath name; bool preloaded; @@ -53,7 +54,7 @@ private: std::shared_ptr getFromExtraDef(std::string filename); public: - CAnimation(std::string Name); + CAnimation(const AnimationPath & Name); CAnimation(); ~CAnimation(); diff --git a/client/render/CBitmapHandler.cpp b/client/render/CBitmapHandler.cpp index c18612e8f..9fc4e93ac 100644 --- a/client/render/CBitmapHandler.cpp +++ b/client/render/CBitmapHandler.cpp @@ -110,14 +110,14 @@ SDL_Surface * BitmapHandler::loadBitmapFromDir(std::string path, std::string fna logGlobal->warn("Call to loadBitmap with void fname!"); return nullptr; } - if (!CResourceHandler::get()->existsResource(ResourceID(path + fname, EResType::IMAGE))) + if (!CResourceHandler::get()->existsResource(ResourcePath(path + fname, EResType::IMAGE))) { return nullptr; } SDL_Surface * ret=nullptr; - auto readFile = CResourceHandler::get()->load(ResourceID(path + fname, EResType::IMAGE))->readAll(); + auto readFile = CResourceHandler::get()->load(ResourcePath(path + fname, EResType::IMAGE))->readAll(); if (isPCX(readFile.first.get())) {//H3-style PCX diff --git a/client/render/CDefFile.cpp b/client/render/CDefFile.cpp index a19acc5be..bf4a79b06 100644 --- a/client/render/CDefFile.cpp +++ b/client/render/CDefFile.cpp @@ -24,7 +24,7 @@ class CFileCache static const int cacheSize = 50; //Max number of cached files struct FileData { - ResourceID name; + AnimationPath name; size_t size; std::unique_ptr data; @@ -34,7 +34,7 @@ class CFileCache std::copy(data.get(), data.get() + size, ret.get()); return ret; } - FileData(ResourceID name_, size_t size_, std::unique_ptr data_): + FileData(AnimationPath name_, size_t size_, std::unique_ptr data_): name{std::move(name_)}, size{size_}, data{std::move(data_)} @@ -43,7 +43,7 @@ class CFileCache std::deque cache; public: - std::unique_ptr getCachedFile(ResourceID rid) + std::unique_ptr getCachedFile(AnimationPath rid) { for(auto & file : cache) { @@ -97,7 +97,7 @@ static bool colorsSimilar (const SDL_Color & lhs, const SDL_Color & rhs) return std::abs(diffR) < threshold && std::abs(diffG) < threshold && std::abs(diffB) < threshold && std::abs(diffA) < threshold; } -CDefFile::CDefFile(std::string Name): +CDefFile::CDefFile(const AnimationPath & Name): data(nullptr), palette(nullptr) { @@ -124,7 +124,7 @@ CDefFile::CDefFile(std::string Name): {0, 0, 0, 64 } // shadow border below selection ( used in battle def's ) }; - data = animationCache.getCachedFile(ResourceID(std::string("SPRITES/") + Name, EResType::ANIMATION)); + data = animationCache.getCachedFile(Name); palette = std::unique_ptr(new SDL_Color[256]); int it = 0; diff --git a/client/render/CDefFile.h b/client/render/CDefFile.h index 3aec57f4c..ad6de846e 100644 --- a/client/render/CDefFile.h +++ b/client/render/CDefFile.h @@ -10,6 +10,7 @@ #pragma once #include "../../lib/vcmi_endian.h" +#include "../../lib/filesystem/ResourcePath.h" class IImageLoader; struct SDL_Color; @@ -39,7 +40,7 @@ private: std::unique_ptr palette; public: - CDefFile(std::string Name); + CDefFile(const AnimationPath & Name); ~CDefFile(); //load frame as SDL_Surface diff --git a/client/render/Graphics.cpp b/client/render/Graphics.cpp index ea9b55122..c23751484 100644 --- a/client/render/Graphics.cpp +++ b/client/render/Graphics.cpp @@ -44,7 +44,7 @@ Graphics * graphics = nullptr; void Graphics::loadPaletteAndColors() { - auto textFile = CResourceHandler::get()->load(ResourceID("DATA/PLAYERS.PAL"))->readAll(); + auto textFile = CResourceHandler::get()->load(ResourcePath("DATA/PLAYERS.PAL"))->readAll(); std::string pals((char*)textFile.first.get(), textFile.second); int startPoint = 24; //beginning byte; used to read @@ -62,7 +62,7 @@ void Graphics::loadPaletteAndColors() } } - auto stream = CResourceHandler::get()->load(ResourceID("config/NEUTRAL.PAL")); + auto stream = CResourceHandler::get()->load(ResourcePath("config/NEUTRAL.PAL")); CBinaryReader reader(stream.get()); for(int i=0; i<32; ++i) @@ -102,10 +102,10 @@ void Graphics::initializeBattleGraphics() allConfigs.insert(allConfigs.begin(), ModScope::scopeBuiltin()); for(auto & mod : allConfigs) { - if(!CResourceHandler::get(mod)->existsResource(ResourceID("config/battles_graphics.json"))) + if(!CResourceHandler::get(mod)->existsResource(ResourcePath("config/battles_graphics.json"))) continue; - const JsonNode config(mod, ResourceID("config/battles_graphics.json")); + const JsonNode config(mod, ResourcePath("config/battles_graphics.json")); //initialization of AC->def name mapping if(!config["ac_mapping"].isNull()) @@ -204,7 +204,7 @@ void Graphics::blueToPlayersAdv(SDL_Surface * sur, PlayerColor player) void Graphics::loadFonts() { - const JsonNode config(ResourceID("config/fonts.json")); + const JsonNode config(ResourcePath("config/fonts.json")); const JsonVector & bmpConf = config["bitmap"].Vector(); const JsonNode & ttfConf = config["trueType"]; @@ -228,7 +228,7 @@ void Graphics::loadFonts() void Graphics::loadErmuToPicture() { //loading ERMU to picture - const JsonNode config(ResourceID("config/ERMU_to_picture.json")); + const JsonNode config(ResourcePath("config/ERMU_to_picture.json")); int etp_idx = 0; for(const JsonNode &etp : config["ERMU_to_picture"].Vector()) { int idx = 0; @@ -279,16 +279,14 @@ void Graphics::initializeImageLists() addImageListEntries(CGI->skills()); } -std::shared_ptr Graphics::getAnimation(const std::string & path) +std::shared_ptr Graphics::getAnimation(const AnimationPath & path) { - ResourceID animationPath(path, EResType::ANIMATION); + if (cachedAnimations.count(path) != 0) + return cachedAnimations.at(path); - if (cachedAnimations.count(animationPath.getName()) != 0) - return cachedAnimations.at(animationPath.getName()); - - auto newAnimation = std::make_shared(animationPath.getName()); + auto newAnimation = std::make_shared(path); newAnimation->preload(); - cachedAnimations[animationPath.getName()] = newAnimation; + cachedAnimations[path] = newAnimation; return newAnimation; } diff --git a/client/render/Graphics.h b/client/render/Graphics.h index 281226d9b..dfa0e1123 100644 --- a/client/render/Graphics.h +++ b/client/render/Graphics.h @@ -11,6 +11,7 @@ #include "../lib/GameConstants.h" #include "../lib/Color.h" +#include "../lib/filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -42,10 +43,10 @@ class Graphics void loadFonts(); void initializeImageLists(); - std::map> cachedAnimations; + std::map> cachedAnimations; public: - std::shared_ptr getAnimation(const std::string & path); + std::shared_ptr getAnimation(const AnimationPath & path); //Fonts static const int FONTS_NUMBER = 9; diff --git a/client/render/IImage.h b/client/render/IImage.h index bc9b37727..e5961082a 100644 --- a/client/render/IImage.h +++ b/client/render/IImage.h @@ -9,6 +9,8 @@ */ #pragma once +#include "../../lib/filesystem/ResourcePath.h" + VCMI_LIB_NAMESPACE_BEGIN class PlayerColor; @@ -84,8 +86,8 @@ public: virtual ~IImage(); /// loads image from specified file. Returns 0-sized images on failure - static std::shared_ptr createFromFile( const std::string & path ); - static std::shared_ptr createFromFile( const std::string & path, EImageBlitMode mode ); + static std::shared_ptr createFromFile( const ImagePath & path ); + static std::shared_ptr createFromFile( const ImagePath & path, EImageBlitMode mode ); /// temporary compatibility method. Creates IImage from existing SDL_Surface /// Surface will be shared, called must still free it with SDL_FreeSurface diff --git a/client/renderSDL/CBitmapFont.cpp b/client/renderSDL/CBitmapFont.cpp index 3271254cd..36a29d174 100644 --- a/client/renderSDL/CBitmapFont.cpp +++ b/client/renderSDL/CBitmapFont.cpp @@ -24,7 +24,7 @@ #include -void CBitmapFont::loadModFont(const std::string & modName, const ResourceID & resource) +void CBitmapFont::loadModFont(const std::string & modName, const ResourcePath & resource) { if (!CResourceHandler::get(modName)->existsResource(resource)) { @@ -72,7 +72,7 @@ void CBitmapFont::loadModFont(const std::string & modName, const ResourceID & re CBitmapFont::CBitmapFont(const std::string & filename): maxHeight(0) { - ResourceID resource("data/" + filename, EResType::BMP_FONT); + ResourcePath resource("data/" + filename, EResType::BMP_FONT); loadModFont("core", resource); diff --git a/client/renderSDL/CBitmapFont.h b/client/renderSDL/CBitmapFont.h index b1d5bc5b1..b5fa2b4f4 100644 --- a/client/renderSDL/CBitmapFont.h +++ b/client/renderSDL/CBitmapFont.h @@ -12,7 +12,7 @@ #include "../render/IFont.h" VCMI_LIB_NAMESPACE_BEGIN -class ResourceID; +class ResourcePath; VCMI_LIB_NAMESPACE_END class CBitmapFont : public IFont @@ -31,7 +31,7 @@ class CBitmapFont : public IFont std::unordered_map chars; uint32_t maxHeight; - void loadModFont(const std::string & modName, const ResourceID & resource); + void loadModFont(const std::string & modName, const ResourcePath & resource); void renderCharacter(SDL_Surface * surface, const BitmapChar & character, const ColorRGBA & color, int &posX, int &posY) const; void renderText(SDL_Surface * surface, const std::string & data, const ColorRGBA & color, const Point & pos) const override; diff --git a/client/renderSDL/CBitmapHanFont.cpp b/client/renderSDL/CBitmapHanFont.cpp index d97b2ca2b..cb527d054 100644 --- a/client/renderSDL/CBitmapHanFont.cpp +++ b/client/renderSDL/CBitmapHanFont.cpp @@ -98,7 +98,7 @@ void CBitmapHanFont::renderText(SDL_Surface * surface, const std::string & data, CBitmapHanFont::CBitmapHanFont(const JsonNode &config): fallback(new CBitmapFont(config["fallback"].String())), - data(CResourceHandler::get()->load(ResourceID("data/" + config["name"].String(), EResType::OTHER))->readAll()), + data(CResourceHandler::get()->load(ResourcePath("data/" + config["name"].String(), EResType::OTHER))->readAll()), size((size_t)config["size"].Float()) { // basic tests to make sure that fonts are OK diff --git a/client/renderSDL/CTrueTypeFont.cpp b/client/renderSDL/CTrueTypeFont.cpp index 47246d708..76bf4ed96 100644 --- a/client/renderSDL/CTrueTypeFont.cpp +++ b/client/renderSDL/CTrueTypeFont.cpp @@ -24,7 +24,7 @@ std::pair, ui64> CTrueTypeFont::loadData(const JsonNode & config) { std::string filename = "Data/" + config["file"].String(); - return CResourceHandler::get()->load(ResourceID(filename, EResType::TTF_FONT))->readAll(); + return CResourceHandler::get()->load(ResourcePath(filename, EResType::TTF_FONT))->readAll(); } TTF_Font * CTrueTypeFont::loadFont(const JsonNode &config) diff --git a/client/renderSDL/SDLImage.cpp b/client/renderSDL/SDLImage.cpp index 1778bbad6..0a53abb23 100644 --- a/client/renderSDL/SDLImage.cpp +++ b/client/renderSDL/SDLImage.cpp @@ -24,14 +24,14 @@ class SDLImageLoader; -std::shared_ptr IImage::createFromFile( const std::string & path ) +std::shared_ptr IImage::createFromFile( const ImagePath & path ) { return createFromFile(path, EImageBlitMode::ALPHA); } -std::shared_ptr IImage::createFromFile( const std::string & path, EImageBlitMode mode ) +std::shared_ptr IImage::createFromFile( const ImagePath & path, EImageBlitMode mode ) { - return std::shared_ptr(new SDLImage(path, mode)); + return std::shared_ptr(new SDLImage(path.getName(), mode)); } std::shared_ptr IImage::createFromSurface( SDL_Surface * source ) diff --git a/client/widgets/Buttons.cpp b/client/widgets/Buttons.cpp index ae3411330..585029634 100644 --- a/client/widgets/Buttons.cpp +++ b/client/widgets/Buttons.cpp @@ -89,7 +89,7 @@ void CButton::addOverlay(std::shared_ptr newOverlay) update(); } -void CButton::addImage(std::string filename) +void CButton::addImage(const AnimationPath & filename) { imageNames.push_back(filename); } @@ -232,7 +232,7 @@ void CButton::hover (bool on) } } -CButton::CButton(Point position, const std::string &defName, const std::pair &help, CFunctionList Callback, EShortcut key, bool playerColoredButton): +CButton::CButton(Point position, const AnimationPath &defName, const std::pair &help, CFunctionList Callback, EShortcut key, bool playerColoredButton): CKeyShortcut(key), callback(Callback) { @@ -357,7 +357,7 @@ void CToggleBase::addCallback(std::function function) callback += function; } -CToggleButton::CToggleButton(Point position, const std::string &defName, const std::pair &help, +CToggleButton::CToggleButton(Point position, const AnimationPath &defName, const std::pair &help, CFunctionList callback, EShortcut key, bool playerColoredButton): CButton(position, defName, help, 0, key, playerColoredButton), CToggleBase(callback) diff --git a/client/widgets/Buttons.h b/client/widgets/Buttons.h index ec387451f..8944d2928 100644 --- a/client/widgets/Buttons.h +++ b/client/widgets/Buttons.h @@ -12,6 +12,7 @@ #include "../gui/CIntObject.h" #include "../render/EFont.h" #include "../../lib/FunctionList.h" +#include "../../lib/filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN class Rect; @@ -36,7 +37,7 @@ public: HIGHLIGHTED=3 }; protected: - std::vector imageNames;//store list of images that can be used by this button + std::vector imageNames;//store list of images that can be used by this button size_t currentImage; ButtonState state;//current state of button from enum @@ -72,7 +73,7 @@ public: void addOverlay(std::shared_ptr newOverlay); void addTextOverlay(const std::string & Text, EFonts font, ColorRGBA color); - void addImage(std::string filename); + void addImage(const AnimationPath & filename); void addHoverText(ButtonState state, std::string text); void setImageOrder(int state1, int state2, int state3, int state4); @@ -84,7 +85,7 @@ public: bool isHighlighted(); /// Constructor - CButton(Point position, const std::string & defName, const std::pair & help, + CButton(Point position, const AnimationPath & defName, const std::pair & help, CFunctionList Callback = 0, EShortcut key = {}, bool playerColoredButton = false ); /// Appearance modifiers @@ -145,7 +146,7 @@ class CToggleButton : public CButton, public CToggleBase void setEnabled(bool enabled) override; public: - CToggleButton(Point position, const std::string &defName, const std::pair &help, + CToggleButton(Point position, const AnimationPath &defName, const std::pair &help, CFunctionList Callback = 0, EShortcut key = {}, bool playerColoredButton = false ); void clickPressed(const Point & cursorPosition) override; diff --git a/client/widgets/CArtifactHolder.cpp b/client/widgets/CArtifactHolder.cpp index 5e443d959..d27a2975f 100644 --- a/client/widgets/CArtifactHolder.cpp +++ b/client/widgets/CArtifactHolder.cpp @@ -89,7 +89,7 @@ void CCommanderArtPlace::createImage() if(ourArt) imageIndex = ourArt->artType->getIconIndex(); - image = std::make_shared("artifact", imageIndex); + image = std::make_shared(AnimationPath::builtin("artifact"), imageIndex); if(!ourArt) image->disable(); } @@ -247,11 +247,11 @@ void CHeroArtPlace::createImage() else if(ourArt) imageIndex = ourArt->artType->getIconIndex(); - image = std::make_shared("artifact", imageIndex); + image = std::make_shared(AnimationPath::builtin("artifact"), imageIndex); if(!ourArt) image->disable(); - selection = std::make_shared("artifact", ArtifactID::ART_SELECTION); + selection = std::make_shared(AnimationPath::builtin("artifact"), ArtifactID::ART_SELECTION); selection->disable(); } diff --git a/client/widgets/CArtifactsOfHeroBackpack.cpp b/client/widgets/CArtifactsOfHeroBackpack.cpp index f8c509d05..d0cb80bd3 100644 --- a/client/widgets/CArtifactsOfHeroBackpack.cpp +++ b/client/widgets/CArtifactsOfHeroBackpack.cpp @@ -42,7 +42,7 @@ CArtifactsOfHeroBackpack::CArtifactsOfHeroBackpack(const Point & position) for(int i = 0; i < visibleCapacityMax; i++) { - auto artifactSlotBackground = std::make_shared("heroWindow/artifactSlotEmpty", + auto artifactSlotBackground = std::make_shared( ImagePath::builtin("heroWindow/artifactSlotEmpty"), Point(slotSizeWithMargin * (i % HERO_BACKPACK_WINDOW_SLOT_COLUMNS), slotSizeWithMargin * (i / HERO_BACKPACK_WINDOW_SLOT_COLUMNS))); backpackSlotsBackgrounds.emplace_back(artifactSlotBackground); diff --git a/client/widgets/CArtifactsOfHeroBase.cpp b/client/widgets/CArtifactsOfHeroBase.cpp index f24d836ae..3ee38c6d7 100644 --- a/client/widgets/CArtifactsOfHeroBase.cpp +++ b/client/widgets/CArtifactsOfHeroBase.cpp @@ -86,8 +86,8 @@ void CArtifactsOfHeroBase::init( artPlace->leftClickCallback = lClickCallback; artPlace->rightClickCallback = rClickCallback; } - leftBackpackRoll = std::make_shared(Point(379, 364), "hsbtns3.def", CButton::tooltip(), [scrollHandler]() { scrollHandler(-1); }, EShortcut::MOVE_LEFT); - rightBackpackRoll = std::make_shared(Point(632, 364), "hsbtns5.def", CButton::tooltip(), [scrollHandler]() { scrollHandler(+1); }, EShortcut::MOVE_RIGHT); + leftBackpackRoll = std::make_shared(Point(379, 364), AnimationPath::builtin("hsbtns3.def"), CButton::tooltip(), [scrollHandler]() { scrollHandler(-1); }, EShortcut::MOVE_LEFT); + rightBackpackRoll = std::make_shared(Point(632, 364), AnimationPath::builtin("hsbtns5.def"), CButton::tooltip(), [scrollHandler]() { scrollHandler(+1); }, EShortcut::MOVE_RIGHT); leftBackpackRoll->block(true); rightBackpackRoll->block(true); } diff --git a/client/widgets/CComponent.cpp b/client/widgets/CComponent.cpp index c4d4dee7d..0ad59f1dd 100644 --- a/client/widgets/CComponent.cpp +++ b/client/widgets/CComponent.cpp @@ -102,7 +102,7 @@ void CComponent::init(Etype Type, int Subtype, int Val, ESize imageSize, EFonts } } -const std::vector CComponent::getFileName() +std::vector CComponent::getFileName() { static const std::string primSkillsArr [] = {"PSKIL32", "PSKIL32", "PSKIL42", "PSKILL"}; static const std::string secSkillsArr [] = {"SECSK32", "SECSK32", "SECSKILL", "SECSK82"}; @@ -115,9 +115,9 @@ const std::vector CComponent::getFileName() static const std::string heroArr [] = {"PortraitsSmall", "PortraitsSmall", "PortraitsSmall", "PortraitsLarge"}; static const std::string flagArr [] = {"CREST58", "CREST58", "CREST58", "CREST58"}; - auto gen = [](const std::string * arr) + auto gen = [](const std::string * arr) -> std::vector { - return std::vector(arr, arr + 4); + return { AnimationPath::builtin(arr[0]), AnimationPath::builtin(arr[1]), AnimationPath::builtin(arr[2]), AnimationPath::builtin(arr[3]) }; }; switch(compType) @@ -131,12 +131,12 @@ const std::vector CComponent::getFileName() case spell: return gen(spellsArr); case morale: return gen(moraleArr); case luck: return gen(luckArr); - case building: return std::vector(4, (*CGI->townh)[subtype]->town->clientInfo.buildingsIcons); + case building: return std::vector(4, (*CGI->townh)[subtype]->town->clientInfo.buildingsIcons); case hero: return gen(heroArr); case flag: return gen(flagArr); } assert(0); - return std::vector(); + return {}; } size_t CComponent::getIndex() @@ -251,7 +251,7 @@ std::string CComponent::getSubtitleInternal() return ""; } -void CComponent::setSurface(std::string defName, int imgPos) +void CComponent::setSurface(const AnimationPath & defName, int imgPos) { OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE); image = std::make_shared(defName, imgPos); diff --git a/client/widgets/CComponent.h b/client/widgets/CComponent.h index 7799d7b8f..6db60c438 100644 --- a/client/widgets/CComponent.h +++ b/client/widgets/CComponent.h @@ -11,7 +11,7 @@ #include "../gui/CIntObject.h" #include "../render/EFont.h" - +#include "../../lib/filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -45,8 +45,8 @@ private: std::vector> lines; size_t getIndex(); - const std::vector getFileName(); - void setSurface(std::string defName, int imgPos); + std::vector getFileName(); + void setSurface(const AnimationPath & defName, int imgPos); std::string getSubtitleInternal(); void init(Etype Type, int Subtype, int Val, ESize imageSize, EFonts font = FONT_SMALL); diff --git a/client/widgets/CGarrisonInt.cpp b/client/widgets/CGarrisonInt.cpp index 18bb0388f..593ace244 100644 --- a/client/widgets/CGarrisonInt.cpp +++ b/client/widgets/CGarrisonInt.cpp @@ -421,7 +421,7 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt * Owner, int x, int y, SlotID IID, EGa pos.x += x; pos.y += y; - std::string imgName = owner->smallIcons ? "cprsmall" : "TWCRPORT"; + AnimationPath imgName = AnimationPath::builtin(owner->smallIcons ? "cprsmall" : "TWCRPORT"); creatureImage = std::make_shared(graphics->getAnimation(imgName), 0); creatureImage->disable(); diff --git a/client/widgets/CWindowWithArtifacts.cpp b/client/widgets/CWindowWithArtifacts.cpp index 3a9c3156a..16b6dd950 100644 --- a/client/widgets/CWindowWithArtifacts.cpp +++ b/client/widgets/CWindowWithArtifacts.cpp @@ -271,7 +271,7 @@ void CWindowWithArtifacts::artifactMoved(const ArtifactLocation & srcLoc, const { if(artSetPtr->isActive()) { - CCS->curh->dragAndDropCursor("artifact", pickedArtInst->artType->getIconIndex()); + CCS->curh->dragAndDropCursor(AnimationPath::builtin("artifact"), pickedArtInst->artType->getIconIndex()); if(srcLoc.isHolder(hero) || !std::is_same_v>) artSetPtr->markPossibleSlots(pickedArtInst, hero->tempOwner == LOCPLINT->playerID); } diff --git a/client/widgets/ComboBox.cpp b/client/widgets/ComboBox.cpp index 29ac42d0c..7b6ee4920 100644 --- a/client/widgets/ComboBox.cpp +++ b/client/widgets/ComboBox.cpp @@ -155,7 +155,7 @@ void ComboBox::DropDown::setItem(const void * item) GH.windows().popWindows(1); } -ComboBox::ComboBox(Point position, const std::string & defName, const std::pair & help, const JsonNode & dropDownDescriptor, EShortcut key, bool playerColoredButton): +ComboBox::ComboBox(Point position, const AnimationPath & defName, const std::pair & help, const JsonNode & dropDownDescriptor, EShortcut key, bool playerColoredButton): CButton(position, defName, help, 0, key, playerColoredButton) { addCallback([&, dropDownDescriptor]() diff --git a/client/widgets/ComboBox.h b/client/widgets/ComboBox.h index ced39987d..dafd496bf 100644 --- a/client/widgets/ComboBox.h +++ b/client/widgets/ComboBox.h @@ -54,7 +54,7 @@ class ComboBox : public CButton void setItem(const void *); public: - ComboBox(Point position, const std::string & defName, const std::pair & help, const JsonNode & dropDownDescriptor, EShortcut key = {}, bool playerColoredButton = false); + ComboBox(Point position, const AnimationPath & defName, const std::pair & help, const JsonNode & dropDownDescriptor, EShortcut key = {}, bool playerColoredButton = false); //define this callback to fill input vector with data for the combo box std::function &)> onConstructItems; diff --git a/client/widgets/CreatureCostBox.cpp b/client/widgets/CreatureCostBox.cpp index 94c31e29d..546c71864 100644 --- a/client/widgets/CreatureCostBox.cpp +++ b/client/widgets/CreatureCostBox.cpp @@ -38,7 +38,7 @@ void CreatureCostBox::createItems(TResources res) TResources::nziterator iter(res); while(iter.valid()) { - ImagePtr image = std::make_shared("RESOURCE", iter->resType); + ImagePtr image = std::make_shared(AnimationPath::builtin("RESOURCE"), iter->resType); LabelPtr text = std::make_shared(15, 43, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, "0"); resources.insert(std::make_pair(iter->resType, std::make_pair(text, image))); diff --git a/client/widgets/Images.cpp b/client/widgets/Images.cpp index 9767717b7..e86923bc9 100644 --- a/client/widgets/Images.cpp +++ b/client/widgets/Images.cpp @@ -42,15 +42,15 @@ CPicture::CPicture(std::shared_ptr image, const Point & position) pos.h = bg->height(); } -CPicture::CPicture( const std::string &bmpname, int x, int y ) +CPicture::CPicture( const ImagePath &bmpname, int x, int y ) : CPicture(bmpname, Point(x,y)) {} -CPicture::CPicture( const std::string &bmpname ) +CPicture::CPicture( const ImagePath & bmpname ) : CPicture(bmpname, Point(0,0)) {} -CPicture::CPicture( const std::string &bmpname, const Point & position ) +CPicture::CPicture( const ImagePath & bmpname, const Point & position ) : bg(IImage::createFromFile(bmpname)) , visible(true) , needRefresh(false) @@ -113,7 +113,7 @@ void CPicture::colorize(PlayerColor player) bg->playerColored(player); } -CFilledTexture::CFilledTexture(std::string imageName, Rect position): +CFilledTexture::CFilledTexture(const ImagePath & imageName, Rect position): CIntObject(0, position.topLeft()), texture(IImage::createFromFile(imageName)) { @@ -142,7 +142,7 @@ void CFilledTexture::showAll(Canvas & to) } } -FilledTexturePlayerColored::FilledTexturePlayerColored(std::string imageName, Rect position) +FilledTexturePlayerColored::FilledTexturePlayerColored(const ImagePath & imageName, Rect position) : CFilledTexture(imageName, position) { } @@ -171,7 +171,7 @@ void FilledTexturePlayerColored::playerColored(PlayerColor player) texture->adjustPalette(filters[player.getNum()], 0); } -CAnimImage::CAnimImage(const std::string & name, size_t Frame, size_t Group, int x, int y, ui8 Flags): +CAnimImage::CAnimImage(const AnimationPath & name, size_t Frame, size_t Group, int x, int y, ui8 Flags): frame(Frame), group(Group), flags(Flags) @@ -307,7 +307,7 @@ bool CAnimImage::isPlayerColored() const return player.has_value(); } -CShowableAnim::CShowableAnim(int x, int y, std::string name, ui8 Flags, ui32 frameTime, size_t Group, uint8_t alpha): +CShowableAnim::CShowableAnim(int x, int y, const AnimationPath & name, ui8 Flags, ui32 frameTime, size_t Group, uint8_t alpha): anim(std::make_shared(name)), group(Group), frame(0), @@ -448,7 +448,7 @@ void CShowableAnim::setDuration(int durationMs) frameTimeTotal = durationMs/(last - first); } -CCreatureAnim::CCreatureAnim(int x, int y, std::string name, ui8 flags, ECreatureAnimType type): +CCreatureAnim::CCreatureAnim(int x, int y, const AnimationPath & name, ui8 flags, ECreatureAnimType type): CShowableAnim(x, y, name, flags, 100, size_t(type)) // H3 uses 100 ms per frame, irregardless of battle speed settings { xOffset = 0; diff --git a/client/widgets/Images.h b/client/widgets/Images.h index bfc06f4e3..7716cf8e9 100644 --- a/client/widgets/Images.h +++ b/client/widgets/Images.h @@ -11,6 +11,7 @@ #include "../gui/CIntObject.h" #include "../battle/BattleConstants.h" +#include "../../lib/filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN class Rect; @@ -49,9 +50,9 @@ public: CPicture(std::shared_ptr image, const Rect &SrcRext, int x = 0, int y = 0); //wrap subrect of given surface /// Loads image from specified file name - CPicture(const std::string & bmpname); - CPicture(const std::string & bmpname, const Point & position); - CPicture(const std::string & bmpname, int x, int y); + CPicture(const ImagePath & bmpname); + CPicture(const ImagePath & bmpname, const Point & position); + CPicture(const ImagePath & bmpname, int x, int y); /// set alpha value for whole surface. Note: may be messed up if surface is shared /// 0=transparent, 255=opaque @@ -71,7 +72,7 @@ protected: Rect imageArea; public: - CFilledTexture(std::string imageName, Rect position); + CFilledTexture(const ImagePath & imageName, Rect position); CFilledTexture(std::shared_ptr image, Rect position, Rect imageArea); void showAll(Canvas & to) override; @@ -80,7 +81,7 @@ public: class FilledTexturePlayerColored : public CFilledTexture { public: - FilledTexturePlayerColored(std::string imageName, Rect position); + FilledTexturePlayerColored(const ImagePath & imageName, Rect position); void playerColored(PlayerColor player); }; @@ -105,7 +106,7 @@ private: public: bool visible; - CAnimImage(const std::string & name, size_t Frame, size_t Group=0, int x=0, int y=0, ui8 Flags=0); + CAnimImage(const AnimationPath & name, size_t Frame, size_t Group=0, int x=0, int y=0, ui8 Flags=0); CAnimImage(std::shared_ptr Anim, size_t Frame, size_t Group=0, int x=0, int y=0, ui8 Flags=0); CAnimImage(std::shared_ptr Anim, size_t Frame, Rect targetPos, size_t Group=0, ui8 Flags=0); ~CAnimImage(); @@ -166,7 +167,7 @@ public: //Set per-surface alpha, 0 = transparent, 255 = opaque void setAlpha(ui32 alphaValue); - CShowableAnim(int x, int y, std::string name, ui8 flags, ui32 frameTime, size_t Group=0, uint8_t alpha = UINT8_MAX); + CShowableAnim(int x, int y, const AnimationPath & name, ui8 flags, ui32 frameTime, size_t Group=0, uint8_t alpha = UINT8_MAX); ~CShowableAnim(); //set animation to group or part of group @@ -213,6 +214,6 @@ public: //clear queue and set animation to this sequence void clearAndSet(ECreatureAnimType type); - CCreatureAnim(int x, int y, std::string name, ui8 flags = 0, ECreatureAnimType = ECreatureAnimType::HOLDING); + CCreatureAnim(int x, int y, const AnimationPath & name, ui8 flags = 0, ECreatureAnimType = ECreatureAnimType::HOLDING); }; diff --git a/client/widgets/MiscWidgets.cpp b/client/widgets/MiscWidgets.cpp index e1fdbda5b..7e5ab637f 100644 --- a/client/widgets/MiscWidgets.cpp +++ b/client/widgets/MiscWidgets.cpp @@ -126,7 +126,7 @@ CHeroArea::CHeroArea(int x, int y, const CGHeroInstance * _hero) pos.h = 64; if(hero) - portrait = std::make_shared("PortraitsLarge", hero->portrait); + portrait = std::make_shared(AnimationPath::builtin("PortraitsLarge"), hero->portrait); } void CHeroArea::clickPressed(const Point & cursorPosition) @@ -201,7 +201,7 @@ CMinorResDataBar::CMinorResDataBar() pos.x = 7; pos.y = 575; - background = std::make_shared("KRESBAR.bmp"); + background = std::make_shared(ImagePath::builtin("KRESBAR.bmp")); background->colorize(LOCPLINT->playerID); pos.w = background->pos.w; @@ -233,7 +233,7 @@ void CArmyTooltip::init(const InfoAboutArmy &army) continue; } - icons.push_back(std::make_shared("CPRSMALL", slot.second.type->getIconIndex(), 0, slotsPos[slot.first.getNum()].x, slotsPos[slot.first.getNum()].y)); + icons.push_back(std::make_shared(AnimationPath::builtin("CPRSMALL"), slot.second.type->getIconIndex(), 0, slotsPos[slot.first.getNum()].x, slotsPos[slot.first.getNum()].y)); std::string subtitle; if(army.army.isDetailed) @@ -276,7 +276,7 @@ CArmyTooltip::CArmyTooltip(Point pos, const CArmedInstance * army): void CHeroTooltip::init(const InfoAboutHero & hero) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - portrait = std::make_shared("PortraitsLarge", hero.portrait, 0, 3, 2); + portrait = std::make_shared(AnimationPath::builtin("PortraitsLarge"), hero.portrait, 0, 3, 2); if(hero.details) { @@ -286,8 +286,8 @@ void CHeroTooltip::init(const InfoAboutHero & hero) labels.push_back(std::make_shared(158, 98, FONT_TINY, ETextAlignment::CENTER, Colors::WHITE, std::to_string(hero.details->mana))); - morale = std::make_shared("IMRL22", hero.details->morale + 3, 0, 5, 74); - luck = std::make_shared("ILCK22", hero.details->luck + 3, 0, 5, 91); + morale = std::make_shared(AnimationPath::builtin("IMRL22"), hero.details->morale + 3, 0, 5, 74); + luck = std::make_shared(AnimationPath::builtin("ILCK22"), hero.details->luck + 3, 0, 5, 91); } } @@ -314,7 +314,7 @@ CInteractableHeroTooltip::CInteractableHeroTooltip(Point pos, const CGHeroInstan void CInteractableHeroTooltip::init(const InfoAboutHero & hero) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - portrait = std::make_shared("PortraitsLarge", hero.portrait, 0, 3, 2); + portrait = std::make_shared(AnimationPath::builtin("PortraitsLarge"), hero.portrait, 0, 3, 2); title = std::make_shared(66, 2, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, hero.name); if(hero.details) @@ -325,8 +325,8 @@ void CInteractableHeroTooltip::init(const InfoAboutHero & hero) labels.push_back(std::make_shared(158, 98, FONT_TINY, ETextAlignment::CENTER, Colors::WHITE, std::to_string(hero.details->mana))); - morale = std::make_shared("IMRL22", hero.details->morale + 3, 0, 5, 74); - luck = std::make_shared("ILCK22", hero.details->luck + 3, 0, 5, 91); + morale = std::make_shared(AnimationPath::builtin("IMRL22"), hero.details->morale + 3, 0, 5, 74); + luck = std::make_shared(AnimationPath::builtin("ILCK22"), hero.details->luck + 3, 0, 5, 91); } } @@ -337,17 +337,17 @@ void CTownTooltip::init(const InfoAboutTown & town) //order of icons in def: fort, citadel, castle, no fort size_t fortIndex = town.fortLevel ? town.fortLevel - 1 : 3; - fort = std::make_shared("ITMCLS", fortIndex, 0, 105, 31); + fort = std::make_shared(AnimationPath::builtin("ITMCLS"), fortIndex, 0, 105, 31); assert(town.tType); size_t iconIndex = town.tType->clientInfo.icons[town.fortLevel > 0][town.built >= CGI->settings()->getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)]; - build = std::make_shared("itpt", iconIndex, 0, 3, 2); + build = std::make_shared(AnimationPath::builtin("itpt"), iconIndex, 0, 3, 2); if(town.details) { - hall = std::make_shared("ITMTLS", town.details->hallLevel, 0, 67, 31); + hall = std::make_shared(AnimationPath::builtin("ITMTLS"), town.details->hallLevel, 0, 67, 31); if(town.details->goldIncome) { @@ -355,18 +355,18 @@ void CTownTooltip::init(const InfoAboutTown & town) std::to_string(town.details->goldIncome)); } if(town.details->garrisonedHero) //garrisoned hero icon - garrisonedHero = std::make_shared("TOWNQKGH", 149, 76); + garrisonedHero = std::make_shared(ImagePath::builtin("TOWNQKGH"), 149, 76); if(town.details->customRes)//silo is built { if(town.tType->primaryRes == EGameResID::WOOD_AND_ORE )// wood & ore { - res1 = std::make_shared("SMALRES", GameResID(EGameResID::WOOD), 0, 7, 75); - res2 = std::make_shared("SMALRES", GameResID(EGameResID::ORE), 0, 7, 88); + res1 = std::make_shared(AnimationPath::builtin("SMALRES"), GameResID(EGameResID::WOOD), 0, 7, 75); + res2 = std::make_shared(AnimationPath::builtin("SMALRES"), GameResID(EGameResID::ORE), 0, 7, 88); } else { - res1 = std::make_shared("SMALRES", town.tType->primaryRes, 0, 7, 81); + res1 = std::make_shared(AnimationPath::builtin("SMALRES"), town.tType->primaryRes, 0, 7, 81); } } } @@ -399,18 +399,18 @@ void CInteractableTownTooltip::init(const InfoAboutTown & town) //order of icons in def: fort, citadel, castle, no fort size_t fortIndex = town.fortLevel ? town.fortLevel - 1 : 3; - fort = std::make_shared("ITMCLS", fortIndex, 0, 105, 31); + fort = std::make_shared(AnimationPath::builtin("ITMCLS"), fortIndex, 0, 105, 31); assert(town.tType); size_t iconIndex = town.tType->clientInfo.icons[town.fortLevel > 0][town.built >= CGI->settings()->getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)]; - build = std::make_shared("itpt", iconIndex, 0, 3, 2); + build = std::make_shared(AnimationPath::builtin("itpt"), iconIndex, 0, 3, 2); title = std::make_shared(66, 2, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, town.name); if(town.details) { - hall = std::make_shared("ITMTLS", town.details->hallLevel, 0, 67, 31); + hall = std::make_shared(AnimationPath::builtin("ITMTLS"), town.details->hallLevel, 0, 67, 31); if(town.details->goldIncome) { @@ -418,18 +418,18 @@ void CInteractableTownTooltip::init(const InfoAboutTown & town) std::to_string(town.details->goldIncome)); } if(town.details->garrisonedHero) //garrisoned hero icon - garrisonedHero = std::make_shared("TOWNQKGH", 149, 76); + garrisonedHero = std::make_shared(ImagePath::builtin("TOWNQKGH"), 149, 76); if(town.details->customRes)//silo is built { if(town.tType->primaryRes == EGameResID::WOOD_AND_ORE )// wood & ore { - res1 = std::make_shared("SMALRES", GameResID(EGameResID::WOOD), 0, 7, 75); - res2 = std::make_shared("SMALRES", GameResID(EGameResID::ORE), 0, 7, 88); + res1 = std::make_shared(AnimationPath::builtin("SMALRES"), GameResID(EGameResID::WOOD), 0, 7, 75); + res2 = std::make_shared(AnimationPath::builtin("SMALRES"), GameResID(EGameResID::ORE), 0, 7, 88); } else { - res1 = std::make_shared("SMALRES", town.tType->primaryRes, 0, 7, 81); + res1 = std::make_shared(AnimationPath::builtin("SMALRES"), town.tType->primaryRes, 0, 7, 81); } } } @@ -492,7 +492,7 @@ void MoraleLuckBox::set(const AFactionMember * node) else imageName = morale ? "IMRL42" : "ILCK42"; - image = std::make_shared(imageName, bonusValue + 3); + image = std::make_shared(AnimationPath::builtin(imageName), bonusValue + 3); image->moveBy(Point(pos.w/2 - image->pos.w/2, pos.h/2 - image->pos.h/2));//center icon } diff --git a/client/widgets/RadialMenu.cpp b/client/widgets/RadialMenu.cpp index 2d6aa478b..b2e9d44fe 100644 --- a/client/widgets/RadialMenu.cpp +++ b/client/widgets/RadialMenu.cpp @@ -27,10 +27,10 @@ RadialMenuItem::RadialMenuItem(const std::string & imageName, const std::string { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - inactiveImage = std::make_shared("radialMenu/itemInactive", Point(0, 0)); - selectedImage = std::make_shared("radialMenu/itemEmpty", Point(0, 0)); + inactiveImage = std::make_shared(ImagePath::builtin("radialMenu/itemInactive"), Point(0, 0)); + selectedImage = std::make_shared(ImagePath::builtin("radialMenu/itemEmpty"), Point(0, 0)); - iconImage = std::make_shared("radialMenu/" + imageName, Point(0, 0)); + iconImage = std::make_shared(ImagePath::builtin("radialMenu/" + imageName), Point(0, 0)); pos = selectedImage->pos; selectedImage->setEnabled(false); @@ -56,7 +56,7 @@ RadialMenu::RadialMenu(const Point & positionToCenter, const std::vectorpos); diff --git a/client/widgets/Slider.cpp b/client/widgets/Slider.cpp index b65e2f31e..955c01649 100644 --- a/client/widgets/Slider.cpp +++ b/client/widgets/Slider.cpp @@ -178,7 +178,7 @@ CSlider::CSlider(Point position, int totalw, std::function Moved, int if(style == BROWN) { - std::string name = getOrientation() == Orientation::HORIZONTAL ? "IGPCRDIV.DEF" : "OVBUTN2.DEF"; + AnimationPath name = AnimationPath::builtin(getOrientation() == Orientation::HORIZONTAL ? "IGPCRDIV.DEF" : "OVBUTN2.DEF"); //NOTE: this images do not have "blocked" frames. They should be implemented somehow (e.g. palette transform or something...) left = std::make_shared(Point(), name, CButton::tooltip()); @@ -191,9 +191,9 @@ CSlider::CSlider(Point position, int totalw, std::function Moved, int } else { - left = std::make_shared(Point(), getOrientation() == Orientation::HORIZONTAL ? "SCNRBLF.DEF" : "SCNRBUP.DEF", CButton::tooltip()); - right = std::make_shared(Point(), getOrientation() == Orientation::HORIZONTAL ? "SCNRBRT.DEF" : "SCNRBDN.DEF", CButton::tooltip()); - slider = std::make_shared(Point(), "SCNRBSL.DEF", CButton::tooltip()); + left = std::make_shared(Point(), AnimationPath::builtin(getOrientation() == Orientation::HORIZONTAL ? "SCNRBLF.DEF" : "SCNRBUP.DEF"), CButton::tooltip()); + right = std::make_shared(Point(), AnimationPath::builtin(getOrientation() == Orientation::HORIZONTAL ? "SCNRBRT.DEF" : "SCNRBDN.DEF"), CButton::tooltip()); + slider = std::make_shared(Point(), AnimationPath::builtin("SCNRBSL.DEF"), CButton::tooltip()); } slider->actOnDown = true; slider->soundDisabled = true; diff --git a/client/widgets/TextControls.cpp b/client/widgets/TextControls.cpp index be496a84e..6d8dc59b9 100644 --- a/client/widgets/TextControls.cpp +++ b/client/widgets/TextControls.cpp @@ -419,7 +419,7 @@ CGStatusBar::CGStatusBar(std::shared_ptr background_, EFonts Font, E autoRedraw = false; } -CGStatusBar::CGStatusBar(int x, int y, std::string name, int maxw) +CGStatusBar::CGStatusBar(int x, int y, const ImagePath & name, int maxw) : CLabel(x, y, FONT_SMALL, ETextAlignment::CENTER) , enteringText(false) { @@ -503,7 +503,7 @@ CTextInput::CTextInput(const Rect & Pos, EFonts font, const CFunctionList & CB) +CTextInput::CTextInput(const Rect & Pos, const Point & bgOffset, const ImagePath & bgName, const CFunctionList & CB) :cb(CB), CFocusable(std::make_shared(this)) { pos += Pos.topLeft(); diff --git a/client/widgets/TextControls.h b/client/widgets/TextControls.h index ec7fe6bfa..c1623835b 100644 --- a/client/widgets/TextControls.h +++ b/client/widgets/TextControls.h @@ -14,6 +14,7 @@ #include "../render/Colors.h" #include "../render/EFont.h" #include "../../lib/FunctionList.h" +#include "../../lib/filesystem/ResourcePath.h" class IImage; class CSlider; @@ -124,7 +125,7 @@ class CGStatusBar : public CLabel, public std::enable_shared_from_this background_, EFonts Font = FONT_SMALL, ETextAlignment Align = ETextAlignment::CENTER, const ColorRGBA & Color = Colors::WHITE); - CGStatusBar(int x, int y, std::string name, int maxw = -1); + CGStatusBar(int x, int y, const ImagePath & name, int maxw = -1); //make CLabel API private using CLabel::getText; @@ -223,7 +224,7 @@ public: void setHelpText(const std::string &); CTextInput(const Rect & Pos, EFonts font, const CFunctionList & CB); - CTextInput(const Rect & Pos, const Point & bgOffset, const std::string & bgName, const CFunctionList & CB); + CTextInput(const Rect & Pos, const Point & bgOffset, const ImagePath & bgName, const CFunctionList & CB); CTextInput(const Rect & Pos, std::shared_ptr srf); void clickPressed(const Point & cursorPosition) override; diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index 9364ad703..74bd835a1 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -263,7 +263,7 @@ bool CBuildingRect::receiveEvent(const Point & position, int eventType) const } CDwellingInfoBox::CDwellingInfoBox(int centerX, int centerY, const CGTownInstance * Town, int level) - : CWindowObject(RCLICK_POPUP, "CRTOINFO", Point(centerX, centerY)) + : CWindowObject(RCLICK_POPUP, ImagePath::builtin("CRTOINFO"), Point(centerX, centerY)) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); background->colorize(Town->tempOwner); @@ -282,7 +282,7 @@ CDwellingInfoBox::CDwellingInfoBox(int centerX, int centerY, const CGTownInstanc auto res = static_cast(i); if(creature->getRecruitCost(res)) { - resPicture.push_back(std::make_shared("RESOURCE", i, 0, 0, 0)); + resPicture.push_back(std::make_shared(AnimationPath::builtin("RESOURCE"), i, 0, 0, 0)); resAmount.push_back(std::make_shared(0,0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, std::to_string(creature->getRecruitCost(res)))); } } @@ -310,13 +310,13 @@ CHeroGSlot::CHeroGSlot(int x, int y, int updown, const CGHeroInstance * h, HeroS pos.h = 64; upg = updown; - portrait = std::make_shared("PortraitsLarge", 0, 0, 0, 0); + portrait = std::make_shared(AnimationPath::builtin("PortraitsLarge"), 0, 0, 0, 0); portrait->visible = false; - flag = std::make_shared("CREST58", 0, 0, 0, 0); + flag = std::make_shared(AnimationPath::builtin("CREST58"), 0, 0, 0, 0); flag->visible = false; - selection = std::make_shared("TWCRPORT", 1, 0); + selection = std::make_shared(AnimationPath::builtin("TWCRPORT"), 1, 0); selection->visible = false; set(h); @@ -981,9 +981,8 @@ void CCastleBuildings::enterTownHall() void CCastleBuildings::openMagesGuild() { - std::string mageGuildBackground; - mageGuildBackground = LOCPLINT->castleInt->town->town->clientInfo.guildBackground; - GH.windows().createAndPushWindow(LOCPLINT->castleInt,mageGuildBackground); + auto mageGuildBackground = LOCPLINT->castleInt->town->town->clientInfo.guildBackground; + GH.windows().createAndPushWindow(LOCPLINT->castleInt, mageGuildBackground); } void CCastleBuildings::openTownHall() @@ -1009,7 +1008,7 @@ CCreaInfo::CCreaInfo(Point position, const CGTownInstance * Town, int Level, boo ui32 creatureID = town->creatures[level].second.back(); creature = CGI->creh->objects[creatureID]; - picture = std::make_shared("CPRSMALL", creature->getIconIndex(), 0, 8, 0); + picture = std::make_shared(AnimationPath::builtin("CPRSMALL"), creature->getIconIndex(), 0, 8, 0); std::string value; if(showAvailable) @@ -1109,14 +1108,14 @@ CTownInfo::CTownInfo(int posX, int posY, const CGTownInstance * Town, bool townH if(townHall) { buildID = 10 + town->hallLevel(); - picture = std::make_shared("ITMTL.DEF", town->hallLevel()); + picture = std::make_shared(AnimationPath::builtin("ITMTL.DEF"), town->hallLevel()); } else { buildID = 6 + town->fortLevel(); if(buildID == 6) return;//FIXME: suspicious statement, fix or comment - picture = std::make_shared("ITMCL.DEF", town->fortLevel()-1); + picture = std::make_shared(AnimationPath::builtin("ITMCL.DEF"), town->fortLevel()-1); } building = town->town->buildings.at(BuildingID(buildID)); pos = picture->pos; @@ -1154,7 +1153,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst addUsedEvents(KEYBOARD); builds = std::make_shared(town); - panel = std::make_shared("TOWNSCRN", 0, builds->pos.h); + panel = std::make_shared(ImagePath::builtin("TOWNSCRN"), 0, builds->pos.h); panel->colorize(LOCPLINT->playerID); pos.w = panel->pos.w; pos.h = builds->pos.h + panel->pos.h; @@ -1167,12 +1166,12 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst heroes = std::make_shared(town, Point(241, 387), Point(241, 483), garr, true); title = std::make_shared(85, 387, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE, town->getNameTranslated()); income = std::make_shared(195, 443, FONT_SMALL, ETextAlignment::CENTER); - icon = std::make_shared("ITPT", 0, 0, 15, 387); + icon = std::make_shared(AnimationPath::builtin("ITPT"), 0, 0, 15, 387); - exit = std::make_shared(Point(744, 544), "TSBTNS", CButton::tooltip(CGI->generaltexth->tcommands[8]), [&](){close();}, EShortcut::GLOBAL_RETURN); + exit = std::make_shared(Point(744, 544), AnimationPath::builtin("TSBTNS"), CButton::tooltip(CGI->generaltexth->tcommands[8]), [&](){close();}, EShortcut::GLOBAL_RETURN); exit->setImageOrder(4, 5, 6, 7); - auto split = std::make_shared(Point(744, 382), "TSBTNS", CButton::tooltip(CGI->generaltexth->tcommands[3]), [&]() + auto split = std::make_shared(Point(744, 382), AnimationPath::builtin("TSBTNS"), CButton::tooltip(CGI->generaltexth->tcommands[3]), [&]() { garr->splitClick(); heroes->splitClicked(); @@ -1182,11 +1181,11 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst Rect barRect(9, 182, 732, 18); auto statusbarBackground = std::make_shared(panel->getSurface(), barRect, 9, 555); statusbar = CGStatusBar::create(statusbarBackground); - resdatabar = std::make_shared("ARESBAR", 3, 575, 37, 3, 84, 78); + resdatabar = std::make_shared(ImagePath::builtin("ARESBAR"), 3, 575, 37, 3, 84, 78); townlist = std::make_shared(3, Rect(Point(743, 414), Point(48, 128)), Point(1,16), Point(0, 32), LOCPLINT->localState->getOwnedTowns().size() ); - townlist->setScrollUpButton( std::make_shared( Point(744, 414), "IAM014", CButton::tooltipLocalized("core.help.306"))); - townlist->setScrollDownButton( std::make_shared( Point(744, 526), "IAM015", CButton::tooltipLocalized("core.help.307"))); + townlist->setScrollUpButton( std::make_shared( Point(744, 414), AnimationPath::builtin("IAM014"), CButton::tooltipLocalized("core.help.306"))); + townlist->setScrollDownButton( std::make_shared( Point(744, 526), AnimationPath::builtin("IAM015"), CButton::tooltipLocalized("core.help.307"))); if(from) townlist->select(from); @@ -1277,7 +1276,7 @@ void CCastleInterface::recreateIcons() hall = std::make_shared(80, 413, town, true); fort = std::make_shared(122, 413, town, false); - fastArmyPurchase = std::make_shared(Point(122, 413), "itmcl.def", CButton::tooltip(), [&](){ builds->enterToTheQuickRecruitmentWindow(); }); + fastArmyPurchase = std::make_shared(Point(122, 413), AnimationPath::builtin("itmcl.def"), CButton::tooltip(), [&](){ builds->enterToTheQuickRecruitmentWindow(); }); fastArmyPurchase->setImageOrder(town->fortLevel() - 1, town->fortLevel() - 1, town->fortLevel() - 1, town->fortLevel() - 1); fastArmyPurchase->setAnimateLonelyFrame(true); @@ -1351,9 +1350,9 @@ CHallInterface::CBuildingBox::CBuildingBox(int x, int y, const CGTownInstance * }; icon = std::make_shared(town->town->clientInfo.buildingsIcons, building->bid, 0, 2, 2); - header = std::make_shared("TPTHBAR", panelIndex[static_cast(state)], 0, 1, 73); + header = std::make_shared(AnimationPath::builtin("TPTHBAR"), panelIndex[static_cast(state)], 0, 1, 73); if(iconIndex[static_cast(state)] >=0) - mark = std::make_shared("TPTHCHK", iconIndex[static_cast(state)], 0, 136, 56); + mark = std::make_shared(AnimationPath::builtin("TPTHCHK"), iconIndex[static_cast(state)], 0, 136, 56); name = std::make_shared(75, 81, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, building->getNameTranslated()); //todo: add support for all possible states @@ -1405,7 +1404,7 @@ CHallInterface::CHallInterface(const CGTownInstance * Town): statusbar = CGStatusBar::create(statusbarBackground); title = std::make_shared(399, 12, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, town->town->buildings.at(BuildingID(town->hallLevel()+BuildingID::VILLAGE_HALL))->getNameTranslated()); - exit = std::make_shared(Point(748, 556), "TPMAGE1.DEF", CButton::tooltip(CGI->generaltexth->hcommands[8]), [&](){close();}, EShortcut::GLOBAL_RETURN); + exit = std::make_shared(Point(748, 556), AnimationPath::builtin("TPMAGE1.DEF"), CButton::tooltip(CGI->generaltexth->hcommands[8]), [&](){close();}, EShortcut::GLOBAL_RETURN); auto & boxList = town->town->clientInfo.hallSlots; boxes.resize(boxList.size()); @@ -1440,7 +1439,7 @@ CHallInterface::CHallInterface(const CGTownInstance * Town): } CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Building, EBuildingState state, bool rightClick): - CStatusbarWindow(PLAYER_COLORED | (rightClick ? RCLICK_POPUP : 0), "TPUBUILD"), + CStatusbarWindow(PLAYER_COLORED | (rightClick ? RCLICK_POPUP : 0), ImagePath::builtin("TPUBUILD")), town(Town), building(Building) { @@ -1480,11 +1479,11 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin tooltipNo.appendTextID("core.genrltxt.596"); tooltipNo.replaceTextID(building->getNameTextID()); - buy = std::make_shared(Point(45, 446), "IBUY30", CButton::tooltip(tooltipYes.toString()), [&](){ buyFunc(); }, EShortcut::GLOBAL_ACCEPT); + buy = std::make_shared(Point(45, 446), AnimationPath::builtin("IBUY30"), CButton::tooltip(tooltipYes.toString()), [&](){ buyFunc(); }, EShortcut::GLOBAL_ACCEPT); buy->setBorderColor(Colors::METALLIC_GOLD); buy->block(state!=EBuildingState::ALLOWED || LOCPLINT->playerID != town->tempOwner); - cancel = std::make_shared(Point(290, 445), "ICANCEL", CButton::tooltip(tooltipNo.toString()), [&](){ close();}, EShortcut::GLOBAL_CANCEL); + cancel = std::make_shared(Point(290, 445), AnimationPath::builtin("ICANCEL"), CButton::tooltip(tooltipNo.toString()), [&](){ close();}, EShortcut::GLOBAL_CANCEL); cancel->setBorderColor(Colors::METALLIC_GOLD); } } @@ -1589,7 +1588,7 @@ CFortScreen::CFortScreen(const CGTownInstance * town): title = std::make_shared(400, 12, FONT_BIG, ETextAlignment::CENTER, Colors::WHITE, fortBuilding->getNameTranslated()); std::string text = boost::str(boost::format(CGI->generaltexth->fcommands[6]) % fortBuilding->getNameTranslated()); - exit = std::make_shared(Point(748, 556), "TPMAGE1", CButton::tooltip(text), [&](){ close(); }, EShortcut::GLOBAL_RETURN); + exit = std::make_shared(Point(748, 556), AnimationPath::builtin("TPMAGE1"), CButton::tooltip(text), [&](){ close(); }, EShortcut::GLOBAL_RETURN); std::vector positions = { @@ -1637,16 +1636,16 @@ CFortScreen::CFortScreen(const CGTownInstance * town): statusbar = CGStatusBar::create(statusbarBackground); } -std::string CFortScreen::getBgName(const CGTownInstance * town) +ImagePath CFortScreen::getBgName(const CGTownInstance * town) { ui32 fortSize = static_cast(town->creatures.size()); if(fortSize > GameConstants::CREATURES_PER_TOWN && town->creatures.back().second.empty()) fortSize--; if(fortSize == GameConstants::CREATURES_PER_TOWN) - return "TPCASTL7"; + return ImagePath::builtin("TPCASTL7"); else - return "TPCASTL8"; + return ImagePath::builtin("TPCASTL8"); } void CFortScreen::creaturesChangedEventHandler() @@ -1673,7 +1672,7 @@ CFortScreen::RecruitArea::RecruitArea(int posX, int posY, const CGTownInstance * addUsedEvents(SHOW_POPUP); - icons = std::make_shared("TPCAINFO", 261, 3); + icons = std::make_shared(ImagePath::builtin("TPCAINFO"), 261, 3); if(getMyBuilding() != nullptr) { @@ -1766,8 +1765,8 @@ void CFortScreen::RecruitArea::showPopupWindow(const Point & cursorPosition) GH.windows().createAndPushWindow(getMyCreature(), true); } -CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner,std::string imagem) - : CStatusbarWindow(BORDERED, imagem) +CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner, const ImagePath & imagename) + : CStatusbarWindow(BORDERED, imagename) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -1781,7 +1780,7 @@ CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner,std::string imagem) auto statusbarBackground = std::make_shared(background->getSurface(), barRect, 7, 556); statusbar = CGStatusBar::create(statusbarBackground); - exit = std::make_shared(Point(748, 556), "TPMAGE1.DEF", CButton::tooltip(CGI->generaltexth->allTexts[593]), [&](){ close(); }, EShortcut::GLOBAL_RETURN); + exit = std::make_shared(Point(748, 556), AnimationPath::builtin("TPMAGE1.DEF"), CButton::tooltip(CGI->generaltexth->allTexts[593]), [&](){ close(); }, EShortcut::GLOBAL_RETURN); static const std::vector > positions = { @@ -1800,7 +1799,7 @@ CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner,std::string imagem) if(itown->mageGuildLevel() && owner->town->spells[i].size()>j) spells.push_back(std::make_shared(positions[i][j], CGI->spellh->objects[owner->town->spells[i][j]])); else - emptyScrolls.push_back(std::make_shared("TPMAGES.DEF", 1, 0, positions[i][j].x, positions[i][j].y)); + emptyScrolls.push_back(std::make_shared(AnimationPath::builtin("TPMAGES.DEF"), 1, 0, positions[i][j].x, positions[i][j].y)); } } } @@ -1812,7 +1811,7 @@ CMageGuildScreen::Scroll::Scroll(Point position, const CSpell *Spell) addUsedEvents(LCLICK | SHOW_POPUP | HOVER); pos += position; - image = std::make_shared("SPELLSCR", spell->id); + image = std::make_shared(AnimationPath::builtin("SPELLSCR"), spell->id); pos = image->pos; } @@ -1836,7 +1835,7 @@ void CMageGuildScreen::Scroll::hover(bool on) } CBlacksmithDialog::CBlacksmithDialog(bool possible, CreatureID creMachineID, ArtifactID aid, ObjectInstanceID hid): - CStatusbarWindow(PLAYER_COLORED, "TPSMITH") + CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("TPSMITH")) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -1845,7 +1844,7 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, CreatureID creMachineID, Art auto statusbarBackground = std::make_shared(background->getSurface(), barRect, 8, pos.h - 26); statusbar = CGStatusBar::create(statusbarBackground); - animBG = std::make_shared("TPSMITBK", 64, 50); + animBG = std::make_shared(ImagePath::builtin("TPSMITBK"), 64, 50); animBG->needRefresh = true; const CCreature * creature = CGI->creh->objects[creMachineID]; @@ -1869,13 +1868,13 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, CreatureID creMachineID, Art title = std::make_shared(165, 28, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, titleString.toString()); costText = std::make_shared(165, 218, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->jktexts[43]); costValue = std::make_shared(165, 292, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, costString); - buy = std::make_shared(Point(42, 312), "IBUY30.DEF", CButton::tooltip(buyText.toString()), [&](){ close(); }, EShortcut::GLOBAL_ACCEPT); - cancel = std::make_shared(Point(224, 312), "ICANCEL.DEF", CButton::tooltip(cancelText.toString()), [&](){ close(); }, EShortcut::GLOBAL_CANCEL); + buy = std::make_shared(Point(42, 312), AnimationPath::builtin("IBUY30.DEF"), CButton::tooltip(buyText.toString()), [&](){ close(); }, EShortcut::GLOBAL_ACCEPT); + cancel = std::make_shared(Point(224, 312), AnimationPath::builtin("ICANCEL.DEF"), CButton::tooltip(cancelText.toString()), [&](){ close(); }, EShortcut::GLOBAL_CANCEL); if(possible) buy->addCallback([=](){ LOCPLINT->cb->buyArtifact(LOCPLINT->cb->getHero(hid),aid); }); else buy->block(true); - costIcon = std::make_shared("RESOURCE", GameResID(EGameResID::GOLD), 0, 148, 244); + costIcon = std::make_shared(AnimationPath::builtin("RESOURCE"), GameResID(EGameResID::GOLD), 0, 148, 244); } diff --git a/client/windows/CCastleInterface.h b/client/windows/CCastleInterface.h index 3e05f3079..353d96542 100644 --- a/client/windows/CCastleInterface.h +++ b/client/windows/CCastleInterface.h @@ -355,7 +355,7 @@ class CFortScreen : public CStatusbarWindow std::shared_ptr resdatabar; std::shared_ptr exit; - std::string getBgName(const CGTownInstance * town); + ImagePath getBgName(const CGTownInstance * town); public: CFortScreen(const CGTownInstance * town); @@ -385,7 +385,7 @@ class CMageGuildScreen : public CStatusbarWindow std::shared_ptr resdatabar; public: - CMageGuildScreen(CCastleInterface * owner,std::string image); + CMageGuildScreen(CCastleInterface * owner, const ImagePath & image); }; /// The blacksmith window where you can buy available in town war machine diff --git a/client/windows/CCreatureWindow.cpp b/client/windows/CCreatureWindow.cpp index 0511bb649..67c0b8f58 100644 --- a/client/windows/CCreatureWindow.cpp +++ b/client/windows/CCreatureWindow.cpp @@ -118,7 +118,7 @@ void CCommanderSkillIcon::clickPressed(const Point & cursorPosition) callback(); } -static std::string skillToFile(int skill, int level, bool selected) +static ImagePath skillToFile(int skill, int level, bool selected) { // FIXME: is this a correct hadling? // level 0 = skill not present, use image with "no" suffix @@ -156,24 +156,24 @@ static std::string skillToFile(int skill, int level, bool selected) if (selected) sufix += "="; //level-up highlight - return file + sufix + ".bmp"; + return ImagePath::builtin(file + sufix + ".bmp"); } -CStackWindow::CWindowSection::CWindowSection(CStackWindow * parent, std::string backgroundPath, int yOffset) +CStackWindow::CWindowSection::CWindowSection(CStackWindow * parent, const ImagePath & backgroundPath, int yOffset) : parent(parent) { pos.y += yOffset; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); if(!backgroundPath.empty()) { - background = std::make_shared("stackWindow/" + backgroundPath); + background = std::make_shared(backgroundPath); pos.w = background->pos.w; pos.h = background->pos.h; } } CStackWindow::ActiveSpellsSection::ActiveSpellsSection(CStackWindow * owner, int yOffset) - : CWindowSection(owner, "spell-effects", yOffset) + : CWindowSection(owner, ImagePath::builtin("stackWindow/spell-effects"), yOffset) { static const Point firstPos(6, 2); // position of 1st spell box static const Point offset(54, 0); // offset of each spell box from previous @@ -205,7 +205,7 @@ CStackWindow::ActiveSpellsSection::ActiveSpellsSection(CStackWindow * owner, int int duration = battleStack->getBonusLocalFirst(Selector::source(BonusSource::SPELL_EFFECT,effect))->turnsRemain; boost::replace_first(spellText, "%d", std::to_string(duration)); - spellIcons.push_back(std::make_shared("SpellInt", effect + 1, 0, firstPos.x + offset.x * printed, firstPos.y + offset.y * printed)); + spellIcons.push_back(std::make_shared(AnimationPath::builtin("SpellInt"), effect + 1, 0, firstPos.x + offset.x * printed, firstPos.y + offset.y * printed)); clickableAreas.push_back(std::make_shared(Rect(firstPos + offset * printed, Point(50, 38)), spellText, spellText)); if(++printed >= 8) // interface limit reached break; @@ -214,7 +214,7 @@ CStackWindow::ActiveSpellsSection::ActiveSpellsSection(CStackWindow * owner, int } CStackWindow::BonusLineSection::BonusLineSection(CStackWindow * owner, size_t lineIndex) - : CWindowSection(owner, "bonus-effects", 0) + : CWindowSection(owner, ImagePath::builtin("stackWindow/bonus-effects"), 0) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -240,7 +240,7 @@ CStackWindow::BonusLineSection::BonusLineSection(CStackWindow * owner, size_t li } CStackWindow::BonusesSection::BonusesSection(CStackWindow * owner, int yOffset, std::optional preferredSize): - CWindowSection(owner, "", yOffset) + CWindowSection(owner, {}, yOffset) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -262,7 +262,7 @@ CStackWindow::BonusesSection::BonusesSection(CStackWindow * owner, int yOffset, } CStackWindow::ButtonsSection::ButtonsSection(CStackWindow * owner, int yOffset) - : CWindowSection(owner, "button-panel", yOffset) + : CWindowSection(owner, ImagePath::builtin("stackWindow/button-panel"), yOffset) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -277,7 +277,7 @@ CStackWindow::ButtonsSection::ButtonsSection(CStackWindow * owner, int yOffset) { LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[12], onDismiss, nullptr); }; - dismiss = std::make_shared(Point(5, 5),"IVIEWCR2.DEF", CGI->generaltexth->zelp[445], onClick, EShortcut::HERO_DISMISS); + dismiss = std::make_shared(Point(5, 5),AnimationPath::builtin("IVIEWCR2.DEF"), CGI->generaltexth->zelp[445], onClick, EShortcut::HERO_DISMISS); } if(parent->info->upgradeInfo && !parent->info->commander) @@ -314,9 +314,9 @@ CStackWindow::ButtonsSection::ButtonsSection(CStackWindow * owner, int yOffset) LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[314], resComps); } }; - auto upgradeBtn = std::make_shared(Point(221 + (int)buttonIndex * 40, 5), "stackWindow/upgradeButton", CGI->generaltexth->zelp[446], onClick); + auto upgradeBtn = std::make_shared(Point(221 + (int)buttonIndex * 40, 5), AnimationPath::builtin("stackWindow/upgradeButton"), CGI->generaltexth->zelp[446], onClick); - upgradeBtn->addOverlay(std::make_shared("CPRSMALL", VLC->creh->objects[upgradeInfo.info.newID[buttonIndex]]->getIconIndex())); + upgradeBtn->addOverlay(std::make_shared(AnimationPath::builtin("CPRSMALL"), VLC->creh->objects[upgradeInfo.info.newID[buttonIndex]]->getIconIndex())); if(buttonsToCreate == 1) // single upgrade avaialbe upgradeBtn->assignedKey = EShortcut::RECRUITMENT_UPGRADE; @@ -341,17 +341,17 @@ CStackWindow::ButtonsSection::ButtonsSection(CStackWindow * owner, int yOffset) }; std::string tooltipText = "vcmi.creatureWindow." + btnIDs[buttonIndex]; - parent->switchButtons[buttonIndex] = std::make_shared(Point(302 + (int)buttonIndex*40, 5), "stackWindow/upgradeButton", CButton::tooltipLocalized(tooltipText), onSwitch); - parent->switchButtons[buttonIndex]->addOverlay(std::make_shared("stackWindow/switchModeIcons", buttonIndex)); + parent->switchButtons[buttonIndex] = std::make_shared(Point(302 + (int)buttonIndex*40, 5), AnimationPath::builtin("stackWindow/upgradeButton"), CButton::tooltipLocalized(tooltipText), onSwitch); + parent->switchButtons[buttonIndex]->addOverlay(std::make_shared(AnimationPath::builtin("stackWindow/switchModeIcons"), buttonIndex)); } parent->switchButtons[parent->activeTab]->disable(); } - exit = std::make_shared(Point(382, 5), "hsbtns.def", CGI->generaltexth->zelp[447], [=](){ parent->close(); }, EShortcut::GLOBAL_RETURN); + exit = std::make_shared(Point(382, 5), AnimationPath::builtin("hsbtns.def"), CGI->generaltexth->zelp[447], [=](){ parent->close(); }, EShortcut::GLOBAL_RETURN); } CStackWindow::CommanderMainSection::CommanderMainSection(CStackWindow * owner, int yOffset) - : CWindowSection(owner, "commander-bg", yOffset) + : CWindowSection(owner, ImagePath::builtin("stackWindow/commander-bg"), yOffset) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -360,7 +360,7 @@ CStackWindow::CommanderMainSection::CommanderMainSection(CStackWindow * owner, i return Point(10 + 80 * (index%3), 20 + 80 * (index/3)); }; - auto getSkillImage = [this](int skillIndex) -> std::string + auto getSkillImage = [this](int skillIndex) { bool selected = ((parent->selectedSkill == skillIndex) && parent->info->levelupInfo ); return skillToFile(skillIndex, parent->info->commander->secondarySkills[skillIndex], selected); @@ -413,7 +413,7 @@ CStackWindow::CommanderMainSection::CommanderMainSection(CStackWindow * owner, i if(parent->info->levelupInfo) { - abilitiesBackground = std::make_shared("stackWindow/commander-abilities.png"); + abilitiesBackground = std::make_shared(ImagePath::builtin("stackWindow/commander-abilities.png")); abilitiesBackground->moveBy(Point(0, pos.h)); size_t abilitiesCount = boost::range::count_if(parent->info->levelupInfo->skills, [](ui32 skillID) @@ -447,8 +447,8 @@ CStackWindow::CommanderMainSection::CommanderMainSection(CStackWindow * owner, i abilities = std::make_shared(onCreate, Point(38, 3+pos.h), Point(63, 0), 6, abilitiesCount); - leftBtn = std::make_shared(Point(10, pos.h + 6), "hsbtns3.def", CButton::tooltip(), [=](){ abilities->moveToPrev(); }, EShortcut::MOVE_LEFT); - rightBtn = std::make_shared(Point(411, pos.h + 6), "hsbtns5.def", CButton::tooltip(), [=](){ abilities->moveToNext(); }, EShortcut::MOVE_RIGHT); + leftBtn = std::make_shared(Point(10, pos.h + 6), AnimationPath::builtin("hsbtns3.def"), CButton::tooltip(), [=](){ abilities->moveToPrev(); }, EShortcut::MOVE_LEFT); + rightBtn = std::make_shared(Point(411, pos.h + 6), AnimationPath::builtin("hsbtns5.def"), CButton::tooltip(), [=](){ abilities->moveToNext(); }, EShortcut::MOVE_RIGHT); if(abilitiesCount <= 6) { @@ -505,7 +505,7 @@ CStackWindow::MainSection::MainSection(CStackWindow * owner, int yOffset, bool s if(parent->info->owner && parent->info->stackNode->hasBonusOfType(BonusType::SIEGE_WEAPON)) dmgMultiply += parent->info->owner->getPrimSkillLevel(PrimarySkill::ATTACK); - icons = std::make_shared("stackWindow/icons", 117, 32); + icons = std::make_shared(ImagePath::builtin("stackWindow/icons"), 117, 32); const CStack * battleStack = parent->info->stack; @@ -556,7 +556,7 @@ CStackWindow::MainSection::MainSection(CStackWindow * owner, int yOffset, bool s if(parent->info->commander) { const CCommanderInstance * commander = parent->info->commander; - expRankIcon = std::make_shared("PSKIL42", 4, 0, pos.x, pos.y); + expRankIcon = std::make_shared(AnimationPath::builtin("PSKIL42"), 4, 0, pos.x, pos.y); auto area = std::make_shared(Rect(pos.x, pos.y, 44, 44), CComponent::experience); expArea = area; @@ -568,7 +568,7 @@ CStackWindow::MainSection::MainSection(CStackWindow * owner, int yOffset, bool s } else { - expRankIcon = std::make_shared("stackWindow/levels", stack->getExpRank(), 0, pos.x, pos.y); + expRankIcon = std::make_shared(AnimationPath::builtin("stackWindow/levels"), stack->getExpRank(), 0, pos.x, pos.y); expArea = std::make_shared(Rect(pos.x, pos.y, 44, 44)); expArea->text = parent->generateStackExpDescription(); } @@ -586,14 +586,14 @@ CStackWindow::MainSection::MainSection(CStackWindow * owner, int yOffset, bool s auto art = parent->info->stackNode->getArt(ArtifactPosition::CREATURE_SLOT); if(art) { - parent->stackArtifactIcon = std::make_shared("ARTIFACT", art->artType->getIconIndex(), 0, pos.x, pos.y); + parent->stackArtifactIcon = std::make_shared(AnimationPath::builtin("ARTIFACT"), art->artType->getIconIndex(), 0, pos.x, pos.y); parent->stackArtifactHelp = std::make_shared(Rect(pos, Point(44, 44)), CComponent::artifact); parent->stackArtifactHelp->type = art->artType->getId(); if(parent->info->owner) { parent->stackArtifactButton = std::make_shared( - Point(pos.x - 2 , pos.y + 46), "stackWindow/cancelButton", + Point(pos.x - 2 , pos.y + 46), AnimationPath::builtin("stackWindow/cancelButton"), CButton::tooltipLocalized("vcmi.creatureWindow.returnArtifact"), [=]() { parent->removeStackArtifact(ArtifactPosition::CREATURE_SLOT); @@ -604,14 +604,14 @@ CStackWindow::MainSection::MainSection(CStackWindow * owner, int yOffset, bool s } -std::string CStackWindow::MainSection::getBackgroundName(bool showExp, bool showArt) +ImagePath CStackWindow::MainSection::getBackgroundName(bool showExp, bool showArt) { if(showExp && showArt) - return "info-panel-2"; + return ImagePath::builtin("stackWindow/info-panel-2"); else if(showExp || showArt) - return "info-panel-1"; + return ImagePath::builtin("stackWindow/info-panel-1"); else - return "info-panel-0"; + return ImagePath::builtin("stackWindow/info-panel-0"); } void CStackWindow::MainSection::addStatLabel(EStat index, int64_t value1, int64_t value2) @@ -882,7 +882,7 @@ void CStackWindow::setSelection(si32 newSkill, std::shared_ptrgeneraltexth->znpc00[152 + (12 * skillIndex) + (info->commander->secondarySkills[skillIndex] * 2)]; }; - auto getSkillImage = [this](int skillIndex) -> std::string + auto getSkillImage = [this](int skillIndex) { bool selected = ((selectedSkill == skillIndex) && info->levelupInfo ); return skillToFile(skillIndex, info->commander->secondarySkills[skillIndex], selected); diff --git a/client/windows/CCreatureWindow.h b/client/windows/CCreatureWindow.h index 0ffe83a88..8dcf88066 100644 --- a/client/windows/CCreatureWindow.h +++ b/client/windows/CCreatureWindow.h @@ -10,6 +10,7 @@ #pragma once #include "../../lib/bonuses/Bonus.h" +#include "../../lib/filesystem/ResourcePath.h" #include "../widgets/MiscWidgets.h" #include "CWindowObject.h" @@ -48,7 +49,7 @@ class CStackWindow : public CWindowObject { std::string name; std::string description; - std::string imagePath; + ImagePath imagePath; }; class CWindowSection : public CIntObject @@ -58,7 +59,7 @@ class CStackWindow : public CWindowObject protected: CStackWindow * parent; public: - CWindowSection(CStackWindow * parent, std::string backgroundPath, int yOffset); + CWindowSection(CStackWindow * parent, const ImagePath & backgroundPath, int yOffset); }; class ActiveSpellsSection : public CWindowSection @@ -138,7 +139,7 @@ class CStackWindow : public CWindowObject void addStatLabel(EStat index, int64_t value1, int64_t value2); void addStatLabel(EStat index, int64_t value); - static std::string getBackgroundName(bool showExp, bool showArt); + static ImagePath getBackgroundName(bool showExp, bool showArt); std::array statNames; std::array statFormats; diff --git a/client/windows/CHeroBackpackWindow.cpp b/client/windows/CHeroBackpackWindow.cpp index 46bcfda40..797e18816 100644 --- a/client/windows/CHeroBackpackWindow.cpp +++ b/client/windows/CHeroBackpackWindow.cpp @@ -24,7 +24,7 @@ CHeroBackpackWindow::CHeroBackpackWindow(const CGHeroInstance * hero) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - stretchedBackground = std::make_shared("DIBOXBCK", Rect(0, 0, 410, 425)); + stretchedBackground = std::make_shared(ImagePath::builtin("DIBOXBCK"), Rect(0, 0, 410, 425)); pos.w = stretchedBackground->pos.w; pos.h = stretchedBackground->pos.h; center(); @@ -36,7 +36,7 @@ CHeroBackpackWindow::CHeroBackpackWindow(const CGHeroInstance * hero) addCloseCallback(std::bind(&CHeroBackpackWindow::close, this)); - quitButton = std::make_shared(Point(173, 385), "IOKAY32.def", CButton::tooltip(""), [this]() { close(); }, EShortcut::GLOBAL_RETURN); + quitButton = std::make_shared(Point(173, 385), AnimationPath::builtin("IOKAY32.def"), CButton::tooltip(""), [this]() { close(); }, EShortcut::GLOBAL_RETURN); } void CHeroBackpackWindow::showAll(Canvas &to) diff --git a/client/windows/CHeroWindow.cpp b/client/windows/CHeroWindow.cpp index 05ca48d85..9c7d6808a 100644 --- a/client/windows/CHeroWindow.cpp +++ b/client/windows/CHeroWindow.cpp @@ -63,48 +63,48 @@ CHeroSwitcher::CHeroSwitcher(CHeroWindow * owner_, Point pos_, const CGHeroInsta OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); pos += pos_; - image = std::make_shared("PortraitsSmall", hero->portrait); + image = std::make_shared(AnimationPath::builtin("PortraitsSmall"), hero->portrait); pos.w = image->pos.w; pos.h = image->pos.h; } CHeroWindow::CHeroWindow(const CGHeroInstance * hero) - : CStatusbarWindow(PLAYER_COLORED, "HeroScr4") + : CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("HeroScr4")) { auto & heroscrn = CGI->generaltexth->heroscrn; OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); curHero = hero; - banner = std::make_shared("CREST58", LOCPLINT->playerID.getNum(), 0, 606, 8); + banner = std::make_shared(AnimationPath::builtin("CREST58"), LOCPLINT->playerID.getNum(), 0, 606, 8); name = std::make_shared(190, 38, EFonts::FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW); title = std::make_shared(190, 65, EFonts::FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE); - statusbar = CGStatusBar::create(7, 559, "ADROLLVR.bmp", 660); + statusbar = CGStatusBar::create(7, 559, ImagePath::builtin("ADROLLVR.bmp"), 660); - quitButton = std::make_shared(Point(609, 516), "hsbtns.def", CButton::tooltip(heroscrn[17]), [=](){ close(); }, EShortcut::GLOBAL_RETURN); + quitButton = std::make_shared(Point(609, 516), AnimationPath::builtin("hsbtns.def"), CButton::tooltip(heroscrn[17]), [=](){ close(); }, EShortcut::GLOBAL_RETURN); if(settings["general"]["enableUiEnhancements"].Bool()) { - questlogButton = std::make_shared(Point(314, 429), "hsbtns4.def", CButton::tooltip(heroscrn[0]), [=](){ LOCPLINT->showQuestLog(); }, EShortcut::ADVENTURE_QUEST_LOG); - backpackButton = std::make_shared(Point(424, 429), "buttons/backpack", CButton::tooltipLocalized("vcmi.heroWindow.Backpack"), [=](){ createBackpackWindow(); }, EShortcut::HERO_BACKPACK); - dismissButton = std::make_shared(Point(534, 429), "hsbtns2.def", CButton::tooltip(heroscrn[28]), [=](){ dismissCurrent(); }, EShortcut::HERO_DISMISS); + questlogButton = std::make_shared(Point(314, 429), AnimationPath::builtin("hsbtns4.def"), CButton::tooltip(heroscrn[0]), [=](){ LOCPLINT->showQuestLog(); }, EShortcut::ADVENTURE_QUEST_LOG); + backpackButton = std::make_shared(Point(424, 429), AnimationPath::builtin("buttons/backpack"), CButton::tooltipLocalized("vcmi.heroWindow.Backpack"), [=](){ createBackpackWindow(); }, EShortcut::HERO_BACKPACK); + dismissButton = std::make_shared(Point(534, 429), AnimationPath::builtin("hsbtns2.def"), CButton::tooltip(heroscrn[28]), [=](){ dismissCurrent(); }, EShortcut::HERO_DISMISS); } else { dismissLabel = std::make_shared(CGI->generaltexth->jktexts[8], Rect(370, 430, 65, 35), 0, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE); questlogLabel = std::make_shared(CGI->generaltexth->jktexts[9], Rect(510, 430, 65, 35), 0, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE); - dismissButton = std::make_shared(Point(454, 429), "hsbtns2.def", CButton::tooltip(heroscrn[28]), [=](){ dismissCurrent(); }, EShortcut::HERO_DISMISS); - questlogButton = std::make_shared(Point(314, 429), "hsbtns4.def", CButton::tooltip(heroscrn[0]), [=](){ LOCPLINT->showQuestLog(); }, EShortcut::ADVENTURE_QUEST_LOG); + dismissButton = std::make_shared(Point(454, 429), AnimationPath::builtin("hsbtns2.def"), CButton::tooltip(heroscrn[28]), [=](){ dismissCurrent(); }, EShortcut::HERO_DISMISS); + questlogButton = std::make_shared(Point(314, 429), AnimationPath::builtin("hsbtns4.def"), CButton::tooltip(heroscrn[0]), [=](){ LOCPLINT->showQuestLog(); }, EShortcut::ADVENTURE_QUEST_LOG); } formations = std::make_shared(0); - formations->addToggle(0, std::make_shared(Point(481, 483), "hsbtns6.def", std::make_pair(heroscrn[23], heroscrn[29]), 0, EShortcut::HERO_TIGHT_FORMATION)); - formations->addToggle(1, std::make_shared(Point(481, 519), "hsbtns7.def", std::make_pair(heroscrn[24], heroscrn[30]), 0, EShortcut::HERO_LOOSE_FORMATION)); + formations->addToggle(0, std::make_shared(Point(481, 483), AnimationPath::builtin("hsbtns6.def"), std::make_pair(heroscrn[23], heroscrn[29]), 0, EShortcut::HERO_TIGHT_FORMATION)); + formations->addToggle(1, std::make_shared(Point(481, 519), AnimationPath::builtin("hsbtns7.def"), std::make_pair(heroscrn[24], heroscrn[30]), 0, EShortcut::HERO_LOOSE_FORMATION)); if(hero->commander) { - commanderButton = std::make_shared(Point(317, 18), "buttons/commander", CButton::tooltipLocalized("vcmi.heroWindow.openCommander"), [&](){ commanderWindow(); }, EShortcut::HERO_COMMANDER); + commanderButton = std::make_shared(Point(317, 18), AnimationPath::builtin("buttons/commander"), CButton::tooltipLocalized("vcmi.heroWindow.openCommander"), [&](){ commanderWindow(); }, EShortcut::HERO_COMMANDER); } //right list of heroes @@ -113,7 +113,7 @@ CHeroWindow::CHeroWindow(const CGHeroInstance * hero) //areas portraitArea = std::make_shared(Rect(18, 18, 58, 64)); - portraitImage = std::make_shared("PortraitsLarge", 0, 0, 19, 19); + portraitImage = std::make_shared(AnimationPath::builtin("PortraitsLarge"), 0, 0, 19, 19); for(int v = 0; v < GameConstants::PRIMARY_SKILLS; ++v) { @@ -127,7 +127,7 @@ CHeroWindow::CHeroWindow(const CGHeroInstance * hero) primSkillValues.push_back(value); } - auto primSkills = std::make_shared("PSKIL42"); + auto primSkills = std::make_shared(AnimationPath::builtin("PSKIL42")); primSkills->preload(); primSkillImages.push_back(std::make_shared(primSkills, 0, 0, 32, 111)); primSkillImages.push_back(std::make_shared(primSkills, 1, 0, 102, 111)); @@ -136,7 +136,7 @@ CHeroWindow::CHeroWindow(const CGHeroInstance * hero) primSkillImages.push_back(std::make_shared(primSkills, 4, 0, 20, 230)); primSkillImages.push_back(std::make_shared(primSkills, 5, 0, 242, 111)); - specImage = std::make_shared("UN44", 0, 0, 18, 180); + specImage = std::make_shared(AnimationPath::builtin("UN44"), 0, 0, 18, 180); specArea = std::make_shared(Rect(18, 180, 136, 42), CGI->generaltexth->heroscrn[27]); specName = std::make_shared(69, 205); @@ -148,7 +148,7 @@ CHeroWindow::CHeroWindow(const CGHeroInstance * hero) expValue = std::make_shared(68, 252); manaValue = std::make_shared(211, 252); - auto secSkills = std::make_shared("SECSKILL"); + auto secSkills = std::make_shared(AnimationPath::builtin("SECSKILL")); for(int i = 0; i < std::min(hero->secSkills.size(), 8u); ++i) { Rect r = Rect(i%2 == 0 ? 18 : 162, 276 + 48 * (i/2), 136, 42); @@ -194,7 +194,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded) specImage->setFrame(curHero->type->imageIndex); specName->setText(curHero->type->getSpecialtyNameTranslated()); - tacticsButton = std::make_shared(Point(539, 483), "hsbtns8.def", std::make_pair(heroscrn[26], heroscrn[31]), 0, EShortcut::HERO_TOGGLE_TACTICS); + tacticsButton = std::make_shared(Point(539, 483), AnimationPath::builtin("hsbtns8.def"), std::make_pair(heroscrn[26], heroscrn[31]), 0, EShortcut::HERO_TOGGLE_TACTICS); tacticsButton->addHoverText(CButton::HIGHLIGHTED, CGI->generaltexth->heroscrn[25]); dismissButton->addHoverText(CButton::NORMAL, boost::str(boost::format(CGI->generaltexth->heroscrn[16]) % curHero->getNameTranslated() % curHero->type->heroClass->getNameTranslated())); @@ -210,7 +210,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded) boost::algorithm::replace_first(helpBox, "%s", CGI->generaltexth->allTexts[43]); garr = std::make_shared(Point(15, 485), 8, Point(), curHero); - auto split = std::make_shared(Point(539, 519), "hsbtns9.def", CButton::tooltip(CGI->generaltexth->allTexts[256], helpBox), [&](){ garr->splitClick(); }); + auto split = std::make_shared(Point(539, 519), AnimationPath::builtin("hsbtns9.def"), CButton::tooltip(CGI->generaltexth->allTexts[256], helpBox), [&](){ garr->splitClick(); }); garr->addSplitBtn(split); } if(!arts) @@ -224,7 +224,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded) listSelection.reset(); if(serial >= 0) - listSelection = std::make_shared("HPSYYY", 612, 33 + serial * 54); + listSelection = std::make_shared(ImagePath::builtin("HPSYYY"), 612, 33 + serial * 54); } //primary skills support diff --git a/client/windows/CKingdomInterface.cpp b/client/windows/CKingdomInterface.cpp index cd2c5f40f..95009f659 100644 --- a/client/windows/CKingdomInterface.cpp +++ b/client/windows/CKingdomInterface.cpp @@ -169,7 +169,7 @@ std::string InfoBoxAbstractHeroData::getNameText() return ""; } -std::string InfoBoxAbstractHeroData::getImageName(InfoBox::InfoSize size) +AnimationPath InfoBoxAbstractHeroData::getImageName(InfoBox::InfoSize size) { //TODO: sizes switch(size) @@ -181,11 +181,11 @@ std::string InfoBoxAbstractHeroData::getImageName(InfoBox::InfoSize size) case HERO_PRIMARY_SKILL: case HERO_MANA: case HERO_EXPERIENCE: - return "PSKIL32"; + return AnimationPath::builtin("PSKIL32"); case HERO_SPECIAL: - return "UN32"; + return AnimationPath::builtin("UN32"); case HERO_SECONDARY_SKILL: - return "SECSK32"; + return AnimationPath::builtin("SECSK32"); default: assert(0); } @@ -197,11 +197,11 @@ std::string InfoBoxAbstractHeroData::getImageName(InfoBox::InfoSize size) case HERO_PRIMARY_SKILL: case HERO_MANA: case HERO_EXPERIENCE: - return "PSKIL42"; + return AnimationPath::builtin("PSKIL42"); case HERO_SPECIAL: - return "UN44"; + return AnimationPath::builtin("UN44"); case HERO_SECONDARY_SKILL: - return "SECSKILL"; + return AnimationPath::builtin("SECSKILL"); default: assert(0); } @@ -209,7 +209,7 @@ std::string InfoBoxAbstractHeroData::getImageName(InfoBox::InfoSize size) default: assert(0); } - return ""; + return {}; } std::string InfoBoxAbstractHeroData::getHoverText() @@ -437,7 +437,7 @@ size_t InfoBoxCustom::getImageIndex() return imageIndex; } -std::string InfoBoxCustom::getImageName(InfoBox::InfoSize size) +AnimationPath InfoBoxCustom::getImageName(InfoBox::InfoSize size) { return imageName; } @@ -457,7 +457,7 @@ void InfoBoxCustom::prepareMessage(std::string & text, std::shared_ptr("KSTATBAR", 10,pos.h - 45)); - resdatabar = std::make_shared("KRESBAR", 7, 111+footerPos, 29, 5, 76, 81); + statusbar = CGStatusBar::create(std::make_shared(ImagePath::builtin("KSTATBAR"), 10,pos.h - 45)); + resdatabar = std::make_shared(ImagePath::builtin("KRESBAR"), 7, 111+footerPos, 29, 5, 76, 81); } void CKingdomInterface::generateObjectsList(const std::vector &ownedObjects) @@ -602,27 +602,27 @@ void CKingdomInterface::generateButtons() ui32 footerPos = OVERVIEW_SIZE * 116; //Main control buttons - btnHeroes = std::make_shared(Point(748, 28+footerPos), "OVBUTN1.DEF", CButton::tooltip(CGI->generaltexth->overview[11], CGI->generaltexth->overview[6]), + btnHeroes = std::make_shared(Point(748, 28+footerPos), AnimationPath::builtin("OVBUTN1.DEF"), CButton::tooltip(CGI->generaltexth->overview[11], CGI->generaltexth->overview[6]), std::bind(&CKingdomInterface::activateTab, this, 0), EShortcut::KINGDOM_HEROES_TAB); btnHeroes->block(true); - btnTowns = std::make_shared(Point(748, 64+footerPos), "OVBUTN6.DEF", CButton::tooltip(CGI->generaltexth->overview[12], CGI->generaltexth->overview[7]), + btnTowns = std::make_shared(Point(748, 64+footerPos), AnimationPath::builtin("OVBUTN6.DEF"), CButton::tooltip(CGI->generaltexth->overview[12], CGI->generaltexth->overview[7]), std::bind(&CKingdomInterface::activateTab, this, 1), EShortcut::KINGDOM_TOWNS_TAB); - btnExit = std::make_shared(Point(748,99+footerPos), "OVBUTN1.DEF", CButton::tooltip(CGI->generaltexth->allTexts[600]), + btnExit = std::make_shared(Point(748,99+footerPos), AnimationPath::builtin("OVBUTN1.DEF"), CButton::tooltip(CGI->generaltexth->allTexts[600]), std::bind(&CKingdomInterface::close, this), EShortcut::GLOBAL_RETURN); btnExit->setImageOrder(3, 4, 5, 6); //Object list control buttons - dwellTop = std::make_shared(Point(733, 4), "OVBUTN4.DEF", CButton::tooltip(), [&](){ dwellingsList->moveToPos(0);}); + dwellTop = std::make_shared(Point(733, 4), AnimationPath::builtin("OVBUTN4.DEF"), CButton::tooltip(), [&](){ dwellingsList->moveToPos(0);}); - dwellBottom = std::make_shared(Point(733, footerPos+2), "OVBUTN4.DEF", CButton::tooltip(), [&](){ dwellingsList->moveToPos(-1); }); + dwellBottom = std::make_shared(Point(733, footerPos+2), AnimationPath::builtin("OVBUTN4.DEF"), CButton::tooltip(), [&](){ dwellingsList->moveToPos(-1); }); dwellBottom->setImageOrder(2, 3, 4, 5); - dwellUp = std::make_shared(Point(733, 24), "OVBUTN4.DEF", CButton::tooltip(), [&](){ dwellingsList->moveToPrev(); }); + dwellUp = std::make_shared(Point(733, 24), AnimationPath::builtin("OVBUTN4.DEF"), CButton::tooltip(), [&](){ dwellingsList->moveToPrev(); }); dwellUp->setImageOrder(4, 5, 6, 7); - dwellDown = std::make_shared(Point(733, footerPos-18), "OVBUTN4.DEF", CButton::tooltip(), [&](){ dwellingsList->moveToNext(); }); + dwellDown = std::make_shared(Point(733, footerPos-18), AnimationPath::builtin("OVBUTN4.DEF"), CButton::tooltip(), [&](){ dwellingsList->moveToNext(); }); dwellDown->setImageOrder(6, 7, 8, 9); } @@ -677,7 +677,7 @@ void CKingdomInterface::artifactRemoved(const ArtifactLocation& artLoc) CKingdHeroList::CKingdHeroList(size_t maxSize) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - title = std::make_shared("OVTITLE",16,0); + title = std::make_shared(ImagePath::builtin("OVTITLE"),16,0); title->colorize(LOCPLINT->playerID); heroLabel = std::make_shared(150, 10, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->overview[0]); skillsLabel = std::make_shared(500, 10, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->overview[1]); @@ -711,14 +711,14 @@ std::shared_ptr CKingdHeroList::createHeroItem(size_t index) } else { - return std::make_shared("OVSLOT", (index-2) % picCount ); + return std::make_shared(AnimationPath::builtin("OVSLOT"), (index-2) % picCount ); } } CKingdTownList::CKingdTownList(size_t maxSize) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - title = std::make_shared("OVTITLE", 16, 0); + title = std::make_shared(ImagePath::builtin("OVTITLE"), 16, 0); title->colorize(LOCPLINT->playerID); townLabel = std::make_shared(146, 10,FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->overview[3]); garrHeroLabel = std::make_shared(375, 10, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->overview[4]); @@ -758,14 +758,14 @@ std::shared_ptr CKingdTownList::createTownItem(size_t index) if(index < townsList.size()) return std::make_shared(townsList[index]); else - return std::make_shared("OVSLOT", (index-2) % picCount ); + return std::make_shared(AnimationPath::builtin("OVSLOT"), (index-2) % picCount ); } CTownItem::CTownItem(const CGTownInstance * Town) : town(Town) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - background = std::make_shared("OVSLOT", 6); + background = std::make_shared(AnimationPath::builtin("OVSLOT"), 6); name = std::make_shared(74, 8, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, town->getNameTranslated()); income = std::make_shared( 190, 60, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, std::to_string(town->dailyIncome()[EGameResID::GOLD])); @@ -777,7 +777,7 @@ CTownItem::CTownItem(const CGTownInstance * Town) size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->settings()->getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)]; - picture = std::make_shared("ITPT", iconIndex, 0, 5, 6); + picture = std::make_shared(AnimationPath::builtin("ITPT"), iconIndex, 0, 5, 6); openTown = std::make_shared(Rect(5, 6, 58, 64), town); for(size_t i=0; icreatures.size(); i++) @@ -819,7 +819,7 @@ public: ArtSlotsTab() { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - background = std::make_shared("OVSLOT", 4); + background = std::make_shared(AnimationPath::builtin("OVSLOT"), 4); pos = background->pos; for(int i=0; i<9; i++) arts.push_back(std::make_shared(Point(269+i*48, 66))); @@ -837,10 +837,10 @@ public: BackpackTab() { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - background = std::make_shared("OVSLOT", 5); + background = std::make_shared(AnimationPath::builtin("OVSLOT"), 5); pos = background->pos; - btnLeft = std::make_shared(Point(269, 66), "HSBTNS3", CButton::tooltip(), 0); - btnRight = std::make_shared(Point(675, 66), "HSBTNS5", CButton::tooltip(), 0); + btnLeft = std::make_shared(Point(269, 66), AnimationPath::builtin("HSBTNS3"), CButton::tooltip(), 0); + btnRight = std::make_shared(Point(675, 66), AnimationPath::builtin("HSBTNS5"), CButton::tooltip(), 0); for(int i=0; i<8; i++) arts.push_back(std::make_shared(Point(294+i*48, 66))); } @@ -905,7 +905,7 @@ CHeroItem::CHeroItem(const CGHeroInstance * Hero) std::string hover = CGI->generaltexth->overview[13+it]; std::string overlay = CGI->generaltexth->overview[8+it]; - auto button = std::make_shared(Point(364+(int)it*112, 46), "OVBUTN3", CButton::tooltip(hover, overlay), 0); + auto button = std::make_shared(Point(364+(int)it*112, 46), AnimationPath::builtin("OVBUTN3"), CButton::tooltip(hover, overlay), 0); button->addTextOverlay(CGI->generaltexth->allTexts[stringID[it]], FONT_SMALL, Colors::YELLOW); artButtons->addToggle((int)it, button); } @@ -915,7 +915,7 @@ CHeroItem::CHeroItem(const CGHeroInstance * Hero) garr = std::make_shared(Point(6, 78), 4, Point(), hero, nullptr, true, true); - portrait = std::make_shared("PortraitsLarge", hero->portrait, 0, 5, 6); + portrait = std::make_shared(AnimationPath::builtin("PortraitsLarge"), hero->portrait, 0, 5, 6); heroArea = std::make_shared(5, 6, hero); name = std::make_shared(73, 7, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, hero->getNameTranslated()); diff --git a/client/windows/CKingdomInterface.h b/client/windows/CKingdomInterface.h index 57d853932..0950419d9 100644 --- a/client/windows/CKingdomInterface.h +++ b/client/windows/CKingdomInterface.h @@ -103,7 +103,7 @@ public: //methods that generate values for displaying virtual std::string getValueText()=0; virtual std::string getNameText()=0; - virtual std::string getImageName(InfoBox::InfoSize size)=0; + virtual AnimationPath getImageName(InfoBox::InfoSize size)=0; virtual std::string getHoverText()=0; virtual size_t getImageIndex()=0; @@ -124,7 +124,7 @@ public: std::string getValueText() override; std::string getNameText() override; - std::string getImageName(InfoBox::InfoSize size) override; + AnimationPath getImageName(InfoBox::InfoSize size) override; std::string getHoverText() override; size_t getImageIndex() override; @@ -166,7 +166,7 @@ class InfoBoxCustom : public IInfoBoxData public: std::string valueText; std::string nameText; - std::string imageName; + AnimationPath imageName; std::string hoverText; size_t imageIndex; @@ -174,7 +174,7 @@ public: std::string getValueText() override; std::string getNameText() override; - std::string getImageName(InfoBox::InfoSize size) override; + AnimationPath getImageName(InfoBox::InfoSize size) override; std::string getHoverText() override; size_t getImageIndex() override; @@ -194,7 +194,7 @@ public: std::string getValueText() override; std::string getNameText() override; - std::string getImageName(InfoBox::InfoSize size) override; + AnimationPath getImageName(InfoBox::InfoSize size) override; std::string getHoverText() override; size_t getImageIndex() override; }; diff --git a/client/windows/CMessage.cpp b/client/windows/CMessage.cpp index c2eaf4251..35da927e1 100644 --- a/client/windows/CMessage.cpp +++ b/client/windows/CMessage.cpp @@ -79,7 +79,7 @@ void CMessage::init() { for(int i=0; i("DIALGBOX"); + dialogBorders[i] = std::make_unique(AnimationPath::builtin("DIALGBOX")); dialogBorders[i]->preload(); for(int j=0; j < dialogBorders[i]->size(0); j++) @@ -92,7 +92,7 @@ void CMessage::init() } } - background = IImage::createFromFile("DIBOXBCK.BMP", EImageBlitMode::OPAQUE); + background = IImage::createFromFile(ImagePath::builtin("DIBOXBCK.BMP"), EImageBlitMode::OPAQUE); } void CMessage::dispose() diff --git a/client/windows/CPuzzleWindow.cpp b/client/windows/CPuzzleWindow.cpp index 4f3f6f942..ff6a98a01 100644 --- a/client/windows/CPuzzleWindow.cpp +++ b/client/windows/CPuzzleWindow.cpp @@ -28,7 +28,7 @@ #include "../../lib/StartInfo.h" CPuzzleWindow::CPuzzleWindow(const int3 & GrailPos, double discoveredRatio) - : CWindowObject(PLAYER_COLORED | BORDERED, "PUZZLE"), + : CWindowObject(PLAYER_COLORED | BORDERED, ImagePath::builtin("PUZZLE")), grailPos(GrailPos), currentAlpha(ColorRGBA::ALPHA_OPAQUE) { @@ -36,14 +36,14 @@ CPuzzleWindow::CPuzzleWindow(const int3 & GrailPos, double discoveredRatio) CCS->soundh->playSound(soundBase::OBELISK); - quitb = std::make_shared(Point(670, 538), "IOK6432.DEF", CButton::tooltip(CGI->generaltexth->allTexts[599]), std::bind(&CPuzzleWindow::close, this), EShortcut::GLOBAL_RETURN); + quitb = std::make_shared(Point(670, 538), AnimationPath::builtin("IOK6432.DEF"), CButton::tooltip(CGI->generaltexth->allTexts[599]), std::bind(&CPuzzleWindow::close, this), EShortcut::GLOBAL_RETURN); quitb->setBorderColor(Colors::METALLIC_GOLD); mapView = std::make_shared(Point(8,9), Point(591, 544), grailPos); - logo = std::make_shared("PUZZLOGO", 607, 3); + logo = std::make_shared(ImagePath::builtin("PUZZLOGO"), 607, 3); title = std::make_shared(700, 95, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[463]); - resDataBar = std::make_shared("ARESBAR.bmp", 3, 575, 32, 2, 85, 85); + resDataBar = std::make_shared(ImagePath("ARESBAR.bmp"), 3, 575, 32, 2, 85, 85); int faction = LOCPLINT->cb->getStartInfo()->playerInfos.find(LOCPLINT->playerID)->second.castle; diff --git a/client/windows/CQuestLog.cpp b/client/windows/CQuestLog.cpp index 560f407ad..de1f9878e 100644 --- a/client/windows/CQuestLog.cpp +++ b/client/windows/CQuestLog.cpp @@ -49,7 +49,7 @@ void CQuestLabel::showAll(Canvas & to) CMultiLineLabel::showAll (to); } -CQuestIcon::CQuestIcon (const std::string &defname, int index, int x, int y) : +CQuestIcon::CQuestIcon (const AnimationPath &defname, int index, int x, int y) : CAnimImage(defname, index, 0, x, y) { addUsedEvents(LCLICK); @@ -87,7 +87,7 @@ void CQuestMinimap::addQuestMarks (const QuestInfo * q) onMapViewMoved(Rect(), tile.z); - auto pic = std::make_shared("VwSymbol.def", 3, offset.x, offset.y); + auto pic = std::make_shared(AnimationPath::builtin("VwSymbol.def"), 3, offset.x, offset.y); pic->moveBy (Point ( -pic->pos.w/2, -pic->pos.h/2)); pic->callback = std::bind (&CQuestMinimap::iconClicked, this); @@ -117,7 +117,7 @@ void CQuestMinimap::showAll(Canvas & to) } CQuestLog::CQuestLog (const std::vector & Quests) - : CWindowObject(PLAYER_COLORED | BORDERED, "questDialog"), + : CWindowObject(PLAYER_COLORED | BORDERED, ImagePath::builtin("questDialog")), questIndex(0), currentQuest(nullptr), hideComplete(false), @@ -128,9 +128,9 @@ CQuestLog::CQuestLog (const std::vector & Quests) minimap = std::make_shared(Rect(12, 12, 169, 169)); // TextBox have it's own 4 pixel padding from top at least for English. To achieve 10px from both left and top only add 6px margin description = std::make_shared("", Rect(205, 18, 385, DESCRIPTION_HEIGHT_MAX), CSlider::BROWN, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE); - ok = std::make_shared(Point(539, 398), "IOKAY.DEF", CGI->generaltexth->zelp[445], std::bind(&CQuestLog::close, this), EShortcut::GLOBAL_ACCEPT); + ok = std::make_shared(Point(539, 398), AnimationPath::builtin("IOKAY.DEF"), CGI->generaltexth->zelp[445], std::bind(&CQuestLog::close, this), EShortcut::GLOBAL_ACCEPT); // Both button and lable are shifted to -2px by x and y to not make them actually look like they're on same line with quests list and ok button - hideCompleteButton = std::make_shared(Point(10, 396), "sysopchk.def", CButton::tooltipLocalized("vcmi.questLog.hideComplete"), std::bind(&CQuestLog::toggleComplete, this, _1)); + hideCompleteButton = std::make_shared(Point(10, 396), AnimationPath::builtin("sysopchk.def"), CButton::tooltipLocalized("vcmi.questLog.hideComplete"), std::bind(&CQuestLog::toggleComplete, this, _1)); hideCompleteLabel = std::make_shared(46, 398, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->translate("vcmi.questLog.hideComplete.hover")); slider = std::make_shared(Point(166, 195), 191, std::bind(&CQuestLog::sliderMoved, this, _1), QUEST_COUNT, 0, 0, Orientation::VERTICAL, CSlider::BROWN); slider->setPanningStep(32); diff --git a/client/windows/CQuestLog.h b/client/windows/CQuestLog.h index 68f880e68..3d719d2dd 100644 --- a/client/windows/CQuestLog.h +++ b/client/windows/CQuestLog.h @@ -54,7 +54,7 @@ class CQuestIcon : public CAnimImage public: std::function callback; //TODO: merge with other similar classes? - CQuestIcon(const std::string &defname, int index, int x=0, int y=0); + CQuestIcon(const AnimationPath & defname, int index, int x=0, int y=0); void clickPressed(const Point & cursorPosition) override; void showAll(Canvas & to) override; diff --git a/client/windows/CSpellWindow.cpp b/client/windows/CSpellWindow.cpp index 288a696cb..67d88c2ff 100644 --- a/client/windows/CSpellWindow.cpp +++ b/client/windows/CSpellWindow.cpp @@ -93,7 +93,7 @@ public: } spellsorter; CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _myInt, bool openOnBattleSpells): - CWindowObject(PLAYER_COLORED, "SpelBack"), + CWindowObject(PLAYER_COLORED, ImagePath::builtin("SpelBack")), battleSpellsOnly(openOnBattleSpells), selectedTab(4), currentPage(0), @@ -166,23 +166,23 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m //numbers of spell pages computed - leftCorner = std::make_shared("SpelTrnL.bmp", 97, 77); - rightCorner = std::make_shared("SpelTrnR.bmp", 487, 72); + leftCorner = std::make_shared(ImagePath::builtin("SpelTrnL.bmp"), 97, 77); + rightCorner = std::make_shared(ImagePath::builtin("SpelTrnR.bmp"), 487, 72); - spellIcons = std::make_shared("Spells"); + spellIcons = std::make_shared(AnimationPath::builtin("Spells")); - schoolTab = std::make_shared("SpelTab", selectedTab, 0, 524, 88); - schoolPicture = std::make_shared("Schools", 0, 0, 117, 74); + schoolTab = std::make_shared(AnimationPath::builtin("SpelTab"), selectedTab, 0, 524, 88); + schoolPicture = std::make_shared(AnimationPath::builtin("Schools"), 0, 0, 117, 74); - schoolBorders[0] = std::make_shared("SplevA.def"); - schoolBorders[1] = std::make_shared("SplevF.def"); - schoolBorders[2] = std::make_shared("SplevW.def"); - schoolBorders[3] = std::make_shared("SplevE.def"); + schoolBorders[0] = std::make_shared(AnimationPath::builtin("SplevA.def")); + schoolBorders[1] = std::make_shared(AnimationPath::builtin("SplevF.def")); + schoolBorders[2] = std::make_shared(AnimationPath::builtin("SplevW.def")); + schoolBorders[3] = std::make_shared(AnimationPath::builtin("SplevE.def")); for(auto item : schoolBorders) item->preload(); mana = std::make_shared(435, 426, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, std::to_string(myHero->mana)); - statusBar = CGStatusBar::create(7, 569, "Spelroll.bmp"); + statusBar = CGStatusBar::create(7, 569, ImagePath::builtin("Spelroll.bmp")); interactiveAreas.push_back(std::make_shared( Rect( 479 + pos.x, 405 + pos.y, 36, 56), std::bind(&CSpellWindow::fexitb, this), 460, this)); interactiveAreas.push_back(std::make_shared( Rect( 221 + pos.x, 405 + pos.y, 36, 56), std::bind(&CSpellWindow::fbattleSpellsb, this), 453, this)); diff --git a/client/windows/CTradeWindow.cpp b/client/windows/CTradeWindow.cpp index 4afe99a6c..74a24ced9 100644 --- a/client/windows/CTradeWindow.cpp +++ b/client/windows/CTradeWindow.cpp @@ -87,22 +87,22 @@ void CTradeWindow::CTradeableItem::setID(int newID) } } -std::string CTradeWindow::CTradeableItem::getFilename() +AnimationPath CTradeWindow::CTradeableItem::getFilename() { switch(type) { case RESOURCE: - return "RESOURCE"; + return AnimationPath::builtin("RESOURCE"); case PLAYER: - return "CREST58"; + return AnimationPath::builtin("CREST58"); case ARTIFACT_TYPE: case ARTIFACT_PLACEHOLDER: case ARTIFACT_INSTANCE: - return "artifact"; + return AnimationPath::builtin("artifact"); case CREATURE: - return "TWCRPORT"; + return AnimationPath::builtin("TWCRPORT"); default: - return ""; + return {}; } } @@ -317,7 +317,7 @@ void CTradeWindow::CTradeableItem::setArtInstance(const CArtifactInstance *art) setID(-1); } -CTradeWindow::CTradeWindow(std::string bgName, const IMarket *Market, const CGHeroInstance *Hero, EMarketMode Mode): +CTradeWindow::CTradeWindow(const ImagePath & bgName, const IMarket *Market, const CGHeroInstance *Hero, EMarketMode Mode): CWindowObject(PLAYER_COLORED, bgName), market(Market), hero(Hero), @@ -616,23 +616,23 @@ void CTradeWindow::artifactSelected(CHeroArtPlace *slot) selectionChanged(true); } -std::string CMarketplaceWindow::getBackgroundForMode(EMarketMode mode) +ImagePath CMarketplaceWindow::getBackgroundForMode(EMarketMode mode) { switch(mode) { case EMarketMode::RESOURCE_RESOURCE: - return "TPMRKRES.bmp"; + return ImagePath::builtin("TPMRKRES.bmp"); case EMarketMode::RESOURCE_PLAYER: - return "TPMRKPTS.bmp"; + return ImagePath::builtin("TPMRKPTS.bmp"); case EMarketMode::CREATURE_RESOURCE: - return "TPMRKCRS.bmp"; + return ImagePath::builtin("TPMRKCRS.bmp"); case EMarketMode::RESOURCE_ARTIFACT: - return "TPMRKABS.bmp"; + return ImagePath::builtin("TPMRKABS.bmp"); case EMarketMode::ARTIFACT_RESOURCE: - return "TPMRKASS.bmp"; + return ImagePath::builtin("TPMRKASS.bmp"); } assert(0); - return ""; + return {}; } CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInstance * Hero, EMarketMode Mode) @@ -685,14 +685,14 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInsta initItems(false); initItems(true); - ok = std::make_shared(Point(516, 520), "IOK6432.DEF", CGI->generaltexth->zelp[600], [&](){ close(); }, EShortcut::GLOBAL_RETURN); - deal = std::make_shared(Point(307, 520), "TPMRKB.DEF", CGI->generaltexth->zelp[595], [&](){ makeDeal(); } ); + ok = std::make_shared(Point(516, 520), AnimationPath::builtin("IOK6432.DEF"), CGI->generaltexth->zelp[600], [&](){ close(); }, EShortcut::GLOBAL_RETURN); + deal = std::make_shared(Point(307, 520), AnimationPath::builtin("TPMRKB.DEF"), CGI->generaltexth->zelp[595], [&](){ makeDeal(); } ); deal->block(true); if(sliderNeeded) { slider = std::make_shared(Point(231, 490), 137, std::bind(&CMarketplaceWindow::sliderMoved, this, _1), 0, 0, 0, Orientation::HORIZONTAL); - max = std::make_shared(Point(229, 520), "IRCBTNS.DEF", CGI->generaltexth->zelp[596], [&](){ setMax(); }); + max = std::make_shared(Point(229, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596], [&](){ setMax(); }); max->block(true); } else @@ -740,15 +740,15 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInsta int specialOffset = mode == EMarketMode::ARTIFACT_RESOURCE ? 35 : 0; //in selling artifacts mode we need to move res-res and art-res buttons down if(printButtonFor(EMarketMode::RESOURCE_PLAYER)) - buttons.push_back(std::make_shared(Point(18, 520),"TPMRKBU1.DEF", CGI->generaltexth->zelp[612], [&](){ setMode(EMarketMode::RESOURCE_PLAYER);})); + buttons.push_back(std::make_shared(Point(18, 520),AnimationPath::builtin("TPMRKBU1.DEF"), CGI->generaltexth->zelp[612], [&](){ setMode(EMarketMode::RESOURCE_PLAYER);})); if(printButtonFor(EMarketMode::RESOURCE_RESOURCE)) - buttons.push_back(std::make_shared(Point(516, 450 + specialOffset),"TPMRKBU5.DEF", CGI->generaltexth->zelp[605], [&](){ setMode(EMarketMode::RESOURCE_RESOURCE);})); + buttons.push_back(std::make_shared(Point(516, 450 + specialOffset),AnimationPath::builtin("TPMRKBU5.DEF"), CGI->generaltexth->zelp[605], [&](){ setMode(EMarketMode::RESOURCE_RESOURCE);})); if(printButtonFor(EMarketMode::CREATURE_RESOURCE)) - buttons.push_back(std::make_shared(Point(516, 485),"TPMRKBU4.DEF", CGI->generaltexth->zelp[599], [&](){ setMode(EMarketMode::CREATURE_RESOURCE);})); + buttons.push_back(std::make_shared(Point(516, 485),AnimationPath::builtin("TPMRKBU4.DEF"), CGI->generaltexth->zelp[599], [&](){ setMode(EMarketMode::CREATURE_RESOURCE);})); if(printButtonFor(EMarketMode::RESOURCE_ARTIFACT)) - buttons.push_back(std::make_shared(Point(18, 450 + specialOffset),"TPMRKBU2.DEF", CGI->generaltexth->zelp[598], [&](){ setMode(EMarketMode::RESOURCE_ARTIFACT);})); + buttons.push_back(std::make_shared(Point(18, 450 + specialOffset),AnimationPath::builtin("TPMRKBU2.DEF"), CGI->generaltexth->zelp[598], [&](){ setMode(EMarketMode::RESOURCE_ARTIFACT);})); if(printButtonFor(EMarketMode::ARTIFACT_RESOURCE)) - buttons.push_back(std::make_shared(Point(18, 485),"TPMRKBU3.DEF", CGI->generaltexth->zelp[613], [&](){ setMode(EMarketMode::ARTIFACT_RESOURCE);})); + buttons.push_back(std::make_shared(Point(18, 485),AnimationPath::builtin("TPMRKBU3.DEF"), CGI->generaltexth->zelp[613], [&](){ setMode(EMarketMode::ARTIFACT_RESOURCE);})); updateTraderText(); } @@ -1076,7 +1076,7 @@ void CMarketplaceWindow::updateTraderText() } CAltarWindow::CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, EMarketMode Mode) - : CTradeWindow((Mode == EMarketMode::CREATURE_EXP ? "ALTARMON.bmp" : "ALTRART2.bmp"), Market, Hero, Mode) + : CTradeWindow(ImagePath::builtin(Mode == EMarketMode::CREATURE_EXP ? "ALTARMON.bmp" : "ALTRART2.bmp"), Market, Hero, Mode) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -1093,10 +1093,10 @@ CAltarWindow::CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, new CTextBox(CGI->generaltexth->allTexts[480], Rect(320, 56, 256, 40), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW); slider = std::make_shared(Point(231, 481), 137, std::bind(&CAltarWindow::sliderMoved, this, _1), 0, 0, 0, Orientation::HORIZONTAL); - max = std::make_shared(Point(147, 520), "IRCBTNS.DEF", CGI->generaltexth->zelp[578], std::bind(&CSlider::scrollToMax, slider)); + max = std::make_shared(Point(147, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[578], std::bind(&CSlider::scrollToMax, slider)); sacrificedUnits.resize(GameConstants::ARMY_SIZE, 0); - sacrificeAll = std::make_shared(Point(393, 520), "ALTARMY.DEF", CGI->generaltexth->zelp[579], std::bind(&CAltarWindow::SacrificeAll,this)); + sacrificeAll = std::make_shared(Point(393, 520), AnimationPath::builtin("ALTARMY.DEF"), CGI->generaltexth->zelp[579], std::bind(&CAltarWindow::SacrificeAll,this)); initItems(true); mimicCres(); @@ -1108,9 +1108,9 @@ CAltarWindow::CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, //%s's Creatures labels.push_back(std::make_shared(302, 423, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[478])); - sacrificeAll = std::make_shared(Point(393, 520), "ALTFILL.DEF", CGI->generaltexth->zelp[571], std::bind(&CAltarWindow::SacrificeAll,this)); + sacrificeAll = std::make_shared(Point(393, 520), AnimationPath::builtin("ALTFILL.DEF"), CGI->generaltexth->zelp[571], std::bind(&CAltarWindow::SacrificeAll,this)); sacrificeAll->block(hero->artifactsInBackpack.empty() && hero->artifactsWorn.empty()); - sacrificeBackpack = std::make_shared(Point(147, 520), "ALTEMBK.DEF", CGI->generaltexth->zelp[570], std::bind(&CAltarWindow::SacrificeBackpack,this)); + sacrificeBackpack = std::make_shared(Point(147, 520), AnimationPath::builtin("ALTEMBK.DEF"), CGI->generaltexth->zelp[570], std::bind(&CAltarWindow::SacrificeBackpack,this)); sacrificeBackpack->block(hero->artifactsInBackpack.empty()); arts = std::make_shared(Point(-365, -12)); @@ -1119,7 +1119,7 @@ CAltarWindow::CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, initItems(true); initItems(false); - artIcon = std::make_shared("ARTIFACT", 0, 0, 281, 442); + artIcon = std::make_shared(AnimationPath::builtin("ARTIFACT"), 0, 0, 281, 442); artIcon->disable(); } @@ -1130,20 +1130,20 @@ CAltarWindow::CAltarWindow(const IMarket * Market, const CGHeroInstance * Hero, statusBar = CGStatusBar::create(std::make_shared(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); - ok = std::make_shared(Point(516, 520), "IOK6432.DEF", CGI->generaltexth->zelp[568], [&](){ close();}, EShortcut::GLOBAL_RETURN); + ok = std::make_shared(Point(516, 520), AnimationPath::builtin("IOK6432.DEF"), CGI->generaltexth->zelp[568], [&](){ close();}, EShortcut::GLOBAL_RETURN); - deal = std::make_shared(Point(269, 520), "ALTSACR.DEF", CGI->generaltexth->zelp[585], std::bind(&CAltarWindow::makeDeal,this)); + deal = std::make_shared(Point(269, 520), AnimationPath::builtin("ALTSACR.DEF"), CGI->generaltexth->zelp[585], std::bind(&CAltarWindow::makeDeal,this)); if(Mode == EMarketMode::CREATURE_EXP) { - auto changeMode = std::make_shared(Point(516, 421), "ALTART.DEF", CGI->generaltexth->zelp[580], std::bind(&CTradeWindow::setMode,this, EMarketMode::ARTIFACT_EXP)); + auto changeMode = std::make_shared(Point(516, 421), AnimationPath::builtin("ALTART.DEF"), CGI->generaltexth->zelp[580], std::bind(&CTradeWindow::setMode,this, EMarketMode::ARTIFACT_EXP)); if(Hero->getAlignment() == ::EAlignment::EVIL) changeMode->block(true); buttons.push_back(changeMode); } else if(Mode == EMarketMode::ARTIFACT_EXP) { - auto changeMode = std::make_shared(Point(516, 421), "ALTSACC.DEF", CGI->generaltexth->zelp[572], std::bind(&CTradeWindow::setMode,this, EMarketMode::CREATURE_EXP)); + auto changeMode = std::make_shared(Point(516, 421), AnimationPath::builtin("ALTSACC.DEF"), CGI->generaltexth->zelp[572], std::bind(&CTradeWindow::setMode,this, EMarketMode::CREATURE_EXP)); if(Hero->getAlignment() == ::EAlignment::GOOD) changeMode->block(true); buttons.push_back(changeMode); diff --git a/client/windows/CTradeWindow.h b/client/windows/CTradeWindow.h index 9b154f013..bdf253b89 100644 --- a/client/windows/CTradeWindow.h +++ b/client/windows/CTradeWindow.h @@ -35,7 +35,7 @@ public: class CTradeableItem : public CIntObject, public std::enable_shared_from_this { std::shared_ptr image; - std::string getFilename(); + AnimationPath getFilename(); int getIndex(); public: const CArtifactInstance * hlp; //holds ptr to artifact instance id type artifact @@ -83,7 +83,7 @@ public: std::shared_ptr slider; //for choosing amount to be exchanged bool readyToTrade; - CTradeWindow(std::string bgName, const IMarket * Market, const CGHeroInstance * Hero, EMarketMode Mode); //c + CTradeWindow(const ImagePath & bgName, const IMarket * Market, const CGHeroInstance * Hero, EMarketMode Mode); //c void showAll(Canvas & to) override; @@ -120,7 +120,7 @@ class CMarketplaceWindow : public CTradeWindow bool printButtonFor(EMarketMode M) const; - std::string getBackgroundForMode(EMarketMode mode); + ImagePath getBackgroundForMode(EMarketMode mode); public: int r1, r2; //suggested amounts of traded resources bool madeTransaction; //if player made at least one transaction diff --git a/client/windows/CWindowObject.cpp b/client/windows/CWindowObject.cpp index e164090f4..b9eafdcb3 100644 --- a/client/windows/CWindowObject.cpp +++ b/client/windows/CWindowObject.cpp @@ -33,7 +33,7 @@ #include -CWindowObject::CWindowObject(int options_, std::string imageName, Point centerAt): +CWindowObject::CWindowObject(int options_, const ImagePath & imageName, Point centerAt): WindowBase(0, Point()), options(options_), background(createBg(imageName, options & PLAYER_COLORED)) @@ -54,7 +54,7 @@ CWindowObject::CWindowObject(int options_, std::string imageName, Point centerAt setShadow(true); } -CWindowObject::CWindowObject(int options_, std::string imageName): +CWindowObject::CWindowObject(int options_, const ImagePath & imageName): WindowBase(0, Point()), options(options_), background(createBg(imageName, options_ & PLAYER_COLORED)) @@ -81,7 +81,7 @@ CWindowObject::~CWindowObject() CCS->curh->show(); } -std::shared_ptr CWindowObject::createBg(std::string imageName, bool playerColored) +std::shared_ptr CWindowObject::createBg(const ImagePath & imageName, bool playerColored) { OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE); @@ -95,7 +95,7 @@ std::shared_ptr CWindowObject::createBg(std::string imageName, bool pl return image; } -void CWindowObject::setBackground(std::string filename) +void CWindowObject::setBackground(const ImagePath & filename) { OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE); @@ -237,10 +237,10 @@ bool CWindowObject::isPopupWindow() const return options & RCLICK_POPUP; } -CStatusbarWindow::CStatusbarWindow(int options, std::string imageName, Point centerAt) : CWindowObject(options, imageName, centerAt) +CStatusbarWindow::CStatusbarWindow(int options, const ImagePath & imageName, Point centerAt) : CWindowObject(options, imageName, centerAt) { } -CStatusbarWindow::CStatusbarWindow(int options, std::string imageName) : CWindowObject(options, imageName) +CStatusbarWindow::CStatusbarWindow(int options, const ImagePath & imageName) : CWindowObject(options, imageName) { } diff --git a/client/windows/CWindowObject.h b/client/windows/CWindowObject.h index 66e7ca27a..dd49f107b 100644 --- a/client/windows/CWindowObject.h +++ b/client/windows/CWindowObject.h @@ -10,12 +10,13 @@ #pragma once #include "../gui/CIntObject.h" +#include "../../lib/filesystem/ResourcePath.h" class CGStatusBar; class CWindowObject : public WindowBase { - std::shared_ptr createBg(std::string imageName, bool playerColored); + std::shared_ptr createBg(const ImagePath & imageName, bool playerColored); std::vector> shadowParts; @@ -30,7 +31,7 @@ protected: bool isPopupWindow() const override; //To display border void updateShadow(); - void setBackground(std::string filename); + void setBackground(const ImagePath & filename); public: enum EOptions { @@ -45,8 +46,8 @@ public: * imageName - name for background image, can be empty * centerAt - position of window center. Default - center of the screen */ - CWindowObject(int options, std::string imageName, Point centerAt); - CWindowObject(int options, std::string imageName = ""); + CWindowObject(int options, const ImagePath & imageName, Point centerAt); + CWindowObject(int options, const ImagePath & imageName = {}); ~CWindowObject(); void showAll(Canvas & to) override; @@ -55,8 +56,8 @@ public: class CStatusbarWindow : public CWindowObject { public: - CStatusbarWindow(int options, std::string imageName, Point centerAt); - CStatusbarWindow(int options, std::string imageName = ""); + CStatusbarWindow(int options, const ImagePath & imageName, Point centerAt); + CStatusbarWindow(int options, const ImagePath & imageName = {}); protected: std::shared_ptr statusbar; }; diff --git a/client/windows/CreaturePurchaseCard.cpp b/client/windows/CreaturePurchaseCard.cpp index 18be16e94..879f0e588 100644 --- a/client/windows/CreaturePurchaseCard.cpp +++ b/client/windows/CreaturePurchaseCard.cpp @@ -35,17 +35,17 @@ void CreaturePurchaseCard::initButtons() void CreaturePurchaseCard::initMaxButton() { - maxButton = std::make_shared(Point(pos.x + 52, pos.y + 180), "QuickRecruitmentWindow/QuickRecruitmentAllButton.def", CButton::tooltip(), std::bind(&CSlider::scrollToMax,slider), EShortcut::RECRUITMENT_MAX); + maxButton = std::make_shared(Point(pos.x + 52, pos.y + 180), AnimationPath::builtin("QuickRecruitmentWindow/QuickRecruitmentAllButton.def"), CButton::tooltip(), std::bind(&CSlider::scrollToMax,slider), EShortcut::RECRUITMENT_MAX); } void CreaturePurchaseCard::initMinButton() { - minButton = std::make_shared(Point(pos.x, pos.y + 180), "QuickRecruitmentWindow/QuickRecruitmentNoneButton.def", CButton::tooltip(), std::bind(&CSlider::scrollToMin,slider), EShortcut::RECRUITMENT_MIN); + minButton = std::make_shared(Point(pos.x, pos.y + 180), AnimationPath::builtin("QuickRecruitmentWindow/QuickRecruitmentNoneButton.def"), CButton::tooltip(), std::bind(&CSlider::scrollToMin,slider), EShortcut::RECRUITMENT_MIN); } void CreaturePurchaseCard::initCreatureSwitcherButton() { - creatureSwitcher = std::make_shared(Point(pos.x + 18, pos.y-37), "iDv6432.def", CButton::tooltip(), [&](){ switchCreatureLevel(); }); + creatureSwitcher = std::make_shared(Point(pos.x + 18, pos.y-37), AnimationPath::builtin("iDv6432.def"), CButton::tooltip(), [&](){ switchCreatureLevel(); }); } void CreaturePurchaseCard::switchCreatureLevel() @@ -104,7 +104,7 @@ CreaturePurchaseCard::CreaturePurchaseCard(const std::vector & creat void CreaturePurchaseCard::initView() { picture = std::make_shared(pos.x, pos.y, creatureOnTheCard); - background = std::make_shared("QuickRecruitmentWindow/CreaturePurchaseCard.png", pos.x-4, pos.y-50); + background = std::make_shared(ImagePath::builtin("QuickRecruitmentWindow/CreaturePurchaseCard.png"), pos.x-4, pos.y-50); creatureClickArea = std::make_shared(Point(pos.x, pos.y), picture, creatureOnTheCard); initAmountInfo(); diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 74ceb4317..1e8097c26 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -213,7 +213,7 @@ void CRecruitmentWindow::showAll(Canvas & to) } CRecruitmentWindow::CRecruitmentWindow(const CGDwelling * Dwelling, int Level, const CArmedInstance * Dst, const std::function & Recruit, int y_offset): - CStatusbarWindow(PLAYER_COLORED, "TPRCRT"), + CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("TPRCRT")), onRecruit(Recruit), level(Level), dst(Dst), @@ -228,9 +228,9 @@ CRecruitmentWindow::CRecruitmentWindow(const CGDwelling * Dwelling, int Level, c slider = std::make_shared(Point(176, 279), 135, std::bind(&CRecruitmentWindow::sliderMoved, this, _1), 0, 0, 0, Orientation::HORIZONTAL); - maxButton = std::make_shared(Point(134, 313), "IRCBTNS.DEF", CGI->generaltexth->zelp[553], std::bind(&CSlider::scrollToMax, slider), EShortcut::RECRUITMENT_MAX); - buyButton = std::make_shared(Point(212, 313), "IBY6432.DEF", CGI->generaltexth->zelp[554], std::bind(&CRecruitmentWindow::buy, this), EShortcut::GLOBAL_ACCEPT); - cancelButton = std::make_shared(Point(290, 313), "ICN6432.DEF", CGI->generaltexth->zelp[555], std::bind(&CRecruitmentWindow::close, this), EShortcut::GLOBAL_CANCEL); + maxButton = std::make_shared(Point(134, 313), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[553], std::bind(&CSlider::scrollToMax, slider), EShortcut::RECRUITMENT_MAX); + buyButton = std::make_shared(Point(212, 313), AnimationPath::builtin("IBY6432.DEF"), CGI->generaltexth->zelp[554], std::bind(&CRecruitmentWindow::buy, this), EShortcut::GLOBAL_ACCEPT); + cancelButton = std::make_shared(Point(290, 313), AnimationPath::builtin("ICN6432.DEF"), CGI->generaltexth->zelp[555], std::bind(&CRecruitmentWindow::close, this), EShortcut::GLOBAL_CANCEL); title = std::make_shared(243, 32, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW); availableValue = std::make_shared(205, 253, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); @@ -318,7 +318,7 @@ void CRecruitmentWindow::sliderMoved(int to) } CSplitWindow::CSplitWindow(const CCreature * creature, std::function callback_, int leftMin_, int rightMin_, int leftAmount_, int rightAmount_) - : CWindowObject(PLAYER_COLORED, "GPUCRDIV"), + : CWindowObject(PLAYER_COLORED, ImagePath::builtin("GPUCRDIV")), callback(callback_), leftAmount(leftAmount_), rightAmount(rightAmount_), @@ -331,8 +331,8 @@ CSplitWindow::CSplitWindow(const CCreature * creature, std::function(Point(20, 263), "IOK6432", CButton::tooltip(), std::bind(&CSplitWindow::apply, this), EShortcut::GLOBAL_ACCEPT); - cancel = std::make_shared(Point(214, 263), "ICN6432", CButton::tooltip(), std::bind(&CSplitWindow::close, this), EShortcut::GLOBAL_CANCEL); + ok = std::make_shared(Point(20, 263), AnimationPath::builtin("IOK6432"), CButton::tooltip(), std::bind(&CSplitWindow::apply, this), EShortcut::GLOBAL_ACCEPT); + cancel = std::make_shared(Point(214, 263), AnimationPath::builtin("ICN6432"), CButton::tooltip(), std::bind(&CSplitWindow::close, this), EShortcut::GLOBAL_CANCEL); int sliderPosition = total - leftMin - rightMin; @@ -401,7 +401,7 @@ void CSplitWindow::sliderMoved(int to) } CLevelWindow::CLevelWindow(const CGHeroInstance * hero, PrimarySkill pskill, std::vector & skills, std::function callback) - : CWindowObject(PLAYER_COLORED, "LVLUPBKG"), + : CWindowObject(PLAYER_COLORED, ImagePath::builtin("LVLUPBKG")), cb(callback) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -420,8 +420,8 @@ CLevelWindow::CLevelWindow(const CGHeroInstance * hero, PrimarySkill pskill, std box = std::make_shared(comps, Rect(75, 300, pos.w - 150, 100)); } - portrait = std::make_shared("PortraitsLarge", hero->portrait, 0, 170, 66); - ok = std::make_shared(Point(297, 413), "IOKAY", CButton::tooltip(), std::bind(&CLevelWindow::close, this), EShortcut::GLOBAL_ACCEPT); + portrait = std::make_shared(AnimationPath::builtin("PortraitsLarge"), hero->portrait, 0, 170, 66); + ok = std::make_shared(Point(297, 413), AnimationPath::builtin("IOKAY"), CButton::tooltip(), std::bind(&CLevelWindow::close, this), EShortcut::GLOBAL_ACCEPT); //%s has gained a level. mainTitle = std::make_shared(192, 33, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[444]) % hero->getNameTranslated())); @@ -434,7 +434,7 @@ CLevelWindow::CLevelWindow(const CGHeroInstance * hero, PrimarySkill pskill, std levelTitle = std::make_shared(192, 162, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, levelTitleText); - skillIcon = std::make_shared("PSKIL42", static_cast(pskill), 0, 174, 190); + skillIcon = std::make_shared(AnimationPath::builtin("PSKIL42"), static_cast(pskill), 0, 174, 190); skillValue = std::make_shared(192, 253, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->primarySkillNames[static_cast(pskill)] + " +1"); } @@ -450,7 +450,7 @@ CLevelWindow::~CLevelWindow() } CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj) - : CStatusbarWindow(PLAYER_COLORED, "TPTAVERN"), + : CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("TPTAVERN")), tavernObj(TavernObj) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -479,9 +479,9 @@ CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj) rumor = std::make_shared(rumorText, Rect(32, 188, 330, 66), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); statusbar = CGStatusBar::create(std::make_shared(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); - cancel = std::make_shared(Point(310, 428), "ICANCEL.DEF", CButton::tooltip(CGI->generaltexth->tavernInfo[7]), std::bind(&CTavernWindow::close, this), EShortcut::GLOBAL_CANCEL); - recruit = std::make_shared(Point(272, 355), "TPTAV01.DEF", CButton::tooltip(), std::bind(&CTavernWindow::recruitb, this), EShortcut::GLOBAL_ACCEPT); - thiefGuild = std::make_shared(Point(22, 428), "TPTAV02.DEF", CButton::tooltip(CGI->generaltexth->tavernInfo[5]), std::bind(&CTavernWindow::thievesguildb, this), EShortcut::ADVENTURE_THIEVES_GUILD); + cancel = std::make_shared(Point(310, 428), AnimationPath::builtin("ICANCEL.DEF"), CButton::tooltip(CGI->generaltexth->tavernInfo[7]), std::bind(&CTavernWindow::close, this), EShortcut::GLOBAL_CANCEL); + recruit = std::make_shared(Point(272, 355), AnimationPath::builtin("TPTAV01.DEF"), CButton::tooltip(), std::bind(&CTavernWindow::recruitb, this), EShortcut::GLOBAL_ACCEPT); + thiefGuild = std::make_shared(Point(22, 428), AnimationPath::builtin("TPTAV02.DEF"), CButton::tooltip(CGI->generaltexth->tavernInfo[5]), std::bind(&CTavernWindow::thievesguildb, this), EShortcut::ADVENTURE_THIEVES_GUILD); if(LOCPLINT->cb->getResourceAmount(EGameResID::GOLD) < GameConstants::HERO_GOLD_COST) //not enough gold { @@ -600,7 +600,7 @@ CTavernWindow::HeroPortrait::HeroPortrait(int & sel, int id, int x, int y, const boost::algorithm::replace_first(description, "%s", h->type->heroClass->getNameTranslated()); boost::algorithm::replace_first(description, "%d", std::to_string(artifs)); - portrait = std::make_shared("portraitsLarge", h->portrait); + portrait = std::make_shared(AnimationPath::builtin("portraitsLarge"), h->portrait); } } @@ -618,7 +618,7 @@ static const std::string QUICK_EXCHANGE_BG = QUICK_EXCHANGE_MOD_PREFIX + "/TRADE static bool isQuickExchangeLayoutAvailable() { - return CResourceHandler::get()->existsResource(ResourceID(std::string("SPRITES/") + QUICK_EXCHANGE_BG, EResType::IMAGE)); + return CResourceHandler::get()->existsResource(ResourcePath(std::string("SPRITES/") + QUICK_EXCHANGE_BG, EResType::IMAGE)); } CExchangeController::CExchangeController(CExchangeWindow * view, ObjectInstanceID hero1, ObjectInstanceID hero2) @@ -828,7 +828,7 @@ void CExchangeController::moveArtifact( } CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID queryID) - : CStatusbarWindow(PLAYER_COLORED | BORDERED, isQuickExchangeLayoutAvailable() ? QUICK_EXCHANGE_BG : "TRADE2"), + : CStatusbarWindow(PLAYER_COLORED | BORDERED, ImagePath::builtin(isQuickExchangeLayoutAvailable() ? QUICK_EXCHANGE_BG : "TRADE2")), controller(this, hero1, hero2), moveStackLeftButtons(), moveStackRightButtons() @@ -850,10 +850,10 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, titles[0] = std::make_shared(147, 25, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, genTitle(heroInst[0])); titles[1] = std::make_shared(653, 25, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, genTitle(heroInst[1])); - auto PSKIL32 = std::make_shared("PSKIL32"); + auto PSKIL32 = std::make_shared(AnimationPath::builtin("PSKIL32")); PSKIL32->preload(); - auto SECSK32 = std::make_shared("SECSK32"); + auto SECSK32 = std::make_shared(AnimationPath::builtin("SECSK32")); for(int g = 0; g < 4; ++g) { @@ -874,7 +874,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, for(int m=0; m < hero->secSkills.size(); ++m) secSkillIcons[leftRight].push_back(std::make_shared(SECSK32, 0, 0, 32 + 36 * m + 454 * leftRight, qeLayout ? 83 : 88)); - specImages[leftRight] = std::make_shared("UN32", hero->type->imageIndex, 0, 67 + 490 * leftRight, qeLayout ? 41 : 45); + specImages[leftRight] = std::make_shared(AnimationPath::builtin("UN32"), hero->type->imageIndex, 0, 67 + 490 * leftRight, qeLayout ? 41 : 45); expImages[leftRight] = std::make_shared(PSKIL32, 4, 0, 103 + 490 * leftRight, qeLayout ? 41 : 45); expValues[leftRight] = std::make_shared(119 + 490 * leftRight, qeLayout ? 66 : 71, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); @@ -883,8 +883,8 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, manaValues[leftRight] = std::make_shared(155 + 490 * leftRight, qeLayout ? 66 : 71, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); } - portraits[0] = std::make_shared("PortraitsLarge", heroInst[0]->portrait, 0, 257, 13); - portraits[1] = std::make_shared("PortraitsLarge", heroInst[1]->portrait, 0, 485, 13); + portraits[0] = std::make_shared(AnimationPath::builtin("PortraitsLarge"), heroInst[0]->portrait, 0, 257, 13); + portraits[1] = std::make_shared(AnimationPath::builtin("PortraitsLarge"), heroInst[1]->portrait, 0, 485, 13); artifs[0] = std::make_shared(Point(-334, 150)); artifs[0]->setHero(heroInst[0]); @@ -959,12 +959,12 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, luck[b] = std::make_shared(false, Rect(Point(212 + 490 * b, 39), Point(32, 32)), true); } - quit = std::make_shared(Point(732, 567), "IOKAY.DEF", CGI->generaltexth->zelp[600], std::bind(&CExchangeWindow::close, this), EShortcut::GLOBAL_ACCEPT); + quit = std::make_shared(Point(732, 567), AnimationPath::builtin("IOKAY.DEF"), CGI->generaltexth->zelp[600], std::bind(&CExchangeWindow::close, this), EShortcut::GLOBAL_ACCEPT); if(queryID.getNum() > 0) quit->addCallback([=](){ LOCPLINT->cb->selectionMade(0, queryID); }); - questlogButton[0] = std::make_shared(Point( 10, qeLayout ? 39 : 44), "hsbtns4.def", CButton::tooltip(CGI->generaltexth->heroscrn[0]), std::bind(&CExchangeWindow::questlog, this, 0)); - questlogButton[1] = std::make_shared(Point(740, qeLayout ? 39 : 44), "hsbtns4.def", CButton::tooltip(CGI->generaltexth->heroscrn[0]), std::bind(&CExchangeWindow::questlog, this, 1)); + questlogButton[0] = std::make_shared(Point( 10, qeLayout ? 39 : 44), AnimationPath::builtin("hsbtns4.def"), CButton::tooltip(CGI->generaltexth->heroscrn[0]), std::bind(&CExchangeWindow::questlog, this, 0)); + questlogButton[1] = std::make_shared(Point(740, qeLayout ? 39 : 44), AnimationPath::builtin("hsbtns4.def"), CButton::tooltip(CGI->generaltexth->heroscrn[0]), std::bind(&CExchangeWindow::questlog, this, 1)); Rect barRect(5, 578, 725, 18); statusbar = CGStatusBar::create(std::make_shared(background->getSurface(), barRect, 5, 578)); @@ -973,31 +973,31 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, garr = std::make_shared(Point(69, qeLayout ? 122 : 131), 4, Point(418,0), heroInst[0], heroInst[1], true, true); auto splitButtonCallback = [&](){ garr->splitClick(); }; - garr->addSplitBtn(std::make_shared( Point( 10, qeLayout ? 122 : 132), "TSBTNS.DEF", CButton::tooltip(CGI->generaltexth->tcommands[3]), splitButtonCallback)); - garr->addSplitBtn(std::make_shared( Point(744, qeLayout ? 122 : 132), "TSBTNS.DEF", CButton::tooltip(CGI->generaltexth->tcommands[3]), splitButtonCallback)); + garr->addSplitBtn(std::make_shared( Point( 10, qeLayout ? 122 : 132), AnimationPath::builtin("TSBTNS.DEF"), CButton::tooltip(CGI->generaltexth->tcommands[3]), splitButtonCallback)); + garr->addSplitBtn(std::make_shared( Point(744, qeLayout ? 122 : 132), AnimationPath::builtin("TSBTNS.DEF"), CButton::tooltip(CGI->generaltexth->tcommands[3]), splitButtonCallback)); if(qeLayout) { - moveAllGarrButtonLeft = std::make_shared(Point(325, 118), QUICK_EXCHANGE_MOD_PREFIX + "/armRight.DEF", CButton::tooltip(CGI->generaltexth->qeModCommands[1]), controller.onMoveArmyToRight()); - echangeGarrButton = std::make_shared(Point(377, 118), QUICK_EXCHANGE_MOD_PREFIX + "/swapAll.DEF", CButton::tooltip(CGI->generaltexth->qeModCommands[2]), controller.onSwapArmy()); - moveAllGarrButtonRight = std::make_shared(Point(425, 118), QUICK_EXCHANGE_MOD_PREFIX + "/armLeft.DEF", CButton::tooltip(CGI->generaltexth->qeModCommands[1]), controller.onMoveArmyToLeft()); - moveArtifactsButtonLeft = std::make_shared(Point(325, 154), QUICK_EXCHANGE_MOD_PREFIX + "/artRight.DEF", CButton::tooltip(CGI->generaltexth->qeModCommands[3]), controller.onMoveArtifactsToRight()); - echangeArtifactsButton = std::make_shared(Point(377, 154), QUICK_EXCHANGE_MOD_PREFIX + "/swapAll.DEF", CButton::tooltip(CGI->generaltexth->qeModCommands[4]), controller.onSwapArtifacts()); - moveArtifactsButtonRight = std::make_shared(Point(425, 154), QUICK_EXCHANGE_MOD_PREFIX + "/artLeft.DEF", CButton::tooltip(CGI->generaltexth->qeModCommands[3]), controller.onMoveArtifactsToLeft()); + moveAllGarrButtonLeft = std::make_shared(Point(325, 118), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/armRight.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[1]), controller.onMoveArmyToRight()); + echangeGarrButton = std::make_shared(Point(377, 118), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/swapAll.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[2]), controller.onSwapArmy()); + moveAllGarrButtonRight = std::make_shared(Point(425, 118), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/armLeft.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[1]), controller.onMoveArmyToLeft()); + moveArtifactsButtonLeft = std::make_shared(Point(325, 154), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/artRight.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[3]), controller.onMoveArtifactsToRight()); + echangeArtifactsButton = std::make_shared(Point(377, 154), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/swapAll.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[4]), controller.onSwapArtifacts()); + moveArtifactsButtonRight = std::make_shared(Point(425, 154), AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/artLeft.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[3]), controller.onMoveArtifactsToLeft()); for(int i = 0; i < GameConstants::ARMY_SIZE; i++) { moveStackLeftButtons.push_back( std::make_shared( Point(484 + 35 * i, 154), - QUICK_EXCHANGE_MOD_PREFIX + "/unitLeft.DEF", + AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/unitLeft.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[1]), controller.onMoveStackToLeft(SlotID(i)))); moveStackRightButtons.push_back( std::make_shared( Point(66 + 35 * i, 154), - QUICK_EXCHANGE_MOD_PREFIX + "/unitRight.DEF", + AnimationPath::builtin(QUICK_EXCHANGE_MOD_PREFIX + "/unitRight.DEF"), CButton::tooltip(CGI->generaltexth->qeModCommands[1]), controller.onMoveStackToRight(SlotID(i)))); } @@ -1053,11 +1053,11 @@ void CExchangeWindow::updateWidgets() } CShipyardWindow::CShipyardWindow(const TResources & cost, int state, BoatId boatType, const std::function & onBuy) - : CStatusbarWindow(PLAYER_COLORED, "TPSHIP") + : CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("TPSHIP")) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - bgWater = std::make_shared("TPSHIPBK", 100, 69); + bgWater = std::make_shared(ImagePath::builtin("TPSHIPBK"), 100, 69); auto handler = CGI->objtypeh->getHandlerFor(Obj::BOAT, boatType); @@ -1067,7 +1067,7 @@ CShipyardWindow::CShipyardWindow(const TResources & cost, int state, BoatId boat if (boatConstructor) { - std::string boatFilename = boatConstructor->getBoatAnimationName(); + AnimationPath boatFilename = boatConstructor->getBoatAnimationName(); Point waterCenter = Point(bgWater->pos.x+bgWater->pos.w/2, bgWater->pos.y+bgWater->pos.h/2); bgShip = std::make_shared(boatFilename, 0, 7, 120, 96, 0); @@ -1081,11 +1081,11 @@ CShipyardWindow::CShipyardWindow(const TResources & cost, int state, BoatId boat goldCost = std::make_shared(118, 294, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, goldValue); woodCost = std::make_shared(212, 294, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, woodValue); - goldPic = std::make_shared("RESOURCE",GameResID(EGameResID::GOLD), 0, 100, 244); - woodPic = std::make_shared("RESOURCE", GameResID(EGameResID::WOOD), 0, 196, 244); + goldPic = std::make_shared(AnimationPath::builtin("RESOURCE"), GameResID(EGameResID::GOLD), 0, 100, 244); + woodPic = std::make_shared(AnimationPath::builtin("RESOURCE"), GameResID(EGameResID::WOOD), 0, 196, 244); - quit = std::make_shared(Point(224, 312), "ICANCEL", CButton::tooltip(CGI->generaltexth->allTexts[599]), std::bind(&CShipyardWindow::close, this), EShortcut::GLOBAL_CANCEL); - build = std::make_shared(Point(42, 312), "IBUY30", CButton::tooltip(CGI->generaltexth->allTexts[598]), std::bind(&CShipyardWindow::close, this), EShortcut::GLOBAL_ACCEPT); + quit = std::make_shared(Point(224, 312), AnimationPath::builtin("ICANCEL"), CButton::tooltip(CGI->generaltexth->allTexts[599]), std::bind(&CShipyardWindow::close, this), EShortcut::GLOBAL_CANCEL); + build = std::make_shared(Point(42, 312), AnimationPath::builtin("IBUY30"), CButton::tooltip(CGI->generaltexth->allTexts[598]), std::bind(&CShipyardWindow::close, this), EShortcut::GLOBAL_ACCEPT); build->addCallback(onBuy); for(GameResID i = EGameResID::WOOD; i <= EGameResID::GOLD; ++i) @@ -1136,7 +1136,7 @@ CTransformerWindow::CItem::CItem(CTransformerWindow * parent_, int size_, int id pos.x += 45 + (id%3)*83 + id/6*83; pos.y += 109 + (id/3)*98; - icon = std::make_shared("TWCRPORT", parent->army->getCreature(SlotID(id))->getId() + 2); + icon = std::make_shared(AnimationPath::builtin("TWCRPORT"), parent->army->getCreature(SlotID(id))->getId() + 2); count = std::make_shared(28, 76,FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, std::to_string(size)); } @@ -1166,7 +1166,7 @@ void CTransformerWindow::updateGarrisons() } CTransformerWindow::CTransformerWindow(const IMarket * _market, const CGHeroInstance * _hero) - : CStatusbarWindow(PLAYER_COLORED, "SKTRNBK"), + : CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("SKTRNBK")), hero(_hero), market(_market) { @@ -1185,9 +1185,9 @@ CTransformerWindow::CTransformerWindow(const IMarket * _market, const CGHeroInst } } - all = std::make_shared(Point(146, 416), "ALTARMY.DEF", CGI->generaltexth->zelp[590], [&](){ addAll(); }, EShortcut::RECRUITMENT_UPGRADE_ALL); - convert = std::make_shared(Point(269, 416), "ALTSACR.DEF", CGI->generaltexth->zelp[591], [&](){ makeDeal(); }, EShortcut::GLOBAL_ACCEPT); - cancel = std::make_shared(Point(392, 416), "ICANCEL.DEF", CGI->generaltexth->zelp[592], [&](){ close(); },EShortcut::GLOBAL_CANCEL); + all = std::make_shared(Point(146, 416), AnimationPath::builtin("ALTARMY.DEF"), CGI->generaltexth->zelp[590], [&](){ addAll(); }, EShortcut::RECRUITMENT_UPGRADE_ALL); + convert = std::make_shared(Point(269, 416), AnimationPath::builtin("ALTSACR.DEF"), CGI->generaltexth->zelp[591], [&](){ makeDeal(); }, EShortcut::GLOBAL_ACCEPT); + cancel = std::make_shared(Point(392, 416), AnimationPath::builtin("ICANCEL.DEF"), CGI->generaltexth->zelp[592], [&](){ close(); },EShortcut::GLOBAL_CANCEL); statusbar = CGStatusBar::create(std::make_shared(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); titleLeft = std::make_shared(153, 29,FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[485]);//holding area @@ -1208,7 +1208,7 @@ CUniversityWindow::CItem::CItem(CUniversityWindow * _parent, int _ID, int X, int topBar = std::make_shared(parent->bars, 0, 0, -28, -22); bottomBar = std::make_shared(parent->bars, 0, 0, -28, 48); - icon = std::make_shared("SECSKILL", _ID * 3 + 3, 0); + icon = std::make_shared(AnimationPath::builtin("SECSKILL"), _ID * 3 + 3, 0); name = std::make_shared(22, -13, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->skillh->getByIndex(ID)->getNameTranslated()); level = std::make_shared(22, 57, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->levels[0]); @@ -1256,7 +1256,7 @@ void CUniversityWindow::CItem::showAll(Canvas & to) } CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket * _market) - : CStatusbarWindow(PLAYER_COLORED, "UNIVERS1"), + : CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("UNIVERS1")), hero(_hero), market(_market) { @@ -1285,7 +1285,7 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket } else { - titlePic = std::make_shared("UNIVBLDG"); + titlePic = std::make_shared(ImagePath::builtin("UNIVBLDG")); } titlePic->center(Point(232 + pos.x, 76 + pos.y)); @@ -1298,7 +1298,7 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket for(int i=0; i(this, goods[i], 54+i*104, 234)); - cancel = std::make_shared(Point(200, 313), "IOKAY.DEF", CGI->generaltexth->zelp[632], [&](){ close(); }, EShortcut::GLOBAL_ACCEPT); + cancel = std::make_shared(Point(200, 313), AnimationPath::builtin("IOKAY.DEF"), CGI->generaltexth->zelp[632], [&](){ close(); }, EShortcut::GLOBAL_ACCEPT); statusbar = CGStatusBar::create(std::make_shared(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); } @@ -1309,7 +1309,7 @@ void CUniversityWindow::makeDeal(int skill) CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, int SKILL, bool available) - : CStatusbarWindow(PLAYER_COLORED, "UNIVERS2.PCX"), + : CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("UNIVERS2.PCX")), owner(owner_) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -1322,10 +1322,10 @@ CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, int SKILL, bo clerkSpeech = std::make_shared(text, Rect(24, 129, 413, 70), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE); name = std::make_shared(230, 37, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->skillh->getByIndex(SKILL)->getNameTranslated()); - icon = std::make_shared("SECSKILL", SKILL*3+3, 0, 211, 51); + icon = std::make_shared(AnimationPath::builtin("SECSKILL"), SKILL*3+3, 0, 211, 51); level = std::make_shared(230, 107, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->levels[1]); - costIcon = std::make_shared("RESOURCE", GameResID(EGameResID::GOLD), 0, 210, 210); + costIcon = std::make_shared(AnimationPath::builtin("RESOURCE"), GameResID(EGameResID::GOLD), 0, 210, 210); cost = std::make_shared(230, 267, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, "2000"); std::string hoverText = CGI->generaltexth->allTexts[609]; @@ -1336,10 +1336,10 @@ CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, int SKILL, bo boost::replace_first(text, "%s", CGI->skillh->getByIndex(SKILL)->getNameTranslated()); boost::replace_first(text, "%d", "2000"); - confirm = std::make_shared(Point(148, 299), "IBY6432.DEF", CButton::tooltip(hoverText, text), [=](){makeDeal(SKILL);}, EShortcut::GLOBAL_ACCEPT); + confirm = std::make_shared(Point(148, 299), AnimationPath::builtin("IBY6432.DEF"), CButton::tooltip(hoverText, text), [=](){makeDeal(SKILL);}, EShortcut::GLOBAL_ACCEPT); confirm->block(!available); - cancel = std::make_shared(Point(252,299), "ICANCEL.DEF", CGI->generaltexth->zelp[631], [&](){ close(); }, EShortcut::GLOBAL_CANCEL); + cancel = std::make_shared(Point(252,299), AnimationPath::builtin("ICANCEL.DEF"), CGI->generaltexth->zelp[631], [&](){ close(); }, EShortcut::GLOBAL_CANCEL); statusbar = CGStatusBar::create(std::make_shared(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); } @@ -1350,16 +1350,16 @@ void CUnivConfirmWindow::makeDeal(int skill) } CGarrisonWindow::CGarrisonWindow(const CArmedInstance * up, const CGHeroInstance * down, bool removableUnits) - : CWindowObject(PLAYER_COLORED, "GARRISON") + : CWindowObject(PLAYER_COLORED, ImagePath::builtin("GARRISON")) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); garr = std::make_shared(Point(92, 127), 4, Point(0,96), up, down, removableUnits); { - auto split = std::make_shared(Point(88, 314), "IDV6432.DEF", CButton::tooltip(CGI->generaltexth->tcommands[3], ""), [&](){ garr->splitClick(); } ); + auto split = std::make_shared(Point(88, 314), AnimationPath::builtin("IDV6432.DEF"), CButton::tooltip(CGI->generaltexth->tcommands[3], ""), [&](){ garr->splitClick(); } ); garr->addSplitBtn(split); } - quit = std::make_shared(Point(399, 314), "IOK6432.DEF", CButton::tooltip(CGI->generaltexth->tcommands[8], ""), [&](){ close(); }, EShortcut::GLOBAL_ACCEPT); + quit = std::make_shared(Point(399, 314), AnimationPath::builtin("IOK6432.DEF"), CButton::tooltip(CGI->generaltexth->tcommands[8], ""), [&](){ close(); }, EShortcut::GLOBAL_ACCEPT); std::string titleText; if(down->tempOwner == up->tempOwner) @@ -1381,8 +1381,8 @@ CGarrisonWindow::CGarrisonWindow(const CArmedInstance * up, const CGHeroInstance } title = std::make_shared(275, 30, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, titleText); - banner = std::make_shared("CREST58", up->getOwner().getNum(), 0, 28, 124); - portrait = std::make_shared("PortraitsLarge", down->portrait, 0, 29, 222); + banner = std::make_shared(AnimationPath::builtin("CREST58"), up->getOwner().getNum(), 0, 28, 124); + portrait = std::make_shared(AnimationPath::builtin("PortraitsLarge"), down->portrait, 0, 29, 222); } void CGarrisonWindow::updateGarrisons() @@ -1391,7 +1391,7 @@ void CGarrisonWindow::updateGarrisons() } CHillFortWindow::CHillFortWindow(const CGHeroInstance * visitor, const CGObjectInstance * object) - : CStatusbarWindow(PLAYER_COLORED, "APHLFTBK"), + : CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("APHLFTBK")), fort(object), hero(visitor) { @@ -1403,28 +1403,28 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance * visitor, const CGObjectI for(int i=0; i < resCount; i++) { - totalIcons[i] = std::make_shared("SMALRES", i, 0, 104 + 76 * i, 237); + totalIcons[i] = std::make_shared(AnimationPath::builtin("SMALRES"), i, 0, 104 + 76 * i, 237); totalLabels[i] = std::make_shared(166 + 76 * i, 253, FONT_SMALL, ETextAlignment::BOTTOMRIGHT); } for(int i = 0; i < slotsCount; i++) { - upgrade[i] = std::make_shared(Point(107 + i * 76, 171), "", CButton::tooltip(getTextForSlot(SlotID(i))), [=](){ makeDeal(SlotID(i)); }, vstd::next(EShortcut::SELECT_INDEX_1, i)); + upgrade[i] = std::make_shared(Point(107 + i * 76, 171), AnimationPath(), CButton::tooltip(getTextForSlot(SlotID(i))), [=](){ makeDeal(SlotID(i)); }, vstd::next(EShortcut::SELECT_INDEX_1, i)); for(auto image : { "APHLF1R.DEF", "APHLF1Y.DEF", "APHLF1G.DEF" }) - upgrade[i]->addImage(image); + upgrade[i]->addImage(AnimationPath::builtin(image)); for(int j : {0,1}) { - slotIcons[i][j] = std::make_shared("SMALRES", 0, 0, 104 + 76 * i, 128 + 20 * j); + slotIcons[i][j] = std::make_shared(AnimationPath::builtin("SMALRES"), 0, 0, 104 + 76 * i, 128 + 20 * j); slotLabels[i][j] = std::make_shared(168 + 76 * i, 144 + 20 * j, FONT_SMALL, ETextAlignment::BOTTOMRIGHT); } } - upgradeAll = std::make_shared(Point(30, 231), "", CButton::tooltip(CGI->generaltexth->allTexts[432]), [&](){ makeDeal(SlotID(slotsCount));}, EShortcut::RECRUITMENT_UPGRADE_ALL); + upgradeAll = std::make_shared(Point(30, 231), AnimationPath(), CButton::tooltip(CGI->generaltexth->allTexts[432]), [&](){ makeDeal(SlotID(slotsCount));}, EShortcut::RECRUITMENT_UPGRADE_ALL); for(auto image : { "APHLF4R.DEF", "APHLF4Y.DEF", "APHLF4G.DEF" }) - upgradeAll->addImage(image); + upgradeAll->addImage(AnimationPath::builtin(image)); - quit = std::make_shared(Point(294, 275), "IOKAY.DEF", CButton::tooltip(), std::bind(&CHillFortWindow::close, this), EShortcut::GLOBAL_ACCEPT); + quit = std::make_shared(Point(294, 275), AnimationPath::builtin("IOKAY.DEF"), CButton::tooltip(), std::bind(&CHillFortWindow::close, this), EShortcut::GLOBAL_ACCEPT); statusbar = CGStatusBar::create(std::make_shared(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26)); garr = std::make_shared(Point(108, 60), 18, Point(), hero, nullptr); @@ -1591,7 +1591,7 @@ int CHillFortWindow::getState(SlotID slot) } CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner): - CStatusbarWindow(PLAYER_COLORED | BORDERED, "TpRank"), + CStatusbarWindow(PLAYER_COLORED | BORDERED, ImagePath::builtin("TpRank")), owner(_owner) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -1599,8 +1599,8 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner): SThievesGuildInfo tgi; //info to be displayed LOCPLINT->cb->getThievesGuildInfo(tgi, owner); - exitb = std::make_shared(Point(748, 556), "TPMAGE1", CButton::tooltip(CGI->generaltexth->allTexts[600]), [&](){ close();}, EShortcut::GLOBAL_RETURN); - statusbar = CGStatusBar::create(3, 555, "TStatBar.bmp", 742); + exitb = std::make_shared(Point(748, 556), AnimationPath::builtin("TPMAGE1"), CButton::tooltip(CGI->generaltexth->allTexts[600]), [&](){ close();}, EShortcut::GLOBAL_RETURN); + statusbar = CGStatusBar::create(3, 555, ImagePath::builtin("TStatBar.bmp"), 742); resdatabar = std::make_shared(); resdatabar->moveBy(pos.topLeft(), true); @@ -1626,7 +1626,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner): rowHeaders.push_back(std::make_shared(135, y, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, text)); } - auto PRSTRIPS = std::make_shared("PRSTRIPS"); + auto PRSTRIPS = std::make_shared(AnimationPath::builtin("PRSTRIPS")); PRSTRIPS->preload(); for(int g=1; g(283 + 66*g, 24, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[16+g])); - auto itgflags = std::make_shared("itgflags"); + auto itgflags = std::make_shared(AnimationPath::builtin("itgflags")); itgflags->preload(); //printing flags @@ -1672,10 +1672,10 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner): int counter = 0; for(auto & iter : tgi.colorToBestHero) { - banners.push_back(std::make_shared(colorToBox[iter.first.getNum()], 253 + 66 * counter, 334)); + banners.push_back(std::make_shared(ImagePath::builtin(colorToBox[iter.first.getNum()]), 253 + 66 * counter, 334)); if(iter.second.portrait >= 0) { - bestHeroes.push_back(std::make_shared("PortraitsSmall", iter.second.portrait, 0, 260 + 66 * counter, 360)); + bestHeroes.push_back(std::make_shared(AnimationPath::builtin("PortraitsSmall"), iter.second.portrait, 0, 260 + 66 * counter, 360)); //TODO: r-click info: // - r-click on hero // - r-click on primary skill label @@ -1699,7 +1699,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner): for(auto & it : tgi.bestCreature) { if(it.second >= 0) - bestCreatures.push_back(std::make_shared("TWCRPORT", it.second+2, 0, 255 + 66 * counter, 479)); + bestCreatures.push_back(std::make_shared(AnimationPath::builtin("TWCRPORT"), it.second+2, 0, 255 + 66 * counter, 479)); counter++; } @@ -1729,7 +1729,7 @@ CObjectListWindow::CItem::CItem(CObjectListWindow * _parent, size_t _id, std::st index(_id) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - border = std::make_shared("TPGATES"); + border = std::make_shared(ImagePath::builtin("TPGATES")); pos = border->pos; setRedrawParent(true); @@ -1759,7 +1759,7 @@ void CObjectListWindow::CItem::clickDouble(const Point & cursorPosition) } CObjectListWindow::CObjectListWindow(const std::vector & _items, std::shared_ptr titleWidget_, std::string _title, std::string _descr, std::function Callback, size_t initialSelection) - : CWindowObject(PLAYER_COLORED, "TPGATE"), + : CWindowObject(PLAYER_COLORED, ImagePath::builtin("TPGATE")), onSelect(Callback), selected(initialSelection) { @@ -1775,7 +1775,7 @@ CObjectListWindow::CObjectListWindow(const std::vector & _items, std::share } CObjectListWindow::CObjectListWindow(const std::vector & _items, std::shared_ptr titleWidget_, std::string _title, std::string _descr, std::function Callback, size_t initialSelection) - : CWindowObject(PLAYER_COLORED, "TPGATE"), + : CWindowObject(PLAYER_COLORED, ImagePath::builtin("TPGATE")), onSelect(Callback), selected(initialSelection) { @@ -1794,7 +1794,7 @@ void CObjectListWindow::init(std::shared_ptr titleWidget_, std::stri title = std::make_shared(152, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, _title); descr = std::make_shared(145, 133, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, _descr); - exit = std::make_shared( Point(228, 402), "ICANCEL.DEF", CButton::tooltip(), std::bind(&CObjectListWindow::exitPressed, this), EShortcut::GLOBAL_CANCEL); + exit = std::make_shared( Point(228, 402), AnimationPath::builtin("ICANCEL.DEF"), CButton::tooltip(), std::bind(&CObjectListWindow::exitPressed, this), EShortcut::GLOBAL_CANCEL); if(titleWidget) { @@ -1807,7 +1807,7 @@ void CObjectListWindow::init(std::shared_ptr titleWidget_, std::stri Point(14, 151), Point(0, 25), 9, items.size(), 0, 1, Rect(262, -32, 256, 256) ); list->setRedrawParent(true); - ok = std::make_shared(Point(15, 402), "IOKAY.DEF", CButton::tooltip(), std::bind(&CObjectListWindow::elementSelected, this), EShortcut::GLOBAL_ACCEPT); + ok = std::make_shared(Point(15, 402), AnimationPath::builtin("IOKAY.DEF"), CButton::tooltip(), std::bind(&CObjectListWindow::elementSelected, this), EShortcut::GLOBAL_ACCEPT); ok->block(!list->size()); } diff --git a/client/windows/InfoWindows.cpp b/client/windows/InfoWindows.cpp index 4b9a541bb..d9d09e27a 100644 --- a/client/windows/InfoWindows.cpp +++ b/client/windows/InfoWindows.cpp @@ -68,7 +68,7 @@ void CSelWindow::selectionChange(unsigned to) redraw(); } -CSelWindow::CSelWindow(const std::string &Text, PlayerColor player, int charperline, const std::vector> & comps, const std::vector > > &Buttons, QueryID askID) +CSelWindow::CSelWindow(const std::string &Text, PlayerColor player, int charperline, const std::vector> & comps, const std::vector > > &Buttons, QueryID askID) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); ID = askID; @@ -199,9 +199,9 @@ void CInfoWindow::showInfoDialog(const std::string &text, const TCompsInfo & com void CInfoWindow::showYesNoDialog(const std::string & text, const TCompsInfo & components, const CFunctionList &onYes, const CFunctionList &onNo, PlayerColor player) { assert(!LOCPLINT || LOCPLINT->showingDialog->get()); - std::vector > > pom; - pom.push_back(std::pair >("IOKAY.DEF",0)); - pom.push_back(std::pair >("ICANCEL.DEF",0)); + std::vector > > pom; + pom.push_back( { AnimationPath::builtin("IOKAY.DEF"), 0 }); + pom.push_back( { AnimationPath::builtin("ICANCEL.DEF"), 0 }); std::shared_ptr temp = std::make_shared(text, player, components, pom); temp->buttons[0]->addCallback( onYes ); @@ -212,8 +212,8 @@ void CInfoWindow::showYesNoDialog(const std::string & text, const TCompsInfo & c std::shared_ptr CInfoWindow::create(const std::string &text, PlayerColor playerID, const TCompsInfo & components) { - std::vector > > pom; - pom.push_back(std::pair >("IOKAY.DEF",0)); + std::vector > > pom; + pom.push_back({AnimationPath::builtin("IOKAY.DEF"), 0}); return std::make_shared(text, playerID, components, pom); } @@ -372,7 +372,7 @@ Point CInfoBoxPopup::toScreen(Point p) } CInfoBoxPopup::CInfoBoxPopup(Point position, const CGTownInstance * town) - : CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "TOWNQVBK", toScreen(position)) + : CWindowObject(RCLICK_POPUP | PLAYER_COLORED, ImagePath::builtin("TOWNQVBK"), toScreen(position)) { InfoAboutTown iah; LOCPLINT->cb->getTownInfo(town, iah, LOCPLINT->localState->getCurrentTown()); //todo: should this be nearest hero? @@ -382,7 +382,7 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGTownInstance * town) } CInfoBoxPopup::CInfoBoxPopup(Point position, const CGHeroInstance * hero) - : CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "HEROQVBK", toScreen(position)) + : CWindowObject(RCLICK_POPUP | PLAYER_COLORED, ImagePath::builtin("HEROQVBK"), toScreen(position)) { InfoAboutHero iah; LOCPLINT->cb->getHeroInfo(hero, iah, LOCPLINT->localState->getCurrentHero());//todo: should this be nearest hero? @@ -392,7 +392,7 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGHeroInstance * hero) } CInfoBoxPopup::CInfoBoxPopup(Point position, const CGGarrison * garr) - : CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "TOWNQVBK", toScreen(position)) + : CWindowObject(RCLICK_POPUP | PLAYER_COLORED, ImagePath::builtin("TOWNQVBK"), toScreen(position)) { InfoAboutTown iah; LOCPLINT->cb->getTownInfo(garr, iah); diff --git a/client/windows/InfoWindows.h b/client/windows/InfoWindows.h index e7911884a..707bc0505 100644 --- a/client/windows/InfoWindows.h +++ b/client/windows/InfoWindows.h @@ -48,7 +48,7 @@ public: class CInfoWindow : public CSimpleWindow { public: - using TButtonsInfo = std::vector>>; + using TButtonsInfo = std::vector>>; using TCompsInfo = std::vector>; QueryID ID; //for identification std::shared_ptr text; @@ -128,7 +128,7 @@ class CSelWindow : public CInfoWindow public: void selectionChange(unsigned to); void madeChoice(); //looks for selected component and calls callback - CSelWindow(const std::string & text, PlayerColor player, int charperline, const std::vector> & comps, const std::vector > > &Buttons, QueryID askID); + CSelWindow(const std::string & text, PlayerColor player, int charperline, const std::vector> & comps, const std::vector > > &Buttons, QueryID askID); //notification - this class inherits important destructor from CInfoWindow }; diff --git a/client/windows/QuickRecruitmentWindow.cpp b/client/windows/QuickRecruitmentWindow.cpp index f2c718018..ae976282b 100644 --- a/client/windows/QuickRecruitmentWindow.cpp +++ b/client/windows/QuickRecruitmentWindow.cpp @@ -31,19 +31,19 @@ void QuickRecruitmentWindow::setButtons() void QuickRecruitmentWindow::setCancelButton() { - cancelButton = std::make_shared(Point((pos.w / 2) + 48, 418), "ICN6432.DEF", CButton::tooltip(), [&](){ close(); }, EShortcut::GLOBAL_CANCEL); + cancelButton = std::make_shared(Point((pos.w / 2) + 48, 418), AnimationPath::builtin("ICN6432.DEF"), CButton::tooltip(), [&](){ close(); }, EShortcut::GLOBAL_CANCEL); cancelButton->setImageOrder(0, 1, 2, 3); } void QuickRecruitmentWindow::setBuyButton() { - buyButton = std::make_shared(Point((pos.w / 2) - 32, 418), "IBY6432.DEF", CButton::tooltip(), [&](){ purchaseUnits(); }, EShortcut::GLOBAL_ACCEPT); + buyButton = std::make_shared(Point((pos.w / 2) - 32, 418), AnimationPath::builtin("IBY6432.DEF"), CButton::tooltip(), [&](){ purchaseUnits(); }, EShortcut::GLOBAL_ACCEPT); buyButton->setImageOrder(0, 1, 2, 3); } void QuickRecruitmentWindow::setMaxButton() { - maxButton = std::make_shared(Point((pos.w/2)-112, 418), "IRCBTNS.DEF", CButton::tooltip(), [&](){ maxAllCards(cards); }, EShortcut::RECRUITMENT_MAX); + maxButton = std::make_shared(Point((pos.w/2)-112, 418), AnimationPath::builtin("IRCBTNS.DEF"), CButton::tooltip(), [&](){ maxAllCards(cards); }, EShortcut::RECRUITMENT_MAX); maxButton->setImageOrder(0, 1, 2, 3); } @@ -74,8 +74,8 @@ void QuickRecruitmentWindow::initWindow(Rect startupPosition) pos.w += 108 * (creaturesAmount - 3); pos.x -= 55 * (creaturesAmount - 3); } - backgroundTexture = std::make_shared("DIBOXBCK.pcx", Rect(0, 0, pos.w, pos.h)); - costBackground = std::make_shared("QuickRecruitmentWindow/costBackground.png", pos.w/2-113, 335); + backgroundTexture = std::make_shared(ImagePath::builtin("DIBOXBCK.pcx"), Rect(0, 0, pos.w, pos.h)); + costBackground = std::make_shared(ImagePath::builtin("QuickRecruitmentWindow/costBackground.png"), pos.w/2-113, 335); } void QuickRecruitmentWindow::maxAllCards(std::vector > cards) diff --git a/client/windows/settings/AdventureOptionsTab.cpp b/client/windows/settings/AdventureOptionsTab.cpp index 499858037..d48b8dcc1 100644 --- a/client/windows/settings/AdventureOptionsTab.cpp +++ b/client/windows/settings/AdventureOptionsTab.cpp @@ -11,7 +11,7 @@ #include "AdventureOptionsTab.h" -#include "../../../lib/filesystem/ResourceID.h" +#include "../../../lib/filesystem/ResourcePath.h" #include "../../gui/CGuiHandler.h" #include "../../widgets/Buttons.h" #include "../../widgets/TextControls.h" @@ -44,7 +44,7 @@ AdventureOptionsTab::AdventureOptionsTab() addConditional("desktop", true); #endif - const JsonNode config(ResourceID("config/widgets/settings/adventureOptionsTab.json")); + const JsonNode config(ResourcePath("config/widgets/settings/adventureOptionsTab.json")); addCallback("playerHeroSpeedChanged", [this](int value) { auto targetLabel = widget("heroSpeedValueLabel"); diff --git a/client/windows/settings/BattleOptionsTab.cpp b/client/windows/settings/BattleOptionsTab.cpp index 1e657d61c..0b95198bd 100644 --- a/client/windows/settings/BattleOptionsTab.cpp +++ b/client/windows/settings/BattleOptionsTab.cpp @@ -13,7 +13,7 @@ #include "../../battle/BattleInterface.h" #include "../../gui/CGuiHandler.h" #include "../../../lib/CConfigHandler.h" -#include "../../../lib/filesystem/ResourceID.h" +#include "../../../lib/filesystem/ResourcePath.h" #include "../../../lib/CGeneralTextHandler.h" #include "../../widgets/Buttons.h" #include "../../widgets/TextControls.h" @@ -23,7 +23,7 @@ BattleOptionsTab::BattleOptionsTab(BattleInterface * owner) OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; setRedrawParent(true); - const JsonNode config(ResourceID("config/widgets/settings/battleOptionsTab.json")); + const JsonNode config(ResourcePath("config/widgets/settings/battleOptionsTab.json")); addCallback("viewGridChanged", [this, owner](bool value) { viewGridChangedCallback(value, owner); diff --git a/client/windows/settings/GeneralOptionsTab.cpp b/client/windows/settings/GeneralOptionsTab.cpp index ae747f90e..6ed20cabf 100644 --- a/client/windows/settings/GeneralOptionsTab.cpp +++ b/client/windows/settings/GeneralOptionsTab.cpp @@ -26,7 +26,7 @@ #include "../../widgets/TextControls.h" #include "../../../lib/CGeneralTextHandler.h" -#include "../../../lib/filesystem/ResourceID.h" +#include "../../../lib/filesystem/ResourcePath.h" static void setIntSetting(std::string group, std::string field, int value) { @@ -105,7 +105,7 @@ GeneralOptionsTab::GeneralOptionsTab() addConditional("desktop", true); #endif - const JsonNode config(ResourceID("config/widgets/settings/generalOptionsTab.json")); + const JsonNode config(ResourcePath("config/widgets/settings/generalOptionsTab.json")); addCallback("spellbookAnimationChanged", [](bool value) { setBoolSetting("video", "spellbookAnimation", value); diff --git a/client/windows/settings/OtherOptionsTab.cpp b/client/windows/settings/OtherOptionsTab.cpp index 90e288e07..aa5e5325a 100644 --- a/client/windows/settings/OtherOptionsTab.cpp +++ b/client/windows/settings/OtherOptionsTab.cpp @@ -11,7 +11,7 @@ #include "OtherOptionsTab.h" -#include "../../../lib/filesystem/ResourceID.h" +#include "../../../lib/filesystem/ResourcePath.h" #include "../../gui/CGuiHandler.h" #include "../../widgets/Buttons.h" #include "CConfigHandler.h" @@ -26,7 +26,7 @@ OtherOptionsTab::OtherOptionsTab() : InterfaceObjectConfigurable() { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - const JsonNode config(ResourceID("config/widgets/settings/otherOptionsTab.json")); + const JsonNode config(ResourcePath("config/widgets/settings/otherOptionsTab.json")); addCallback("availableCreaturesAsDwellingLabelChanged", [](bool value) { return setBoolSetting("gameTweaks", "availableCreaturesAsDwellingLabel", value); diff --git a/client/windows/settings/SettingsMainWindow.cpp b/client/windows/settings/SettingsMainWindow.cpp index c05592e7d..2dfa11577 100644 --- a/client/windows/settings/SettingsMainWindow.cpp +++ b/client/windows/settings/SettingsMainWindow.cpp @@ -21,7 +21,7 @@ #include "CGeneralTextHandler.h" #include "CPlayerInterface.h" #include "CServerHandler.h" -#include "filesystem/ResourceID.h" +#include "filesystem/ResourcePath.h" #include "gui/CGuiHandler.h" #include "gui/WindowHandler.h" #include "render/Canvas.h" @@ -35,7 +35,7 @@ SettingsMainWindow::SettingsMainWindow(BattleInterface * parentBattleUi) : Inter { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - const JsonNode config(ResourceID("config/widgets/settings/settingsMainContainer.json")); + const JsonNode config(ResourcePath("config/widgets/settings/settingsMainContainer.json")); addCallback("activateSettingsTab", [this](int tabId) { openTab(tabId); }); addCallback("loadGame", [this](int) { loadGameButtonCallback(); }); addCallback("saveGame", [this](int) { saveGameButtonCallback(); }); diff --git a/cmake_modules/VCMI_lib.cmake b/cmake_modules/VCMI_lib.cmake index ab2fbea2c..785979d74 100644 --- a/cmake_modules/VCMI_lib.cmake +++ b/cmake_modules/VCMI_lib.cmake @@ -64,7 +64,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) ${MAIN_LIB_DIR}/filesystem/FileInfo.cpp ${MAIN_LIB_DIR}/filesystem/Filesystem.cpp ${MAIN_LIB_DIR}/filesystem/MinizipExtensions.cpp - ${MAIN_LIB_DIR}/filesystem/ResourceID.cpp + ${MAIN_LIB_DIR}/filesystem/ResourcePath.cpp ${MAIN_LIB_DIR}/gameState/CGameState.cpp ${MAIN_LIB_DIR}/gameState/CGameStateCampaign.cpp @@ -401,7 +401,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) ${MAIN_LIB_DIR}/filesystem/Filesystem.h ${MAIN_LIB_DIR}/filesystem/ISimpleResourceLoader.h ${MAIN_LIB_DIR}/filesystem/MinizipExtensions.h - ${MAIN_LIB_DIR}/filesystem/ResourceID.h + ${MAIN_LIB_DIR}/filesystem/ResourcePath.h ${MAIN_LIB_DIR}/gameState/CGameState.h ${MAIN_LIB_DIR}/gameState/CGameStateCampaign.h diff --git a/launcher/firstLaunch/firstlaunch_moc.cpp b/launcher/firstLaunch/firstlaunch_moc.cpp index 8f1d43ecd..9748b3f27 100644 --- a/launcher/firstLaunch/firstlaunch_moc.cpp +++ b/launcher/firstLaunch/firstlaunch_moc.cpp @@ -230,8 +230,8 @@ bool FirstLaunchView::heroesDataDetect() CResourceHandler::load("config/filesystem.json"); // use file from lod archive to check presence of H3 data. Very rough estimate, but will work in majority of cases - bool heroesDataFoundROE = CResourceHandler::get()->existsResource(ResourceID("DATA/GENRLTXT.TXT")); - bool heroesDataFoundSOD = CResourceHandler::get()->existsResource(ResourceID("DATA/TENTCOLR.TXT")); + bool heroesDataFoundROE = CResourceHandler::get()->existsResource(ResourcePath("DATA/GENRLTXT.TXT")); + bool heroesDataFoundSOD = CResourceHandler::get()->existsResource(ResourcePath("DATA/TENTCOLR.TXT")); return heroesDataFoundROE && heroesDataFoundSOD; } diff --git a/launcher/mainwindow_moc.cpp b/launcher/mainwindow_moc.cpp index 99db438c9..6bb00171a 100644 --- a/launcher/mainwindow_moc.cpp +++ b/launcher/mainwindow_moc.cpp @@ -110,7 +110,7 @@ MainWindow::MainWindow(QWidget * parent) computeSidePanelSizes(); - bool h3DataFound = CResourceHandler::get()->existsResource(ResourceID("DATA/GENRLTXT.TXT")); + bool h3DataFound = CResourceHandler::get()->existsResource(ResourcePath("DATA/GENRLTXT.TXT")); if (h3DataFound && setupCompleted) ui->tabListWidget->setCurrentIndex(TabRows::MODS); diff --git a/launcher/modManager/cmodmanager.cpp b/launcher/modManager/cmodmanager.cpp index 27824b826..dc7144a14 100644 --- a/launcher/modManager/cmodmanager.cpp +++ b/launcher/modManager/cmodmanager.cpp @@ -84,7 +84,7 @@ void CModManager::loadMods() for(auto modname : installedMods) { - ResourceID resID(CModInfo::getModFile(modname)); + ResourcePath resID(CModInfo::getModFile(modname)); if(CResourceHandler::get()->existsResource(resID)) { boost::filesystem::path name = *CResourceHandler::get()->getResourceName(resID); @@ -295,7 +295,7 @@ bool CModManager::doInstallMod(QString modname, QString archivePath) bool CModManager::doUninstallMod(QString modname) { - ResourceID resID(std::string("Mods/") + modname.toStdString(), EResType::DIRECTORY); + ResourcePath resID(std::string("Mods/") + modname.toStdString(), EResType::DIRECTORY); // Get location of the mod, in case-insensitive way QString modDir = pathToQString(*CResourceHandler::get()->getResourceName(resID)); diff --git a/lib/BattleFieldHandler.cpp b/lib/BattleFieldHandler.cpp index 2f6df594b..9c559ffe7 100644 --- a/lib/BattleFieldHandler.cpp +++ b/lib/BattleFieldHandler.cpp @@ -21,7 +21,7 @@ BattleFieldInfo * BattleFieldHandler::loadFromJson(const std::string & scope, co auto * info = new BattleFieldInfo(BattleField(index), identifier); - info->graphics = json["graphics"].String(); + info->graphics = ImagePath::fromJson(json["graphics"]); info->icon = json["icon"].String(); info->name = json["name"].String(); for(const auto & b : json["bonuses"].Vector()) diff --git a/lib/BattleFieldHandler.h b/lib/BattleFieldHandler.h index a3e550485..9bacf79a2 100644 --- a/lib/BattleFieldHandler.h +++ b/lib/BattleFieldHandler.h @@ -15,6 +15,7 @@ #include "GameConstants.h" #include "IHandlerBase.h" #include "battle/BattleHex.h" +#include "filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -24,7 +25,7 @@ public: BattleField battlefield; std::vector> bonuses; bool isSpecial; - std::string graphics; + ImagePath graphics; std::string name; std::string identifier; std::string icon; diff --git a/lib/CBonusTypeHandler.cpp b/lib/CBonusTypeHandler.cpp index 60f3211e3..8de2163d9 100644 --- a/lib/CBonusTypeHandler.cpp +++ b/lib/CBonusTypeHandler.cpp @@ -85,7 +85,7 @@ std::string CBonusTypeHandler::bonusToString(const std::shared_ptr & bonu return text; } -std::string CBonusTypeHandler::bonusToGraphics(const std::shared_ptr & bonus) const +ImagePath CBonusTypeHandler::bonusToGraphics(const std::shared_ptr & bonus) const { std::string fileName; bool fullPath = false; @@ -191,12 +191,12 @@ std::string CBonusTypeHandler::bonusToGraphics(const std::shared_ptr & bo if(!fileName.empty() && !fullPath) fileName = "zvs/Lib1.res/" + fileName; - return fileName; + return ImagePath::builtinTODO(fileName); } void CBonusTypeHandler::load() { - const JsonNode gameConf(ResourceID("config/gameConfig.json")); + const JsonNode gameConf(ResourcePath("config/gameConfig.json")); const JsonNode config(JsonUtils::assembleFromFiles(gameConf["bonuses"].convertTo>())); load(config); } diff --git a/lib/CBonusTypeHandler.h b/lib/CBonusTypeHandler.h index d747b8d98..01d36809f 100644 --- a/lib/CBonusTypeHandler.h +++ b/lib/CBonusTypeHandler.h @@ -51,7 +51,7 @@ public: virtual ~CBonusTypeHandler(); std::string bonusToString(const std::shared_ptr & bonus, const IBonusBearer * bearer, bool description) const override; - std::string bonusToGraphics(const std::shared_ptr & bonus) const override; + ImagePath bonusToGraphics(const std::shared_ptr & bonus) const override; template void serialize(Handler & h, const int version) { diff --git a/lib/CConfigHandler.cpp b/lib/CConfigHandler.cpp index 091135723..6aa7321e8 100644 --- a/lib/CConfigHandler.cpp +++ b/lib/CConfigHandler.cpp @@ -60,7 +60,7 @@ void SettingsStorage::init() JsonUtils::assembleFromFiles(confName).swap(config); // Probably new install. Create config file to save settings to - if (!CResourceHandler::get("local")->existsResource(ResourceID(confName))) + if (!CResourceHandler::get("local")->existsResource(ResourcePath(confName))) CResourceHandler::get("local")->createResource(confName); JsonUtils::maximize(config, "vcmi:settings"); @@ -76,7 +76,7 @@ void SettingsStorage::invalidateNode(const std::vector &changedPath savedConf.Struct().erase("session"); JsonUtils::minimize(savedConf, "vcmi:settings"); - std::fstream file(CResourceHandler::get()->getResourceName(ResourceID("config/settings.json"))->c_str(), std::ofstream::out | std::ofstream::trunc); + std::fstream file(CResourceHandler::get()->getResourceName(ResourcePath("config/settings.json"))->c_str(), std::ofstream::out | std::ofstream::trunc); file << savedConf.toJson(); } diff --git a/lib/CCreatureHandler.cpp b/lib/CCreatureHandler.cpp index 8a49bb8b6..872804635 100644 --- a/lib/CCreatureHandler.cpp +++ b/lib/CCreatureHandler.cpp @@ -415,7 +415,7 @@ const CCreature * CCreatureHandler::getCreature(const std::string & scope, const void CCreatureHandler::loadCommanders() { - ResourceID configResource("config/commanders.json"); + ResourcePath configResource("config/commanders.json"); std::string modSource = VLC->modh->findResourceOrigin(configResource); JsonNode data(configResource); @@ -884,7 +884,7 @@ void CCreatureHandler::loadJsonAnimation(CCreature * cre, const JsonNode & graph void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & config) const { - creature->animDefName = config["graphics"]["animation"].String(); + creature->animDefName = AnimationPath::fromJson(config["graphics"]["animation"]); //FIXME: MOD COMPATIBILITY if (config["abilities"].getType() == JsonNode::JsonType::DATA_STRUCT) @@ -933,7 +933,7 @@ void CCreatureHandler::loadCreatureJson(CCreature * creature, const JsonNode & c }); } - creature->animation.projectileImageName = config["graphics"]["missile"]["projectile"].String(); + creature->animation.projectileImageName = AnimationPath::fromJson(config["graphics"]["missile"]["projectile"]); for(const JsonNode & value : config["graphics"]["missile"]["ray"].Vector()) { diff --git a/lib/CCreatureHandler.h b/lib/CCreatureHandler.h index 0ef2a26df..f1dee53ca 100644 --- a/lib/CCreatureHandler.h +++ b/lib/CCreatureHandler.h @@ -18,6 +18,7 @@ #include "IHandlerBase.h" #include "CRandomGenerator.h" #include "Color.h" +#include "filesystem/ResourcePath.h" #include #include @@ -57,7 +58,7 @@ public: std::set upgrades; // IDs of creatures to which this creature can be upgraded - std::string animDefName; // creature animation used during battles + AnimationPath animDefName; // creature animation used during battles si32 iconIndex = -1; // index of icon in files like twcrport, used in tests now. /// names of files with appropriate icons. Used only during loading @@ -97,7 +98,7 @@ public: std::vector missleFrameAngles; int troopCountLocationOffset, attackClimaxFrame; - std::string projectileImageName; + AnimationPath projectileImageName; std::vector projectileRay; //bool projectileSpin; //if true, appropriate projectile is spinning during flight diff --git a/lib/CCreatureSet.cpp b/lib/CCreatureSet.cpp index 6da4ad768..ec09548c0 100644 --- a/lib/CCreatureSet.cpp +++ b/lib/CCreatureSet.cpp @@ -777,7 +777,7 @@ std::string CStackInstance::bonusToString(const std::shared_ptr& bonus, b return VLC->getBth()->bonusToString(bonus, this, description); } -std::string CStackInstance::bonusToGraphics(const std::shared_ptr & bonus) const +ImagePath CStackInstance::bonusToGraphics(const std::shared_ptr & bonus) const { return VLC->getBth()->bonusToGraphics(bonus); } diff --git a/lib/CCreatureSet.h b/lib/CCreatureSet.h index c103a6af7..7c81c544f 100644 --- a/lib/CCreatureSet.h +++ b/lib/CCreatureSet.h @@ -96,7 +96,7 @@ public: //overrides CBonusSystemNode std::string bonusToString(const std::shared_ptr& bonus, bool description) const override; // how would bonus description look for this particular type of node - std::string bonusToGraphics(const std::shared_ptr & bonus) const; //file name of graphics from StackSkills , in future possibly others + ImagePath bonusToGraphics(const std::shared_ptr & bonus) const; //file name of graphics from StackSkills , in future possibly others //IConstBonusProvider const IBonusBearer* getBonusBearer() const override; diff --git a/lib/CGeneralTextHandler.cpp b/lib/CGeneralTextHandler.cpp index a8c66a578..624a0b08b 100644 --- a/lib/CGeneralTextHandler.cpp +++ b/lib/CGeneralTextHandler.cpp @@ -48,7 +48,7 @@ void CGeneralTextHandler::detectInstallParameters() "ukrainian" } }; - if(!CResourceHandler::get("core")->existsResource(ResourceID("DATA/GENRLTXT.TXT", EResType::TEXT))) + if(!CResourceHandler::get("core")->existsResource(ResourcePath("DATA/GENRLTXT.TXT", EResType::TEXT))) { 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(ResourceID("DATA/GENRLTXT.TXT", EResType::TEXT)); + auto resource = CResourceHandler::get("core")->load(ResourcePath("DATA/GENRLTXT.TXT", EResType::TEXT)); std::array charCount{}; std::array footprint{}; @@ -121,7 +121,7 @@ protected: CLegacyConfigParser::CLegacyConfigParser(std::string URI) { - ResourceID resource(URI, EResType::TEXT); + ResourcePath resource(URI, EResType::TEXT); auto input = CResourceHandler::get()->load(resource); std::string modName = VLC->modh->findResourceOrigin(resource); std::string language = VLC->modh->getModLanguage(modName); @@ -430,7 +430,7 @@ CGeneralTextHandler::CGeneralTextHandler(): readToVector("core.mineevnt", "DATA/MINEEVNT.TXT" ); static const char * QE_MOD_COMMANDS = "DATA/QECOMMANDS.TXT"; - if (CResourceHandler::get()->existsResource(ResourceID(QE_MOD_COMMANDS, EResType::TEXT))) + if (CResourceHandler::get()->existsResource(ResourcePath(QE_MOD_COMMANDS, EResType::TEXT))) readToVector("vcmi.quickExchange", QE_MOD_COMMANDS); { @@ -575,7 +575,7 @@ CGeneralTextHandler::CGeneralTextHandler(): } if (VLC->settings()->getBoolean(EGameSettings::MODULE_COMMANDERS)) { - if(CResourceHandler::get()->existsResource(ResourceID("DATA/ZNPC00.TXT", EResType::TEXT))) + if(CResourceHandler::get()->existsResource(ResourcePath("DATA/ZNPC00.TXT", EResType::TEXT))) readToVector("vcmi.znpc00", "DATA/ZNPC00.TXT" ); } } diff --git a/lib/CHeroHandler.cpp b/lib/CHeroHandler.cpp index 4b9923b36..280d09105 100644 --- a/lib/CHeroHandler.cpp +++ b/lib/CHeroHandler.cpp @@ -243,8 +243,8 @@ CHeroClass * CHeroClassHandler::loadFromJson(const std::string & scope, const Js heroClass->id = HeroClassID(index); heroClass->identifier = identifier; heroClass->modScope = scope; - heroClass->imageBattleFemale = node["animation"]["battle"]["female"].String(); - heroClass->imageBattleMale = node["animation"]["battle"]["male"].String(); + heroClass->imageBattleFemale = AnimationPath::fromJson(node["animation"]["battle"]["female"]); + heroClass->imageBattleMale = AnimationPath::fromJson(node["animation"]["battle"]["male"]); //MODS COMPATIBILITY FOR 0.96 heroClass->imageMapFemale = node["animation"]["map"]["female"].String(); heroClass->imageMapMale = node["animation"]["map"]["male"].String(); @@ -438,7 +438,7 @@ CHero * CHeroHandler::loadFromJson(const std::string & scope, const JsonNode & n hero->iconSpecLarge = node["images"]["specialtyLarge"].String(); hero->portraitSmall = node["images"]["small"].String(); hero->portraitLarge = node["images"]["large"].String(); - hero->battleImage = node["battleImage"].String(); + hero->battleImage = AnimationPath::fromJson(node["battleImage"]); loadHeroArmy(hero, node); loadHeroSkills(hero, node); diff --git a/lib/CHeroHandler.h b/lib/CHeroHandler.h index 2e9c5df84..86f328f8c 100644 --- a/lib/CHeroHandler.h +++ b/lib/CHeroHandler.h @@ -14,11 +14,12 @@ #include #include -#include "../lib/ConstTransitivePtr.h" +#include "ConstTransitivePtr.h" #include "GameConstants.h" #include "bonuses/Bonus.h" #include "bonuses/BonusList.h" #include "IHandlerBase.h" +#include "filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -78,7 +79,7 @@ public: std::string iconSpecLarge; std::string portraitSmall; std::string portraitLarge; - std::string battleImage; + AnimationPath battleImage; CHero(); virtual ~CHero(); @@ -160,8 +161,8 @@ public: std::map selectionProbability; //probability of selection in towns - std::string imageBattleMale; - std::string imageBattleFemale; + AnimationPath imageBattleMale; + AnimationPath imageBattleFemale; std::string imageMapMale; std::string imageMapFemale; diff --git a/lib/CTownHandler.cpp b/lib/CTownHandler.cpp index cb19a3983..3d4e1388c 100644 --- a/lib/CTownHandler.cpp +++ b/lib/CTownHandler.cpp @@ -752,9 +752,9 @@ void CTownHandler::loadStructure(CTown &town, const std::string & stringID, cons ret->pos.z = static_cast(source["z"].Float()); ret->hiddenUpgrade = source["hidden"].Bool(); - ret->defName = source["animation"].String(); - ret->borderName = source["border"].String(); - ret->areaName = source["area"].String(); + ret->defName = AnimationPath::fromJson(source["animation"]); + ret->borderName = ImagePath::fromJson(source["border"]); + ret->areaName = ImagePath::fromJson(source["area"]); town.clientInfo.structures.emplace_back(ret); } @@ -877,22 +877,14 @@ void CTownHandler::loadClientData(CTown &town, const JsonNode & source) const readIcon(source["icons"]["fort"]["normal"], info.iconSmall[1][0], info.iconLarge[1][0]); readIcon(source["icons"]["fort"]["built"], info.iconSmall[1][1], info.iconLarge[1][1]); - info.hallBackground = source["hallBackground"].String(); + info.hallBackground = ImagePath::fromJson(source["hallBackground"]); info.musicTheme = source["musicTheme"].String(); - info.townBackground = source["townBackground"].String(); - info.guildWindow = source["guildWindow"].String(); - info.buildingsIcons = source["buildingsIcons"].String(); + info.townBackground = ImagePath::fromJson(source["townBackground"]); + info.guildWindow = ImagePath::fromJson(source["guildWindow"]); + info.buildingsIcons = AnimationPath::fromJson(source["buildingsIcons"]); - //left for back compatibility - will be removed later - if(!source["guildBackground"].String().empty()) - info.guildBackground = source["guildBackground"].String(); - else - info.guildBackground = "TPMAGE.bmp"; - if(!source["tavernVideo"].String().empty()) - info.tavernVideo = source["tavernVideo"].String(); - else - info.tavernVideo = "TAVERN.BIK"; - //end of legacy assignment + info.guildBackground = ImagePath::fromJson(source["guildBackground"]); + info.tavernVideo = source["tavernVideo"].String(); loadTownHall(town, source["hallSlots"]); loadStructures(town, source["structures"]); @@ -1012,7 +1004,7 @@ void CTownHandler::loadPuzzle(CFaction &faction, const JsonNode &source) const std::ostringstream suffix; suffix << std::setfill('0') << std::setw(2) << index; - spi.filename = prefix + suffix.str(); + spi.filename = ImagePath::builtinTODO(prefix + suffix.str()); faction.puzzleMap.push_back(spi); } @@ -1031,8 +1023,8 @@ CFaction * CTownHandler::loadFromJson(const std::string & scope, const JsonNode VLC->generaltexth->registerString(scope, faction->getNameTextID(), source["name"].String()); - faction->creatureBg120 = source["creatureBackground"]["120px"].String(); - faction->creatureBg130 = source["creatureBackground"]["130px"].String(); + faction->creatureBg120 = ImagePath::fromJson(source["creatureBackground"]["120px"]); + faction->creatureBg130 = ImagePath::fromJson(source["creatureBackground"]["130px"]); faction->boatType = BoatId::CASTLE; //Do not crash if (!source["boat"].isNull()) @@ -1156,7 +1148,7 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod void CTownHandler::loadRandomFaction() { - static const ResourceID randomFactionPath("config/factions/random.json"); + static const ResourcePath randomFactionPath("config/factions/random.json"); JsonNode randomFactionJson(randomFactionPath); randomFactionJson.setMeta(ModScope::scopeBuiltin(), true); diff --git a/lib/CTownHandler.h b/lib/CTownHandler.h index 0c15ef396..4c8da2082 100644 --- a/lib/CTownHandler.h +++ b/lib/CTownHandler.h @@ -23,6 +23,7 @@ #include "bonuses/BonusList.h" #include "Point.h" #include "rewardable/Info.h" +#include "filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -154,7 +155,10 @@ struct DLL_LINKAGE CStructure CBuilding * buildable; // building that will be used to determine built building and visible cost. Usually same as "building" int3 pos; - std::string defName, borderName, areaName, identifier; + AnimationPath defName; + ImagePath borderName; + ImagePath areaName; + std::string identifier; bool hiddenUpgrade; // used only if "building" is upgrade, if true - structure on town screen will behave exactly like parent (mouse clicks, hover texts, etc) template void serialize(Handler &h, const int version) @@ -175,7 +179,7 @@ struct DLL_LINKAGE SPuzzleInfo ui16 number; //type of puzzle si16 x, y; //position ui16 whenUncovered; //determines the sequnce of discovering (the lesser it is the sooner puzzle will be discovered) - std::string filename; //file with graphic of this puzzle + ImagePath filename; //file with graphic of this puzzle template void serialize(Handler &h, const int version) { @@ -209,11 +213,10 @@ public: /// and for placing heroes directly on boat (in map editor, water prisons & taverns) BoatId boatType = BoatId::CASTLE; - CTown * town = nullptr; //NOTE: can be null - std::string creatureBg120; - std::string creatureBg130; + ImagePath creatureBg120; + ImagePath creatureBg130; std::vector puzzleMap; @@ -303,11 +306,11 @@ public: std::string iconLarge[2][2]; std::string tavernVideo; std::string musicTheme; - std::string townBackground; - std::string guildBackground; - std::string guildWindow; - std::string buildingsIcons; - std::string hallBackground; + ImagePath townBackground; + ImagePath guildBackground; + ImagePath guildWindow; + AnimationPath buildingsIcons; + ImagePath hallBackground; /// vector[row][column] = list of buildings in this slot std::vector< std::vector< std::vector > > hallSlots; diff --git a/lib/IBonusTypeHandler.h b/lib/IBonusTypeHandler.h index 60914bace..b38c56f3d 100644 --- a/lib/IBonusTypeHandler.h +++ b/lib/IBonusTypeHandler.h @@ -9,6 +9,8 @@ */ #pragma once +#include "filesystem/ResourcePath.h" + VCMI_LIB_NAMESPACE_BEGIN class IBonusBearer; @@ -22,7 +24,7 @@ public: virtual ~IBonusTypeHandler() = default; virtual std::string bonusToString(const std::shared_ptr & bonus, const IBonusBearer * bearer, bool description) const = 0; - virtual std::string bonusToGraphics(const std::shared_ptr & bonus) const = 0; + virtual ImagePath bonusToGraphics(const std::shared_ptr & bonus) const = 0; }; VCMI_LIB_NAMESPACE_END diff --git a/lib/JsonDetail.cpp b/lib/JsonDetail.cpp index c056f434b..ce1b2a96d 100644 --- a/lib/JsonDetail.cpp +++ b/lib/JsonDetail.cpp @@ -1005,7 +1005,7 @@ namespace namespace Formats { - bool testFilePresence(const std::string & scope, const ResourceID & resource) + bool testFilePresence(const std::string & scope, const ResourcePath & resource) { std::set allowedScopes; if(scope != ModScope::scopeBuiltin() && !scope.empty()) // all real mods may have dependencies @@ -1030,7 +1030,7 @@ namespace } #define TEST_FILE(scope, prefix, file, type) \ - if (testFilePresence(scope, ResourceID(prefix + file, type))) \ + if (testFilePresence(scope, ResourcePath(prefix + file, type))) \ return "" std::string testAnimation(const std::string & path, const std::string & scope) diff --git a/lib/JsonNode.cpp b/lib/JsonNode.cpp index 842b3fdf2..66a1596ac 100644 --- a/lib/JsonNode.cpp +++ b/lib/JsonNode.cpp @@ -80,7 +80,7 @@ JsonNode::JsonNode(const char *data, size_t datasize): *this = parser.parse(""); } -JsonNode::JsonNode(ResourceID && fileURI): +JsonNode::JsonNode(ResourcePath && fileURI): type(JsonType::DATA_NULL) { auto file = CResourceHandler::get()->load(fileURI)->readAll(); @@ -89,7 +89,7 @@ JsonNode::JsonNode(ResourceID && fileURI): *this = parser.parse(fileURI.getName()); } -JsonNode::JsonNode(const ResourceID & fileURI): +JsonNode::JsonNode(const ResourcePath & fileURI): type(JsonType::DATA_NULL) { auto file = CResourceHandler::get()->load(fileURI)->readAll(); @@ -98,7 +98,7 @@ JsonNode::JsonNode(const ResourceID & fileURI): *this = parser.parse(fileURI.getName()); } -JsonNode::JsonNode(const std::string & idx, const ResourceID & fileURI): +JsonNode::JsonNode(const std::string & idx, const ResourcePath & fileURI): type(JsonType::DATA_NULL) { auto file = CResourceHandler::get(idx)->load(fileURI)->readAll(); @@ -107,7 +107,7 @@ type(JsonType::DATA_NULL) *this = parser.parse(fileURI.getName()); } -JsonNode::JsonNode(ResourceID && fileURI, bool &isValidSyntax): +JsonNode::JsonNode(ResourcePath && fileURI, bool &isValidSyntax): type(JsonType::DATA_NULL) { auto file = CResourceHandler::get()->load(fileURI)->readAll(); @@ -1255,9 +1255,9 @@ const JsonNode & getSchemaByName(const std::string & name) std::string filename = "config/schemas/" + name; - if (CResourceHandler::get()->existsResource(ResourceID(filename))) + if (CResourceHandler::get()->existsResource(ResourcePath(filename))) { - loadedSchemas[name] = JsonNode(ResourceID(filename)); + loadedSchemas[name] = JsonNode(ResourcePath(filename)); return loadedSchemas[name]; } @@ -1447,7 +1447,7 @@ JsonNode JsonUtils::assembleFromFiles(const std::vector & files, bo for(const std::string & file : files) { bool isValidFile = false; - JsonNode section(ResourceID(file, EResType::TEXT), isValidFile); + JsonNode section(ResourcePath(file, EResType::TEXT), isValidFile); merge(result, section); isValid |= isValidFile; } @@ -1457,7 +1457,7 @@ JsonNode JsonUtils::assembleFromFiles(const std::vector & files, bo JsonNode JsonUtils::assembleFromFiles(const std::string & filename) { JsonNode result; - ResourceID resID(filename, EResType::TEXT); + ResourcePath resID(filename, EResType::TEXT); for(auto & loader : CResourceHandler::get()->getResourcesWithName(resID)) { diff --git a/lib/JsonNode.h b/lib/JsonNode.h index c1d39991e..bdae6ea58 100644 --- a/lib/JsonNode.h +++ b/lib/JsonNode.h @@ -18,7 +18,7 @@ using JsonVector = std::vector; struct Bonus; class CSelector; -class ResourceID; +class ResourcePath; class CAddInfo; class ILimiter; @@ -61,10 +61,10 @@ public: //Create tree from Json-formatted input explicit JsonNode(const char * data, size_t datasize); //Create tree from JSON file - explicit JsonNode(ResourceID && fileURI); - explicit JsonNode(const ResourceID & fileURI); - explicit JsonNode(const std::string& idx, const ResourceID & fileURI); - explicit JsonNode(ResourceID && fileURI, bool & isValidSyntax); + explicit JsonNode(ResourcePath && fileURI); + explicit JsonNode(const ResourcePath & fileURI); + explicit JsonNode(const std::string& idx, const ResourcePath & fileURI); + explicit JsonNode(ResourcePath && fileURI, bool & isValidSyntax); //Copy c-tor JsonNode(const JsonNode ©); diff --git a/lib/ObstacleHandler.cpp b/lib/ObstacleHandler.cpp index fde260dd6..fbfc7efe2 100644 --- a/lib/ObstacleHandler.cpp +++ b/lib/ObstacleHandler.cpp @@ -90,7 +90,7 @@ ObstacleInfo * ObstacleHandler::loadFromJson(const std::string & scope, const Js auto * info = new ObstacleInfo(Obstacle(index), identifier); - info->animation = json["animation"].String(); + info->animation = AnimationPath::fromJson(json["animation"]); info->width = json["width"].Integer(); info->height = json["height"].Integer(); for(const auto & t : json["allowedTerrains"].Vector()) diff --git a/lib/ObstacleHandler.h b/lib/ObstacleHandler.h index 09bd52fd2..d5b2ab3f0 100644 --- a/lib/ObstacleHandler.h +++ b/lib/ObstacleHandler.h @@ -14,6 +14,7 @@ #include "GameConstants.h" #include "IHandlerBase.h" #include "battle/BattleHex.h" +#include "filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -31,7 +32,9 @@ public: Obstacle obstacle; si32 iconIndex; std::string identifier; - std::string appearSound, appearAnimation, animation; + std::string appearSound; + AnimationPath appearAnimation; + AnimationPath animation; std::vector allowedTerrains; std::vector allowedSpecialBfields; diff --git a/lib/RiverHandler.cpp b/lib/RiverHandler.cpp index 1f4022391..3cc04eb37 100644 --- a/lib/RiverHandler.cpp +++ b/lib/RiverHandler.cpp @@ -36,7 +36,7 @@ RiverType * RiverTypeHandler::loadFromJson( info->id = RiverId(index); info->identifier = identifier; info->modScope = scope; - info->tilesFilename = json["tilesFilename"].String(); + info->tilesFilename = AnimationPath::fromJson(json["tilesFilename"]); info->shortIdentifier = json["shortIdentifier"].String(); info->deltaName = json["delta"].String(); diff --git a/lib/RiverHandler.h b/lib/RiverHandler.h index 22fad8660..dddd81d41 100644 --- a/lib/RiverHandler.h +++ b/lib/RiverHandler.h @@ -14,6 +14,7 @@ #include #include "GameConstants.h" #include "IHandlerBase.h" +#include "filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -49,7 +50,7 @@ public: std::string getNameTextID() const override; std::string getNameTranslated() const override; - std::string tilesFilename; + AnimationPath tilesFilename; std::string shortIdentifier; std::string deltaName; diff --git a/lib/RoadHandler.cpp b/lib/RoadHandler.cpp index ba8620f39..458d1588d 100644 --- a/lib/RoadHandler.cpp +++ b/lib/RoadHandler.cpp @@ -36,7 +36,7 @@ RoadType * RoadTypeHandler::loadFromJson( info->id = RoadId(index); info->identifier = identifier; info->modScope = scope; - info->tilesFilename = json["tilesFilename"].String(); + info->tilesFilename = AnimationPath::fromJson(json["tilesFilename"]); info->shortIdentifier = json["shortIdentifier"].String(); info->movementCost = json["moveCost"].Integer(); diff --git a/lib/RoadHandler.h b/lib/RoadHandler.h index 156d7635d..e9e1d9df6 100644 --- a/lib/RoadHandler.h +++ b/lib/RoadHandler.h @@ -14,6 +14,7 @@ #include #include "GameConstants.h" #include "IHandlerBase.h" +#include "filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -35,7 +36,7 @@ public: std::string getNameTextID() const override; std::string getNameTranslated() const override; - std::string tilesFilename; + AnimationPath tilesFilename; std::string shortIdentifier; ui8 movementCost; diff --git a/lib/ScriptHandler.cpp b/lib/ScriptHandler.cpp index c9528b109..d672c74dd 100644 --- a/lib/ScriptHandler.cpp +++ b/lib/ScriptHandler.cpp @@ -90,7 +90,7 @@ void ScriptImpl::serializeJson(vstd::CLoggerBase * logger, JsonSerializeFormat & { resolveHost(); - ResourceID sourcePathId("SCRIPTS/" + sourcePath); + ResourcePath sourcePathId("SCRIPTS/" + sourcePath); auto rawData = CResourceHandler::get()->load(sourcePathId)->readAll(); @@ -115,7 +115,7 @@ void ScriptImpl::serializeJsonState(JsonSerializeFormat & handler) void ScriptImpl::resolveHost() { - ResourceID sourcePathId(sourcePath); + ResourcePath sourcePathId(sourcePath); if(sourcePathId.getType() == EResType::ERM) host = owner->erm; diff --git a/lib/TerrainHandler.cpp b/lib/TerrainHandler.cpp index c48436dfa..6bd09d3c6 100644 --- a/lib/TerrainHandler.cpp +++ b/lib/TerrainHandler.cpp @@ -28,7 +28,7 @@ TerrainType * TerrainTypeHandler::loadFromJson( const std::string & scope, const info->modScope = scope; info->moveCost = static_cast(json["moveCost"].Integer()); info->musicFilename = json["music"].String(); - info->tilesFilename = json["tiles"].String(); + info->tilesFilename = AnimationPath::fromJson(json["tiles"]); info->horseSound = json["horseSound"].String(); info->horseSoundPenalty = json["horseSoundPenalty"].String(); info->transitionRequired = json["transitionRequired"].Bool(); diff --git a/lib/TerrainHandler.h b/lib/TerrainHandler.h index 5a10f1afa..fa7623136 100644 --- a/lib/TerrainHandler.h +++ b/lib/TerrainHandler.h @@ -15,6 +15,7 @@ #include "GameConstants.h" #include "IHandlerBase.h" #include "Color.h" +#include "filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -67,7 +68,7 @@ public: ColorRGBA minimapUnblocked; std::string shortIdentifier; std::string musicFilename; - std::string tilesFilename; + AnimationPath tilesFilename; std::string terrainViewPatterns; std::string horseSound; std::string horseSoundPenalty; diff --git a/lib/battle/BattleInfo.cpp b/lib/battle/BattleInfo.cpp index d5a714dcb..ba7f0d5c3 100644 --- a/lib/battle/BattleInfo.cpp +++ b/lib/battle/BattleInfo.cpp @@ -348,7 +348,7 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, TerrainId terrain, const std::vector> creBankFormations[2]; std::vector commanderField; std::vector commanderBank; - const JsonNode config(ResourceID("config/battleStartpos.json")); + const JsonNode config(ResourcePath("config/battleStartpos.json")); const JsonVector &positions = config["battle_positions"].Vector(); CGH::readBattlePositions(positions[0]["levels"], looseFormations[0]); diff --git a/lib/battle/CObstacleInstance.cpp b/lib/battle/CObstacleInstance.cpp index c69db1117..e1de4b984 100644 --- a/lib/battle/CObstacleInstance.cpp +++ b/lib/battle/CObstacleInstance.cpp @@ -60,12 +60,12 @@ bool CObstacleInstance::visibleForSide(ui8 side, bool hasNativeStack) const return true; } -const std::string & CObstacleInstance::getAnimation() const +const AnimationPath & CObstacleInstance::getAnimation() const { return getInfo().animation; } -const std::string & CObstacleInstance::getAppearAnimation() const +const AnimationPath & CObstacleInstance::getAppearAnimation() const { return getInfo().appearAnimation; } @@ -119,8 +119,8 @@ 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.serializeString("appearAnimation", obstacleInfo.appearAnimation); - handler.serializeString("animation", obstacleInfo.animation); + handler.serializeStruct("appearAnimation", obstacleInfo.appearAnimation); + handler.serializeStruct("animation", obstacleInfo.animation); handler.serializeInt("animationYOffset", animationYOffset); handler.serializeBool("hidden", hidden); @@ -214,8 +214,8 @@ void SpellCreatedObstacle::serializeJson(JsonSerializeFormat & handler) handler.serializeBool("nativeVisible", nativeVisible); handler.serializeString("appearSound", appearSound); - handler.serializeString("appearAnimation", appearAnimation); - handler.serializeString("animation", animation); + handler.serializeStruct("appearAnimation", appearAnimation); + handler.serializeStruct("animation", animation); handler.serializeInt("animationYOffset", animationYOffset); @@ -239,12 +239,12 @@ void SpellCreatedObstacle::battleTurnPassed() turnsRemaining--; } -const std::string & SpellCreatedObstacle::getAnimation() const +const AnimationPath & SpellCreatedObstacle::getAnimation() const { return animation; } -const std::string & SpellCreatedObstacle::getAppearAnimation() const +const AnimationPath & SpellCreatedObstacle::getAppearAnimation() const { return appearAnimation; } diff --git a/lib/battle/CObstacleInstance.h b/lib/battle/CObstacleInstance.h index 9cf304d97..0d74d95fd 100644 --- a/lib/battle/CObstacleInstance.h +++ b/lib/battle/CObstacleInstance.h @@ -10,6 +10,7 @@ #pragma once #include "BattleHex.h" #include "NetPacksBase.h" +#include "../filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -51,8 +52,8 @@ struct DLL_LINKAGE CObstacleInstance virtual void battleTurnPassed(){}; //Client helper functions, make it easier to render animations - virtual const std::string & getAnimation() const; - virtual const std::string & getAppearAnimation() const; + virtual const AnimationPath & getAnimation() const; + virtual const AnimationPath & getAppearAnimation() const; virtual const std::string & getAppearSound() const; virtual int getAnimationYOffset(int imageHeight) const; @@ -88,8 +89,8 @@ struct DLL_LINKAGE SpellCreatedObstacle : CObstacleInstance bool nativeVisible; //Should native terrain creatures reveal obstacle std::string appearSound; - std::string appearAnimation; - std::string animation; + AnimationPath appearAnimation; + AnimationPath animation; int animationYOffset; @@ -107,8 +108,8 @@ struct DLL_LINKAGE SpellCreatedObstacle : CObstacleInstance void battleTurnPassed() override; //Client helper functions, make it easier to render animations - const std::string & getAnimation() const override; - const std::string & getAppearAnimation() const override; + const AnimationPath & getAnimation() const override; + const AnimationPath & getAppearAnimation() const override; const std::string & getAppearSound() const override; int getAnimationYOffset(int imageHeight) const override; diff --git a/lib/campaign/CampaignHandler.cpp b/lib/campaign/CampaignHandler.cpp index 63630b6e2..133e99a62 100644 --- a/lib/campaign/CampaignHandler.cpp +++ b/lib/campaign/CampaignHandler.cpp @@ -59,7 +59,7 @@ void CampaignHandler::readCampaign(Campaign * ret, const std::vector & inpu std::unique_ptr CampaignHandler::getHeader( const std::string & name) { - ResourceID resourceID(name, EResType::CAMPAIGN); + ResourcePath resourceID(name, EResType::CAMPAIGN); std::string modName = VLC->modh->findResourceOrigin(resourceID); std::string language = VLC->modh->getModLanguage(modName); std::string encoding = Languages::getLanguageOptions(language).encoding; @@ -75,7 +75,7 @@ std::unique_ptr CampaignHandler::getHeader( const std::string & name) std::shared_ptr CampaignHandler::getCampaign( const std::string & name ) { - ResourceID resourceID(name, EResType::CAMPAIGN); + ResourcePath resourceID(name, EResType::CAMPAIGN); std::string modName = VLC->modh->findResourceOrigin(resourceID); std::string language = VLC->modh->getModLanguage(modName); std::string encoding = Languages::getLanguageOptions(language).encoding; @@ -592,7 +592,7 @@ std::vector< std::vector > CampaignHandler::getFile(std::unique_ptr campDescriptions; if(campDescriptions.empty()) //read once { - const JsonNode config(ResourceID("config/campaign_regions.json")); + const JsonNode config(ResourcePath("config/campaign_regions.json")); for(const JsonNode & campaign : config["campaign_regions"].Vector()) campDescriptions.push_back(CampaignRegions::fromJson(campaign)); } @@ -66,9 +66,9 @@ CampaignRegions CampaignRegions::getLegacy(int campId) return campDescriptions.at(campId); } -std::string CampaignRegions::getBackgroundName() const +ImagePath CampaignRegions::getBackgroundName() const { - return campPrefix + "_BG.BMP"; + return ImagePath::builtin(campPrefix + "_BG.BMP"); } Point CampaignRegions::getPosition(CampaignScenarioID which) const @@ -77,7 +77,7 @@ Point CampaignRegions::getPosition(CampaignScenarioID which) const return Point(region.xpos, region.ypos); } -std::string CampaignRegions::getNameFor(CampaignScenarioID which, int colorIndex, std::string type) const +ImagePath CampaignRegions::getNameFor(CampaignScenarioID which, int colorIndex, std::string type) const { auto const & region = regions[static_cast(which)]; @@ -89,20 +89,20 @@ std::string CampaignRegions::getNameFor(CampaignScenarioID which, int colorIndex std::string color = colors[colorSuffixLength - 1][colorIndex]; - return campPrefix + region.infix + "_" + type + color + ".BMP"; + return ImagePath::builtin(campPrefix + region.infix + "_" + type + color + ".BMP"); } -std::string CampaignRegions::getAvailableName(CampaignScenarioID which, int color) const +ImagePath CampaignRegions::getAvailableName(CampaignScenarioID which, int color) const { return getNameFor(which, color, "En"); } -std::string CampaignRegions::getSelectedName(CampaignScenarioID which, int color) const +ImagePath CampaignRegions::getSelectedName(CampaignScenarioID which, int color) const { return getNameFor(which, color, "Se"); } -std::string CampaignRegions::getConqueredName(CampaignScenarioID which, int color) const +ImagePath CampaignRegions::getConqueredName(CampaignScenarioID which, int color) const { return getNameFor(which, color, "Co"); } diff --git a/lib/campaign/CampaignState.h b/lib/campaign/CampaignState.h index 51fb5c034..aa73801e3 100644 --- a/lib/campaign/CampaignState.h +++ b/lib/campaign/CampaignState.h @@ -9,7 +9,8 @@ */ #pragma once -#include "../../lib/GameConstants.h" +#include "../lib/GameConstants.h" +#include "../lib/filesystem/ResourcePath.h" #include "CampaignConstants.h" #include "CampaignScenarioPrologEpilog.h" @@ -47,14 +48,14 @@ class DLL_LINKAGE CampaignRegions std::vector regions; - std::string getNameFor(CampaignScenarioID which, int color, std::string type) const; + ImagePath getNameFor(CampaignScenarioID which, int color, std::string type) const; public: - std::string getBackgroundName() const; + ImagePath getBackgroundName() const; Point getPosition(CampaignScenarioID which) const; - std::string getAvailableName(CampaignScenarioID which, int color) const; - std::string getSelectedName(CampaignScenarioID which, int color) const; - std::string getConqueredName(CampaignScenarioID which, int color) const; + ImagePath getAvailableName(CampaignScenarioID which, int color) const; + ImagePath getSelectedName(CampaignScenarioID which, int color) const; + ImagePath getConqueredName(CampaignScenarioID which, int color) const; template void serialize(Handler &h, const int formatVersion) { diff --git a/lib/filesystem/AdapterLoaders.cpp b/lib/filesystem/AdapterLoaders.cpp index fddd889fb..c15b1b4a8 100644 --- a/lib/filesystem/AdapterLoaders.cpp +++ b/lib/filesystem/AdapterLoaders.cpp @@ -19,17 +19,17 @@ CMappedFileLoader::CMappedFileLoader(const std::string & mountPoint, const JsonN { for(auto entry : config.Struct()) { - //fileList[ResourceID(mountPoint + entry.first)] = ResourceID(mountPoint + entry.second.String()); - fileList.emplace(ResourceID(mountPoint + entry.first), ResourceID(mountPoint + entry.second.String())); + //fileList[ResourcePath(mountPoint + entry.first)] = ResourcePath(mountPoint + entry.second.String()); + fileList.emplace(ResourcePath(mountPoint + entry.first), ResourcePath(mountPoint + entry.second.String())); } } -std::unique_ptr CMappedFileLoader::load(const ResourceID & resourceName) const +std::unique_ptr CMappedFileLoader::load(const ResourcePath & resourceName) const { return CResourceHandler::get()->load(fileList.at(resourceName)); } -bool CMappedFileLoader::existsResource(const ResourceID & resourceName) const +bool CMappedFileLoader::existsResource(const ResourcePath & resourceName) const { return fileList.count(resourceName) != 0; } @@ -39,14 +39,14 @@ std::string CMappedFileLoader::getMountPoint() const return ""; // does not have any meaning with this type of data source } -std::optional CMappedFileLoader::getResourceName(const ResourceID & resourceName) const +std::optional CMappedFileLoader::getResourceName(const ResourcePath & resourceName) const { return CResourceHandler::get()->getResourceName(fileList.at(resourceName)); } -std::unordered_set CMappedFileLoader::getFilteredFiles(std::function filter) const +std::unordered_set CMappedFileLoader::getFilteredFiles(std::function filter) const { - std::unordered_set foundID; + std::unordered_set foundID; for(const auto & file : fileList) { @@ -64,7 +64,7 @@ CFilesystemList::~CFilesystemList() { } -std::unique_ptr CFilesystemList::load(const ResourceID & resourceName) const +std::unique_ptr CFilesystemList::load(const ResourcePath & resourceName) const { // load resource from last loader that have it (last overridden version) for(const auto & loader : boost::adaptors::reverse(loaders)) @@ -77,7 +77,7 @@ std::unique_ptr CFilesystemList::load(const ResourceID & resourceN + EResTypeHelper::getEResTypeAsString(resourceName.getType()) + " wasn't found."); } -bool CFilesystemList::existsResource(const ResourceID & resourceName) const +bool CFilesystemList::existsResource(const ResourcePath & resourceName) const { for(const auto & loader : loaders) if (loader->existsResource(resourceName)) @@ -90,14 +90,14 @@ std::string CFilesystemList::getMountPoint() const return ""; } -std::optional CFilesystemList::getResourceName(const ResourceID & resourceName) const +std::optional CFilesystemList::getResourceName(const ResourcePath & resourceName) const { if (existsResource(resourceName)) return getResourcesWithName(resourceName).back()->getResourceName(resourceName); return std::optional(); } -std::set CFilesystemList::getResourceNames(const ResourceID & resourceName) const +std::set CFilesystemList::getResourceNames(const ResourcePath & resourceName) const { std::set paths; for(auto& loader : getResourcesWithName(resourceName)) @@ -117,9 +117,9 @@ void CFilesystemList::updateFilteredFiles(std::functionupdateFilteredFiles(filter); } -std::unordered_set CFilesystemList::getFilteredFiles(std::function filter) const +std::unordered_set CFilesystemList::getFilteredFiles(std::function filter) const { - std::unordered_set ret; + std::unordered_set ret; for(const auto & loader : loaders) for(const auto & entry : loader->getFilteredFiles(filter)) @@ -139,7 +139,7 @@ bool CFilesystemList::createResource(std::string filename, bool update) // Check if resource was created successfully. Possible reasons for this to fail // a) loader failed to create resource (e.g. read-only FS) // b) in update mode, call with filename that does not exists - assert(load(ResourceID(filename))); + assert(load(ResourcePath(filename))); logGlobal->trace("Resource created successfully"); return true; @@ -149,7 +149,7 @@ bool CFilesystemList::createResource(std::string filename, bool update) return false; } -std::vector CFilesystemList::getResourcesWithName(const ResourceID & resourceName) const +std::vector CFilesystemList::getResourcesWithName(const ResourcePath & resourceName) const { std::vector ret; diff --git a/lib/filesystem/AdapterLoaders.h b/lib/filesystem/AdapterLoaders.h index 3e0386ed5..c54c24d50 100644 --- a/lib/filesystem/AdapterLoaders.h +++ b/lib/filesystem/AdapterLoaders.h @@ -10,7 +10,7 @@ #pragma once #include "ISimpleResourceLoader.h" -#include "ResourceID.h" +#include "ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -38,19 +38,19 @@ public: /// Interface implementation /// @see ISimpleResourceLoader - std::unique_ptr load(const ResourceID & resourceName) const override; - bool existsResource(const ResourceID & resourceName) const override; + std::unique_ptr load(const ResourcePath & resourceName) const override; + bool existsResource(const ResourcePath & resourceName) const override; std::string getMountPoint() const override; - std::optional getResourceName(const ResourceID & resourceName) const override; + std::optional getResourceName(const ResourcePath & resourceName) const override; void updateFilteredFiles(std::function filter) const override {} - std::unordered_set getFilteredFiles(std::function filter) const override; + std::unordered_set getFilteredFiles(std::function filter) const override; private: /** A list of files in this map - * key = ResourceID for resource loader - * value = ResourceID to which file this request will be redirected + * key = ResourcePath for resource loader + * value = ResourcePath to which file this request will be redirected */ - std::unordered_map fileList; + std::unordered_map fileList; }; class DLL_LINKAGE CFilesystemList : public ISimpleResourceLoader @@ -68,15 +68,15 @@ public: ~CFilesystemList(); /// Interface implementation /// @see ISimpleResourceLoader - std::unique_ptr load(const ResourceID & resourceName) const override; - bool existsResource(const ResourceID & resourceName) const override; + std::unique_ptr load(const ResourcePath & resourceName) const override; + bool existsResource(const ResourcePath & resourceName) const override; std::string getMountPoint() const override; - std::optional getResourceName(const ResourceID & resourceName) const override; - std::set getResourceNames(const ResourceID & resourceName) const override; + std::optional getResourceName(const ResourcePath & resourceName) const override; + std::set getResourceNames(const ResourcePath & resourceName) const override; void updateFilteredFiles(std::function filter) const override; - std::unordered_set getFilteredFiles(std::function filter) const override; + std::unordered_set getFilteredFiles(std::function filter) const override; bool createResource(std::string filename, bool update = false) override; - std::vector getResourcesWithName(const ResourceID & resourceName) const override; + std::vector getResourcesWithName(const ResourcePath & resourceName) const override; /** * Adds a resource loader to the loaders list diff --git a/lib/filesystem/CArchiveLoader.cpp b/lib/filesystem/CArchiveLoader.cpp index b50f15f4d..c7b47f59c 100644 --- a/lib/filesystem/CArchiveLoader.cpp +++ b/lib/filesystem/CArchiveLoader.cpp @@ -78,7 +78,7 @@ void CArchiveLoader::initLODArchive(const std::string &mountPoint, CFileInputStr entry.compressedSize = reader.readUInt32(); // Add lod entry to local entries map - entries[ResourceID(mountPoint + entry.name)] = entry; + entries[ResourcePath(mountPoint + entry.name)] = entry; if(extractArchives) { @@ -123,7 +123,7 @@ void CArchiveLoader::initVIDArchive(const std::string &mountPoint, CFileInputStr entry.compressedSize = 0; offsets.insert(entry.offset); - entries[ResourceID(mountPoint + entry.name)] = entry; + entries[ResourcePath(mountPoint + entry.name)] = entry; } offsets.insert(static_cast(fileStream.getSize())); @@ -162,14 +162,14 @@ void CArchiveLoader::initSNDArchive(const std::string &mountPoint, CFileInputStr entry.offset = reader.readInt32(); entry.fullSize = reader.readInt32(); entry.compressedSize = 0; - entries[ResourceID(mountPoint + entry.name)] = entry; + entries[ResourcePath(mountPoint + entry.name)] = entry; if(extractArchives) extractToFolder("SOUND", fileStream, entry); } } -std::unique_ptr CArchiveLoader::load(const ResourceID & resourceName) const +std::unique_ptr CArchiveLoader::load(const ResourcePath & resourceName) const { assert(existsResource(resourceName)); @@ -187,7 +187,7 @@ std::unique_ptr CArchiveLoader::load(const ResourceID & resourceNa } } -bool CArchiveLoader::existsResource(const ResourceID & resourceName) const +bool CArchiveLoader::existsResource(const ResourcePath & resourceName) const { return entries.count(resourceName) != 0; } @@ -197,9 +197,9 @@ std::string CArchiveLoader::getMountPoint() const return mountPoint; } -std::unordered_set CArchiveLoader::getFilteredFiles(std::function filter) const +std::unordered_set CArchiveLoader::getFilteredFiles(std::function filter) const { - std::unordered_set foundID; + std::unordered_set foundID; for(const auto & file : entries) { @@ -229,7 +229,7 @@ void CArchiveLoader::extractToFolder(const std::string & outputSubFolder, CInput void CArchiveLoader::extractToFolder(const std::string & outputSubFolder, const std::string & mountPoint, ArchiveEntry entry) const { - std::unique_ptr inputStream = load(ResourceID(mountPoint + entry.name)); + std::unique_ptr inputStream = load(ResourcePath(mountPoint + entry.name)); entry.offset = 0; extractToFolder(outputSubFolder, *inputStream, entry); diff --git a/lib/filesystem/CArchiveLoader.h b/lib/filesystem/CArchiveLoader.h index d1ed59394..33b410062 100644 --- a/lib/filesystem/CArchiveLoader.h +++ b/lib/filesystem/CArchiveLoader.h @@ -10,7 +10,7 @@ #pragma once #include "ISimpleResourceLoader.h" -#include "ResourceID.h" +#include "ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -60,11 +60,11 @@ public: /// Interface implementation /// @see ISimpleResourceLoader - std::unique_ptr load(const ResourceID & resourceName) const override; - bool existsResource(const ResourceID & resourceName) const override; + std::unique_ptr load(const ResourcePath & resourceName) const override; + bool existsResource(const ResourcePath & resourceName) const override; std::string getMountPoint() const override; void updateFilteredFiles(std::function filter) const override {} - std::unordered_set getFilteredFiles(std::function filter) const override; + std::unordered_set getFilteredFiles(std::function filter) const override; /** Extracts one archive entry to the specified subfolder. Used for Video and Sound */ void extractToFolder(const std::string & outputSubFolder, CInputStream & fileStream, const ArchiveEntry & entry) const; /** Extracts one archive entry to the specified subfolder. Used for Images, Sprites, etc */ @@ -98,7 +98,7 @@ private: std::string mountPoint; /** Holds all entries of the archive file. An entry can be accessed via the entry name. **/ - std::unordered_map entries; + std::unordered_map entries; /** Specifies if Original H3 archives should be extracted to a separate folder **/ bool extractArchives; diff --git a/lib/filesystem/CFilesystemLoader.cpp b/lib/filesystem/CFilesystemLoader.cpp index d56f792be..c90df4dd0 100644 --- a/lib/filesystem/CFilesystemLoader.cpp +++ b/lib/filesystem/CFilesystemLoader.cpp @@ -23,7 +23,7 @@ CFilesystemLoader::CFilesystemLoader(std::string _mountPoint, boost::filesystem: logGlobal->trace("File system loaded, %d files found", fileList.size()); } -std::unique_ptr CFilesystemLoader::load(const ResourceID & resourceName) const +std::unique_ptr CFilesystemLoader::load(const ResourcePath & resourceName) const { assert(fileList.count(resourceName)); boost::filesystem::path file = baseDirectory / fileList.at(resourceName); @@ -31,7 +31,7 @@ std::unique_ptr CFilesystemLoader::load(const ResourceID & resourc return std::make_unique(file); } -bool CFilesystemLoader::existsResource(const ResourceID & resourceName) const +bool CFilesystemLoader::existsResource(const ResourcePath & resourceName) const { return fileList.count(resourceName); } @@ -41,7 +41,7 @@ std::string CFilesystemLoader::getMountPoint() const return mountPoint; } -std::optional CFilesystemLoader::getResourceName(const ResourceID & resourceName) const +std::optional CFilesystemLoader::getResourceName(const ResourcePath & resourceName) const { assert(existsResource(resourceName)); @@ -56,9 +56,9 @@ void CFilesystemLoader::updateFilteredFiles(std::function CFilesystemLoader::getFilteredFiles(std::function filter) const +std::unordered_set CFilesystemLoader::getFilteredFiles(std::function filter) const { - std::unordered_set foundID; + std::unordered_set foundID; for (auto & file : fileList) { @@ -70,7 +70,7 @@ std::unordered_set CFilesystemLoader::getFilteredFiles(std::function bool CFilesystemLoader::createResource(std::string filename, bool update) { - ResourceID resID(filename); + ResourcePath resID(filename); if (fileList.find(resID) != fileList.end()) return true; @@ -99,19 +99,19 @@ bool CFilesystemLoader::createResource(std::string filename, bool update) return true; } -std::unordered_map CFilesystemLoader::listFiles(const std::string &mountPoint, size_t depth, bool initial) const +std::unordered_map CFilesystemLoader::listFiles(const std::string &mountPoint, size_t depth, bool initial) const { - static const EResType::Type initArray[] = { + static const EResType initArray[] = { EResType::DIRECTORY, EResType::TEXT, EResType::ARCHIVE_LOD, EResType::ARCHIVE_VID, EResType::ARCHIVE_SND, EResType::ARCHIVE_ZIP }; - static const std::set initialTypes(initArray, initArray + std::size(initArray)); + static const std::set initialTypes(initArray, initArray + std::size(initArray)); assert(boost::filesystem::is_directory(baseDirectory)); - std::unordered_map fileList; + std::unordered_map fileList; std::vector path; //vector holding relative path to our file @@ -124,7 +124,7 @@ std::unordered_map CFilesystemLoader::listF for(; it != enddir; ++it) { - EResType::Type type; + EResType type; #if BOOST_VERSION >= 107200 const auto currentDepth = it.depth(); #else @@ -177,7 +177,7 @@ std::unordered_map CFilesystemLoader::listF else resName = mountPoint + filename.string(); - fileList[ResourceID(resName, type)] = std::move(filename); + fileList[ResourcePath(resName, type)] = std::move(filename); } } diff --git a/lib/filesystem/CFilesystemLoader.h b/lib/filesystem/CFilesystemLoader.h index 8aeb23581..9d7687865 100644 --- a/lib/filesystem/CFilesystemLoader.h +++ b/lib/filesystem/CFilesystemLoader.h @@ -10,7 +10,7 @@ #pragma once #include "ISimpleResourceLoader.h" -#include "ResourceID.h" +#include "ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -34,13 +34,13 @@ public: /// Interface implementation /// @see ISimpleResourceLoader - std::unique_ptr load(const ResourceID & resourceName) const override; - bool existsResource(const ResourceID & resourceName) const override; + std::unique_ptr load(const ResourcePath & resourceName) const override; + bool existsResource(const ResourcePath & resourceName) const override; std::string getMountPoint() const override; bool createResource(std::string filename, bool update = false) override; - std::optional getResourceName(const ResourceID & resourceName) const override; + std::optional getResourceName(const ResourcePath & resourceName) const override; void updateFilteredFiles(std::function filter) const override; - std::unordered_set getFilteredFiles(std::function filter) const override; + std::unordered_set getFilteredFiles(std::function filter) const override; private: /** The base directory which is scanned and indexed. */ @@ -51,10 +51,10 @@ private: size_t recursiveDepth; /** A list of files in the directory - * key = ResourceID for resource loader + * key = ResourcePath for resource loader * value = name that can be used to access file */ - mutable std::unordered_map fileList; + mutable std::unordered_map fileList; /** * Returns a list of pathnames denoting the files in the directory denoted by this pathname. @@ -65,7 +65,7 @@ private: * @return a list of pathnames denoting the files and directories in the directory denoted by this pathname * The array will be empty if the directory is empty. Ptr is null if the directory doesn't exist or if it isn't a directory. */ - std::unordered_map listFiles(const std::string &mountPoint, size_t depth, bool initial) const; + std::unordered_map listFiles(const std::string &mountPoint, size_t depth, bool initial) const; }; VCMI_LIB_NAMESPACE_END diff --git a/lib/filesystem/CZipLoader.cpp b/lib/filesystem/CZipLoader.cpp index ced952a1c..bc518f0d8 100644 --- a/lib/filesystem/CZipLoader.cpp +++ b/lib/filesystem/CZipLoader.cpp @@ -61,9 +61,9 @@ CZipLoader::CZipLoader(const std::string & mountPoint, const boost::filesystem:: logGlobal->trace("Zip archive loaded, %d files found", files.size()); } -std::unordered_map CZipLoader::listFiles(const std::string & mountPoint, const boost::filesystem::path & archive) +std::unordered_map CZipLoader::listFiles(const std::string & mountPoint, const boost::filesystem::path & archive) { - std::unordered_map ret; + std::unordered_map ret; unzFile file = unzOpen2_64(archive.c_str(), &zlibApi); @@ -84,7 +84,7 @@ std::unordered_map CZipLoader::listFiles(const std:: unzGetCurrentFileInfo64(file, &info, filename.data(), static_cast(filename.size()), nullptr, 0, nullptr, 0); std::string filenameString(filename.data(), filename.size()); - unzGetFilePos64(file, &ret[ResourceID(mountPoint + filenameString)]); + unzGetFilePos64(file, &ret[ResourcePath(mountPoint + filenameString)]); } while (unzGoToNextFile(file) == UNZ_OK); } @@ -93,12 +93,12 @@ std::unordered_map CZipLoader::listFiles(const std:: return ret; } -std::unique_ptr CZipLoader::load(const ResourceID & resourceName) const +std::unique_ptr CZipLoader::load(const ResourcePath & resourceName) const { return std::unique_ptr(new CZipStream(ioApi, archiveName, files.at(resourceName))); } -bool CZipLoader::existsResource(const ResourceID & resourceName) const +bool CZipLoader::existsResource(const ResourcePath & resourceName) const { return files.count(resourceName) != 0; } @@ -108,9 +108,9 @@ std::string CZipLoader::getMountPoint() const return mountPoint; } -std::unordered_set CZipLoader::getFilteredFiles(std::function filter) const +std::unordered_set CZipLoader::getFilteredFiles(std::function filter) const { - std::unordered_set foundID; + std::unordered_set foundID; for(const auto & file : files) { diff --git a/lib/filesystem/CZipLoader.h b/lib/filesystem/CZipLoader.h index 255624164..139e49188 100644 --- a/lib/filesystem/CZipLoader.h +++ b/lib/filesystem/CZipLoader.h @@ -11,7 +11,7 @@ #include "ISimpleResourceLoader.h" #include "CInputStream.h" -#include "ResourceID.h" +#include "ResourcePath.h" #include "CCompressedStream.h" #include "MinizipExtensions.h" @@ -46,19 +46,19 @@ class DLL_LINKAGE CZipLoader : public ISimpleResourceLoader boost::filesystem::path archiveName; std::string mountPoint; - std::unordered_map files; + std::unordered_map files; - std::unordered_map listFiles(const std::string & mountPoint, const boost::filesystem::path &archive); + std::unordered_map listFiles(const std::string & mountPoint, const boost::filesystem::path &archive); public: CZipLoader(const std::string & mountPoint, const boost::filesystem::path & archive, std::shared_ptr api = std::shared_ptr(new CDefaultIOApi())); /// Interface implementation /// @see ISimpleResourceLoader - std::unique_ptr load(const ResourceID & resourceName) const override; - bool existsResource(const ResourceID & resourceName) const override; + std::unique_ptr load(const ResourcePath & resourceName) const override; + bool existsResource(const ResourcePath & resourceName) const override; std::string getMountPoint() const override; void updateFilteredFiles(std::function filter) const override {} - std::unordered_set getFilteredFiles(std::function filter) const override; + std::unordered_set getFilteredFiles(std::function filter) const override; }; namespace ZipArchive diff --git a/lib/filesystem/Filesystem.cpp b/lib/filesystem/Filesystem.cpp index da8bba83e..726e9bb8b 100644 --- a/lib/filesystem/Filesystem.cpp +++ b/lib/filesystem/Filesystem.cpp @@ -84,7 +84,7 @@ void CFilesystemGenerator::loadDirectory(const std::string &mountPoint, const Js if (!config["depth"].isNull()) depth = static_cast(config["depth"].Float()); - ResourceID resID(URI, EResType::DIRECTORY); + ResourcePath resID(URI, EResType::DIRECTORY); for(auto & loader : CResourceHandler::get("initial")->getResourcesWithName(resID)) { @@ -96,16 +96,16 @@ void CFilesystemGenerator::loadDirectory(const std::string &mountPoint, const Js void CFilesystemGenerator::loadZipArchive(const std::string &mountPoint, const JsonNode & config) { std::string URI = prefix + config["path"].String(); - auto filename = CResourceHandler::get("initial")->getResourceName(ResourceID(URI, EResType::ARCHIVE_ZIP)); + auto filename = CResourceHandler::get("initial")->getResourceName(ResourcePath(URI, EResType::ARCHIVE_ZIP)); if (filename) filesystem->addLoader(new CZipLoader(mountPoint, *filename), false); } -template +template void CFilesystemGenerator::loadArchive(const std::string &mountPoint, const JsonNode & config) { std::string URI = prefix + config["path"].String(); - auto filename = CResourceHandler::get("initial")->getResourceName(ResourceID(URI, archiveType)); + auto filename = CResourceHandler::get("initial")->getResourceName(ResourcePath(URI, archiveType)); if (filename) filesystem->addLoader(new CArchiveLoader(mountPoint, *filename, extractArchives), false); } @@ -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(ResourceID(URI, EResType::TEXT)); + auto filename = CResourceHandler::get("initial")->getResourceName(ResourcePath(URI, EResType::TEXT)); if (filename) { - auto configData = CResourceHandler::get("initial")->load(ResourceID(URI, EResType::TEXT))->readAll(); + auto configData = CResourceHandler::get("initial")->load(ResourcePath(URI, EResType::TEXT))->readAll(); const JsonNode configInitial(reinterpret_cast(configData.first.get()), configData.second); filesystem->addLoader(new CMappedFileLoader(mountPoint, configInitial), false); } @@ -131,7 +131,7 @@ ISimpleResourceLoader * CResourceHandler::createInitial() //recurse only into specific directories auto recurseInDir = [&](const std::string & URI, int depth) { - ResourceID ID(URI, EResType::DIRECTORY); + ResourcePath ID(URI, EResType::DIRECTORY); for(auto & loader : initialLoader->getResourcesWithName(ID)) { @@ -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(ResourceID(fsConfigURI, EResType::TEXT))->readAll(); + auto fsConfigData = get("initial")->load(ResourcePath(fsConfigURI, EResType::TEXT))->readAll(); const JsonNode fsConfig(reinterpret_cast(fsConfigData.first.get()), fsConfigData.second); diff --git a/lib/filesystem/Filesystem.h b/lib/filesystem/Filesystem.h index a6b894ab0..1ead410f1 100644 --- a/lib/filesystem/Filesystem.h +++ b/lib/filesystem/Filesystem.h @@ -11,7 +11,7 @@ #include "CInputStream.h" #include "ISimpleResourceLoader.h" -#include "ResourceID.h" +#include "ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -27,7 +27,7 @@ class DLL_LINKAGE CFilesystemGenerator CFilesystemList * filesystem; std::string prefix; - template + template void loadArchive(const std::string & mountPoint, const JsonNode & config); void loadDirectory(const std::string & mountPoint, const JsonNode & config); void loadZipArchive(const std::string & mountPoint, const JsonNode & config); diff --git a/lib/filesystem/ISimpleResourceLoader.h b/lib/filesystem/ISimpleResourceLoader.h index 88c6a9fad..33272b1a9 100644 --- a/lib/filesystem/ISimpleResourceLoader.h +++ b/lib/filesystem/ISimpleResourceLoader.h @@ -12,7 +12,7 @@ VCMI_LIB_NAMESPACE_BEGIN class CInputStream; -class ResourceID; +class ResourcePath; /** * A class which knows the files containing in the archive or system and how to load them. @@ -28,14 +28,14 @@ public: * @param resourceName The unqiue resource name in space of the archive. * @return a input stream object */ - virtual std::unique_ptr load(const ResourceID & resourceName) const = 0; + virtual std::unique_ptr load(const ResourcePath & resourceName) const = 0; /** * Checks if the entry exists. * * @return Returns true if the entry exists, false if not. */ - virtual bool existsResource(const ResourceID & resourceName) const = 0; + virtual bool existsResource(const ResourcePath & resourceName) const = 0; /** * Gets mount point to which this loader was attached @@ -49,7 +49,7 @@ public: * * @return path or empty optional if file can't be accessed independently (e.g. file in archive) */ - virtual std::optional getResourceName(const ResourceID & resourceName) const + virtual std::optional getResourceName(const ResourcePath & resourceName) const { return std::optional(); } @@ -59,7 +59,7 @@ public: * * @return std::set with names. */ - virtual std::set getResourceNames(const ResourceID & resourceName) const + virtual std::set getResourceNames(const ResourcePath & resourceName) const { std::set result; auto rn = getResourceName(resourceName); @@ -83,7 +83,7 @@ public: * @param filter Filter that returns true if specified ID matches filter * @return Returns list of flies */ - virtual std::unordered_set getFilteredFiles(std::function filter) const = 0; + virtual std::unordered_set getFilteredFiles(std::function filter) const = 0; /** * Creates new resource with specified filename. @@ -100,7 +100,7 @@ public: * * @return vector with all loaders */ - virtual std::vector getResourcesWithName(const ResourceID & resourceName) const + virtual std::vector getResourcesWithName(const ResourcePath & resourceName) const { if (existsResource(resourceName)) return std::vector(1, this); diff --git a/lib/filesystem/ResourceID.h b/lib/filesystem/ResourceID.h deleted file mode 100644 index 0e597bd74..000000000 --- a/lib/filesystem/ResourceID.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * ResourceID.h, part of VCMI engine - * - * Authors: listed in file AUTHORS in main folder - * - * License: GNU General Public License v2.0 or later - * Full text of license available in license.txt file, in main folder - * - */ -#pragma once - -VCMI_LIB_NAMESPACE_BEGIN - - -/** - * Specifies the resource type. - * - * Supported file extensions: - * - * Text: .txt .json - * Animation: .def - * Mask: .msk .msg - * Campaign: .h3c - * Map: .h3m - * Font: .fnt - * Image: .bmp, .jpg, .pcx, .png, .tga - * Sound: .wav .82m - * Video: .smk, .bik .mjpg .mpg - * Music: .mp3, .ogg - * Archive: .lod, .snd, .vid .pac .zip - * Palette: .pal - * Savegame: .v*gm1 - */ -namespace EResType -{ - enum Type - { - TEXT, - ANIMATION, - MASK, - CAMPAIGN, - MAP, - BMP_FONT, - TTF_FONT, - IMAGE, - VIDEO, - SOUND, - ARCHIVE_VID, - ARCHIVE_ZIP, - ARCHIVE_SND, - ARCHIVE_LOD, - PALETTE, - SAVEGAME, - DIRECTORY, - ERM, - ERT, - ERS, - OTHER, - UNDEFINED, - LUA - }; -} - -/** - * A struct which identifies a resource clearly. - */ -class DLL_LINKAGE ResourceID -{ -public: - /** - * Default c-tor. - */ - //ResourceID(); - - /** - * Ctor. Can be used to create identifier for resource loading using one parameter - * - * @param fullName The resource name including extension. - */ - explicit ResourceID(std::string fullName); - - /** - * Ctor. - * - * @param name The resource name. - * @param type The resource type. A constant from the enumeration EResType. - */ - ResourceID(std::string name, EResType::Type type); - - /** - * Compares this object with a another resource identifier. - * - * @param other The other resource identifier. - * @return Returns true if both are equally, false if not. - */ - inline bool operator==(ResourceID const & other) const - { - return name == other.name && type == other.type; - } - - std::string getName() const {return name;} - std::string getOriginalName() const {return originalName;} - EResType::Type getType() const {return type;} - //void setName(std::string name); - //void setType(EResType::Type type); - -private: - /** - * Specifies the resource type. EResType::OTHER if not initialized. - * Required to prevent conflicts if files with different types (e.g. text and image) have the same name. - */ - EResType::Type type; - - /** Specifies the resource name. No extension so .pcx and .png can override each other, always in upper case. **/ - std::string name; - - /** name in original case **/ - std::string originalName; -}; - -/** - * A helper class which provides a functionality to convert extension strings to EResTypes. - */ -class DLL_LINKAGE EResTypeHelper -{ -public: - /** - * Converts a extension string to a EResType enum object. - * - * @param extension The extension string e.g. .BMP, .PNG - * @return Returns a EResType enum object - */ - static EResType::Type getTypeFromExtension(std::string extension); - - /** - * Gets the EResType as a string representation. - * - * @param type the EResType - * @return the type as a string representation - */ - static std::string getEResTypeAsString(EResType::Type type); -}; - -VCMI_LIB_NAMESPACE_END - - -namespace std -{ -template <> struct hash -{ - size_t operator()(const VCMI_LIB_WRAP_NAMESPACE(ResourceID) & resourceIdent) const - { - std::hash intHasher; - std::hash stringHasher; - return stringHasher(resourceIdent.getName()) ^ intHasher(static_cast(resourceIdent.getType())); - } -}; -} diff --git a/lib/filesystem/ResourceID.cpp b/lib/filesystem/ResourcePath.cpp similarity index 59% rename from lib/filesystem/ResourceID.cpp rename to lib/filesystem/ResourcePath.cpp index 75c516abf..120cb5203 100644 --- a/lib/filesystem/ResourceID.cpp +++ b/lib/filesystem/ResourcePath.cpp @@ -1,5 +1,5 @@ /* - * ResourceID.cpp, part of VCMI engine + * ResourcePath.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * @@ -8,39 +8,21 @@ * */ #include "StdInc.h" -#include "ResourceID.h" +#include "ResourcePath.h" #include "FileInfo.h" +#include "../JsonNode.h" +#include "../serializer/JsonDeserializer.h" +#include "../serializer/JsonSerializer.h" + VCMI_LIB_NAMESPACE_BEGIN -// trivial to_upper that completely ignores localization and only work with ASCII -// Technically not a problem since -// 1) Right now VCMI does not supports unicode in filenames on Win -// 2) Filesystem case-sensivity is only problem for H3 data which uses ASCII-only symbols -// for me (Ivan) this define gives notable decrease in loading times -// #define ENABLE_TRIVIAL_TOUPPER - -#ifdef ENABLE_TRIVIAL_TOUPPER -static inline void toUpper(char & symbol) -{ - static const int diff = 'a' - 'A'; - if (symbol >= 'a' && symbol <= 'z') - symbol -= diff; -} - -static inline void toUpper(std::string & string) -{ - for (char & symbol : string) - toUpper(symbol); -} -#else static inline void toUpper(std::string & string) { boost::to_upper(string); } -#endif -static inline EResType::Type readType(const std::string& name) +static inline EResType readType(const std::string& name) { return EResTypeHelper::getTypeFromExtension(FileInfo::GetExtension(name).to_string()); } @@ -67,63 +49,49 @@ static inline std::string readName(std::string name, bool uppercase) return name; } -#if 0 -ResourceID::ResourceID() - :type(EResType::OTHER) -{ -} -#endif - -ResourceID::ResourceID(std::string name_): - type{readType(name_)}, - name{readName(name_, true)}, - originalName{readName(std::move(name_), false)} +ResourcePath::ResourcePath(const std::string & name_): + type(readType(name_)), + name(readName(name_, true)), + originalName(readName(name_, false)) {} -ResourceID::ResourceID(std::string name_, EResType::Type type_): - type{type_}, - name{readName(name_, true)}, - originalName{readName(std::move(name_), false)} +ResourcePath::ResourcePath(const std::string & name_, EResType type_): + type(type_), + name(readName(name_, true)), + originalName(readName(name_, false)) {} -#if 0 -std::string ResourceID::getName() const + +ResourcePath::ResourcePath(const JsonNode & name, EResType type): + type(type), + name(readName(name.String(), true)), + originalName(readName(name.String(), false)) { - return name; } -EResType::Type ResourceID::getType() const +void ResourcePath::serializeJson(JsonSerializeFormat & handler) { - return type; -} - -void ResourceID::setName(std::string name) -{ - // setName shouldn't be used if type is UNDEFINED - assert(type != EResType::UNDEFINED); - - this->name = std::move(name); - - size_t dotPos = this->name.find_last_of("/."); - - if(dotPos != std::string::npos && this->name[dotPos] == '.' - && this->type == EResTypeHelper::getTypeFromExtension(this->name.substr(dotPos))) + if (!handler.saving) { - this->name.erase(dotPos); + JsonNode const & node = handler.getCurrent(); + + if (node.isString()) + { + name = readName(node.String(), true); + originalName = readName(node.String(), false); + return; + } } - toUpper(this->name); + handler.serializeInt("type", type); + handler.serializeString("name", name); + handler.serializeString("originalName", originalName); } -void ResourceID::setType(EResType::Type type) -{ - this->type = type; -} -#endif -EResType::Type EResTypeHelper::getTypeFromExtension(std::string extension) +EResType EResTypeHelper::getTypeFromExtension(std::string extension) { toUpper(extension); - static const std::map stringToRes = + static const std::map stringToRes = { {".TXT", EResType::TEXT}, {".JSON", EResType::TEXT}, @@ -173,11 +141,11 @@ EResType::Type EResTypeHelper::getTypeFromExtension(std::string extension) return iter->second; } -std::string EResTypeHelper::getEResTypeAsString(EResType::Type type) +std::string EResTypeHelper::getEResTypeAsString(EResType type) { #define MAP_ENUM(value) {EResType::value, #value}, - static const std::map stringToRes = + static const std::map stringToRes = { MAP_ENUM(TEXT) MAP_ENUM(ANIMATION) diff --git a/lib/filesystem/ResourcePath.h b/lib/filesystem/ResourcePath.h new file mode 100644 index 000000000..6ccfa1d8e --- /dev/null +++ b/lib/filesystem/ResourcePath.h @@ -0,0 +1,203 @@ +/* + * ResourcePath.h, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#pragma once + +VCMI_LIB_NAMESPACE_BEGIN + +class JsonNode; +class JsonSerializeFormat; + +/** + * Specifies the resource type. + * + * Supported file extensions: + * + * Text: .txt .json + * Animation: .def + * Mask: .msk .msg + * Campaign: .h3c + * Map: .h3m + * Font: .fnt + * Image: .bmp, .jpg, .pcx, .png, .tga + * Sound: .wav .82m + * Video: .smk, .bik .mjpg .mpg + * Music: .mp3, .ogg + * Archive: .lod, .snd, .vid .pac .zip + * Palette: .pal + * Savegame: .v*gm1 + */ +enum class EResType +{ + TEXT, + ANIMATION, + MASK, + CAMPAIGN, + MAP, + BMP_FONT, + TTF_FONT, + IMAGE, + VIDEO, + SOUND, + ARCHIVE_VID, + ARCHIVE_ZIP, + ARCHIVE_SND, + ARCHIVE_LOD, + PALETTE, + SAVEGAME, + DIRECTORY, + ERM, + ERT, + ERS, + LUA, + OTHER, + UNDEFINED, +}; + +/** + * A struct which identifies a resource clearly. + */ +class DLL_LINKAGE ResourcePath +{ +protected: + /// Constructs resource path based on JsonNode and selected type. File extension is ignored + ResourcePath(const JsonNode & name, EResType type); + +public: + /// Constructs resource path based on full name including extension + explicit ResourcePath(const std::string & fullName); + + /// Constructs resource path based on filename and selected type. File extension is ignored + ResourcePath(const std::string & name, EResType type); + + inline bool operator==(const ResourcePath & other) const + { + return name == other.name && type == other.type; + } + + inline bool operator<(const ResourcePath & other) const + { + if (type != other.type) + return type < other.type; + return name < other.name; + } + + bool empty() const {return name.empty();} + std::string getName() const {return name;} + std::string getOriginalName() const {return originalName;} + EResType getType() const {return type;} + + void serializeJson(JsonSerializeFormat & handler); + + template void serialize(Handler & h, const int version) + { + h & type; + h & name; + h & originalName; + } + +protected: + /// Specifies the resource type. EResType::OTHER if not initialized. + /// Required to prevent conflicts if files with different types (e.g. text and image) have the same name. + EResType type; + + /// Specifies the resource name. No extension so .pcx and .png can override each other, always in upper case. + std::string name; + + /// name in original case + std::string originalName; +}; + +template +class DLL_LINKAGE ResourcePathTempl : public ResourcePath +{ + template + friend class ResourcePathTempl; + + ResourcePathTempl(const ResourcePath & copy) + :ResourcePath(copy) + { + type = Type; + } + +public: + using ResourcePath::ResourcePath; + + ResourcePathTempl() + :ResourcePath("", Type) + {} + + static ResourcePathTempl builtin(const std::string & filename) + { + return ResourcePathTempl(filename, Type); + } + + static ResourcePathTempl builtinTODO(const std::string & filename) + { + return ResourcePathTempl(filename, Type); + } + + static ResourcePathTempl fromJson(const JsonNode & path) + { + return ResourcePathTempl(path, Type); + } + + template + ResourcePathTempl toType() const + { + ResourcePathTempl result(static_cast(*this)); + return result; + } + + ResourcePathTempl addPrefix(const std::string & prefix) const + { + ResourcePathTempl result; + result.name = prefix + this->getName(); + result.originalName = prefix + this->getOriginalName(); + + return result; + } +}; + +using AnimationPath = ResourcePathTempl; +using ImagePath = ResourcePathTempl; + +namespace EResTypeHelper +{ + /** + * Converts a extension string to a EResType enum object. + * + * @param extension The extension string e.g. .BMP, .PNG + * @return Returns a EResType enum object + */ + EResType getTypeFromExtension(std::string extension); + + /** + * Gets the EResType as a string representation. + * + * @param type the EResType + * @return the type as a string representation + */ + std::string getEResTypeAsString(EResType type); +}; + +VCMI_LIB_NAMESPACE_END + +namespace std +{ +template <> struct hash +{ + size_t operator()(const VCMI_LIB_WRAP_NAMESPACE(ResourcePath) & resourceIdent) const + { + std::hash intHasher; + std::hash stringHasher; + return stringHasher(resourceIdent.getName()) ^ intHasher(static_cast(resourceIdent.getType())); + } +}; +} diff --git a/lib/gameState/CGameState.cpp b/lib/gameState/CGameState.cpp index c81342752..18fd60bb3 100644 --- a/lib/gameState/CGameState.cpp +++ b/lib/gameState/CGameState.cpp @@ -29,7 +29,7 @@ #include "../VCMI_Lib.h" #include "../battle/BattleInfo.h" #include "../campaign/CampaignState.h" -#include "../filesystem/ResourceID.h" +#include "../filesystem/ResourcePath.h" #include "../mapObjectConstructors/AObjectTypeHandler.h" #include "../mapObjectConstructors/CObjectClassesHandler.h" #include "../mapObjectConstructors/DwellingInstanceConstructor.h" @@ -602,7 +602,7 @@ void CGameState::initNewGame(const IMapService * mapService, bool allowSavingRan else { logGlobal->info("Open map file: %s", scenarioOps->mapname); - const ResourceID mapURI(scenarioOps->mapname, EResType::MAP); + const ResourcePath mapURI(scenarioOps->mapname, EResType::MAP); map = mapService->loadMap(mapURI).release(); } } @@ -804,7 +804,7 @@ void CGameState::removeHeroPlaceholders() void CGameState::initStartingResources() { logGlobal->debug("\tSetting up resources"); - const JsonNode config(ResourceID("config/startres.json")); + const JsonNode config(ResourcePath("config/startres.json")); const JsonVector &vector = config["difficulty"].Vector(); const JsonNode &level = vector[scenarioOps->difficulty]; diff --git a/lib/mapObjectConstructors/CommonConstructors.cpp b/lib/mapObjectConstructors/CommonConstructors.cpp index 14aec1665..eab678f1d 100644 --- a/lib/mapObjectConstructors/CommonConstructors.cpp +++ b/lib/mapObjectConstructors/CommonConstructors.cpp @@ -182,10 +182,10 @@ void BoatInstanceConstructor::initTypeData(const JsonNode & input) layer = EPathfindingLayer(pos); onboardAssaultAllowed = input["onboardAssaultAllowed"].Bool(); onboardVisitAllowed = input["onboardVisitAllowed"].Bool(); - actualAnimation = input["actualAnimation"].String(); - overlayAnimation = input["overlayAnimation"].String(); + actualAnimation = AnimationPath::fromJson(input["actualAnimation"]); + overlayAnimation = AnimationPath::fromJson(input["overlayAnimation"]); for(int i = 0; i < flagAnimations.size() && i < input["flagAnimations"].Vector().size(); ++i) - flagAnimations[i] = input["flagAnimations"].Vector()[i].String(); + flagAnimations[i] = AnimationPath::fromJson(input["flagAnimations"].Vector()[i]); bonuses = JsonRandom::loadBonuses(input["bonuses"]); } @@ -201,7 +201,7 @@ void BoatInstanceConstructor::initializeObject(CGBoat * boat) const boat->addNewBonus(std::make_shared(b)); } -std::string BoatInstanceConstructor::getBoatAnimationName() const +AnimationPath BoatInstanceConstructor::getBoatAnimationName() const { return actualAnimation; } diff --git a/lib/mapObjectConstructors/CommonConstructors.h b/lib/mapObjectConstructors/CommonConstructors.h index 58ea22ca7..5c50ded30 100644 --- a/lib/mapObjectConstructors/CommonConstructors.h +++ b/lib/mapObjectConstructors/CommonConstructors.h @@ -113,15 +113,15 @@ protected: bool onboardAssaultAllowed; //if true, hero can attack units from transport bool onboardVisitAllowed; //if true, hero can visit objects from transport - std::string actualAnimation; //for OH3 boats those have actual animations - std::string overlayAnimation; //waves animations - std::array flagAnimations; + AnimationPath actualAnimation; //for OH3 boats those have actual animations + AnimationPath overlayAnimation; //waves animations + std::array flagAnimations; public: void initializeObject(CGBoat * object) const override; /// Returns boat preview animation, for use in Shipyards - std::string getBoatAnimationName() const; + AnimationPath getBoatAnimationName() const; template void serialize(Handler &h, const int version) { diff --git a/lib/mapObjects/CObjectHandler.cpp b/lib/mapObjects/CObjectHandler.cpp index dccbb6610..614877f31 100644 --- a/lib/mapObjects/CObjectHandler.cpp +++ b/lib/mapObjects/CObjectHandler.cpp @@ -12,14 +12,14 @@ #include "CObjectHandler.h" #include "CGObjectInstance.h" -#include "../filesystem/ResourceID.h" +#include "../filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN CObjectHandler::CObjectHandler() { logGlobal->trace("\t\tReading resources prices "); - const JsonNode config2(ResourceID("config/resources.json")); + const JsonNode config2(ResourcePath("config/resources.json")); for(const JsonNode &price : config2["resources_prices"].Vector()) { resVals.push_back(static_cast(price.Float())); diff --git a/lib/mapObjects/MiscObjects.h b/lib/mapObjects/MiscObjects.h index f159f418d..13488e6e2 100644 --- a/lib/mapObjects/MiscObjects.h +++ b/lib/mapObjects/MiscObjects.h @@ -354,9 +354,9 @@ public: EPathfindingLayer layer; //animation filenames. If empty - animations won't be used - std::string actualAnimation; //for OH3 boats those have actual animations - std::string overlayAnimation; //waves animations - std::array flagAnimations; + AnimationPath actualAnimation; //for OH3 boats those have actual animations + AnimationPath overlayAnimation; //waves animations + std::array flagAnimations; CGBoat(); bool isCoastVisitable() const override; diff --git a/lib/mapObjects/ObjectTemplate.cpp b/lib/mapObjects/ObjectTemplate.cpp index 675f98486..3b623c76c 100644 --- a/lib/mapObjects/ObjectTemplate.cpp +++ b/lib/mapObjects/ObjectTemplate.cpp @@ -116,8 +116,6 @@ void ObjectTemplate::afterLoadFixup() usedTiles[0][0] = VISITABLE; visitDir = 0xFF; } - boost::algorithm::replace_all(animationFile, "\\", "/"); - boost::algorithm::replace_all(editorAnimationFile, "\\", "/"); } void ObjectTemplate::readTxt(CLegacyConfigParser & parser) @@ -127,7 +125,7 @@ void ObjectTemplate::readTxt(CLegacyConfigParser & parser) boost::split(strings, data, boost::is_any_of(" ")); assert(strings.size() == 9); - animationFile = strings[0]; + animationFile = AnimationPath::builtin(strings[0]); stringID = strings[0]; std::string & blockStr = strings[1]; //block map, 0 = blocked, 1 = unblocked @@ -182,7 +180,7 @@ void ObjectTemplate::readTxt(CLegacyConfigParser & parser) void ObjectTemplate::readMsk() { - ResourceID resID("SPRITES/" + animationFile, EResType::MASK); + ResourcePath resID(animationFile.getName(), EResType::MASK); if (CResourceHandler::get()->existsResource(resID)) { @@ -197,7 +195,7 @@ void ObjectTemplate::readMsk() void ObjectTemplate::readMap(CBinaryReader & reader) { - animationFile = reader.readBaseString(); + animationFile = AnimationPath::builtin(reader.readBaseString()); setSize(8, 6); ui8 blockMask[6]; @@ -251,8 +249,8 @@ void ObjectTemplate::readMap(CBinaryReader & reader) void ObjectTemplate::readJson(const JsonNode &node, const bool withTerrain) { - animationFile = node["animation"].String(); - editorAnimationFile = node["editorAnimation"].String(); + animationFile = AnimationPath::fromJson(node["animation"]); + editorAnimationFile = AnimationPath::fromJson(node["editorAnimation"]); const JsonVector & visitDirs = node["visitableFrom"].Vector(); if (!visitDirs.empty()) @@ -325,8 +323,8 @@ void ObjectTemplate::readJson(const JsonNode &node, const bool withTerrain) void ObjectTemplate::writeJson(JsonNode & node, const bool withTerrain) const { - node["animation"].String() = animationFile; - node["editorAnimation"].String() = editorAnimationFile; + node["animation"].String() = animationFile.getOriginalName(); + node["editorAnimation"].String() = editorAnimationFile.getOriginalName(); if(visitDir != 0x0 && isVisitable()) { @@ -577,7 +575,7 @@ void ObjectTemplate::recalculate() calculateTopVisibleOffset(); if (visitable && visitDir == 0) - logMod->warn("Template for %s is visitable but has no visitable directions!", animationFile); + logMod->warn("Template for %s is visitable but has no visitable directions!", animationFile.getOriginalName()); } VCMI_LIB_NAMESPACE_END diff --git a/lib/mapObjects/ObjectTemplate.h b/lib/mapObjects/ObjectTemplate.h index 4560d75ea..3f967d76d 100644 --- a/lib/mapObjects/ObjectTemplate.h +++ b/lib/mapObjects/ObjectTemplate.h @@ -11,6 +11,7 @@ #include "../GameConstants.h" #include "../int3.h" +#include "../filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -47,10 +48,10 @@ public: /// print priority, objects with higher priority will be print first, below everything else si32 printPriority; /// animation file that should be used to display object - std::string animationFile; + AnimationPath animationFile; /// map editor only animation file - std::string editorAnimationFile; + AnimationPath editorAnimationFile; /// string ID, equals to def base name for h3m files (lower case, no extension) or specified in mod data std::string stringID; diff --git a/lib/mapping/CMapInfo.cpp b/lib/mapping/CMapInfo.cpp index 64796bb6f..e36ba25c2 100644 --- a/lib/mapping/CMapInfo.cpp +++ b/lib/mapping/CMapInfo.cpp @@ -12,7 +12,7 @@ #include -#include "../filesystem/ResourceID.h" +#include "../filesystem/ResourcePath.h" #include "../StartInfo.h" #include "../GameConstants.h" #include "CMapService.h" @@ -45,14 +45,14 @@ void CMapInfo::mapInit(const std::string & fname) { fileURI = fname; CMapService mapService; - ResourceID resource = ResourceID(fname, EResType::MAP); + ResourcePath resource = ResourcePath(fname, EResType::MAP); originalFileURI = resource.getOriginalName(); fullFileURI = boost::filesystem::canonical(*CResourceHandler::get()->getResourceName(resource)).string(); mapHeader = mapService.loadMapHeader(resource); countPlayers(); } -void CMapInfo::saveInit(const ResourceID & file) +void CMapInfo::saveInit(const ResourcePath & file) { CLoadFile lf(*CResourceHandler::get()->getResourceName(file), MINIMAL_SERIALIZATION_VERSION); lf.checkMagicBytes(SAVEGAME_MAGIC); @@ -73,7 +73,7 @@ void CMapInfo::saveInit(const ResourceID & file) void CMapInfo::campaignInit() { - ResourceID resource = ResourceID(fileURI, EResType::CAMPAIGN); + ResourcePath resource = ResourcePath(fileURI, EResType::CAMPAIGN); originalFileURI = resource.getOriginalName(); fullFileURI = boost::filesystem::canonical(*CResourceHandler::get()->getResourceName(resource)).string(); campaign = CampaignHandler::getHeader(fileURI); diff --git a/lib/mapping/CMapInfo.h b/lib/mapping/CMapInfo.h index 219969c4a..33d3874a1 100644 --- a/lib/mapping/CMapInfo.h +++ b/lib/mapping/CMapInfo.h @@ -15,7 +15,7 @@ struct StartInfo; class CMapHeader; class Campaign; -class ResourceID; +class ResourcePath; /** * A class which stores the count of human players and all players, the filename, @@ -46,7 +46,7 @@ public: CMapInfo &operator=(const CMapInfo &other) = delete; void mapInit(const std::string & fname); - void saveInit(const ResourceID & file); + void saveInit(const ResourcePath & file); void campaignInit(); void countPlayers(); // TODO: Those must be on client-side diff --git a/lib/mapping/CMapService.cpp b/lib/mapping/CMapService.cpp index e8a50e8d7..c17db6fc2 100644 --- a/lib/mapping/CMapService.cpp +++ b/lib/mapping/CMapService.cpp @@ -30,7 +30,7 @@ VCMI_LIB_NAMESPACE_BEGIN -std::unique_ptr CMapService::loadMap(const ResourceID & name) const +std::unique_ptr CMapService::loadMap(const ResourcePath & name) const { std::string modName = VLC->modh->findResourceOrigin(name); std::string language = VLC->modh->getModLanguage(modName); @@ -40,7 +40,7 @@ std::unique_ptr CMapService::loadMap(const ResourceID & name) const return getMapLoader(stream, name.getName(), modName, encoding)->loadMap(); } -std::unique_ptr CMapService::loadMapHeader(const ResourceID & name) const +std::unique_ptr CMapService::loadMapHeader(const ResourcePath & name) const { std::string modName = VLC->modh->findResourceOrigin(name); std::string language = VLC->modh->getModLanguage(modName); @@ -108,7 +108,7 @@ ModCompatibilityInfo CMapService::verifyMapHeaderMods(const CMapHeader & map) return modCompatibilityInfo; } -std::unique_ptr CMapService::getStreamFromFS(const ResourceID & name) +std::unique_ptr CMapService::getStreamFromFS(const ResourcePath & name) { return CResourceHandler::get()->load(name); } diff --git a/lib/mapping/CMapService.h b/lib/mapping/CMapService.h index 27c947a7d..9a8a33c7f 100644 --- a/lib/mapping/CMapService.h +++ b/lib/mapping/CMapService.h @@ -12,7 +12,7 @@ VCMI_LIB_NAMESPACE_BEGIN -class ResourceID; +class ResourcePath; class CMap; class CMapHeader; @@ -39,7 +39,7 @@ public: * @param name the name of the map * @return a unique ptr to the loaded map class */ - virtual std::unique_ptr loadMap(const ResourceID & name) const = 0; + virtual std::unique_ptr loadMap(const ResourcePath & name) const = 0; /** * Loads the VCMI/H3 map header specified by the name. @@ -47,7 +47,7 @@ public: * @param name the name of the map * @return a unique ptr to the loaded map header class */ - virtual std::unique_ptr loadMapHeader(const ResourceID & name) const = 0; + virtual std::unique_ptr loadMapHeader(const ResourcePath & name) const = 0; /** * Loads the VCMI/H3 map file from a buffer. This method is temporarily @@ -81,8 +81,8 @@ public: CMapService() = default; virtual ~CMapService() = default; - std::unique_ptr loadMap(const ResourceID & name) const override; - std::unique_ptr loadMapHeader(const ResourceID & name) const override; + std::unique_ptr loadMap(const ResourcePath & name) const override; + std::unique_ptr loadMapHeader(const ResourcePath & name) const override; std::unique_ptr loadMap(const uint8_t * buffer, int size, const std::string & name, const std::string & modName, const std::string & encoding) const override; std::unique_ptr loadMapHeader(const uint8_t * buffer, int size, const std::string & name, const std::string & modName, const std::string & encoding) const override; void saveMap(const std::unique_ptr & map, boost::filesystem::path fullPath) const override; @@ -101,7 +101,7 @@ private: * @param name the name of the map * @return a unique ptr to the input stream class */ - static std::unique_ptr getStreamFromFS(const ResourceID & name); + static std::unique_ptr getStreamFromFS(const ResourcePath & name); /** * Gets a map input stream from a buffer. diff --git a/lib/mapping/MapEditUtils.cpp b/lib/mapping/MapEditUtils.cpp index e6ff84f86..483abf928 100644 --- a/lib/mapping/MapEditUtils.cpp +++ b/lib/mapping/MapEditUtils.cpp @@ -174,7 +174,7 @@ void TerrainViewPattern::WeightedRule::setNative() CTerrainViewPatternConfig::CTerrainViewPatternConfig() { - const JsonNode config(ResourceID("config/terrainViewPatterns.json")); + const JsonNode config(ResourcePath("config/terrainViewPatterns.json")); static const std::string patternTypes[] = { "terrainView", "terrainType" }; for (int i = 0; i < std::size(patternTypes); ++i) { diff --git a/lib/mapping/MapFormatH3M.cpp b/lib/mapping/MapFormatH3M.cpp index cd8d341a6..e7040ce5d 100644 --- a/lib/mapping/MapFormatH3M.cpp +++ b/lib/mapping/MapFormatH3M.cpp @@ -984,8 +984,8 @@ void CMapLoaderH3M::readObjectTemplates() auto tmpl = reader->readObjectTemplate(); templates.push_back(tmpl); - if (!CResourceHandler::get()->existsResource(ResourceID( "SPRITES/" + tmpl->animationFile, EResType::ANIMATION))) - logMod->warn("Template animation %s of type (%d %d) is missing!", tmpl->animationFile, tmpl->id, tmpl->subid ); + if (!CResourceHandler::get()->existsResource(tmpl->animationFile)) + logMod->warn("Template animation %s of type (%d %d) is missing!", tmpl->animationFile.getOriginalName(), tmpl->id, tmpl->subid ); } } @@ -1328,7 +1328,7 @@ CGObjectInstance * CMapLoaderH3M::readGeneric(const int3 & mapPosition, std::sha if(VLC->objtypeh->knownSubObjects(objectTemplate->id).count(objectTemplate->subid)) return VLC->objtypeh->getHandlerFor(objectTemplate->id, objectTemplate->subid)->create(objectTemplate); - logGlobal->warn("Map '%s': Unrecognized object %d:%d ('%s') at %s found!", mapName, objectTemplate->id.toEnum(), objectTemplate->subid, objectTemplate->animationFile, mapPosition.toString()); + logGlobal->warn("Map '%s': Unrecognized object %d:%d ('%s') at %s found!", mapName, objectTemplate->id.toEnum(), objectTemplate->subid, objectTemplate->animationFile.getOriginalName(), mapPosition.toString()); return new CGObjectInstance(); } diff --git a/lib/mapping/MapFormatJson.cpp b/lib/mapping/MapFormatJson.cpp index e8bd5fbe1..3190ea6e8 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) { - ResourceID resource(archiveFilename, EResType::TEXT); + ResourcePath resource(archiveFilename, EResType::TEXT); if(!loader.existsResource(resource)) throw std::runtime_error(archiveFilename+" not found"); diff --git a/lib/mapping/MapIdentifiersH3M.cpp b/lib/mapping/MapIdentifiersH3M.cpp index 0c327939b..2a50df036 100644 --- a/lib/mapping/MapIdentifiersH3M.cpp +++ b/lib/mapping/MapIdentifiersH3M.cpp @@ -56,7 +56,7 @@ void MapIdentifiersH3M::loadMapping(const JsonNode & mapping) std::string h3mName = boost::to_lower_copy(entryTemplate.second.String()); std::string vcmiName = boost::to_lower_copy(entryTemplate.first); - if (!CResourceHandler::get()->existsResource(ResourceID( "SPRITES/" + vcmiName, EResType::ANIMATION))) + if (!CResourceHandler::get()->existsResource(ResourcePath( "SPRITES/" + vcmiName, EResType::ANIMATION))) logMod->warn("Template animation file %s was not found!", vcmiName); mappingObjectTemplate[h3mName] = vcmiName; @@ -108,10 +108,10 @@ void MapIdentifiersH3M::loadMapping(const JsonNode & mapping) void MapIdentifiersH3M::remapTemplate(ObjectTemplate & objectTemplate) { - std::string name = boost::to_lower_copy(objectTemplate.animationFile); + std::string name = boost::to_lower_copy(objectTemplate.animationFile.getName()); if (mappingObjectTemplate.count(name)) - objectTemplate.animationFile = mappingObjectTemplate.at(name); + objectTemplate.animationFile = AnimationPath::builtinTODO(mappingObjectTemplate.at(name)); ObjectTypeIdentifier objectType{ objectTemplate.id, objectTemplate.subid}; diff --git a/lib/modding/CModHandler.cpp b/lib/modding/CModHandler.cpp index a26ab4248..a43c91666 100644 --- a/lib/modding/CModHandler.cpp +++ b/lib/modding/CModHandler.cpp @@ -30,9 +30,9 @@ VCMI_LIB_NAMESPACE_BEGIN static JsonNode loadModSettings(const std::string & path) { - if (CResourceHandler::get("local")->existsResource(ResourceID(path))) + if (CResourceHandler::get("local")->existsResource(ResourcePath(path))) { - return JsonNode(ResourceID(path, EResType::TEXT)); + return JsonNode(ResourcePath(path, EResType::TEXT)); } // Probably new install. Create initial configuration CResourceHandler::get("local")->createResource(path); @@ -157,7 +157,7 @@ std::vector CModHandler::getModList(const std::string & path) const std::string modDir = boost::to_upper_copy(path + "MODS/"); size_t depth = boost::range::count(modDir, '/'); - auto list = CResourceHandler::get("initial")->getFilteredFiles([&](const ResourceID & id) -> bool + auto list = CResourceHandler::get("initial")->getFilteredFiles([&](const ResourcePath & id) -> bool { if (id.getType() != EResType::DIRECTORY) return false; @@ -200,9 +200,9 @@ void CModHandler::loadOneMod(std::string modName, const std::string & parent, co return; } - if(CResourceHandler::get("initial")->existsResource(ResourceID(CModInfo::getModFile(modFullName)))) + if(CResourceHandler::get("initial")->existsResource(ResourcePath(CModInfo::getModFile(modFullName)))) { - CModInfo mod(modFullName, modSettings[modName], JsonNode(ResourceID(CModInfo::getModFile(modFullName)))); + CModInfo mod(modFullName, modSettings[modName], JsonNode(ResourcePath(CModInfo::getModFile(modFullName)))); if (!parent.empty()) // this is submod, add parent to dependencies mod.dependencies.insert(parent); @@ -228,7 +228,7 @@ void CModHandler::loadMods(bool onlyEssential) loadMods("", "", modConfig["activeMods"], true); } - coreMod = std::make_unique(ModScope::scopeBuiltin(), modConfig[ModScope::scopeBuiltin()], JsonNode(ResourceID("config/gameConfig.json"))); + coreMod = std::make_unique(ModScope::scopeBuiltin(), modConfig[ModScope::scopeBuiltin()], JsonNode(ResourcePath("config/gameConfig.json"))); coreMod->name = "Original game files"; } @@ -283,19 +283,19 @@ static ui32 calculateModChecksum(const std::string & modName, ISimpleResourceLoa // FIXME: remove workaround for core mod if (modName != ModScope::scopeBuiltin()) { - ResourceID modConfFile(CModInfo::getModFile(modName), EResType::TEXT); + ResourcePath modConfFile(CModInfo::getModFile(modName), EResType::TEXT); ui32 configChecksum = CResourceHandler::get("initial")->load(modConfFile)->calculateCRC32(); modChecksum.process_bytes(reinterpret_cast(&configChecksum), sizeof(configChecksum)); } // third - add all detected text files from this mod into checksum - auto files = filesystem->getFilteredFiles([](const ResourceID & resID) + auto files = filesystem->getFilteredFiles([](const ResourcePath & resID) { return resID.getType() == EResType::TEXT && ( boost::starts_with(resID.getName(), "DATA") || boost::starts_with(resID.getName(), "CONFIG")); }); - for (const ResourceID & file : files) + for (const ResourcePath & file : files) { ui32 fileChecksum = filesystem->load(file)->calculateCRC32(); modChecksum.process_bytes(reinterpret_cast(&fileChecksum), sizeof(fileChecksum)); @@ -318,7 +318,7 @@ void CModHandler::loadModFilesystems() } } -TModID CModHandler::findResourceOrigin(const ResourceID & name) +TModID CModHandler::findResourceOrigin(const ResourcePath & name) { for(const auto & modID : boost::adaptors::reverse(activeMods)) { @@ -483,7 +483,7 @@ void CModHandler::afterLoad(bool onlyEssential) if(!onlyEssential) { - std::fstream file(CResourceHandler::get()->getResourceName(ResourceID("config/modSettings.json"))->c_str(), std::ofstream::out | std::ofstream::trunc); + std::fstream file(CResourceHandler::get()->getResourceName(ResourcePath("config/modSettings.json"))->c_str(), std::ofstream::out | std::ofstream::trunc); file << modSettings.toJson(); } diff --git a/lib/modding/CModHandler.h b/lib/modding/CModHandler.h index eaa84d84a..2fbc33fb6 100644 --- a/lib/modding/CModHandler.h +++ b/lib/modding/CModHandler.h @@ -20,7 +20,7 @@ class JsonNode; class IHandlerBase; class CIdentifierStorage; class CContentHandler; -class ResourceID; +class ResourcePath; using TModID = std::string; @@ -67,7 +67,7 @@ public: void loadModFilesystems(); /// returns ID of mod that provides selected file resource - TModID findResourceOrigin(const ResourceID & name); + TModID findResourceOrigin(const ResourcePath & name); std::string getModLanguage(const TModID & modId) const; diff --git a/lib/modding/CModInfo.cpp b/lib/modding/CModInfo.cpp index 4baab342a..7fb5fd48a 100644 --- a/lib/modding/CModInfo.cpp +++ b/lib/modding/CModInfo.cpp @@ -152,7 +152,7 @@ bool CModInfo::checkModGameplayAffecting() const "obstacles" }; - ResourceID modFileResource(CModInfo::getModFile(identifier)); + ResourcePath modFileResource(CModInfo::getModFile(identifier)); if(CResourceHandler::get("initial")->existsResource(modFileResource)) { diff --git a/lib/rmg/CMapGenerator.cpp b/lib/rmg/CMapGenerator.cpp index d526d17c5..d18e7b5c4 100644 --- a/lib/rmg/CMapGenerator.cpp +++ b/lib/rmg/CMapGenerator.cpp @@ -51,7 +51,7 @@ int CMapGenerator::getRandomSeed() const void CMapGenerator::loadConfig() { - static const ResourceID path("config/randomMap.json"); + static const ResourcePath path("config/randomMap.json"); JsonNode randomMapJson(path); config.shipyardGuard = randomMapJson["waterZone"]["shipyard"]["value"].Integer(); diff --git a/lib/rmg/modificators/RiverPlacer.cpp b/lib/rmg/modificators/RiverPlacer.cpp index 3df3f1d03..0738bdc72 100644 --- a/lib/rmg/modificators/RiverPlacer.cpp +++ b/lib/rmg/modificators/RiverPlacer.cpp @@ -390,7 +390,7 @@ void RiverPlacer::connectRiver(const int3 & tile) throw rmgException(boost::str(boost::format("River templates for (%d,%d) at terrain %s, river %s are incorrect") % RIVER_DELTA_ID % RIVER_DELTA_SUBTYPE % zone.getTerrainType() % river->shortIdentifier)); - std::string targetTemplateName = river->deltaName + std::to_string(deltaOrientations[pos]) + ".def"; + AnimationPath targetTemplateName = AnimationPath::builtinTODO(river->deltaName + std::to_string(deltaOrientations[pos]) + ".def"); for(auto & templ : tmplates) { if(templ->animationFile == targetTemplateName) diff --git a/lib/spells/CSpellHandler.cpp b/lib/spells/CSpellHandler.cpp index f048d36c5..fdb16c975 100644 --- a/lib/spells/CSpellHandler.cpp +++ b/lib/spells/CSpellHandler.cpp @@ -516,9 +516,9 @@ CSpell::AnimationItem::AnimationItem() : } ///CSpell::AnimationInfo -std::string CSpell::AnimationInfo::selectProjectile(const double angle) const +AnimationPath CSpell::AnimationInfo::selectProjectile(const double angle) const { - std::string res; + AnimationPath res; double maximum = 0.0; for(const auto & info : projectile) @@ -861,10 +861,10 @@ CSpell * CSpellHandler::loadFromJson(const std::string & scope, const JsonNode & CSpell::TAnimation newItem; if(item.getType() == JsonNode::JsonType::DATA_STRING) - newItem.resourceName = item.String(); + newItem.resourceName = AnimationPath::fromJson(item); else if(item.getType() == JsonNode::JsonType::DATA_STRUCT) { - newItem.resourceName = item["defName"].String(); + newItem.resourceName = AnimationPath::fromJson(item["defName"]); newItem.effectName = item["effectName"].String(); auto vPosStr = item["verticalPosition"].String(); @@ -889,7 +889,7 @@ CSpell * CSpellHandler::loadFromJson(const std::string & scope, const JsonNode & for(const JsonNode & item : projectile) { CSpell::ProjectileInfo info; - info.resourceName = item["defName"].String(); + info.resourceName = AnimationPath::fromJson(item["defName"]); info.minimumAngle = item["minimumAngle"].Float(); spell->animationInfo.projectile.push_back(info); diff --git a/lib/spells/CSpellHandler.h b/lib/spells/CSpellHandler.h index c4a419c27..9d8bea267 100644 --- a/lib/spells/CSpellHandler.h +++ b/lib/spells/CSpellHandler.h @@ -20,6 +20,7 @@ #include "../GameConstants.h" #include "../battle/BattleHex.h" #include "../bonuses/Bonus.h" +#include "../filesystem/ResourcePath.h" VCMI_LIB_NAMESPACE_BEGIN @@ -65,7 +66,7 @@ public: double minimumAngle; ///resource name - std::string resourceName; + AnimationPath resourceName; template void serialize(Handler & h, const int version) { @@ -76,7 +77,7 @@ public: struct AnimationItem { - std::string resourceName; + AnimationPath resourceName; std::string effectName; VerticalPosition verticalPosition; int pause; @@ -119,7 +120,7 @@ public: h & affect; } - std::string selectProjectile(const double angle) const; + AnimationPath selectProjectile(const double angle) const; } animationInfo; public: diff --git a/lib/spells/effects/Obstacle.cpp b/lib/spells/effects/Obstacle.cpp index 5a3247694..428e065e3 100644 --- a/lib/spells/effects/Obstacle.cpp +++ b/lib/spells/effects/Obstacle.cpp @@ -86,8 +86,8 @@ void ObstacleSideOptions::serializeJson(JsonSerializeFormat & handler) serializeRelativeShape(handler, "range", range); handler.serializeString("appearSound", appearSound); - handler.serializeString("appearAnimation", appearAnimation); - handler.serializeString("animation", animation); + handler.serializeStruct("appearAnimation", appearAnimation); + handler.serializeStruct("animation", animation); handler.serializeInt("offsetY", offsetY); } diff --git a/lib/spells/effects/Obstacle.h b/lib/spells/effects/Obstacle.h index 4bf9159b3..a1e9b1f56 100644 --- a/lib/spells/effects/Obstacle.h +++ b/lib/spells/effects/Obstacle.h @@ -31,8 +31,8 @@ public: RelativeShape range; //position of obstacles relative to effect destination std::string appearSound; - std::string appearAnimation; - std::string animation; + AnimationPath appearAnimation; + AnimationPath animation; int offsetY = 0; diff --git a/mapeditor/Animation.cpp b/mapeditor/Animation.cpp index 45d003f24..80795d02a 100644 --- a/mapeditor/Animation.cpp +++ b/mapeditor/Animation.cpp @@ -81,7 +81,7 @@ class FileCache static const int cacheSize = 50; //Max number of cached files struct FileData { - ResourceID name; + ResourcePath name; size_t size; std::unique_ptr data; @@ -91,7 +91,7 @@ class FileCache std::copy(data.get(), data.get() + size, ret.get()); return ret; } - FileData(ResourceID name_, size_t size_, std::unique_ptr data_): + FileData(ResourcePath name_, size_t size_, std::unique_ptr data_): name{std::move(name_)}, size{size_}, data{std::move(data_)} @@ -100,7 +100,7 @@ class FileCache std::deque cache; public: - std::unique_ptr getCachedFile(ResourceID rid) + std::unique_ptr getCachedFile(ResourcePath rid) { for(auto & file : cache) { @@ -169,7 +169,7 @@ DefFile::DefFile(std::string Name): qRgba(0, 0, 0, 128), // 50% - shadow body below selection qRgba(0, 0, 0, 64) // 75% - shadow border below selection }; - data = animationCache.getCachedFile(ResourceID(std::string("SPRITES/") + Name, EResType::ANIMATION)); + data = animationCache.getCachedFile(ResourcePath(std::string("SPRITES/") + Name, EResType::ANIMATION)); palette = std::make_unique>(256); int it = 0; @@ -583,7 +583,7 @@ void Animation::init() source[defEntry.first].resize(defEntry.second); } - ResourceID resID(std::string("SPRITES/") + name, EResType::TEXT); + ResourcePath resID(std::string("SPRITES/") + name, EResType::TEXT); //if(vstd::contains(graphics->imageLists, resID.getName())) //initFromJson(graphics->imageLists[resID.getName()]); @@ -656,7 +656,7 @@ Animation::Animation(std::string Name): name.erase(dotPos); std::transform(name.begin(), name.end(), name.begin(), toupper); - ResourceID resource(std::string("SPRITES/") + name, EResType::ANIMATION); + ResourcePath resource(std::string("SPRITES/") + name, EResType::ANIMATION); if(CResourceHandler::get()->existsResource(resource)) defFile = std::make_shared(name); diff --git a/mapeditor/BitmapHandler.cpp b/mapeditor/BitmapHandler.cpp index 79034c88c..67c5d4224 100644 --- a/mapeditor/BitmapHandler.cpp +++ b/mapeditor/BitmapHandler.cpp @@ -92,13 +92,13 @@ namespace BitmapHandler logGlobal->warn("Call to loadBitmap with void fname!"); return QImage(); } - if(!CResourceHandler::get()->existsResource(ResourceID(path + fname, EResType::IMAGE))) + if(!CResourceHandler::get()->existsResource(ResourcePath(path + fname, EResType::IMAGE))) { return QImage(); } - auto fullpath = CResourceHandler::get()->getResourceName(ResourceID(path + fname, EResType::IMAGE)); - auto readFile = CResourceHandler::get()->load(ResourceID(path + fname, EResType::IMAGE))->readAll(); + auto fullpath = CResourceHandler::get()->getResourceName(ResourcePath(path + fname, EResType::IMAGE)); + auto readFile = CResourceHandler::get()->load(ResourcePath(path + fname, EResType::IMAGE))->readAll(); if(isPCX(readFile.first.get())) {//H3-style PCX diff --git a/mapeditor/graphics.cpp b/mapeditor/graphics.cpp index ce797921c..0466a56ca 100644 --- a/mapeditor/graphics.cpp +++ b/mapeditor/graphics.cpp @@ -40,7 +40,7 @@ Graphics * graphics = nullptr; void Graphics::loadPaletteAndColors() { - auto textFile = CResourceHandler::get()->load(ResourceID("DATA/PLAYERS.PAL"))->readAll(); + auto textFile = CResourceHandler::get()->load(ResourcePath("DATA/PLAYERS.PAL"))->readAll(); std::string pals((char*)textFile.first.get(), textFile.second); playerColorPalette.resize(256); @@ -59,7 +59,7 @@ void Graphics::loadPaletteAndColors() neutralColorPalette.resize(32); - auto stream = CResourceHandler::get()->load(ResourceID("config/NEUTRAL.PAL")); + auto stream = CResourceHandler::get()->load(ResourcePath("config/NEUTRAL.PAL")); CBinaryReader reader(stream.get()); for(int i = 0; i < 32; ++i) @@ -129,8 +129,8 @@ void Graphics::loadHeroAnimations() { for(auto templ : VLC->objtypeh->getHandlerFor(Obj::HERO, elem->getIndex())->getTemplates()) { - if(!heroAnimations.count(templ->animationFile)) - heroAnimations[templ->animationFile] = loadHeroAnimation(templ->animationFile); + if(!heroAnimations.count(templ->animationFile.getName())) + heroAnimations[templ->animationFile.getName()] = loadHeroAnimation(templ->animationFile.getName()); } } @@ -270,7 +270,7 @@ std::shared_ptr Graphics::getHeroAnimation(const std::shared_ptr(); } - std::shared_ptr ret = loadHeroAnimation(info->animationFile); + std::shared_ptr ret = loadHeroAnimation(info->animationFile.getName()); //already loaded if(ret) @@ -279,8 +279,8 @@ std::shared_ptr Graphics::getHeroAnimation(const std::shared_ptr(info->animationFile); - heroAnimations[info->animationFile] = ret; + ret = std::make_shared(info->animationFile.getOriginalName()); + heroAnimations[info->animationFile.getName()] = ret; ret->preload(); return ret; @@ -294,7 +294,7 @@ std::shared_ptr Graphics::getAnimation(const std::shared_ptr(); } - std::shared_ptr ret = mapObjectAnimations[info->animationFile]; + std::shared_ptr ret = mapObjectAnimations[info->animationFile.getName()]; //already loaded if(ret) @@ -303,8 +303,8 @@ std::shared_ptr Graphics::getAnimation(const std::shared_ptr(info->animationFile); - mapObjectAnimations[info->animationFile] = ret; + ret = std::make_shared(info->animationFile.getOriginalName()); + mapObjectAnimations[info->animationFile.getName()] = ret; ret->preload(); return ret; diff --git a/mapeditor/mainwindow.cpp b/mapeditor/mainwindow.cpp index bb99703e6..4b481ac72 100644 --- a/mapeditor/mainwindow.cpp +++ b/mapeditor/mainwindow.cpp @@ -181,7 +181,7 @@ MainWindow::MainWindow(QWidget* parent) : // Some basic data validation to produce better error messages in cases of incorrect install auto testFile = [](std::string filename, std::string message) -> bool { - if (CResourceHandler::get()->existsResource(ResourceID(filename))) + if (CResourceHandler::get()->existsResource(ResourcePath(filename))) return true; logGlobal->error("Error: %s was not found!", message); @@ -317,7 +317,7 @@ bool MainWindow::openMap(const QString & filenameSelect) std::string fname = fi.fileName().toStdString(); std::string fdir = fi.dir().path().toStdString(); - ResourceID resId("MAPEDITOR/" + fname, EResType::MAP); + ResourcePath resId("MAPEDITOR/" + fname, EResType::MAP); //addFilesystem takes care about memory deallocation if case of failure, no memory leak here auto * mapEditorFilesystem = new CFilesystemLoader("MAPEDITOR/", fdir, 0); @@ -512,13 +512,13 @@ void MainWindow::addGroupIntoCatalog(const std::string & groupName, bool useCust auto templ = templates[templateId]; //selecting file - const std::string & afile = templ->editorAnimationFile.empty() ? templ->animationFile : templ->editorAnimationFile; + const AnimationPath & afile = templ->editorAnimationFile.empty() ? templ->animationFile : templ->editorAnimationFile; //creating picture QPixmap preview(128, 128); preview.fill(QColor(255, 255, 255)); QPainter painter(&preview); - Animation animation(afile); + Animation animation(afile.getOriginalName()); animation.preload(); auto picture = animation.getImage(0); if(picture && picture->width() && picture->height()) @@ -533,8 +533,8 @@ void MainWindow::addGroupIntoCatalog(const std::string & groupName, bool useCust QJsonObject data{{"id", QJsonValue(ID)}, {"subid", QJsonValue(secondaryID)}, {"template", QJsonValue(templateId)}, - {"animationEditor", QString::fromStdString(templ->editorAnimationFile)}, - {"animation", QString::fromStdString(templ->animationFile)}, + {"animationEditor", QString::fromStdString(templ->editorAnimationFile.getOriginalName())}, + {"animation", QString::fromStdString(templ->animationFile.getOriginalName())}, {"preview", jsonFromPixmap(preview)}}; //create object to extract name diff --git a/mapeditor/maphandler.cpp b/mapeditor/maphandler.cpp index f5f3790ed..891d83901 100644 --- a/mapeditor/maphandler.cpp +++ b/mapeditor/maphandler.cpp @@ -81,15 +81,15 @@ void MapHandler::initTerrainGraphics() std::map riverFiles; for(const auto & terrain : VLC->terrainTypeHandler->objects) { - terrainFiles[terrain->getJsonKey()] = terrain->tilesFilename; + terrainFiles[terrain->getJsonKey()] = terrain->tilesFilename.getName(); } for(const auto & river : VLC->riverTypeHandler->objects) { - riverFiles[river->getJsonKey()] = river->tilesFilename; + riverFiles[river->getJsonKey()] = river->tilesFilename.getName(); } for(const auto & road : VLC->roadTypeHandler->objects) { - roadFiles[road->getJsonKey()] = road->tilesFilename; + roadFiles[road->getJsonKey()] = road->tilesFilename.getName(); } loadFlipped(terrainAnimations, terrainImages, terrainFiles); diff --git a/mapeditor/resourceExtractor/ResourceConverter.cpp b/mapeditor/resourceExtractor/ResourceConverter.cpp index f413c40dc..a6481ed58 100644 --- a/mapeditor/resourceExtractor/ResourceConverter.cpp +++ b/mapeditor/resourceExtractor/ResourceConverter.cpp @@ -69,7 +69,7 @@ void ResourceConverter::doConvertPcxToPng(const boost::filesystem::path & source void ResourceConverter::splitDefFile(const std::string & fileName, const boost::filesystem::path & sourceFolder, bool deleteOriginals) { - if(CResourceHandler::get()->existsResource(ResourceID("SPRITES/" + fileName))) + if(CResourceHandler::get()->existsResource(ResourcePath("SPRITES/" + fileName))) { std::unique_ptr anim = std::make_unique(fileName); anim->preload(); diff --git a/scripting/lua/LuaScriptingContext.cpp b/scripting/lua/LuaScriptingContext.cpp index 4b3508610..8759ad7b3 100644 --- a/scripting/lua/LuaScriptingContext.cpp +++ b/scripting/lua/LuaScriptingContext.cpp @@ -522,7 +522,7 @@ int LuaContext::loadModule() modulePath = "scripts/lib/" + modulePath; - ResourceID id(modulePath, EResType::LUA); + ResourcePath id(modulePath, EResType::LUA); if(!loader->existsResource(id)) return errorRetVoid("Module not found: "+modulePath); diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index d6f700b6e..b60723b28 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1722,7 +1722,7 @@ void CGameHandler::save(const std::string & filename) try { { - CSaveFile save(*CResourceHandler::get("local")->getResourceName(ResourceID(stem.to_string(), EResType::SAVEGAME))); + CSaveFile save(*CResourceHandler::get("local")->getResourceName(ResourcePath(stem.to_string(), EResType::SAVEGAME))); saveCommonState(save); logGlobal->info("Saving server state"); save << *this; @@ -1745,7 +1745,7 @@ bool CGameHandler::load(const std::string & filename) try { { - CLoadFile lf(*CResourceHandler::get()->getResourceName(ResourceID(stem.to_string(), EResType::SAVEGAME)), MINIMAL_SERIALIZATION_VERSION); + CLoadFile lf(*CResourceHandler::get()->getResourceName(ResourcePath(stem.to_string(), EResType::SAVEGAME)), MINIMAL_SERIALIZATION_VERSION); loadCommonState(lf); logGlobal->info("Loading server state"); lf >> *this; diff --git a/test/game/CGameStateTest.cpp b/test/game/CGameStateTest.cpp index 4b41d2e3e..52786cc63 100644 --- a/test/game/CGameStateTest.cpp +++ b/test/game/CGameStateTest.cpp @@ -23,7 +23,7 @@ #include "../../lib/battle/BattleInfo.h" #include "../../lib/CStack.h" -#include "../../lib/filesystem/ResourceID.h" +#include "../../lib/filesystem/ResourcePath.h" #include "../../lib/mapping/CMap.h" @@ -146,7 +146,7 @@ public: si.mode = StartInfo::NEW_GAME; si.seedToBeUsed = 42; - std::unique_ptr header = mapService.loadMapHeader(ResourceID(si.mapname)); + std::unique_ptr header = mapService.loadMapHeader(ResourcePath(si.mapname)); ASSERT_NE(header.get(), nullptr); diff --git a/test/map/CMapEditManagerTest.cpp b/test/map/CMapEditManagerTest.cpp index 0b29d06ef..048c2f5bd 100644 --- a/test/map/CMapEditManagerTest.cpp +++ b/test/map/CMapEditManagerTest.cpp @@ -10,7 +10,7 @@ #include "StdInc.h" -#include "../lib/filesystem/ResourceID.h" +#include "../lib/filesystem/ResourcePath.h" #include "../lib/mapping/CMapService.h" #include "../lib/mapping/CMap.h" #include "../lib/TerrainHandler.h" @@ -111,7 +111,7 @@ TEST(MapManager, DrawTerrain_View) { try { - const ResourceID testMap("test/TerrainViewTest", EResType::MAP); + const ResourcePath testMap("test/TerrainViewTest", EResType::MAP); // Load maps and json config CMapService mapService; const auto originalMap = mapService.loadMap(testMap); @@ -120,7 +120,7 @@ TEST(MapManager, DrawTerrain_View) // Validate edit manager auto editManager = map->getEditManager(); CRandomGenerator gen; - const JsonNode viewNode(ResourceID("test/terrainViewMappings", EResType::TEXT)); + const JsonNode viewNode(ResourcePath("test/terrainViewMappings", EResType::TEXT)); const auto & mappingsNode = viewNode["mappings"].Vector(); for (const auto & node : mappingsNode) { diff --git a/test/map/CMapFormatTest.cpp b/test/map/CMapFormatTest.cpp index c1acc6b35..030cfd20a 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) { - ResourceID resource(archiveFilename, EResType::TEXT); + ResourcePath resource(archiveFilename, EResType::TEXT); if(!archive.existsResource(resource)) throw std::runtime_error(archiveFilename + " not found"); @@ -153,14 +153,14 @@ TEST(MapFormat, Objects) { static const std::string MAP_DATA_PATH = "test/ObjectPropertyTest/"; - const JsonNode initialHeader(ResourceID(MAP_DATA_PATH + CMapFormatJson::HEADER_FILE_NAME)); - const JsonNode expectedHeader(ResourceID(MAP_DATA_PATH + CMapFormatJson::HEADER_FILE_NAME));//same as initial for now + const JsonNode initialHeader(ResourcePath(MAP_DATA_PATH + CMapFormatJson::HEADER_FILE_NAME)); + const JsonNode expectedHeader(ResourcePath(MAP_DATA_PATH + CMapFormatJson::HEADER_FILE_NAME));//same as initial for now - const JsonNode initialObjects(ResourceID(MAP_DATA_PATH + CMapFormatJson::OBJECTS_FILE_NAME)); - const JsonNode expectedObjects(ResourceID(MAP_DATA_PATH + "objects.ex.json")); + const JsonNode initialObjects(ResourcePath(MAP_DATA_PATH + CMapFormatJson::OBJECTS_FILE_NAME)); + const JsonNode expectedObjects(ResourcePath(MAP_DATA_PATH + "objects.ex.json")); - const JsonNode expectedSurface(ResourceID(MAP_DATA_PATH + "surface_terrain.json")); - const JsonNode expectedUnderground(ResourceID(MAP_DATA_PATH + "underground_terrain.json")); + const JsonNode expectedSurface(ResourcePath(MAP_DATA_PATH + "surface_terrain.json")); + const JsonNode expectedUnderground(ResourcePath(MAP_DATA_PATH + "underground_terrain.json")); std::unique_ptr originalMap = loadOriginal(initialHeader, initialObjects, expectedSurface, expectedUnderground); @@ -192,11 +192,11 @@ TEST(MapFormat, Terrain) { static const std::string MAP_DATA_PATH = "test/TerrainTest/"; - const JsonNode expectedHeader(ResourceID(MAP_DATA_PATH + CMapFormatJson::HEADER_FILE_NAME)); - const JsonNode expectedObjects(ResourceID(MAP_DATA_PATH + CMapFormatJson::OBJECTS_FILE_NAME)); + const JsonNode expectedHeader(ResourcePath(MAP_DATA_PATH + CMapFormatJson::HEADER_FILE_NAME)); + const JsonNode expectedObjects(ResourcePath(MAP_DATA_PATH + CMapFormatJson::OBJECTS_FILE_NAME)); - const JsonNode expectedSurface(ResourceID(MAP_DATA_PATH + "surface_terrain.json")); - const JsonNode expectedUnderground(ResourceID(MAP_DATA_PATH + "underground_terrain.json")); + const JsonNode expectedSurface(ResourcePath(MAP_DATA_PATH + "surface_terrain.json")); + const JsonNode expectedUnderground(ResourcePath(MAP_DATA_PATH + "underground_terrain.json")); std::unique_ptr originalMap = loadOriginal(expectedHeader, expectedObjects, expectedSurface, expectedUnderground); diff --git a/test/mock/mock_MapService.cpp b/test/mock/mock_MapService.cpp index 1b85b9edf..8e0c83591 100644 --- a/test/mock/mock_MapService.cpp +++ b/test/mock/mock_MapService.cpp @@ -23,15 +23,15 @@ MapServiceMock::MapServiceMock(const std::string & path, MapListener * mapListen CZipSaver saver(io, "_"); - const JsonNode header(ResourceID(path+CMapFormatJson::HEADER_FILE_NAME)); - const JsonNode objects(ResourceID(path+CMapFormatJson::OBJECTS_FILE_NAME)); - const JsonNode surface(ResourceID(path+"surface_terrain.json")); + const JsonNode header(ResourcePath(path+CMapFormatJson::HEADER_FILE_NAME)); + const JsonNode objects(ResourcePath(path+CMapFormatJson::OBJECTS_FILE_NAME)); + const JsonNode surface(ResourcePath(path+"surface_terrain.json")); addToArchive(saver, header, CMapFormatJson::HEADER_FILE_NAME); addToArchive(saver, objects, CMapFormatJson::OBJECTS_FILE_NAME); addToArchive(saver, surface, "surface_terrain.json"); - ResourceID undergroundPath(path+"underground_terrain.json"); + ResourcePath undergroundPath(path+"underground_terrain.json"); if(CResourceHandler::get()->existsResource(undergroundPath)) { @@ -53,12 +53,12 @@ std::unique_ptr MapServiceMock::loadMap() const return res; } -std::unique_ptr MapServiceMock::loadMap(const ResourceID & name) const +std::unique_ptr MapServiceMock::loadMap(const ResourcePath & name) const { return loadMap(); } -std::unique_ptr MapServiceMock::loadMapHeader(const ResourceID & name) const +std::unique_ptr MapServiceMock::loadMapHeader(const ResourcePath & name) const { initialBuffer.seek(0); CMapLoaderJson initialLoader(&initialBuffer); diff --git a/test/mock/mock_MapService.h b/test/mock/mock_MapService.h index 656b3c771..cf2da28a9 100644 --- a/test/mock/mock_MapService.h +++ b/test/mock/mock_MapService.h @@ -29,8 +29,8 @@ class MapServiceMock : public IMapService public: MapServiceMock(const std::string & path, MapListener * mapListener_); - std::unique_ptr loadMap(const ResourceID & name) const override; - std::unique_ptr loadMapHeader(const ResourceID & name) const override; + std::unique_ptr loadMap(const ResourcePath & name) const override; + std::unique_ptr loadMapHeader(const ResourcePath & name) const override; std::unique_ptr loadMap(const ui8 * buffer, int size, const std::string & name, const std::string & modName, const std::string & encoding) const override; std::unique_ptr loadMapHeader(const ui8 * buffer, int size, const std::string & name, const std::string & modName, const std::string & encoding) const override;