From d27c51ae7661fcb7352b24c8f3fd28b98df1ce0f Mon Sep 17 00:00:00 2001 From: Dydzio Date: Fri, 19 Jan 2024 18:13:05 +0100 Subject: [PATCH 01/54] Update bonuses.json --- config/bonuses.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/bonuses.json b/config/bonuses.json index 350ec5d5a..b6d3ca125 100644 --- a/config/bonuses.json +++ b/config/bonuses.json @@ -149,7 +149,7 @@ { "graphics": { - "icon": "zvs/Lib1.res/E_RDEF" + "icon": "zvs/Lib1.res/E_RATT" } }, @@ -197,7 +197,7 @@ { "graphics": { - "icon": "" + "icon": "zvs/Lib1.res/Ferocity" } }, @@ -448,7 +448,7 @@ { "graphics": { - "icon": "" + "icon": "zvs/Lib1.res/Revenge" } }, From 3fe8872abd4be7a4afd58f85c6537cfab656f2a5 Mon Sep 17 00:00:00 2001 From: luk3Z Date: Fri, 19 Jan 2024 19:15:19 +0100 Subject: [PATCH 02/54] Update difficulty.json --- config/difficulty.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/difficulty.json b/config/difficulty.json index a3e8beffa..50f93d545 100644 --- a/config/difficulty.json +++ b/config/difficulty.json @@ -28,7 +28,7 @@ }, "king": { - "resources": { "wood" : 0, "mercury": 0, "ore": 0 , "sulfur": 0, "crystal": 0, "gems": 0, "gold": 0, "mithril": 0 }, + "resources": { "wood" : 0, "mercury": 0, "ore": 0, "sulfur": 0, "crystal": 0, "gems": 0, "gold": 0, "mithril": 0 }, "globalBonuses": [], "battleBonuses": [] } From 1fb2a026ec0d75f306e9a54f0a88b10beb4a6ccf Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Fri, 19 Jan 2024 23:31:21 +0100 Subject: [PATCH 03/54] enable doubleclick --- client/windows/GUIClasses.cpp | 18 +++++++++++++----- client/windows/GUIClasses.h | 5 ++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 94c11a178..8fed1bd40 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -459,8 +459,8 @@ CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj, const std::func oldSelected = -1; - h1 = std::make_shared(selected, 0, 72, 299, h[0]); - h2 = std::make_shared(selected, 1, 162, 299, h[1]); + h1 = std::make_shared(selected, 0, 72, 299, h[0], [&]() { if(!recruit->isBlocked()) recruitb(); }); + h2 = std::make_shared(selected, 1, 162, 299, h[1], [&]() { if(!recruit->isBlocked()) recruitb(); }); title = std::make_shared(197, 32, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[37]); cost = std::make_shared(320, 328, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, std::to_string(GameConstants::HERO_GOLD_COST)); @@ -569,15 +569,23 @@ void CTavernWindow::HeroPortrait::clickPressed(const Point & cursorPosition) *_sel = _id; } +void CTavernWindow::HeroPortrait::clickDouble(const Point & cursorPosition) +{ + clickPressed(cursorPosition); + + if(onChoose) + onChoose(); +} + void CTavernWindow::HeroPortrait::showPopupWindow(const Point & cursorPosition) { if(h) GH.windows().createAndPushWindow(std::make_shared(h)); } -CTavernWindow::HeroPortrait::HeroPortrait(int & sel, int id, int x, int y, const CGHeroInstance * H) - : CIntObject(LCLICK | SHOW_POPUP | HOVER), - h(H), _sel(&sel), _id(id) +CTavernWindow::HeroPortrait::HeroPortrait(int & sel, int id, int x, int y, const CGHeroInstance * H, std::function OnChoose) + : CIntObject(LCLICK | DOUBLECLICK | SHOW_POPUP | HOVER), + h(H), _sel(&sel), _id(id), onChoose(OnChoose) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); h = H; diff --git a/client/windows/GUIClasses.h b/client/windows/GUIClasses.h index 1d57d7454..281d30e16 100644 --- a/client/windows/GUIClasses.h +++ b/client/windows/GUIClasses.h @@ -206,10 +206,13 @@ public: std::string description; // "XXX is a level Y ZZZ with N artifacts" const CGHeroInstance * h; + std::function onChoose; + void clickPressed(const Point & cursorPosition) override; + void clickDouble(const Point & cursorPosition) override; void showPopupWindow(const Point & cursorPosition) override; void hover (bool on) override; - HeroPortrait(int & sel, int id, int x, int y, const CGHeroInstance * H); + HeroPortrait(int & sel, int id, int x, int y, const CGHeroInstance * H, std::function OnChoose = nullptr); private: int *_sel; From 346beea49ca36aa4c9e420adb7fbb4f95dfdecb9 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sat, 20 Jan 2024 01:09:55 +0100 Subject: [PATCH 04/54] invite hero backend --- CCallback.cpp | 4 ++-- CCallback.h | 4 ++-- client/windows/GUIClasses.cpp | 15 ++++++++++++++- lib/networkPacks/PacksForServer.h | 5 ++++- server/NetPacksServer.cpp | 2 +- server/processors/HeroPoolProcessor.cpp | 12 ++++++++---- server/processors/HeroPoolProcessor.h | 6 ++++-- 7 files changed, 35 insertions(+), 13 deletions(-) diff --git a/CCallback.cpp b/CCallback.cpp index 85cf0471b..4d932b117 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -260,12 +260,12 @@ void CCallback::setFormation(const CGHeroInstance * hero, EArmyFormation mode) sendRequest(&pack); } -void CCallback::recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero) +void CCallback::recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero, const HeroTypeID & nextHero) { assert(townOrTavern); assert(hero); - HireHero pack(hero->getHeroType(), townOrTavern->id); + HireHero pack(hero->getHeroType(), townOrTavern->id, nextHero); pack.player = *player; sendRequest(&pack); } diff --git a/CCallback.h b/CCallback.h index 068ac547b..5e9f1cf1a 100644 --- a/CCallback.h +++ b/CCallback.h @@ -73,7 +73,7 @@ public: virtual void castSpell(const CGHeroInstance *hero, SpellID spellID, const int3 &pos = int3(-1, -1, -1))=0; //cast adventure map spell //town - virtual void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero)=0; + virtual void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero, const HeroTypeID & nextHero=HeroTypeID::NONE)=0; virtual bool buildBuilding(const CGTownInstance *town, BuildingID buildingID)=0; virtual void recruitCreatures(const CGDwelling *obj, const CArmedInstance * dst, CreatureID ID, ui32 amount, si32 level=-1)=0; virtual bool upgradeCreature(const CArmedInstance *obj, SlotID stackPos, CreatureID newID=CreatureID::NONE)=0; //if newID==-1 then best possible upgrade will be made @@ -185,7 +185,7 @@ public: void trade(const IMarket * market, EMarketMode mode, TradeItemSell id1, TradeItemBuy id2, ui32 val1, const CGHeroInstance * hero = nullptr) override; void trade(const IMarket * market, EMarketMode mode, const std::vector & id1, const std::vector & id2, const std::vector & val1, const CGHeroInstance * hero = nullptr) override; void setFormation(const CGHeroInstance * hero, EArmyFormation mode) override; - void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero) override; + void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero, const HeroTypeID & nextHero=HeroTypeID::NONE) override; void save(const std::string &fname) override; void sendMessage(const std::string &mess, const CGObjectInstance * currentObject = nullptr) override; void gamePause(bool pause) override; diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 8fed1bd40..c433451fb 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -17,6 +17,8 @@ #include "InfoWindows.h" #include "../CGameInfo.h" +#include "../CServerHandler.h" +#include "../Client.h" #include "../CMusicHandler.h" #include "../CPlayerInterface.h" #include "../CVideoHandler.h" @@ -48,6 +50,7 @@ #include "../lib/mapObjects/ObjectTemplate.h" #include "../lib/gameState/CGameState.h" #include "../lib/gameState/SThievesGuildInfo.h" +#include "../lib/gameState/TavernHeroesPool.h" #include "../lib/CGeneralTextHandler.h" #include "../lib/CHeroHandler.h" #include "../lib/GameSettings.h" @@ -514,7 +517,17 @@ void CTavernWindow::recruitb() const CGHeroInstance *toBuy = (selected ? h2 : h1)->h; const CGObjectInstance *obj = tavernObj; - LOCPLINT->cb->recruitHero(obj, toBuy); + const auto & heroesPool = CSH->client->gameState()->heroesPool; + HeroTypeID nextHero = HeroTypeID::NONE; + + for(auto & elem : heroesPool->unusedHeroesFromPool()) + { + bool heroAvailable = heroesPool->isHeroAvailableFor(elem.first, tavernObj->getOwner()); + if(heroAvailable && elem.second->getNameTranslated() == "Sir Mullich") + nextHero = elem.first; + } + + LOCPLINT->cb->recruitHero(obj, toBuy, nextHero); close(); } diff --git a/lib/networkPacks/PacksForServer.h b/lib/networkPacks/PacksForServer.h index de1d7d613..3b3df13c6 100644 --- a/lib/networkPacks/PacksForServer.h +++ b/lib/networkPacks/PacksForServer.h @@ -516,12 +516,14 @@ struct DLL_LINKAGE SetFormation : public CPackForServer struct DLL_LINKAGE HireHero : public CPackForServer { HireHero() = default; - HireHero(HeroTypeID HID, const ObjectInstanceID & TID) + HireHero(HeroTypeID HID, const ObjectInstanceID & TID, const HeroTypeID & NHID) : hid(HID) , tid(TID) + , nhid(NHID) { } HeroTypeID hid; //available hero serial + HeroTypeID nhid; //next hero ObjectInstanceID tid; //town (tavern) id PlayerColor player; @@ -531,6 +533,7 @@ struct DLL_LINKAGE HireHero : public CPackForServer { h & static_cast(*this); h & hid; + h & nhid; h & tid; h & player; } diff --git a/server/NetPacksServer.cpp b/server/NetPacksServer.cpp index a3d77db31..2d064316b 100644 --- a/server/NetPacksServer.cpp +++ b/server/NetPacksServer.cpp @@ -282,7 +282,7 @@ void ApplyGhNetPackVisitor::visitHireHero(HireHero & pack) { gh.throwIfWrongPlayer(&pack); - result = gh.heroPool->hireHero(pack.tid, pack.hid, pack.player); + result = gh.heroPool->hireHero(pack.tid, pack.hid, pack.player, pack.nhid); } void ApplyGhNetPackVisitor::visitBuildBoat(BuildBoat & pack) diff --git a/server/processors/HeroPoolProcessor.cpp b/server/processors/HeroPoolProcessor.cpp index 623340e6c..40ce321f3 100644 --- a/server/processors/HeroPoolProcessor.cpp +++ b/server/processors/HeroPoolProcessor.cpp @@ -104,7 +104,7 @@ void HeroPoolProcessor::clearHeroFromSlot(const PlayerColor & color, TavernHeroS gameHandler->sendAndApply(&sah); } -void HeroPoolProcessor::selectNewHeroForSlot(const PlayerColor & color, TavernHeroSlot slot, bool needNativeHero, bool giveArmy) +void HeroPoolProcessor::selectNewHeroForSlot(const PlayerColor & color, TavernHeroSlot slot, bool needNativeHero, bool giveArmy, const HeroTypeID & nextHero) { SetAvailableHero sah; sah.player = color; @@ -113,6 +113,10 @@ void HeroPoolProcessor::selectNewHeroForSlot(const PlayerColor & color, TavernHe CGHeroInstance *newHero = pickHeroFor(needNativeHero, color); + const auto & heroesPool = gameHandler->gameState()->heroesPool; + if(gameHandler->getStartInfo()->extraOptionsInfo.unlimitedReplay && heroesPool->unusedHeroesFromPool().count(nextHero) && heroesPool->isHeroAvailableFor(nextHero, color)) + newHero = heroesPool->unusedHeroesFromPool()[nextHero]; + if (newHero) { sah.hid = newHero->getHeroType(); @@ -145,7 +149,7 @@ void HeroPoolProcessor::onNewWeek(const PlayerColor & color) selectNewHeroForSlot(color, TavernHeroSlot::RANDOM, false, true); } -bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTypeID & heroToRecruit, const PlayerColor & player) +bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTypeID & heroToRecruit, const PlayerColor & player, const HeroTypeID & nextHero) { const PlayerState * playerState = gameHandler->getPlayerState(player); const CGObjectInstance * mapObject = gameHandler->getObj(objectID); @@ -226,9 +230,9 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy gameHandler->sendAndApply(&hr); if(recruitableHeroes[0] == recruitedHero) - selectNewHeroForSlot(player, TavernHeroSlot::NATIVE, false, false); + selectNewHeroForSlot(player, TavernHeroSlot::NATIVE, false, false, nextHero); else - selectNewHeroForSlot(player, TavernHeroSlot::RANDOM, false, false); + selectNewHeroForSlot(player, TavernHeroSlot::RANDOM, false, false, nextHero); gameHandler->giveResource(player, EGameResID::GOLD, -GameConstants::HERO_GOLD_COST); diff --git a/server/processors/HeroPoolProcessor.h b/server/processors/HeroPoolProcessor.h index eed300a79..c69255496 100644 --- a/server/processors/HeroPoolProcessor.h +++ b/server/processors/HeroPoolProcessor.h @@ -9,6 +9,8 @@ */ #pragma once +#include "../../lib/constants/EntityIdentifiers.h" + VCMI_LIB_NAMESPACE_BEGIN enum class TavernHeroSlot : int8_t; @@ -33,7 +35,7 @@ class HeroPoolProcessor : boost::noncopyable std::map> heroSeed; void clearHeroFromSlot(const PlayerColor & color, TavernHeroSlot slot); - void selectNewHeroForSlot(const PlayerColor & color, TavernHeroSlot slot, bool needNativeHero, bool giveStartingArmy); + void selectNewHeroForSlot(const PlayerColor & color, TavernHeroSlot slot, bool needNativeHero, bool giveStartingArmy, const HeroTypeID & nextHero = HeroTypeID::NONE); std::vector findAvailableClassesFor(const PlayerColor & player) const; std::vector findAvailableHeroesFor(const PlayerColor & player, const CHeroClass * heroClass) const; @@ -60,7 +62,7 @@ public: CRandomGenerator & getHeroSkillsRandomGenerator(const HeroTypeID & hero); /// Incoming net pack handling - bool hireHero(const ObjectInstanceID & objectID, const HeroTypeID & hid, const PlayerColor & player); + bool hireHero(const ObjectInstanceID & objectID, const HeroTypeID & hid, const PlayerColor & player, const HeroTypeID & nextHero); template void serialize(Handler &h, const int version) { From 4813179abb51f211f24d4657abb134104d0db7e5 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sat, 20 Jan 2024 01:24:34 +0100 Subject: [PATCH 05/54] Invite hero setting --- Mods/vcmi/config/vcmi/english.json | 2 ++ Mods/vcmi/config/vcmi/german.json | 2 ++ client/lobby/OptionsTabBase.cpp | 9 +++++++++ config/widgets/extraOptionsTab.json | 16 ++++++++++++++++ lib/ExtraOptionsInfo.cpp | 3 ++- lib/ExtraOptionsInfo.h | 2 ++ server/processors/HeroPoolProcessor.cpp | 2 +- 7 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Mods/vcmi/config/vcmi/english.json b/Mods/vcmi/config/vcmi/english.json index 81215b65c..aefc46864 100644 --- a/Mods/vcmi/config/vcmi/english.json +++ b/Mods/vcmi/config/vcmi/english.json @@ -317,8 +317,10 @@ "vcmi.optionsTab.cheatAllowed.hover" : "Allow cheats", "vcmi.optionsTab.unlimitedReplay.hover" : "Unlimited battle replay", + "vcmi.optionsTab.inviteHero.hover" : "Invite hero", "vcmi.optionsTab.cheatAllowed.help" : "{Allow cheats}\nAllows the inputs of cheats during the game.", "vcmi.optionsTab.unlimitedReplay.help" : "{Unlimited battle replay}\nNo limit of replaying battles.", + "vcmi.optionsTab.inviteHero.help" : "{Invite hero}\nPossibility to invite hero in the tavern.", // Custom victory conditions for H3 campaigns and HotA maps "vcmi.map.victoryCondition.daysPassed.toOthers" : "The enemy has managed to survive till this day. Victory is theirs!", diff --git a/Mods/vcmi/config/vcmi/german.json b/Mods/vcmi/config/vcmi/german.json index ffbe4bf94..344acd9b2 100644 --- a/Mods/vcmi/config/vcmi/german.json +++ b/Mods/vcmi/config/vcmi/german.json @@ -317,8 +317,10 @@ "vcmi.optionsTab.cheatAllowed.hover" : "Cheats erlauben", "vcmi.optionsTab.unlimitedReplay.hover" : "Unbegrenzte Kampfwiederholung", + "vcmi.optionsTab.inviteHero.hover" : "Helden einladen", "vcmi.optionsTab.cheatAllowed.help" : "{Cheats erlauben}\nErlaubt die Eingabe von Cheats während des Spiels.", "vcmi.optionsTab.unlimitedReplay.help" : "{Unbegrenzte Kampfwiederholung}\nKämpfe lassen sich unbegrenzt wiederholen.", + "vcmi.optionsTab.inviteHero.help" : "{Helden einladen}\nMöglichkeit Helden in der Taverne einzuladen.", // Custom victory conditions for H3 campaigns and HotA maps "vcmi.map.victoryCondition.daysPassed.toOthers" : "Der Feind hat es geschafft, bis zum heutigen Tag zu überleben. Der Sieg gehört ihm!", diff --git a/client/lobby/OptionsTabBase.cpp b/client/lobby/OptionsTabBase.cpp index 42bfab108..218b1ccb4 100644 --- a/client/lobby/OptionsTabBase.cpp +++ b/client/lobby/OptionsTabBase.cpp @@ -110,6 +110,12 @@ OptionsTabBase::OptionsTabBase(const JsonPath & configPath) CSH->setExtraOptionsInfo(info); }); + addCallback("setInviteHero", [&](int index){ + ExtraOptionsInfo info = SEL->getStartInfo()->extraOptionsInfo; + info.inviteHero = index; + CSH->setExtraOptionsInfo(info); + }); + addCallback("setTurnTimerAccumulate", [&](int index){ TurnTimerInfo info = SEL->getStartInfo()->turnTimerInfo; info.accumulatingTurnTimer = index; @@ -411,4 +417,7 @@ void OptionsTabBase::recreate() if(auto buttonUnlimitedReplay = widget("buttonUnlimitedReplay")) buttonUnlimitedReplay->setSelectedSilent(SEL->getStartInfo()->extraOptionsInfo.unlimitedReplay); + + if(auto buttonInviteHero = widget("buttonInviteHero")) + buttonInviteHero->setSelectedSilent(SEL->getStartInfo()->extraOptionsInfo.inviteHero); } diff --git a/config/widgets/extraOptionsTab.json b/config/widgets/extraOptionsTab.json index 1c77dfeab..5f6635254 100644 --- a/config/widgets/extraOptionsTab.json +++ b/config/widgets/extraOptionsTab.json @@ -64,12 +64,21 @@ "name": "buttonCheatAllowed", "image": "lobby/checkbox", "callback" : "setCheatAllowed", + "help" : "vcmi.optionsTab.cheatAllowed", "selected" : true }, { "name": "buttonUnlimitedReplay", "image": "lobby/checkbox", "callback" : "setUnlimitedReplay", + "help" : "vcmi.optionsTab.unlimitedReplay", + "selected" : true + }, + { + "name": "buttonInviteHero", + "image": "lobby/checkbox", + "callback" : "setInviteHero", + "help" : "vcmi.optionsTab.inviteHero", "selected" : true } ] @@ -94,6 +103,13 @@ "alignment": "left", "color": "yellow", "text": "vcmi.optionsTab.unlimitedReplay.hover" + }, + { + "name": "labelInviteHero", + "font": "small", + "alignment": "left", + "color": "yellow", + "text": "vcmi.optionsTab.inviteHero.hover" } ] } diff --git a/lib/ExtraOptionsInfo.cpp b/lib/ExtraOptionsInfo.cpp index 2411608b7..bd0efb124 100644 --- a/lib/ExtraOptionsInfo.cpp +++ b/lib/ExtraOptionsInfo.cpp @@ -15,7 +15,8 @@ VCMI_LIB_NAMESPACE_BEGIN bool ExtraOptionsInfo::operator == (const ExtraOptionsInfo & other) const { return cheatsAllowed == other.cheatsAllowed && - unlimitedReplay == other.unlimitedReplay; + unlimitedReplay == other.unlimitedReplay && + inviteHero == other.inviteHero; } VCMI_LIB_NAMESPACE_END diff --git a/lib/ExtraOptionsInfo.h b/lib/ExtraOptionsInfo.h index 3b1e65d1b..f433008c2 100644 --- a/lib/ExtraOptionsInfo.h +++ b/lib/ExtraOptionsInfo.h @@ -16,6 +16,7 @@ struct DLL_LINKAGE ExtraOptionsInfo { bool cheatsAllowed = true; bool unlimitedReplay = false; + bool inviteHero = false; bool operator == (const ExtraOptionsInfo & other) const; @@ -24,6 +25,7 @@ struct DLL_LINKAGE ExtraOptionsInfo { h & cheatsAllowed; h & unlimitedReplay; + h & inviteHero; } }; diff --git a/server/processors/HeroPoolProcessor.cpp b/server/processors/HeroPoolProcessor.cpp index 40ce321f3..ebf4b4edc 100644 --- a/server/processors/HeroPoolProcessor.cpp +++ b/server/processors/HeroPoolProcessor.cpp @@ -114,7 +114,7 @@ void HeroPoolProcessor::selectNewHeroForSlot(const PlayerColor & color, TavernHe CGHeroInstance *newHero = pickHeroFor(needNativeHero, color); const auto & heroesPool = gameHandler->gameState()->heroesPool; - if(gameHandler->getStartInfo()->extraOptionsInfo.unlimitedReplay && heroesPool->unusedHeroesFromPool().count(nextHero) && heroesPool->isHeroAvailableFor(nextHero, color)) + if(gameHandler->getStartInfo()->extraOptionsInfo.inviteHero && heroesPool->unusedHeroesFromPool().count(nextHero) && heroesPool->isHeroAvailableFor(nextHero, color)) newHero = heroesPool->unusedHeroesFromPool()[nextHero]; if (newHero) From 522e251d2128a834d22d346ecd2bb77fc4ff541e Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Sat, 20 Jan 2024 11:39:40 +0100 Subject: [PATCH 06/54] Update Readme.md Removed 1.4.3 release to not confuse players. Added 1.4.4 counter instead. --- docs/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Readme.md b/docs/Readme.md index 8f9a0ba59..513215aac 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -2,7 +2,7 @@ [![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.4.0/total)](https://github.com/vcmi/vcmi/releases/tag/1.4.0) [![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.4.1/total)](https://github.com/vcmi/vcmi/releases/tag/1.4.1) [![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.4.2/total)](https://github.com/vcmi/vcmi/releases/tag/1.4.2) -[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.4.3/total)](https://github.com/vcmi/vcmi/releases/tag/1.4.3) +[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.4.4/total)](https://github.com/vcmi/vcmi/releases/tag/1.4.4) [![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/total)](https://github.com/vcmi/vcmi/releases) # VCMI Project From a0098eb065e1729b999ed241e7ecb562eeb40c6d Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sat, 20 Jan 2024 04:32:59 +0100 Subject: [PATCH 07/54] Gui for hero invite --- Mods/vcmi/config/vcmi/english.json | 2 + Mods/vcmi/config/vcmi/german.json | 2 + client/windows/GUIClasses.cpp | 69 ++++++++++++++++++++++++------ client/windows/GUIClasses.h | 24 +++++++++++ 4 files changed, 85 insertions(+), 12 deletions(-) diff --git a/Mods/vcmi/config/vcmi/english.json b/Mods/vcmi/config/vcmi/english.json index aefc46864..482bd67c4 100644 --- a/Mods/vcmi/config/vcmi/english.json +++ b/Mods/vcmi/config/vcmi/english.json @@ -232,6 +232,8 @@ "vcmi.heroWindow.openBackpack.hover" : "Open artifact backpack window", "vcmi.heroWindow.openBackpack.help" : "Opens window that allows easier artifact backpack management.", + "vcmi.tavernWindow.inviteHero" : "Invite hero", + "vcmi.commanderWindow.artifactMessage" : "Do you want to return this artifact to the hero?", "vcmi.creatureWindow.showBonuses.hover" : "Switch to bonuses view", diff --git a/Mods/vcmi/config/vcmi/german.json b/Mods/vcmi/config/vcmi/german.json index 344acd9b2..268caf197 100644 --- a/Mods/vcmi/config/vcmi/german.json +++ b/Mods/vcmi/config/vcmi/german.json @@ -232,6 +232,8 @@ "vcmi.heroWindow.openBackpack.hover" : "Artefakt-Rucksack-Fenster öffnen", "vcmi.heroWindow.openBackpack.help" : "Öffnet ein Fenster, das die Verwaltung des Artefakt-Rucksacks erleichtert", + "vcmi.tavernWindow.inviteHero" : "Helden einladen", + "vcmi.commanderWindow.artifactMessage" : "Möchtet Ihr diesen Artefakt dem Helden zurückgeben?", "vcmi.creatureWindow.showBonuses.hover" : "Wechsle zur Bonus-Ansicht", diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index c433451fb..9c9b12d8d 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -446,7 +446,8 @@ CLevelWindow::~CLevelWindow() CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj, const std::function & onWindowClosed) : CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("TPTAVERN")), onWindowClosed(onWindowClosed), - tavernObj(TavernObj) + tavernObj(TavernObj), + heroToInvite(nullptr) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -510,6 +511,34 @@ CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj, const std::func CCS->videoh->open(townObj->town->clientInfo.tavernVideo); else CCS->videoh->open(VideoPath::builtin("TAVERN.BIK")); + + addInvite(); +} + +void CTavernWindow::addInvite() +{ + OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); + + if(CSH->client->getStartInfo()->extraOptionsInfo.inviteHero) + { + const auto & heroesPool = CSH->client->gameState()->heroesPool; + for(auto & elem : heroesPool->unusedHeroesFromPool()) + { + bool heroAvailable = heroesPool->isHeroAvailableFor(elem.first, tavernObj->getOwner()); + if(heroAvailable) + inviteableHeroes[elem.first] = elem.second; + } + + if(inviteableHeroes.size() > 0) + { + if(!heroToInvite) + heroToInvite = (*RandomGeneratorUtil::nextItem(inviteableHeroes, CRandomGenerator::getDefault())).second; + + inviteHero = std::make_shared(170, 444, EFonts::FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->translate("vcmi.tavernWindow.inviteHero")); + inviteHeroImage = std::make_shared(AnimationPath::builtin("PortraitsSmall"), (*CGI->heroh)[heroToInvite->getHeroType()]->imageIndex, 0, 245, 428); + inviteHeroImageArea = std::make_shared(Rect(245, 428, 48, 32), [&](){ GH.windows().createAndPushWindow(inviteableHeroes, [&](CGHeroInstance* h){ heroToInvite = h; addInvite(); }); }, [&](){ GH.windows().createAndPushWindow(std::make_shared(heroToInvite)); }); + } + } } void CTavernWindow::recruitb() @@ -517,17 +546,7 @@ void CTavernWindow::recruitb() const CGHeroInstance *toBuy = (selected ? h2 : h1)->h; const CGObjectInstance *obj = tavernObj; - const auto & heroesPool = CSH->client->gameState()->heroesPool; - HeroTypeID nextHero = HeroTypeID::NONE; - - for(auto & elem : heroesPool->unusedHeroesFromPool()) - { - bool heroAvailable = heroesPool->isHeroAvailableFor(elem.first, tavernObj->getOwner()); - if(heroAvailable && elem.second->getNameTranslated() == "Sir Mullich") - nextHero = elem.first; - } - - LOCPLINT->cb->recruitHero(obj, toBuy, nextHero); + LOCPLINT->cb->recruitHero(obj, toBuy, heroToInvite ? heroToInvite->getHeroType() : HeroTypeID::NONE); close(); } @@ -636,6 +655,32 @@ void CTavernWindow::HeroPortrait::hover(bool on) GH.statusbar()->clear(); } +CTavernWindow::HeroSelector::HeroSelector(std::map InviteableHeroes, std::function OnChoose) + : CWindowObject(BORDERED), inviteableHeroes(InviteableHeroes), onChoose(OnChoose) +{ + OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; + + pos = Rect(0, 0, 16 * 48, (inviteableHeroes.size() / 16 + (inviteableHeroes.size() % 16 != 0)) * 32); + background = std::make_shared(ImagePath::builtin("DIBOXBCK"), Rect(0, 0, pos.w, pos.h)); + + int x = 0, y = 0; + for(auto & h : inviteableHeroes) + { + portraits.push_back(std::make_shared(AnimationPath::builtin("PortraitsSmall"), (*CGI->heroh)[h.first]->imageIndex, 0, x * 48, y * 32)); + portraitAreas.push_back(std::make_shared(Rect(x * 48, y * 32, 48, 32), [&](){ close(); onChoose(inviteableHeroes[h.first]); }, [&](){ GH.windows().createAndPushWindow(std::make_shared(inviteableHeroes[h.first])); })); + + if(x > 0 && x % 15 == 0) + { + x = 0; + y++; + } + else + x++; + } + + center(); +} + static const std::string QUICK_EXCHANGE_MOD_PREFIX = "quick-exchange"; static const std::string QUICK_EXCHANGE_BG = QUICK_EXCHANGE_MOD_PREFIX + "/TRADEQE"; diff --git a/client/windows/GUIClasses.h b/client/windows/GUIClasses.h index 281d30e16..e37c510ee 100644 --- a/client/windows/GUIClasses.h +++ b/client/windows/GUIClasses.h @@ -36,6 +36,8 @@ class CTextBox; class CGarrisonInt; class CGarrisonSlot; class CHeroArea; +class CAnimImage; +class CFilledTexture; enum class EUserEvent; @@ -221,6 +223,21 @@ public: std::shared_ptr portrait; }; + class HeroSelector : public CWindowObject + { + public: + std::shared_ptr background; + + HeroSelector(std::map InviteableHeroes, std::function OnChoose); + + private: + std::map inviteableHeroes; + std::function onChoose; + + std::vector> portraits; + std::vector> portraitAreas; + }; + //recruitable heroes std::shared_ptr h1; std::shared_ptr h2; //recruitable heroes @@ -240,6 +257,13 @@ public: std::shared_ptr heroDescription; std::shared_ptr rumor; + + std::shared_ptr inviteHero; + std::shared_ptr inviteHeroImage; + std::shared_ptr inviteHeroImageArea; + std::map inviteableHeroes; + CGHeroInstance* heroToInvite; + void addInvite(); CTavernWindow(const CGObjectInstance * TavernObj, const std::function & onWindowClosed); ~CTavernWindow(); From d6172a9c4c2fae17481533260d83c2690c21ea34 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sat, 20 Jan 2024 13:42:37 +0100 Subject: [PATCH 08/54] disable buttons while loading (not changable) --- client/lobby/OptionsTabBase.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/client/lobby/OptionsTabBase.cpp b/client/lobby/OptionsTabBase.cpp index 218b1ccb4..19bc145b4 100644 --- a/client/lobby/OptionsTabBase.cpp +++ b/client/lobby/OptionsTabBase.cpp @@ -413,11 +413,20 @@ void OptionsTabBase::recreate() } if(auto buttonCheatAllowed = widget("buttonCheatAllowed")) + { buttonCheatAllowed->setSelectedSilent(SEL->getStartInfo()->extraOptionsInfo.cheatsAllowed); + buttonCheatAllowed->setInputEnabled(SEL->screenType != ESelectionScreen::loadGame); + } if(auto buttonUnlimitedReplay = widget("buttonUnlimitedReplay")) + { buttonUnlimitedReplay->setSelectedSilent(SEL->getStartInfo()->extraOptionsInfo.unlimitedReplay); + buttonUnlimitedReplay->setInputEnabled(SEL->screenType != ESelectionScreen::loadGame); + } if(auto buttonInviteHero = widget("buttonInviteHero")) + { buttonInviteHero->setSelectedSilent(SEL->getStartInfo()->extraOptionsInfo.inviteHero); + buttonInviteHero->setInputEnabled(SEL->screenType != ESelectionScreen::loadGame); + } } From 3084cb2e46275065d320c77e4fd9e9cdad8679ab Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sat, 20 Jan 2024 14:33:13 +0100 Subject: [PATCH 09/54] fix battle text position fix space --- client/battle/BattleStacksController.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/battle/BattleStacksController.cpp b/client/battle/BattleStacksController.cpp index 70532320f..4db1280c4 100644 --- a/client/battle/BattleStacksController.cpp +++ b/client/battle/BattleStacksController.cpp @@ -30,6 +30,8 @@ #include "../render/Colors.h" #include "../render/Canvas.h" #include "../render/IRenderHandler.h" +#include "../render/Graphics.h" +#include "../render/IFont.h" #include "../../CCallback.h" #include "../../lib/spells/ISpellMechanics.h" @@ -327,10 +329,10 @@ void BattleStacksController::showStackAmountBox(Canvas & canvas, const CStack * boxPosition = owner.fieldController->hexPositionLocal(frontPos).center() + Point(-8, -14); } - Point textPosition = amountBG->dimensions()/2 + boxPosition + Point(0, 1); + Point textPosition = Point(amountBG->dimensions().x/2 + boxPosition.x, boxPosition.y + graphics->fonts[EFonts::FONT_TINY]->getLineHeight() - 6); canvas.draw(amountBG, boxPosition); - canvas.drawText(textPosition, EFonts::FONT_TINY, Colors::WHITE, ETextAlignment::CENTER, TextOperations::formatMetric(stack->getCount(), 4)); + canvas.drawText(textPosition, EFonts::FONT_TINY, Colors::WHITE, ETextAlignment::TOPCENTER, TextOperations::formatMetric(stack->getCount(), 4)); } void BattleStacksController::showStack(Canvas & canvas, const CStack * stack) From 31b04780c99918b002db61110ccb5bc833523f33 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sat, 20 Jan 2024 16:40:51 +0200 Subject: [PATCH 10/54] Added hasValue method to identifiers --- lib/constants/IdentifierBase.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/constants/IdentifierBase.h b/lib/constants/IdentifierBase.h index 62c2e671b..8b1628abe 100644 --- a/lib/constants/IdentifierBase.h +++ b/lib/constants/IdentifierBase.h @@ -52,6 +52,11 @@ public: num = value; } + constexpr bool hasValue() const + { + return num >= 0; + } + struct hash { size_t operator()(const IdentifierBase & id) const From 24d25730ad58dec12099afeef72227a257042855 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sat, 20 Jan 2024 16:41:10 +0200 Subject: [PATCH 11/54] Changed checks for null with checks for hasValue --- client/battle/BattleActionsController.cpp | 10 +++++----- client/battle/BattleInterface.cpp | 8 ++++---- lib/battle/CBattleInfoCallback.cpp | 5 +++-- server/CGameHandler.cpp | 4 ++-- server/NetPacksServer.cpp | 5 +++-- server/battles/BattleActionProcessor.cpp | 4 ++-- 6 files changed, 19 insertions(+), 17 deletions(-) diff --git a/client/battle/BattleActionsController.cpp b/client/battle/BattleActionsController.cpp index a6e4f5784..3484689c1 100644 --- a/client/battle/BattleActionsController.cpp +++ b/client/battle/BattleActionsController.cpp @@ -750,7 +750,7 @@ void BattleActionsController::actionRealize(PossiblePlayerBattleAction action, B if (!spellcastingModeActive()) { - if (action.spell().toSpell()) + if (action.spell().hasValue()) { owner.giveCommand(EActionType::MONSTER_SPELL, targetHex, action.spell()); } @@ -887,17 +887,17 @@ void BattleActionsController::tryActivateStackSpellcasting(const CStack *casterS { // faerie dragon can cast only one, randomly selected spell until their next move //TODO: faerie dragon type spell should be selected by server - const auto * spellToCast = owner.getBattle()->getRandomCastedSpell(CRandomGenerator::getDefault(), casterStack).toSpell(); + const auto spellToCast = owner.getBattle()->getRandomCastedSpell(CRandomGenerator::getDefault(), casterStack); - if (spellToCast) - creatureSpells.push_back(spellToCast); + if (spellToCast.hasValue()) + creatureSpells.push_back(spellToCast.toSpell()); } TConstBonusListPtr bl = casterStack->getBonuses(Selector::type()(BonusType::SPELLCASTER)); for(const auto & bonus : *bl) { - if (bonus->additionalInfo[0] <= 0) + if (bonus->additionalInfo[0] <= 0 && bonus->subtype.as().hasValue()) creatureSpells.push_back(bonus->subtype.as().toSpell()); } } diff --git a/client/battle/BattleInterface.cpp b/client/battle/BattleInterface.cpp index c2255b6f5..d534f0556 100644 --- a/client/battle/BattleInterface.cpp +++ b/client/battle/BattleInterface.cpp @@ -352,13 +352,13 @@ void BattleInterface::spellCast(const BattleSpellCast * sc) CCS->curh->set(Cursor::Combat::BLOCKED); const SpellID spellID = sc->spellID; + + if(!spellID.hasValue()) + return; + const CSpell * spell = spellID.toSpell(); auto targetedTile = sc->tile; - assert(spell); - if(!spell) - return; - const AudioPath & castSoundPath = spell->getCastSound(); if (!castSoundPath.empty()) diff --git a/lib/battle/CBattleInfoCallback.cpp b/lib/battle/CBattleInfoCallback.cpp index 7db5cc7aa..14509999d 100644 --- a/lib/battle/CBattleInfoCallback.cpp +++ b/lib/battle/CBattleInfoCallback.cpp @@ -867,9 +867,10 @@ bool CBattleInfoCallback::handleObstacleTriggersForUnit(SpellCastEnvironment & s auto shouldReveal = !spellObstacle->hidden || !battleIsObstacleVisibleForSide(*obstacle, (BattlePerspective::BattlePerspective)side); const auto * hero = battleGetFightingHero(spellObstacle->casterSide); auto caster = spells::ObstacleCasterProxy(getBattle()->getSidePlayer(spellObstacle->casterSide), hero, *spellObstacle); - const auto * sp = obstacle->getTrigger().toSpell(); - if(obstacle->triggersEffects() && sp) + + if(obstacle->triggersEffects() && obstacle->getTrigger().hasValue()) { + const auto * sp = obstacle->getTrigger().toSpell(); auto cast = spells::BattleCast(this, &caster, spells::Mode::PASSIVE, sp); spells::detail::ProblemImpl ignored; auto target = spells::Target(1, spells::Destination(&unit)); diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index ad9baed9e..dc9bcb999 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -3955,14 +3955,14 @@ bool CGameHandler::moveStack(const StackLocation &src, const StackLocation &dst, void CGameHandler::castSpell(const spells::Caster * caster, SpellID spellID, const int3 &pos) { - const CSpell * s = spellID.toSpell(); - if(!s) + if (!spellID.hasValue()) return; AdventureSpellCastParameters p; p.caster = caster; p.pos = pos; + const CSpell * s = spellID.toSpell(); s->adventureCast(spellEnv, p); } diff --git a/server/NetPacksServer.cpp b/server/NetPacksServer.cpp index a3d77db31..846ddcd42 100644 --- a/server/NetPacksServer.cpp +++ b/server/NetPacksServer.cpp @@ -327,9 +327,9 @@ void ApplyGhNetPackVisitor::visitCastAdvSpell(CastAdvSpell & pack) { gh.throwIfWrongOwner(&pack, pack.hid); - const CSpell * s = pack.sid.toSpell(); - if(!s) + if (!pack.sid.hasValue()) gh.throwNotAllowedAction(&pack); + const CGHeroInstance * h = gh.getHero(pack.hid); if(!h) gh.throwNotAllowedAction(&pack); @@ -338,6 +338,7 @@ void ApplyGhNetPackVisitor::visitCastAdvSpell(CastAdvSpell & pack) p.caster = h; p.pos = pack.pos; + const CSpell * s = pack.sid.toSpell(); result = s->adventureCast(gh.spellEnv, p); } diff --git a/server/battles/BattleActionProcessor.cpp b/server/battles/BattleActionProcessor.cpp index af8e88994..8a706a8c1 100644 --- a/server/battles/BattleActionProcessor.cpp +++ b/server/battles/BattleActionProcessor.cpp @@ -102,13 +102,13 @@ bool BattleActionProcessor::doHeroSpellAction(const CBattleInfoCallback & battle return false; } - const CSpell * s = ba.spell.toSpell(); - if (!s) + if (!ba.spell.hasValue()) { logGlobal->error("Wrong spell id (%d)!", ba.spell.getNum()); return false; } + const CSpell * s = ba.spell.toSpell(); spells::BattleCast parameters(&battle, h, spells::Mode::HERO, s); spells::detail::ProblemImpl problem; From dffa1746059cbec7efb833f1200e92bbe997e18c Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sat, 20 Jan 2024 16:48:05 +0200 Subject: [PATCH 12/54] Attempt to fix crash --- server/TurnTimerHandler.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/server/TurnTimerHandler.cpp b/server/TurnTimerHandler.cpp index 9aa3e5dc7..84a05c740 100644 --- a/server/TurnTimerHandler.cpp +++ b/server/TurnTimerHandler.cpp @@ -88,21 +88,21 @@ void TurnTimerHandler::onPlayerGetTurn(PlayerColor player) void TurnTimerHandler::update(int waitTime) { std::lock_guard guard(mx); - if(const auto * gs = gameHandler.gameState()) - { - for(PlayerColor player(0); player < PlayerColor::PLAYER_LIMIT; ++player) - if(gs->isPlayerMakingTurn(player)) - onPlayerMakingTurn(player, waitTime); - - // create copy for iterations - battle might end during onBattleLoop call - std::vector ongoingBattles; + if(!gameHandler.getStartInfo()->turnTimerInfo.isEnabled()) + return; - for (auto & battle : gs->currentBattles) - ongoingBattles.push_back(battle->battleID); + for(PlayerColor player(0); player < PlayerColor::PLAYER_LIMIT; ++player) + if(gameHandler.gameState()->isPlayerMakingTurn(player)) + onPlayerMakingTurn(player, waitTime); - for (auto & battleID : ongoingBattles) - onBattleLoop(battleID, waitTime); - } + // create copy for iterations - battle might end during onBattleLoop call + std::vector ongoingBattles; + + for (auto & battle : gameHandler.gameState()->currentBattles) + ongoingBattles.push_back(battle->battleID); + + for (auto & battleID : ongoingBattles) + onBattleLoop(battleID, waitTime); } bool TurnTimerHandler::timerCountDown(int & timer, int initialTimer, PlayerColor player, int waitTime) From 62935b4ba4f5ad65e7a71cecb932fffdbb49bcdd Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sat, 20 Jan 2024 17:15:51 +0200 Subject: [PATCH 13/54] Fix crash on using StupidAI for player actions --- AI/StupidAI/StupidAI.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/AI/StupidAI/StupidAI.cpp b/AI/StupidAI/StupidAI.cpp index 3888e5a6b..b24cf3285 100644 --- a/AI/StupidAI/StupidAI.cpp +++ b/AI/StupidAI/StupidAI.cpp @@ -16,8 +16,6 @@ #include "../../lib/battle/BattleAction.h" #include "../../lib/battle/BattleInfo.h" -static std::shared_ptr cbc; - CStupidAI::CStupidAI() : side(-1) , wasWaitingForRealize(false) @@ -41,7 +39,7 @@ void CStupidAI::initBattleInterface(std::shared_ptr ENV, std::share { print("init called, saving ptr to IBattleCallback"); env = ENV; - cbc = cb = CB; + cb = CB; wasWaitingForRealize = CB->waitTillRealize; wasUnlockingGs = CB->unlockGsWhenWaiting; @@ -72,11 +70,11 @@ public: std::vector attackFrom; //for melee fight EnemyInfo(const CStack * _s) : s(_s), adi(0), adr(0) {} - void calcDmg(const BattleID & battleID, const CStack * ourStack) + void calcDmg(std::shared_ptr cb, const BattleID & battleID, const CStack * ourStack) { // FIXME: provide distance info for Jousting bonus DamageEstimation retal; - DamageEstimation dmg = cbc->getBattle(battleID)->battleEstimateDamage(ourStack, s, 0, &retal); + DamageEstimation dmg = cb->getBattle(battleID)->battleEstimateDamage(ourStack, s, 0, &retal); adi = static_cast((dmg.damage.min + dmg.damage.max) / 2); adr = static_cast((retal.damage.min + retal.damage.max) / 2); } @@ -92,14 +90,14 @@ bool isMoreProfitable(const EnemyInfo &ei1, const EnemyInfo& ei2) return (ei1.adi-ei1.adr) < (ei2.adi - ei2.adr); } -static bool willSecondHexBlockMoreEnemyShooters(const BattleID & battleID, const BattleHex &h1, const BattleHex &h2) +static bool willSecondHexBlockMoreEnemyShooters(std::shared_ptr cb, const BattleID & battleID, const BattleHex &h1, const BattleHex &h2) { int shooters[2] = {0}; //count of shooters on hexes for(int i = 0; i < 2; i++) { for (auto & neighbour : (i ? h2 : h1).neighbouringTiles()) - if(const auto * s = cbc->getBattle(battleID)->battleGetUnitByPos(neighbour)) + if(const auto * s = cb->getBattle(battleID)->battleGetUnitByPos(neighbour)) if(s->isShooter()) shooters[i]++; } @@ -169,10 +167,10 @@ void CStupidAI::activeStack(const BattleID & battleID, const CStack * stack) } for ( auto & enemy : enemiesReachable ) - enemy.calcDmg(battleID, stack); + enemy.calcDmg(cb, battleID, stack); for ( auto & enemy : enemiesShootable ) - enemy.calcDmg(battleID, stack); + enemy.calcDmg(cb, battleID, stack); if(enemiesShootable.size()) { @@ -183,7 +181,7 @@ void CStupidAI::activeStack(const BattleID & battleID, const CStack * stack) else if(enemiesReachable.size()) { const EnemyInfo &ei= *std::max_element(enemiesReachable.begin(), enemiesReachable.end(), &isMoreProfitable); - BattleHex targetHex = *std::max_element(ei.attackFrom.begin(), ei.attackFrom.end(), [&](auto a, auto b) { return willSecondHexBlockMoreEnemyShooters(battleID, a, b);}); + BattleHex targetHex = *std::max_element(ei.attackFrom.begin(), ei.attackFrom.end(), [&](auto a, auto b) { return willSecondHexBlockMoreEnemyShooters(cb, battleID, a, b);}); cb->battleMakeUnitAction(battleID, BattleAction::makeMeleeAttack(stack, ei.s->getPosition(), targetHex)); return; From 06517acd67228b4e2d518e5941f8742d63c4da88 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sat, 20 Jan 2024 17:31:11 +0200 Subject: [PATCH 14/54] Version bump for Android --- android/vcmi-app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/vcmi-app/build.gradle b/android/vcmi-app/build.gradle index f4c216501..7a88a69fd 100644 --- a/android/vcmi-app/build.gradle +++ b/android/vcmi-app/build.gradle @@ -10,7 +10,7 @@ android { applicationId "is.xyz.vcmi" minSdk 19 targetSdk 33 - versionCode 1440 + versionCode 1441 versionName "1.4.4" setProperty("archivesBaseName", "vcmi") } From 912262e826ce155bc8dfe8c8ed34e9fd9cbd3ce6 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sat, 20 Jan 2024 18:17:23 +0200 Subject: [PATCH 15/54] Avoid crash on invalid artifact in bank config --- lib/JsonRandom.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/JsonRandom.cpp b/lib/JsonRandom.cpp index ca068c973..142edd2a1 100644 --- a/lib/JsonRandom.cpp +++ b/lib/JsonRandom.cpp @@ -82,7 +82,7 @@ namespace JsonRandom IdentifierType decodeKey(const std::string & modScope, const std::string & value, const Variables & variables) { if (value.empty() || value[0] != '@') - return IdentifierType(*VLC->identifiers()->getIdentifier(modScope, IdentifierType::entityType(), value)); + return IdentifierType(VLC->identifiers()->getIdentifier(modScope, IdentifierType::entityType(), value).value_or(-1)); else return loadVariable(IdentifierType::entityType(), value, variables, IdentifierType::NONE); } @@ -91,7 +91,7 @@ namespace JsonRandom IdentifierType decodeKey(const JsonNode & value, const Variables & variables) { if (value.String().empty() || value.String()[0] != '@') - return IdentifierType(*VLC->identifiers()->getIdentifier(IdentifierType::entityType(), value)); + return IdentifierType(VLC->identifiers()->getIdentifier(IdentifierType::entityType(), value).value_or(-1)); else return loadVariable(IdentifierType::entityType(), value.String(), variables, IdentifierType::NONE); } From 8e8d42bfa29252ce18343c15a51f53bfdc4fe350 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sat, 20 Jan 2024 18:40:03 +0200 Subject: [PATCH 16/54] Try to simplify / cleanup code to localize crash --- .../AObjectTypeHandler.cpp | 21 ++++++------------- .../CObjectClassesHandler.cpp | 4 ++-- .../DwellingInstanceConstructor.cpp | 8 +++---- lib/mapping/MapFormatJson.cpp | 4 ++-- 4 files changed, 14 insertions(+), 23 deletions(-) diff --git a/lib/mapObjectConstructors/AObjectTypeHandler.cpp b/lib/mapObjectConstructors/AObjectTypeHandler.cpp index b5ead3f79..a3ed75ef4 100644 --- a/lib/mapObjectConstructors/AObjectTypeHandler.cpp +++ b/lib/mapObjectConstructors/AObjectTypeHandler.cpp @@ -21,17 +21,7 @@ VCMI_LIB_NAMESPACE_BEGIN AObjectTypeHandler::AObjectTypeHandler() = default; - -AObjectTypeHandler::~AObjectTypeHandler() -{ - // FIXME: currently on Android there is a weird crash in destructor of 'base' member - // this code attempts to localize and fix this crash - if (base) - { - base->clear(); - base.reset(); - } -} +AObjectTypeHandler::~AObjectTypeHandler() = default; std::string AObjectTypeHandler::getJsonKey() const { @@ -89,12 +79,12 @@ void AObjectTypeHandler::init(const JsonNode & input) if (base) JsonUtils::inherit(entry.second, *base); - auto * tmpl = new ObjectTemplate; + auto tmpl = std::make_shared(); tmpl->id = Obj(type); tmpl->subid = subtype; tmpl->stringID = entry.first; // FIXME: create "fullID" - type.object.template? tmpl->readJson(entry.second); - templates.push_back(std::shared_ptr(tmpl)); + templates.push_back(tmpl); } for(const JsonNode & node : input["sounds"]["ambient"].Vector()) @@ -188,12 +178,13 @@ void AObjectTypeHandler::addTemplate(JsonNode config) config.setType(JsonNode::JsonType::DATA_STRUCT); // ensure that input is not null if (base) JsonUtils::inherit(config, *base); - auto * tmpl = new ObjectTemplate; + + auto tmpl = std::make_shared(); tmpl->id = Obj(type); tmpl->subid = subtype; tmpl->stringID.clear(); // TODO? tmpl->readJson(config); - templates.emplace_back(tmpl); + templates.push_back(tmpl); } std::vector> AObjectTypeHandler::getTemplates() const diff --git a/lib/mapObjectConstructors/CObjectClassesHandler.cpp b/lib/mapObjectConstructors/CObjectClassesHandler.cpp index 2c758b0f6..de608e33d 100644 --- a/lib/mapObjectConstructors/CObjectClassesHandler.cpp +++ b/lib/mapObjectConstructors/CObjectClassesHandler.cpp @@ -109,13 +109,13 @@ std::vector CObjectClassesHandler::loadLegacyData() for (size_t i = 0; i < totalNumber; i++) { - auto * tmpl = new ObjectTemplate; + auto tmpl = std::make_shared(); tmpl->readTxt(parser); parser.endLine(); std::pair key(tmpl->id, tmpl->subid); - legacyTemplates.insert(std::make_pair(key, std::shared_ptr(tmpl))); + legacyTemplates.insert(std::make_pair(key, tmpl)); } objects.resize(256); diff --git a/lib/mapObjectConstructors/DwellingInstanceConstructor.cpp b/lib/mapObjectConstructors/DwellingInstanceConstructor.cpp index 6a137b976..ea86a5cb8 100644 --- a/lib/mapObjectConstructors/DwellingInstanceConstructor.cpp +++ b/lib/mapObjectConstructors/DwellingInstanceConstructor.cpp @@ -35,17 +35,17 @@ void DwellingInstanceConstructor::initTypeData(const JsonNode & input) const auto totalLevels = levels.size(); availableCreatures.resize(totalLevels); - for(auto currentLevel = 0; currentLevel < totalLevels; currentLevel++) + for(int currentLevel = 0; currentLevel < totalLevels; currentLevel++) { const JsonVector & creaturesOnLevel = levels[currentLevel].Vector(); const auto creaturesNumber = creaturesOnLevel.size(); availableCreatures[currentLevel].resize(creaturesNumber); - for(auto currentCreature = 0; currentCreature < creaturesNumber; currentCreature++) + for(int currentCreature = 0; currentCreature < creaturesNumber; currentCreature++) { - VLC->identifiers()->requestIdentifier("creature", creaturesOnLevel[currentCreature], [=] (si32 index) + VLC->identifiers()->requestIdentifier("creature", creaturesOnLevel[currentCreature], [this, currentLevel, currentCreature] (si32 index) { - availableCreatures[currentLevel][currentCreature] = VLC->creh->objects[index]; + availableCreatures.at(currentLevel).at(currentCreature) = VLC->creh->objects[index]; }); } assert(!availableCreatures[currentLevel].empty()); diff --git a/lib/mapping/MapFormatJson.cpp b/lib/mapping/MapFormatJson.cpp index 7f6059400..ca4b706fb 100644 --- a/lib/mapping/MapFormatJson.cpp +++ b/lib/mapping/MapFormatJson.cpp @@ -1074,14 +1074,14 @@ void CMapLoaderJson::MapObjectLoader::construct() auto handler = VLC->objtypeh->getHandlerFor( ModScope::scopeMap(), typeName, subtypeName); - auto * appearance = new ObjectTemplate; + auto appearance = std::make_shared(); appearance->id = Obj(handler->getIndex()); appearance->subid = handler->getSubIndex(); appearance->readJson(configuration["template"], false); // Will be destroyed soon and replaced with shared template - instance = handler->create(std::shared_ptr(appearance)); + instance = handler->create(appearance); instance->id = ObjectInstanceID(static_cast(owner->map->objects.size())); instance->instanceName = jsonKey; From 99207836289d9de69f56d1bf281e295494280c45 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sat, 20 Jan 2024 18:50:59 +0200 Subject: [PATCH 17/54] Avoid crash on invalid H3 data --- client/renderSDL/SDLImage.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/renderSDL/SDLImage.cpp b/client/renderSDL/SDLImage.cpp index e8930abd3..4ce8e869c 100644 --- a/client/renderSDL/SDLImage.cpp +++ b/client/renderSDL/SDLImage.cpp @@ -205,6 +205,8 @@ void SDLImage::exportBitmap(const boost::filesystem::path& path) const void SDLImage::playerColored(PlayerColor player) { + if (!surf) + return; graphics->blueToPlayersAdv(surf, player); } From 883ea2349540c478f972881be35d14175625bc4b Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sat, 20 Jan 2024 17:54:15 +0100 Subject: [PATCH 18/54] moved to gameconfig --- client/lobby/OptionsTabBase.cpp | 12 ------------ client/windows/GUIClasses.cpp | 2 +- config/gameConfig.json | 4 +++- config/widgets/extraOptionsTab.json | 14 -------------- lib/ExtraOptionsInfo.cpp | 3 +-- lib/ExtraOptionsInfo.h | 2 -- lib/GameSettings.cpp | 1 + lib/GameSettings.h | 1 + server/processors/HeroPoolProcessor.cpp | 3 ++- 9 files changed, 9 insertions(+), 33 deletions(-) diff --git a/client/lobby/OptionsTabBase.cpp b/client/lobby/OptionsTabBase.cpp index 19bc145b4..aa1b97c9a 100644 --- a/client/lobby/OptionsTabBase.cpp +++ b/client/lobby/OptionsTabBase.cpp @@ -110,12 +110,6 @@ OptionsTabBase::OptionsTabBase(const JsonPath & configPath) CSH->setExtraOptionsInfo(info); }); - addCallback("setInviteHero", [&](int index){ - ExtraOptionsInfo info = SEL->getStartInfo()->extraOptionsInfo; - info.inviteHero = index; - CSH->setExtraOptionsInfo(info); - }); - addCallback("setTurnTimerAccumulate", [&](int index){ TurnTimerInfo info = SEL->getStartInfo()->turnTimerInfo; info.accumulatingTurnTimer = index; @@ -423,10 +417,4 @@ void OptionsTabBase::recreate() buttonUnlimitedReplay->setSelectedSilent(SEL->getStartInfo()->extraOptionsInfo.unlimitedReplay); buttonUnlimitedReplay->setInputEnabled(SEL->screenType != ESelectionScreen::loadGame); } - - if(auto buttonInviteHero = widget("buttonInviteHero")) - { - buttonInviteHero->setSelectedSilent(SEL->getStartInfo()->extraOptionsInfo.inviteHero); - buttonInviteHero->setInputEnabled(SEL->screenType != ESelectionScreen::loadGame); - } } diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 9c9b12d8d..3a10c2870 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -519,7 +519,7 @@ void CTavernWindow::addInvite() { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - if(CSH->client->getStartInfo()->extraOptionsInfo.inviteHero) + if(VLC->settings()->getBoolean(EGameSettings::HEROES_INVITE)) { const auto & heroesPool = CSH->client->gameState()->heroesPool; for(auto & elem : heroesPool->unusedHeroesFromPool()) diff --git a/config/gameConfig.json b/config/gameConfig.json index 56260f4e2..24e3c4580 100644 --- a/config/gameConfig.json +++ b/config/gameConfig.json @@ -289,7 +289,9 @@ // Chances for a hero with default army to receive corresponding stack out of his predefined starting troops "startingStackChances": [ 100, 88, 25], // number of artifacts that can fit in a backpack. -1 is unlimited. - "backpackSize" : -1 + "backpackSize" : -1, + // if heroes are invitable in tavern + "invite" : false }, "towns": diff --git a/config/widgets/extraOptionsTab.json b/config/widgets/extraOptionsTab.json index 5f6635254..d8a333b9c 100644 --- a/config/widgets/extraOptionsTab.json +++ b/config/widgets/extraOptionsTab.json @@ -73,13 +73,6 @@ "callback" : "setUnlimitedReplay", "help" : "vcmi.optionsTab.unlimitedReplay", "selected" : true - }, - { - "name": "buttonInviteHero", - "image": "lobby/checkbox", - "callback" : "setInviteHero", - "help" : "vcmi.optionsTab.inviteHero", - "selected" : true } ] }, @@ -103,13 +96,6 @@ "alignment": "left", "color": "yellow", "text": "vcmi.optionsTab.unlimitedReplay.hover" - }, - { - "name": "labelInviteHero", - "font": "small", - "alignment": "left", - "color": "yellow", - "text": "vcmi.optionsTab.inviteHero.hover" } ] } diff --git a/lib/ExtraOptionsInfo.cpp b/lib/ExtraOptionsInfo.cpp index bd0efb124..2411608b7 100644 --- a/lib/ExtraOptionsInfo.cpp +++ b/lib/ExtraOptionsInfo.cpp @@ -15,8 +15,7 @@ VCMI_LIB_NAMESPACE_BEGIN bool ExtraOptionsInfo::operator == (const ExtraOptionsInfo & other) const { return cheatsAllowed == other.cheatsAllowed && - unlimitedReplay == other.unlimitedReplay && - inviteHero == other.inviteHero; + unlimitedReplay == other.unlimitedReplay; } VCMI_LIB_NAMESPACE_END diff --git a/lib/ExtraOptionsInfo.h b/lib/ExtraOptionsInfo.h index f433008c2..3b1e65d1b 100644 --- a/lib/ExtraOptionsInfo.h +++ b/lib/ExtraOptionsInfo.h @@ -16,7 +16,6 @@ struct DLL_LINKAGE ExtraOptionsInfo { bool cheatsAllowed = true; bool unlimitedReplay = false; - bool inviteHero = false; bool operator == (const ExtraOptionsInfo & other) const; @@ -25,7 +24,6 @@ struct DLL_LINKAGE ExtraOptionsInfo { h & cheatsAllowed; h & unlimitedReplay; - h & inviteHero; } }; diff --git a/lib/GameSettings.cpp b/lib/GameSettings.cpp index e3ef38929..248300fea 100644 --- a/lib/GameSettings.cpp +++ b/lib/GameSettings.cpp @@ -74,6 +74,7 @@ void GameSettings::load(const JsonNode & input) {EGameSettings::HEROES_RETREAT_ON_WIN_WITHOUT_TROOPS, "heroes", "retreatOnWinWithoutTroops" }, {EGameSettings::HEROES_STARTING_STACKS_CHANCES, "heroes", "startingStackChances" }, {EGameSettings::HEROES_BACKPACK_CAP, "heroes", "backpackSize" }, + {EGameSettings::HEROES_INVITE, "heroes", "invite" }, {EGameSettings::MAP_FORMAT_RESTORATION_OF_ERATHIA, "mapFormat", "restorationOfErathia" }, {EGameSettings::MAP_FORMAT_ARMAGEDDONS_BLADE, "mapFormat", "armageddonsBlade" }, {EGameSettings::MAP_FORMAT_SHADOW_OF_DEATH, "mapFormat", "shadowOfDeath" }, diff --git a/lib/GameSettings.h b/lib/GameSettings.h index 7241e9b92..a33581320 100644 --- a/lib/GameSettings.h +++ b/lib/GameSettings.h @@ -38,6 +38,7 @@ enum class EGameSettings HEROES_RETREAT_ON_WIN_WITHOUT_TROOPS, HEROES_STARTING_STACKS_CHANCES, HEROES_BACKPACK_CAP, + HEROES_INVITE, MARKETS_BLACK_MARKET_RESTOCK_PERIOD, BANKS_SHOW_GUARDS_COMPOSITION, MODULE_COMMANDERS, diff --git a/server/processors/HeroPoolProcessor.cpp b/server/processors/HeroPoolProcessor.cpp index ebf4b4edc..789775804 100644 --- a/server/processors/HeroPoolProcessor.cpp +++ b/server/processors/HeroPoolProcessor.cpp @@ -23,6 +23,7 @@ #include "../../lib/gameState/CGameState.h" #include "../../lib/gameState/TavernHeroesPool.h" #include "../../lib/gameState/TavernSlot.h" +#include "../../lib/GameSettings.h" HeroPoolProcessor::HeroPoolProcessor() : gameHandler(nullptr) @@ -114,7 +115,7 @@ void HeroPoolProcessor::selectNewHeroForSlot(const PlayerColor & color, TavernHe CGHeroInstance *newHero = pickHeroFor(needNativeHero, color); const auto & heroesPool = gameHandler->gameState()->heroesPool; - if(gameHandler->getStartInfo()->extraOptionsInfo.inviteHero && heroesPool->unusedHeroesFromPool().count(nextHero) && heroesPool->isHeroAvailableFor(nextHero, color)) + if(VLC->settings()->getBoolean(EGameSettings::HEROES_INVITE) && heroesPool->unusedHeroesFromPool().count(nextHero) && heroesPool->isHeroAvailableFor(nextHero, color)) newHero = heroesPool->unusedHeroesFromPool()[nextHero]; if (newHero) From b82a51d184aee4a6d93f40ce655e49bf49abc65a Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sat, 20 Jan 2024 17:58:54 +0100 Subject: [PATCH 19/54] remove unused translation --- Mods/vcmi/config/vcmi/english.json | 2 -- Mods/vcmi/config/vcmi/german.json | 2 -- 2 files changed, 4 deletions(-) diff --git a/Mods/vcmi/config/vcmi/english.json b/Mods/vcmi/config/vcmi/english.json index 482bd67c4..c9a383fba 100644 --- a/Mods/vcmi/config/vcmi/english.json +++ b/Mods/vcmi/config/vcmi/english.json @@ -319,10 +319,8 @@ "vcmi.optionsTab.cheatAllowed.hover" : "Allow cheats", "vcmi.optionsTab.unlimitedReplay.hover" : "Unlimited battle replay", - "vcmi.optionsTab.inviteHero.hover" : "Invite hero", "vcmi.optionsTab.cheatAllowed.help" : "{Allow cheats}\nAllows the inputs of cheats during the game.", "vcmi.optionsTab.unlimitedReplay.help" : "{Unlimited battle replay}\nNo limit of replaying battles.", - "vcmi.optionsTab.inviteHero.help" : "{Invite hero}\nPossibility to invite hero in the tavern.", // Custom victory conditions for H3 campaigns and HotA maps "vcmi.map.victoryCondition.daysPassed.toOthers" : "The enemy has managed to survive till this day. Victory is theirs!", diff --git a/Mods/vcmi/config/vcmi/german.json b/Mods/vcmi/config/vcmi/german.json index 268caf197..8a50c204b 100644 --- a/Mods/vcmi/config/vcmi/german.json +++ b/Mods/vcmi/config/vcmi/german.json @@ -319,10 +319,8 @@ "vcmi.optionsTab.cheatAllowed.hover" : "Cheats erlauben", "vcmi.optionsTab.unlimitedReplay.hover" : "Unbegrenzte Kampfwiederholung", - "vcmi.optionsTab.inviteHero.hover" : "Helden einladen", "vcmi.optionsTab.cheatAllowed.help" : "{Cheats erlauben}\nErlaubt die Eingabe von Cheats während des Spiels.", "vcmi.optionsTab.unlimitedReplay.help" : "{Unbegrenzte Kampfwiederholung}\nKämpfe lassen sich unbegrenzt wiederholen.", - "vcmi.optionsTab.inviteHero.help" : "{Helden einladen}\nMöglichkeit Helden in der Taverne einzuladen.", // Custom victory conditions for H3 campaigns and HotA maps "vcmi.map.victoryCondition.daysPassed.toOthers" : "Der Feind hat es geschafft, bis zum heutigen Tag zu überleben. Der Sieg gehört ihm!", From 0c07384293135a77ab7a05f25e9b5b2c3ba686a4 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sat, 20 Jan 2024 20:34:51 +0200 Subject: [PATCH 20/54] Refactoring of serialization versioning handling - Removed 'version' field from serialize() method - Handler classes - Binary(De)Serializer now have 'version' field - Serialization versioning now uses named enum Save compatibility with 1.4.X saves should be intact --- AI/EmptyAI/CEmptyAI.cpp | 4 +- AI/EmptyAI/CEmptyAI.h | 4 +- AI/Nullkiller/AIGateway.cpp | 14 +- AI/Nullkiller/AIGateway.h | 8 +- AI/Nullkiller/AIUtility.h | 4 +- AI/Nullkiller/Goals/CGoal.h | 2 +- AI/VCAI/AIUtility.h | 4 +- AI/VCAI/Goals/AbstractGoal.h | 2 +- AI/VCAI/Goals/CGoal.h | 2 +- AI/VCAI/ResourceManager.h | 4 +- AI/VCAI/VCAI.cpp | 14 +- AI/VCAI/VCAI.h | 10 +- client/CPlayerInterface.cpp | 8 +- client/CPlayerInterface.h | 4 +- client/Client.cpp | 19 +-- client/Client.h | 4 +- client/PlayerLocalState.h | 4 +- client/windows/CMapOverview.cpp | 2 +- cmake_modules/VCMI_lib.cmake | 20 +-- lib/CArtHandler.h | 4 +- lib/CArtifactInstance.h | 6 +- lib/CBonusTypeHandler.h | 4 +- lib/CCreatureSet.h | 10 +- lib/CGameInterface.cpp | 6 +- lib/CGameInterface.h | 8 +- lib/CGeneralTextHandler.h | 4 +- lib/CPlayerState.h | 8 +- lib/CRandomGenerator.h | 2 +- lib/CStack.h | 2 +- lib/Color.h | 2 +- lib/ConstTransitivePtr.h | 2 +- lib/ExtraOptionsInfo.h | 2 +- lib/GameSettings.h | 2 +- lib/JsonNode.h | 2 +- lib/LogicalExpression.h | 4 +- lib/MetaString.h | 2 +- lib/Point.h | 2 +- lib/Rect.h | 2 +- lib/ResourceSet.h | 2 +- lib/ScriptHandler.h | 2 +- lib/StartInfo.h | 12 +- lib/TerrainHandler.h | 2 +- lib/TurnTimerInfo.h | 2 +- lib/battle/BattleAction.h | 4 +- lib/battle/BattleHex.h | 2 +- lib/battle/BattleInfo.h | 7 +- lib/battle/CBattleInfoCallback.h | 2 +- lib/battle/CObstacleInstance.h | 4 +- lib/battle/SideInBattle.h | 2 +- lib/battle/SiegeInfo.h | 2 +- lib/bonuses/Bonus.h | 2 +- lib/bonuses/BonusList.h | 2 +- lib/bonuses/CBonusSystemNode.h | 2 +- lib/bonuses/Limiters.h | 22 +-- lib/bonuses/Propagators.h | 4 +- lib/bonuses/Updaters.h | 12 +- lib/campaign/CampaignScenarioPrologEpilog.h | 2 +- lib/campaign/CampaignState.h | 20 +-- lib/constants/EntityIdentifiers.h | 4 +- lib/constants/IdentifierBase.h | 8 +- lib/constants/VariantIdentifier.h | 2 +- lib/filesystem/ResourcePath.h | 2 +- lib/gameState/CGameState.h | 4 +- lib/gameState/CGameStateCampaign.h | 2 +- lib/gameState/EVictoryLossCheckResult.h | 2 +- lib/gameState/QuestInfo.h | 2 +- lib/gameState/SThievesGuildInfo.h | 2 +- lib/gameState/TavernHeroesPool.h | 4 +- lib/int3.h | 2 +- .../CBankInstanceConstructor.h | 2 +- lib/mapObjects/CArmedInstance.h | 2 +- lib/mapObjects/CBank.h | 2 +- lib/mapObjects/CGCreature.h | 2 +- lib/mapObjects/CGDwelling.h | 2 +- lib/mapObjects/CGHeroInstance.h | 8 +- lib/mapObjects/CGMarket.h | 6 +- lib/mapObjects/CGObjectInstance.h | 4 +- lib/mapObjects/CGPandoraBox.h | 4 +- lib/mapObjects/CGTownBuilding.h | 8 +- lib/mapObjects/CGTownInstance.h | 2 +- lib/mapObjects/CQuest.h | 16 +- lib/mapObjects/CRewardableObject.h | 2 +- lib/mapObjects/IObjectInterface.h | 2 +- lib/mapObjects/MiscObjects.h | 36 ++--- lib/mapObjects/ObjectTemplate.h | 4 +- lib/mapping/CMap.h | 6 +- lib/mapping/CMapDefines.h | 6 +- lib/mapping/CMapHeader.h | 12 +- lib/mapping/CMapInfo.cpp | 2 +- lib/mapping/CMapInfo.h | 2 +- lib/modding/ActiveModsInSaveList.h | 2 +- lib/modding/CModVersion.h | 2 +- lib/modding/ModVerificationInfo.h | 2 +- lib/networkPacks/ArtifactLocation.h | 2 +- lib/networkPacks/BattleChanges.h | 4 +- lib/networkPacks/Component.h | 2 +- lib/networkPacks/EntityChanges.h | 2 +- lib/networkPacks/NetPacksBase.h | 4 +- lib/networkPacks/PacksForClient.h | 148 +++++++++--------- lib/networkPacks/PacksForClientBattle.h | 46 +++--- lib/networkPacks/PacksForLobby.h | 44 +++--- lib/networkPacks/PacksForServer.h | 60 +++---- lib/networkPacks/SetStackEffect.h | 2 +- lib/networkPacks/StackLocation.h | 2 +- lib/rewardable/Configuration.h | 8 +- lib/rewardable/Info.h | 2 +- lib/rewardable/Interface.h | 2 +- lib/rewardable/Limiter.h | 2 +- lib/rewardable/Reward.h | 4 +- lib/rmg/CMapGenOptions.h | 22 ++- lib/serializer/BinaryDeserializer.cpp | 2 +- lib/serializer/BinaryDeserializer.h | 11 +- lib/serializer/BinarySerializer.h | 8 +- lib/serializer/CLoadFile.cpp | 22 +-- lib/serializer/CLoadFile.h | 5 +- lib/serializer/CMemorySerializer.cpp | 2 +- lib/serializer/CSaveFile.cpp | 2 +- lib/serializer/CSerializer.h | 7 +- lib/serializer/Connection.cpp | 2 +- lib/serializer/SerializerVersion.h | 39 +++++ lib/spells/CSpellHandler.h | 11 +- lib/spells/ViewSpellInt.h | 2 +- server/CGameHandler.cpp | 2 +- server/CGameHandler.h | 2 +- server/battles/BattleProcessor.h | 2 +- server/battles/BattleResultProcessor.h | 2 +- server/processors/HeroPoolProcessor.h | 2 +- server/processors/PlayerMessageProcessor.h | 2 +- server/processors/TurnOrderProcessor.h | 4 +- 129 files changed, 498 insertions(+), 473 deletions(-) create mode 100644 lib/serializer/SerializerVersion.h diff --git a/AI/EmptyAI/CEmptyAI.cpp b/AI/EmptyAI/CEmptyAI.cpp index 2812b7140..0ca26e8c4 100644 --- a/AI/EmptyAI/CEmptyAI.cpp +++ b/AI/EmptyAI/CEmptyAI.cpp @@ -14,11 +14,11 @@ #include "../../lib/CStack.h" #include "../../lib/battle/BattleAction.h" -void CEmptyAI::saveGame(BinarySerializer & h, const int version) +void CEmptyAI::saveGame(BinarySerializer & h) { } -void CEmptyAI::loadGame(BinaryDeserializer & h, const int version) +void CEmptyAI::loadGame(BinaryDeserializer & h) { } diff --git a/AI/EmptyAI/CEmptyAI.h b/AI/EmptyAI/CEmptyAI.h index a2f125fbe..2954564be 100644 --- a/AI/EmptyAI/CEmptyAI.h +++ b/AI/EmptyAI/CEmptyAI.h @@ -19,8 +19,8 @@ class CEmptyAI : public CGlobalAI std::shared_ptr cb; public: - virtual void saveGame(BinarySerializer & h, const int version) override; - virtual void loadGame(BinaryDeserializer & h, const int version) override; + virtual void saveGame(BinarySerializer & h) override; + virtual void loadGame(BinaryDeserializer & h) override; void initGameInterface(std::shared_ptr ENV, std::shared_ptr CB) override; void yourTurn(QueryID queryID) override; diff --git a/AI/Nullkiller/AIGateway.cpp b/AI/Nullkiller/AIGateway.cpp index ae58960af..596a8a0c1 100644 --- a/AI/Nullkiller/AIGateway.cpp +++ b/AI/Nullkiller/AIGateway.cpp @@ -747,27 +747,25 @@ void AIGateway::showMapObjectSelectDialog(QueryID askID, const Component & icon, requestActionASAP([=](){ answerQuery(askID, selectedObject.getNum()); }); } -void AIGateway::saveGame(BinarySerializer & h, const int version) +void AIGateway::saveGame(BinarySerializer & h) { - LOG_TRACE_PARAMS(logAi, "version '%i'", version); NET_EVENT_HANDLER; nullkiller->memory->removeInvisibleObjects(myCb.get()); - CAdventureAI::saveGame(h, version); - serializeInternal(h, version); + CAdventureAI::saveGame(h); + serializeInternal(h); } -void AIGateway::loadGame(BinaryDeserializer & h, const int version) +void AIGateway::loadGame(BinaryDeserializer & h) { - LOG_TRACE_PARAMS(logAi, "version '%i'", version); //NET_EVENT_HANDLER; #if 0 //disabled due to issue 2890 registerGoals(h); #endif // 0 - CAdventureAI::loadGame(h, version); - serializeInternal(h, version); + CAdventureAI::loadGame(h); + serializeInternal(h); } bool AIGateway::makePossibleUpgrades(const CArmedInstance * obj) diff --git a/AI/Nullkiller/AIGateway.h b/AI/Nullkiller/AIGateway.h index 63d7b1a44..e4aa16ab5 100644 --- a/AI/Nullkiller/AIGateway.h +++ b/AI/Nullkiller/AIGateway.h @@ -62,7 +62,7 @@ public: void heroVisit(const CGObjectInstance * obj, bool started); - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battle; h & remainingQueries; @@ -119,8 +119,8 @@ public: void showGarrisonDialog(const CArmedInstance * up, const CGHeroInstance * down, bool removableUnits, QueryID queryID) override; //all stacks operations between these objects become allowed, interface has to call onEnd when done void showTeleportDialog(const CGHeroInstance * hero, TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override; void showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector & objects) override; - void saveGame(BinarySerializer & h, const int version) override; //saving - void loadGame(BinaryDeserializer & h, const int version) override; //loading + void saveGame(BinarySerializer & h) override; //saving + void loadGame(BinaryDeserializer & h) override; //loading void finish() override; void availableCreaturesChanged(const CGDwelling * town) override; @@ -203,7 +203,7 @@ public: //special function that can be called ONLY from game events handling thread and will send request ASAP void requestActionASAP(std::function whatToDo); - template void serializeInternal(Handler & h, const int version) + template void serializeInternal(Handler & h) { h & nullkiller->memory->knownTeleportChannels; h & nullkiller->memory->knownSubterraneanGates; diff --git a/AI/Nullkiller/AIUtility.h b/AI/Nullkiller/AIUtility.h index ba5157883..b4bacdcce 100644 --- a/AI/Nullkiller/AIUtility.h +++ b/AI/Nullkiller/AIUtility.h @@ -115,7 +115,7 @@ public: bool validAndSet() const; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & this->h; h & hid; @@ -147,7 +147,7 @@ struct ObjectIdRef bool operator<(const ObjectIdRef & rhs) const; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & id; } diff --git a/AI/Nullkiller/Goals/CGoal.h b/AI/Nullkiller/Goals/CGoal.h index 722c7ebd2..255535d59 100644 --- a/AI/Nullkiller/Goals/CGoal.h +++ b/AI/Nullkiller/Goals/CGoal.h @@ -37,7 +37,7 @@ namespace Goals { return new T(static_cast(*this)); //casting enforces template instantiation } - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); //h & goalType & isElementar & isAbstract & priority; diff --git a/AI/VCAI/AIUtility.h b/AI/VCAI/AIUtility.h index 2b0fe415e..37a007b9a 100644 --- a/AI/VCAI/AIUtility.h +++ b/AI/VCAI/AIUtility.h @@ -70,7 +70,7 @@ public: bool validAndSet() const; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & this->h; h & hid; @@ -102,7 +102,7 @@ struct ObjectIdRef bool operator<(const ObjectIdRef & rhs) const; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & id; } diff --git a/AI/VCAI/Goals/AbstractGoal.h b/AI/VCAI/Goals/AbstractGoal.h index ed4fc9430..2c54ca56e 100644 --- a/AI/VCAI/Goals/AbstractGoal.h +++ b/AI/VCAI/Goals/AbstractGoal.h @@ -176,7 +176,7 @@ namespace Goals return !(*this == g); } - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & goalType; h & isElementar; diff --git a/AI/VCAI/Goals/CGoal.h b/AI/VCAI/Goals/CGoal.h index 6a8876cbf..bef480c55 100644 --- a/AI/VCAI/Goals/CGoal.h +++ b/AI/VCAI/Goals/CGoal.h @@ -69,7 +69,7 @@ namespace Goals return ptr; } - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); //h & goalType & isElementar & isAbstract & priority; diff --git a/AI/VCAI/ResourceManager.h b/AI/VCAI/ResourceManager.h index cdbc79007..af686081f 100644 --- a/AI/VCAI/ResourceManager.h +++ b/AI/VCAI/ResourceManager.h @@ -28,7 +28,7 @@ struct DLL_EXPORT ResourceObjective Goals::TSubgoal goal; //what for (build, gather army etc...) //TODO: register? - template void serializeInternal(Handler & h, const int version) + template void serializeInternal(Handler & h) { h & resources; //h & goal; //FIXME: goal serialization is broken @@ -105,7 +105,7 @@ private: void dumpToLog() const; //TODO: register? - template void serializeInternal(Handler & h, const int version) + template void serializeInternal(Handler & h) { h & saving; h & queue; diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index 8954ff191..e8296ba26 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -746,9 +746,8 @@ void VCAI::showMapObjectSelectDialog(QueryID askID, const Component & icon, cons requestActionASAP([=](){ answerQuery(askID, selectedObject.getNum()); }); } -void VCAI::saveGame(BinarySerializer & h, const int version) +void VCAI::saveGame(BinarySerializer & h) { - LOG_TRACE_PARAMS(logAi, "version '%i'", version); NET_EVENT_HANDLER; validateVisitableObjs(); @@ -756,21 +755,20 @@ void VCAI::saveGame(BinarySerializer & h, const int version) //disabled due to issue 2890 registerGoals(h); #endif // 0 - CAdventureAI::saveGame(h, version); - serializeInternal(h, version); + CAdventureAI::saveGame(h); + serializeInternal(h); } -void VCAI::loadGame(BinaryDeserializer & h, const int version) +void VCAI::loadGame(BinaryDeserializer & h) { - LOG_TRACE_PARAMS(logAi, "version '%i'", version); //NET_EVENT_HANDLER; #if 0 //disabled due to issue 2890 registerGoals(h); #endif // 0 - CAdventureAI::loadGame(h, version); - serializeInternal(h, version); + CAdventureAI::loadGame(h); + serializeInternal(h); } void makePossibleUpgrades(const CArmedInstance * obj) diff --git a/AI/VCAI/VCAI.h b/AI/VCAI/VCAI.h index 5f327e5c3..0cc43db2c 100644 --- a/AI/VCAI/VCAI.h +++ b/AI/VCAI/VCAI.h @@ -68,7 +68,7 @@ public: void heroVisit(const CGObjectInstance * obj, bool started); - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battle; h & remainingQueries; @@ -152,8 +152,8 @@ public: void showGarrisonDialog(const CArmedInstance * up, const CGHeroInstance * down, bool removableUnits, QueryID queryID) override; //all stacks operations between these objects become allowed, interface has to call onEnd when done void showTeleportDialog(const CGHeroInstance * hero, TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override; void showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector & objects) override; - void saveGame(BinarySerializer & h, const int version) override; //saving - void loadGame(BinaryDeserializer & h, const int version) override; //loading + void saveGame(BinarySerializer & h) override; //saving + void loadGame(BinaryDeserializer & h) override; //loading void finish() override; void availableCreaturesChanged(const CGDwelling * town) override; @@ -301,7 +301,7 @@ public: } #endif - template void serializeInternal(Handler & h, const int version) + template void serializeInternal(Handler & h) { h & knownTeleportChannels; h & knownSubterraneanGates; @@ -341,7 +341,7 @@ public: //we have to explicitly ignore invalid goal class type id h & typeId; Goals::AbstractGoal ignored2; - ignored2.serialize(h, version); + ignored2.serialize(h); } } } diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index fa80b647f..59a66daf0 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -1150,16 +1150,16 @@ void CPlayerInterface::heroBonusChanged( const CGHeroInstance *hero, const Bonus } } -void CPlayerInterface::saveGame( BinarySerializer & h, const int version ) +void CPlayerInterface::saveGame( BinarySerializer & h ) { EVENT_HANDLER_CALLED_BY_CLIENT; - localState->serialize(h, version); + localState->serialize(h); } -void CPlayerInterface::loadGame( BinaryDeserializer & h, const int version ) +void CPlayerInterface::loadGame( BinaryDeserializer & h ) { EVENT_HANDLER_CALLED_BY_CLIENT; - localState->serialize(h, version); + localState->serialize(h); firstCall = -1; } diff --git a/client/CPlayerInterface.h b/client/CPlayerInterface.h index 3d9c17cf2..aa97ba8ad 100644 --- a/client/CPlayerInterface.h +++ b/client/CPlayerInterface.h @@ -145,8 +145,8 @@ protected: // Call-ins from server, should not be called directly, but only via void gameOver(PlayerColor player, const EVictoryLossCheckResult & victoryLossCheckResult) override; void playerStartsTurn(PlayerColor player) override; //called before yourTurn on active itnerface void playerEndsTurn(PlayerColor player) override; - void saveGame(BinarySerializer & h, const int version) override; //saving - void loadGame(BinaryDeserializer & h, const int version) override; //loading + void saveGame(BinarySerializer & h) override; //saving + void loadGame(BinaryDeserializer & h) override; //loading void showWorldViewEx(const std::vector & objectPositions, bool showTerrain) override; //for battles diff --git a/client/Client.cpp b/client/Client.cpp index 10c2b64e9..7ae24d4fc 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -225,7 +225,7 @@ void CClient::loadGame(CGameState * initializedGameState) throw std::runtime_error("Cannot open client part of " + CSH->si->mapname); std::unique_ptr loader (new CLoadFile(clientSaveName)); - serialize(loader->serializer, loader->serializer.fileVersion); + serialize(loader->serializer, loader->serializer.version); logNetwork->info("Client data loaded."); } @@ -238,7 +238,7 @@ void CClient::loadGame(CGameState * initializedGameState) initPlayerInterfaces(); } -void CClient::serialize(BinarySerializer & h, const int version) +void CClient::serialize(BinarySerializer & h) { assert(h.saving); ui8 players = static_cast(playerint.size()); @@ -251,20 +251,17 @@ void CClient::serialize(BinarySerializer & h, const int version) h & i->first; h & i->second->dllName; h & i->second->human; - i->second->saveGame(h, version); + i->second->saveGame(h); } #if SCRIPTING_ENABLED - if(version >= 800) - { - JsonNode scriptsState; - clientScripts->serializeState(h.saving, scriptsState); - h & scriptsState; - } + JsonNode scriptsState; + clientScripts->serializeState(h.saving, scriptsState); + h & scriptsState; #endif } -void CClient::serialize(BinaryDeserializer & h, const int version) +void CClient::serialize(BinaryDeserializer & h) { assert(!h.saving); ui8 players = 0; @@ -320,7 +317,7 @@ void CClient::serialize(BinaryDeserializer & h, const int version) // loadGame needs to be called after initGameInterface to load paths correctly // initGameInterface is called in installNewPlayerInterface - nInt->loadGame(h, version); + nInt->loadGame(h); if (shouldResetInterface) { diff --git a/client/Client.h b/client/Client.h index c6890cd31..85893b5b8 100644 --- a/client/Client.h +++ b/client/Client.h @@ -131,8 +131,8 @@ public: void newGame(CGameState * gameState); void loadGame(CGameState * gameState); - void serialize(BinarySerializer & h, const int version); - void serialize(BinaryDeserializer & h, const int version); + void serialize(BinarySerializer & h); + void serialize(BinaryDeserializer & h); void save(const std::string & fname); void endGame(); diff --git a/client/PlayerLocalState.h b/client/PlayerLocalState.h index 47f8fc4ce..b67940bd8 100644 --- a/client/PlayerLocalState.h +++ b/client/PlayerLocalState.h @@ -47,7 +47,7 @@ public: int spellbookLastTabAdvmap = 4; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & spellbookLastPageBattle; h & spellbookLastPageAdvmap; @@ -94,7 +94,7 @@ public: void setSelection(const CArmedInstance *sel); template - void serialize(Handler & h, int version) + void serialize(Handler & h) { //WARNING: this code is broken and not used. See CClient::loadGame std::map pathsMap; //hero -> dest diff --git a/client/windows/CMapOverview.cpp b/client/windows/CMapOverview.cpp index 68a96bc3a..b60973945 100644 --- a/client/windows/CMapOverview.cpp +++ b/client/windows/CMapOverview.cpp @@ -161,7 +161,7 @@ CMapOverviewWidget::CMapOverviewWidget(CMapOverview& parent): std::unique_ptr campaignMap = nullptr; if(p.tabType != ESelectionScreen::newGame && config["variables"]["mapPreviewForSaves"].Bool()) { - CLoadFile lf(*CResourceHandler::get()->getResourceName(ResourcePath(p.resource.getName(), EResType::SAVEGAME)), MINIMAL_SERIALIZATION_VERSION); + CLoadFile lf(*CResourceHandler::get()->getResourceName(ResourcePath(p.resource.getName(), EResType::SAVEGAME)), ESerializationVersion::MINIMAL); lf.checkMagicBytes(SAVEGAME_MAGIC); auto mapHeader = std::make_unique(); diff --git a/cmake_modules/VCMI_lib.cmake b/cmake_modules/VCMI_lib.cmake index 62172e968..ff5ab40ab 100644 --- a/cmake_modules/VCMI_lib.cmake +++ b/cmake_modules/VCMI_lib.cmake @@ -2,7 +2,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) if(NOT DEFINED MAIN_LIB_DIR) set(MAIN_LIB_DIR "${CMAKE_SOURCE_DIR}/lib") endif() - + set(lib_SRCS ${MAIN_LIB_DIR}/StdInc.cpp @@ -264,13 +264,13 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) ${MAIN_LIB_DIR}/VCMI_Lib.cpp ) - # Version.cpp is a generated file + # Version.cpp is a generated file if(ENABLE_GITVERSION) list(APPEND lib_SRCS ${CMAKE_BINARY_DIR}/Version.cpp) set_source_files_properties(${CMAKE_BINARY_DIR}/Version.cpp PROPERTIES GENERATED TRUE ) - endif() + endif() set(lib_HEADERS ${MAIN_LIB_DIR}/../include/vstd/CLoggerBase.h @@ -557,6 +557,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) ${MAIN_LIB_DIR}/serializer/JsonSerializer.h ${MAIN_LIB_DIR}/serializer/JsonUpdater.h ${MAIN_LIB_DIR}/serializer/Cast.h + ${MAIN_LIB_DIR}/serializer/SerializerVersion.h ${MAIN_LIB_DIR}/spells/AbilityCaster.h ${MAIN_LIB_DIR}/spells/AdventureSpellMechanics.h @@ -618,6 +619,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) ${MAIN_LIB_DIR}/CStopWatch.h ${MAIN_LIB_DIR}/CThreadHelper.h ${MAIN_LIB_DIR}/CTownHandler.h + ${MAIN_LIB_DIR}/ExtraOptionsInfo.h ${MAIN_LIB_DIR}/FunctionList.h ${MAIN_LIB_DIR}/GameCallbackHolder.h ${MAIN_LIB_DIR}/GameConstants.h @@ -653,7 +655,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) ${MAIN_LIB_DIR}/VCMI_Lib.h ) - assign_source_group(${lib_SRCS} ${lib_HEADERS}) + assign_source_group(${lib_SRCS} ${lib_HEADERS}) add_library(${TARGET_NAME} ${LIBRARY_TYPE} ${lib_SRCS} ${lib_HEADERS}) set_target_properties(${TARGET_NAME} PROPERTIES COMPILE_DEFINITIONS "VCMI_DLL=1") @@ -661,7 +663,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) minizip::minizip ZLIB::ZLIB ${SYSTEM_LIBS} Boost::boost Boost::thread Boost::filesystem Boost::program_options Boost::locale Boost::date_time ) - if(APPLE_IOS) + if(APPLE_IOS) target_link_libraries(${TARGET_NAME} PUBLIC iOS_utils) endif() @@ -672,13 +674,13 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) PUBLIC ${MAIN_LIB_DIR} ) - if(WIN32) + if(WIN32) set_target_properties(${TARGET_NAME} PROPERTIES - OUTPUT_NAME "VCMI_lib" + OUTPUT_NAME "VCMI_lib" PROJECT_LABEL "VCMI_lib" ) - endif() + endif() vcmi_set_output_dir(${TARGET_NAME} "") @@ -692,7 +694,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake_modules/create_link.cmake ${MAIN_LIB_DIR}/../config ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/config COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake_modules/create_link.cmake ${MAIN_LIB_DIR}/../Mods ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/Mods ) - endif() + endif() # Update version before vcmi compiling if(TARGET update_version) diff --git a/lib/CArtHandler.h b/lib/CArtHandler.h index 211b1e19e..f4c4df8c3 100644 --- a/lib/CArtHandler.h +++ b/lib/CArtHandler.h @@ -179,7 +179,7 @@ struct DLL_LINKAGE ArtSlotInfo ArtSlotInfo() : locked(false) {} const CArtifactInstance * getArt() const; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & artifact; h & locked; @@ -223,7 +223,7 @@ public: virtual void removeArtifact(ArtifactPosition slot); virtual ~CArtifactSet(); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & artifactsInBackpack; h & artifactsWorn; diff --git a/lib/CArtifactInstance.h b/lib/CArtifactInstance.h index 4a252e931..7c100a91f 100644 --- a/lib/CArtifactInstance.h +++ b/lib/CArtifactInstance.h @@ -27,7 +27,7 @@ public: { ConstTransitivePtr art; ArtifactPosition slot; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & art; h & slot; @@ -41,7 +41,7 @@ public: const std::vector & getPartsInfo() const; void addPlacementMap(CArtifactSet::ArtPlacementMap & placementMap); - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & partsInfo; } @@ -93,7 +93,7 @@ public: void move(CArtifactSet & srcSet, const ArtifactPosition srcSlot, CArtifactSet & dstSet, const ArtifactPosition dstSlot); void deserializationFix(); - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & static_cast(*this); diff --git a/lib/CBonusTypeHandler.h b/lib/CBonusTypeHandler.h index 2ddecfb30..9969f28c6 100644 --- a/lib/CBonusTypeHandler.h +++ b/lib/CBonusTypeHandler.h @@ -27,7 +27,7 @@ public: std::string getNameTextID() const; std::string getDescriptionTextID() const; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & icon; h & identifier; @@ -53,7 +53,7 @@ public: std::string bonusToString(const std::shared_ptr & bonus, const IBonusBearer * bearer, bool description) const override; ImagePath bonusToGraphics(const std::shared_ptr & bonus) const override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { //for now always use up to date configuration //once modded bonus type will be implemented, serialize only them diff --git a/lib/CCreatureSet.h b/lib/CCreatureSet.h index 305149b5b..d84731c2e 100644 --- a/lib/CCreatureSet.h +++ b/lib/CCreatureSet.h @@ -46,7 +46,7 @@ public: friend bool operator== (const CStackBasicDescriptor & l, const CStackBasicDescriptor & r); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { if(h.saving) { @@ -85,7 +85,7 @@ public: const CArmedInstance * const & armyObj; //stack must be part of some army, army must be part of some object TExpType experience;//commander needs same amount of exp as hero - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & static_cast(*this); @@ -157,7 +157,7 @@ public: int getLevel() const override; ArtBearer::ArtBearer bearerType() const override; //from CArtifactSet - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & alive; @@ -197,7 +197,7 @@ public: bool setCreature(SlotID slot, CreatureID cre, TQuantity count) override; operator bool() const; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & army; } @@ -280,7 +280,7 @@ public: bool contains(const CStackInstance *stack) const; bool canBeMergedWith(const CCreatureSet &cs, bool allowMergingStacks = true) const; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & stacks; h & formation; diff --git a/lib/CGameInterface.cpp b/lib/CGameInterface.cpp index 619acd62b..005848079 100644 --- a/lib/CGameInterface.cpp +++ b/lib/CGameInterface.cpp @@ -243,9 +243,8 @@ void CAdventureAI::yourTacticPhase(const BattleID & battleID, int distance) battleAI->yourTacticPhase(battleID, distance); } -void CAdventureAI::saveGame(BinarySerializer & h, const int version) /*saving */ +void CAdventureAI::saveGame(BinarySerializer & h) /*saving */ { - LOG_TRACE_PARAMS(logAi, "version '%i'", version); bool hasBattleAI = static_cast(battleAI); h & hasBattleAI; if(hasBattleAI) @@ -254,9 +253,8 @@ void CAdventureAI::saveGame(BinarySerializer & h, const int version) /*saving */ } } -void CAdventureAI::loadGame(BinaryDeserializer & h, const int version) /*loading */ +void CAdventureAI::loadGame(BinaryDeserializer & h) /*loading */ { - LOG_TRACE_PARAMS(logAi, "version '%i'", version); bool hasBattleAI = false; h & hasBattleAI; if(hasBattleAI) diff --git a/lib/CGameInterface.h b/lib/CGameInterface.h index 6aabc1dcc..656e72a0d 100644 --- a/lib/CGameInterface.h +++ b/lib/CGameInterface.h @@ -111,8 +111,8 @@ public: virtual std::optional makeSurrenderRetreatDecision(const BattleID & battleID, const BattleStateInfoForRetreat & battleState) = 0; - virtual void saveGame(BinarySerializer & h, const int version) = 0; - virtual void loadGame(BinaryDeserializer & h, const int version) = 0; + virtual void saveGame(BinarySerializer & h) = 0; + virtual void loadGame(BinaryDeserializer & h) = 0; }; class DLL_LINKAGE CDynLibHandler @@ -162,8 +162,8 @@ public: virtual void battleEnd(const BattleID & battleID, const BattleResult *br, QueryID queryID) override; virtual void battleUnitsChanged(const BattleID & battleID, const std::vector & units) override; - virtual void saveGame(BinarySerializer & h, const int version) override; - virtual void loadGame(BinaryDeserializer & h, const int version) override; + virtual void saveGame(BinarySerializer & h) override; + virtual void loadGame(BinaryDeserializer & h) override; }; VCMI_LIB_NAMESPACE_END diff --git a/lib/CGeneralTextHandler.h b/lib/CGeneralTextHandler.h index 7b57d9fdb..d68371bac 100644 --- a/lib/CGeneralTextHandler.h +++ b/lib/CGeneralTextHandler.h @@ -135,7 +135,7 @@ protected: std::string modContext; template - void serialize(Handler & h, const int Version) + void serialize(Handler & h) { h & baseValue; h & baseLanguage; @@ -193,7 +193,7 @@ public: void jsonSerialize(JsonNode & dest) const; template - void serialize(Handler & h, const int Version) + void serialize(Handler & h) { std::string key; auto sz = stringsLocalizations.size(); diff --git a/lib/CPlayerState.h b/lib/CPlayerState.h index 87959cdec..bfee08267 100644 --- a/lib/CPlayerState.h +++ b/lib/CPlayerState.h @@ -40,10 +40,10 @@ struct DLL_LINKAGE PlayerState : public CBonusSystemNode, public Player return subID < other.subID; } - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & id; - subID.serializeIdentifier(h, id, version); + subID.serializeIdentifier(h, id); } }; @@ -89,7 +89,7 @@ public: return heroes.empty() && towns.empty(); } - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & color; h & human; @@ -123,7 +123,7 @@ public: TeamState(); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & id; h & players; diff --git a/lib/CRandomGenerator.h b/lib/CRandomGenerator.h index cb0360e60..265b716a7 100644 --- a/lib/CRandomGenerator.h +++ b/lib/CRandomGenerator.h @@ -87,7 +87,7 @@ private: public: template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { if(h.saving) { diff --git a/lib/CStack.h b/lib/CStack.h index 78e8eb750..915f8de5a 100644 --- a/lib/CStack.h +++ b/lib/CStack.h @@ -93,7 +93,7 @@ public: return this->owner; } - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { //this assumes that stack objects is newly created //stackState is not serialized here diff --git a/lib/Color.h b/lib/Color.h index 2c231f2b1..6ad89513a 100644 --- a/lib/Color.h +++ b/lib/Color.h @@ -50,7 +50,7 @@ public: {} template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { h & r; h & g; diff --git a/lib/ConstTransitivePtr.h b/lib/ConstTransitivePtr.h index e29ccbced..3cfa4ea2b 100644 --- a/lib/ConstTransitivePtr.h +++ b/lib/ConstTransitivePtr.h @@ -69,7 +69,7 @@ public: ptr = nullptr; } - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & ptr; } diff --git a/lib/ExtraOptionsInfo.h b/lib/ExtraOptionsInfo.h index 3b1e65d1b..cbbb42263 100644 --- a/lib/ExtraOptionsInfo.h +++ b/lib/ExtraOptionsInfo.h @@ -20,7 +20,7 @@ struct DLL_LINKAGE ExtraOptionsInfo bool operator == (const ExtraOptionsInfo & other) const; template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { h & cheatsAllowed; h & unlimitedReplay; diff --git a/lib/GameSettings.h b/lib/GameSettings.h index 7241e9b92..30b047504 100644 --- a/lib/GameSettings.h +++ b/lib/GameSettings.h @@ -96,7 +96,7 @@ public: const JsonNode & getValue(EGameSettings option) const override; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & gameSettings; } diff --git a/lib/JsonNode.h b/lib/JsonNode.h index 47ae9a1a0..03527a2e8 100644 --- a/lib/JsonNode.h +++ b/lib/JsonNode.h @@ -117,7 +117,7 @@ public: std::string toJson(bool compact = false) const; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & meta; h & flags; diff --git a/lib/LogicalExpression.h b/lib/LogicalExpression.h index 6bc3f36fa..10cf000cb 100644 --- a/lib/LogicalExpression.h +++ b/lib/LogicalExpression.h @@ -57,7 +57,7 @@ namespace LogicalExpressionDetail } template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & expressions; } @@ -614,7 +614,7 @@ public: } template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & data; } diff --git a/lib/MetaString.h b/lib/MetaString.h index ff2ffca19..c148edfd4 100644 --- a/lib/MetaString.h +++ b/lib/MetaString.h @@ -125,7 +125,7 @@ public: void serializeJson(JsonSerializeFormat & handler); - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & exactStrings; h & localStrings; diff --git a/lib/Point.h b/lib/Point.h index 36f7a330c..fd3bde33c 100644 --- a/lib/Point.h +++ b/lib/Point.h @@ -122,7 +122,7 @@ public: } template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { h & x; h & y; diff --git a/lib/Rect.h b/lib/Rect.h index 9aaa3578e..11213d2d0 100644 --- a/lib/Rect.h +++ b/lib/Rect.h @@ -163,7 +163,7 @@ public: DLL_LINKAGE Rect include(const Rect & other) const; template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { h & x; h & y; diff --git a/lib/ResourceSet.h b/lib/ResourceSet.h index 08c145521..4d9a0e695 100644 --- a/lib/ResourceSet.h +++ b/lib/ResourceSet.h @@ -180,7 +180,7 @@ public: // return true; // } - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & container; } diff --git a/lib/ScriptHandler.h b/lib/ScriptHandler.h index a0177fc65..a29688ada 100644 --- a/lib/ScriptHandler.h +++ b/lib/ScriptHandler.h @@ -108,7 +108,7 @@ public: void run(std::shared_ptr pool) const override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { JsonNode state; if(h.saving) diff --git a/lib/StartInfo.h b/lib/StartInfo.h index eed03eb21..550503f40 100644 --- a/lib/StartInfo.h +++ b/lib/StartInfo.h @@ -41,7 +41,7 @@ struct DLL_LINKAGE SimturnsInfo } template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { h & requiredTurns; h & optionalTurns; @@ -76,7 +76,7 @@ struct DLL_LINKAGE PlayerSettings std::set connectedPlayerIDs; //Empty - AI, or connectrd player ids bool compOnly; //true if this player is a computer only player; required for RMG template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { h & castle; h & hero; @@ -131,7 +131,7 @@ struct DLL_LINKAGE StartInfo std::string getCampaignName() const; template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { h & mode; h & difficulty; @@ -143,7 +143,7 @@ struct DLL_LINKAGE StartInfo h & fileURI; h & simturnsInfo; h & turnTimerInfo; - if(version >= 832) + if(h.version >= Handler::Version::HAS_EXTRA_OPTIONS) h & extraOptionsInfo; else extraOptionsInfo = ExtraOptionsInfo(); @@ -164,7 +164,7 @@ struct ClientPlayer int connection; std::string name; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & connection; h & name; @@ -184,7 +184,7 @@ struct DLL_LINKAGE LobbyState LobbyState() : si(new StartInfo()), hostClientId(-1), campaignMap(CampaignScenarioID::NONE), campaignBonus(-1) {} - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & si; h & mi; diff --git a/lib/TerrainHandler.h b/lib/TerrainHandler.h index 68103abd1..8b0f68fed 100644 --- a/lib/TerrainHandler.h +++ b/lib/TerrainHandler.h @@ -26,7 +26,7 @@ struct DLL_LINKAGE TerrainPaletteAnimation /// total numbers of colors to cycle int32_t length; - template void serialize(Handler& h, const int version) + template void serialize(Handler& h) { h & start; h & length; diff --git a/lib/TurnTimerInfo.h b/lib/TurnTimerInfo.h index c6eac7ba8..697c24831 100644 --- a/lib/TurnTimerInfo.h +++ b/lib/TurnTimerInfo.h @@ -34,7 +34,7 @@ struct DLL_LINKAGE TurnTimerInfo bool operator == (const TurnTimerInfo & other) const; template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { h & turnTimer; h & baseTimer; diff --git a/lib/battle/BattleAction.h b/lib/battle/BattleAction.h index 8fc5d0bfc..40253b2a5 100644 --- a/lib/battle/BattleAction.h +++ b/lib/battle/BattleAction.h @@ -55,7 +55,7 @@ public: battle::Target getTarget(const CBattleInfoCallback * cb) const; void setTarget(const battle::Target & target_); - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & side; h & stackNumber; @@ -70,7 +70,7 @@ private: int32_t unitValue; BattleHex hexValue; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & unitValue; h & hexValue; diff --git a/lib/battle/BattleHex.h b/lib/battle/BattleHex.h index 69de2b811..3b06b4828 100644 --- a/lib/battle/BattleHex.h +++ b/lib/battle/BattleHex.h @@ -105,7 +105,7 @@ struct DLL_LINKAGE BattleHex //TODO: decide if this should be changed to class f static BattleHex getClosestTile(ui8 side, BattleHex initialPos, std::set & possibilities); //TODO: vector or set? copying one to another is bad template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { h & hex; } diff --git a/lib/battle/BattleInfo.h b/lib/battle/BattleInfo.h index f22d60ab6..589e435f7 100644 --- a/lib/battle/BattleInfo.h +++ b/lib/battle/BattleInfo.h @@ -50,7 +50,7 @@ public: ui8 tacticsSide; //which side is requested to play tactics phase ui8 tacticDistance; //how many hexes we can go forward (1 = only hexes adjacent to margin line) - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & battleID; h & sides; @@ -66,10 +66,7 @@ public: h & tacticsSide; h & tacticDistance; h & static_cast(*this); - if (version > 824) - h & replayAllowed; - else - replayAllowed = false; + h & replayAllowed; } ////////////////////////////////////////////////////////////////////////// diff --git a/lib/battle/CBattleInfoCallback.h b/lib/battle/CBattleInfoCallback.h index 1ace49408..b1a16ef1f 100644 --- a/lib/battle/CBattleInfoCallback.h +++ b/lib/battle/CBattleInfoCallback.h @@ -36,7 +36,7 @@ struct DLL_LINKAGE AttackableTiles { std::set hostileCreaturePositions; std::set friendlyCreaturePositions; //for Dragon Breath - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & hostileCreaturePositions; h & friendlyCreaturePositions; diff --git a/lib/battle/CObstacleInstance.h b/lib/battle/CObstacleInstance.h index cf8bc157f..c0607b031 100644 --- a/lib/battle/CObstacleInstance.h +++ b/lib/battle/CObstacleInstance.h @@ -63,7 +63,7 @@ struct DLL_LINKAGE CObstacleInstance virtual void serializeJson(JsonSerializeFormat & handler); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & ID; h & pos; @@ -118,7 +118,7 @@ struct DLL_LINKAGE SpellCreatedObstacle : CObstacleInstance void serializeJson(JsonSerializeFormat & handler) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & turnsRemaining; diff --git a/lib/battle/SideInBattle.h b/lib/battle/SideInBattle.h index 152b79361..f1c218526 100644 --- a/lib/battle/SideInBattle.h +++ b/lib/battle/SideInBattle.h @@ -28,7 +28,7 @@ struct DLL_LINKAGE SideInBattle void init(const CGHeroInstance * Hero, const CArmedInstance * Army); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & color; h & hero; diff --git a/lib/battle/SiegeInfo.h b/lib/battle/SiegeInfo.h index 6f69d8041..6ce0b34e1 100644 --- a/lib/battle/SiegeInfo.h +++ b/lib/battle/SiegeInfo.h @@ -23,7 +23,7 @@ struct DLL_LINKAGE SiegeInfo // return EWallState decreased by value of damage points static EWallState applyDamage(EWallState state, unsigned int value); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & wallState; h & gateState; diff --git a/lib/bonuses/Bonus.h b/lib/bonuses/Bonus.h index 51f3dc1de..53693917e 100644 --- a/lib/bonuses/Bonus.h +++ b/lib/bonuses/Bonus.h @@ -86,7 +86,7 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this Bonus(BonusDuration::Type Duration, BonusType Type, BonusSource Src, si32 Val, BonusSourceID sourceID, BonusSubtypeID subtype, BonusValueType ValType); Bonus() = default; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & duration; h & type; diff --git a/lib/bonuses/BonusList.h b/lib/bonuses/BonusList.h index eef5a8777..3629cdf9c 100644 --- a/lib/bonuses/BonusList.h +++ b/lib/bonuses/BonusList.h @@ -91,7 +91,7 @@ public: void insert(TInternalContainer::iterator position, TInternalContainer::size_type n, const std::shared_ptr & x); template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { h & static_cast(bonuses); } diff --git a/lib/bonuses/CBonusSystemNode.h b/lib/bonuses/CBonusSystemNode.h index dd00b66ce..9938a1978 100644 --- a/lib/bonuses/CBonusSystemNode.h +++ b/lib/bonuses/CBonusSystemNode.h @@ -130,7 +130,7 @@ public: return PlayerColor::NEUTRAL; } - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & nodeType; h & exportedBonuses; diff --git a/lib/bonuses/Limiters.h b/lib/bonuses/Limiters.h index c314ab78f..6487f6cd9 100644 --- a/lib/bonuses/Limiters.h +++ b/lib/bonuses/Limiters.h @@ -38,7 +38,7 @@ public: virtual std::string toString() const; virtual JsonNode toJsonNode() const; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { } }; @@ -53,7 +53,7 @@ public: void add(const TLimiterPtr & limiter); JsonNode toJsonNode() const override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & limiters; @@ -104,7 +104,7 @@ public: std::string toString() const override; JsonNode toJsonNode() const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & creature; @@ -132,7 +132,7 @@ public: std::string toString() const override; JsonNode toJsonNode() const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & type; @@ -156,7 +156,7 @@ public: std::string toString() const override; JsonNode toJsonNode() const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & terrainType; @@ -175,7 +175,7 @@ public: std::string toString() const override; JsonNode toJsonNode() const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & minLevel; @@ -193,7 +193,7 @@ public: std::string toString() const override; JsonNode toJsonNode() const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & faction; @@ -210,7 +210,7 @@ public: std::string toString() const override; JsonNode toJsonNode() const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & alignment; @@ -225,7 +225,7 @@ public: EDecision limit(const BonusLimitationContext &context) const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & owner; @@ -242,7 +242,7 @@ public: RankRangeLimiter(ui8 Min, ui8 Max = 255); EDecision limit(const BonusLimitationContext &context) const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & minRank; @@ -259,7 +259,7 @@ public: EDecision limit(const BonusLimitationContext &context) const override; JsonNode toJsonNode() const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & applicableHexes; diff --git a/lib/bonuses/Propagators.h b/lib/bonuses/Propagators.h index 833e6b73d..e9affb097 100644 --- a/lib/bonuses/Propagators.h +++ b/lib/bonuses/Propagators.h @@ -23,7 +23,7 @@ public: virtual bool shouldBeAttached(CBonusSystemNode *dest); virtual CBonusSystemNode::ENodeTypes getPropagatorType() const; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) {} }; @@ -36,7 +36,7 @@ public: bool shouldBeAttached(CBonusSystemNode *dest) override; CBonusSystemNode::ENodeTypes getPropagatorType() const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & nodeType; } diff --git a/lib/bonuses/Updaters.h b/lib/bonuses/Updaters.h index 0df11382c..05219d2e8 100644 --- a/lib/bonuses/Updaters.h +++ b/lib/bonuses/Updaters.h @@ -26,7 +26,7 @@ public: virtual std::string toString() const; virtual JsonNode toJsonNode() const; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { } }; @@ -40,7 +40,7 @@ public: GrowsWithLevelUpdater() = default; GrowsWithLevelUpdater(int valPer20, int stepSize = 1); - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & valPer20; @@ -55,7 +55,7 @@ public: class DLL_LINKAGE TimesHeroLevelUpdater : public IUpdater { public: - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); } @@ -68,7 +68,7 @@ public: class DLL_LINKAGE TimesStackLevelUpdater : public IUpdater { public: - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); } @@ -87,7 +87,7 @@ public: si32 max; ArmyMovementUpdater(); ArmyMovementUpdater(int base, int divider, int multiplier, int max); - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & base; @@ -104,7 +104,7 @@ public: class DLL_LINKAGE OwnerUpdater : public IUpdater { public: - template void serialize(Handler& h, const int version) + template void serialize(Handler& h) { h & static_cast(*this); } diff --git a/lib/campaign/CampaignScenarioPrologEpilog.h b/lib/campaign/CampaignScenarioPrologEpilog.h index 64611be70..8bf9a1aa5 100644 --- a/lib/campaign/CampaignScenarioPrologEpilog.h +++ b/lib/campaign/CampaignScenarioPrologEpilog.h @@ -22,7 +22,7 @@ struct DLL_LINKAGE CampaignScenarioPrologEpilog AudioPath prologVoice; MetaString prologText; - template void serialize(Handler &h, const int formatVersion) + template void serialize(Handler &h) { h & hasPrologEpilog; h & prologVideo; diff --git a/lib/campaign/CampaignState.h b/lib/campaign/CampaignState.h index a1181a337..125f46346 100644 --- a/lib/campaign/CampaignState.h +++ b/lib/campaign/CampaignState.h @@ -40,7 +40,7 @@ class DLL_LINKAGE CampaignRegions int xpos; int ypos; - template void serialize(Handler &h, const int formatVersion) + template void serialize(Handler &h) { h & infix; h & xpos; @@ -61,7 +61,7 @@ public: ImagePath getSelectedName(CampaignScenarioID which, int color) const; ImagePath getConqueredName(CampaignScenarioID which, int color) const; - template void serialize(Handler &h, const int formatVersion) + template void serialize(Handler &h) { h & campPrefix; h & colorSuffixLength; @@ -106,7 +106,7 @@ public: const CampaignRegions & getRegions() const; TextContainerRegistrable & getTexts(); - template void serialize(Handler &h, const int formatVersion) + template void serialize(Handler &h) { h & version; h & campaignRegions; @@ -118,7 +118,7 @@ public: h & modName; h & music; h & encoding; - if (formatVersion >= 832) + if (h.version >= Handler::Version::RELEASE_143) h & textContainer; } }; @@ -134,7 +134,7 @@ struct DLL_LINKAGE CampaignBonus bool isBonusForHero() const; - template void serialize(Handler &h, const int formatVersion) + template void serialize(Handler &h) { h & type; h & info1; @@ -153,7 +153,7 @@ struct DLL_LINKAGE CampaignTravel bool spells = false; bool artifacts = false; - template void serialize(Handler &h, const int formatVersion) + template void serialize(Handler &h) { h & experience; h & primarySkills; @@ -171,7 +171,7 @@ struct DLL_LINKAGE CampaignTravel CampaignStartOptions startOptions = CampaignStartOptions::NONE; //1 - start bonus, 2 - traveling hero, 3 - hero options PlayerColor playerColor = PlayerColor::NEUTRAL; //only for startOptions == 1 - template void serialize(Handler &h, const int formatVersion) + template void serialize(Handler &h) { h & whatHeroKeeps; h & monstersKeptByHero; @@ -199,7 +199,7 @@ struct DLL_LINKAGE CampaignScenario void loadPreconditionRegions(ui32 regions); bool isNotVoid() const; - template void serialize(Handler &h, const int formatVersion) + template void serialize(Handler &h) { h & mapName; h & scenarioName; @@ -225,7 +225,7 @@ public: std::set allScenarios() const; int scenariosCount() const; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & scenarios; @@ -304,7 +304,7 @@ public: std::string campaignSet; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & scenarioHeroPool; diff --git a/lib/constants/EntityIdentifiers.h b/lib/constants/EntityIdentifiers.h index 0c1ff0128..620cce06b 100644 --- a/lib/constants/EntityIdentifiers.h +++ b/lib/constants/EntityIdentifiers.h @@ -527,7 +527,7 @@ public: } template - void serializeIdentifier(Handler &h, const MapObjectID & primaryID, const int version) + void serializeIdentifier(Handler &h, const MapObjectID & primaryID) { std::string secondaryStringID; @@ -959,7 +959,7 @@ public: using Identifier::Identifier; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { FactionID faction = getFaction(); BuildingID building = getBuilding(); diff --git a/lib/constants/IdentifierBase.h b/lib/constants/IdentifierBase.h index 62c2e671b..ba5a00c74 100644 --- a/lib/constants/IdentifierBase.h +++ b/lib/constants/IdentifierBase.h @@ -186,7 +186,7 @@ public: using Identifier::Identifier; template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { auto * finalClass = static_cast(this); std::string value; @@ -208,7 +208,7 @@ public: using IdentifierWithEnum::IdentifierWithEnum; template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { auto * finalClass = static_cast(this); std::string value; @@ -230,7 +230,7 @@ public: using Identifier::Identifier; template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { auto * finalClass = static_cast(this); h & finalClass->num; @@ -244,7 +244,7 @@ public: using IdentifierWithEnum::IdentifierWithEnum; template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { auto * finalClass = static_cast(this); h & finalClass->num; diff --git a/lib/constants/VariantIdentifier.h b/lib/constants/VariantIdentifier.h index 175411f67..a49be1cde 100644 --- a/lib/constants/VariantIdentifier.h +++ b/lib/constants/VariantIdentifier.h @@ -59,7 +59,7 @@ public: return IdentifierType(); } - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & value; } diff --git a/lib/filesystem/ResourcePath.h b/lib/filesystem/ResourcePath.h index 2a4086141..250e76bfc 100644 --- a/lib/filesystem/ResourcePath.h +++ b/lib/filesystem/ResourcePath.h @@ -102,7 +102,7 @@ public: void serializeJson(JsonSerializeFormat & handler); - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & type; h & name; diff --git a/lib/gameState/CGameState.h b/lib/gameState/CGameState.h index b1f4eb74e..705c919ac 100644 --- a/lib/gameState/CGameState.h +++ b/lib/gameState/CGameState.h @@ -59,7 +59,7 @@ struct DLL_LINKAGE RumorState RumorState(){type = TYPE_NONE;}; bool update(int id, int extra); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & type; h & last; @@ -174,7 +174,7 @@ public: /// Any server-side code outside of GH must use CRandomGenerator::getDefault CRandomGenerator & getRandomGenerator(); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & scenarioOps; h & initialOpts; diff --git a/lib/gameState/CGameStateCampaign.h b/lib/gameState/CGameStateCampaign.h index 376ec0ca3..e9c4610bb 100644 --- a/lib/gameState/CGameStateCampaign.h +++ b/lib/gameState/CGameStateCampaign.h @@ -58,7 +58,7 @@ public: bool playerHasStartingHero(PlayerColor player) const; std::unique_ptr getCurrentMap() const; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & gameState; } diff --git a/lib/gameState/EVictoryLossCheckResult.h b/lib/gameState/EVictoryLossCheckResult.h index 1091b4a3a..c6f056222 100644 --- a/lib/gameState/EVictoryLossCheckResult.h +++ b/lib/gameState/EVictoryLossCheckResult.h @@ -58,7 +58,7 @@ public: MetaString messageToSelf; MetaString messageToOthers; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & intValue; h & messageToSelf; diff --git a/lib/gameState/QuestInfo.h b/lib/gameState/QuestInfo.h index b89e467da..37e35de23 100644 --- a/lib/gameState/QuestInfo.h +++ b/lib/gameState/QuestInfo.h @@ -44,7 +44,7 @@ struct DLL_LINKAGE QuestInfo //universal interface for human and AI return (quest == qi.quest && obj == qi.obj); } - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & quest; h & obj; diff --git a/lib/gameState/SThievesGuildInfo.h b/lib/gameState/SThievesGuildInfo.h index 45ed3bdef..6e4c06aeb 100644 --- a/lib/gameState/SThievesGuildInfo.h +++ b/lib/gameState/SThievesGuildInfo.h @@ -25,7 +25,7 @@ struct DLL_LINKAGE SThievesGuildInfo std::map personality; // color to personality // ai tactic std::map bestCreature; // color to ID // id or -1 if not known -// template void serialize(Handler &h, const int version) +// template void serialize(Handler &h) // { // h & playerColors; // h & numOfTowns; diff --git a/lib/gameState/TavernHeroesPool.h b/lib/gameState/TavernHeroesPool.h index 4e109f8c0..ceab10c15 100644 --- a/lib/gameState/TavernHeroesPool.h +++ b/lib/gameState/TavernHeroesPool.h @@ -30,7 +30,7 @@ class DLL_LINKAGE TavernHeroesPool TavernSlotRole role; PlayerColor player; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & hero; h & slot; @@ -76,7 +76,7 @@ public: /// Makes hero available in tavern of specified player void setHeroForPlayer(PlayerColor player, TavernHeroSlot slot, HeroTypeID hero, CSimpleArmy & army, TavernSlotRole role, bool replenishPoints); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & heroesPool; h & perPlayerAvailability; diff --git a/lib/int3.h b/lib/int3.h index 6b065c077..8f01fec33 100644 --- a/lib/int3.h +++ b/lib/int3.h @@ -170,7 +170,7 @@ public: } template - void serialize(Handler &h, const int version) + void serialize(Handler &h) { h & x; h & y; diff --git a/lib/mapObjectConstructors/CBankInstanceConstructor.h b/lib/mapObjectConstructors/CBankInstanceConstructor.h index a0b73ba77..2bf2251ed 100644 --- a/lib/mapObjectConstructors/CBankInstanceConstructor.h +++ b/lib/mapObjectConstructors/CBankInstanceConstructor.h @@ -27,7 +27,7 @@ struct BankConfig std::vector artifacts; //artifacts given in case of victory std::vector spells; // granted spell(s), for Pyramid - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & chance; h & guards; diff --git a/lib/mapObjects/CArmedInstance.h b/lib/mapObjects/CArmedInstance.h index 0e0560816..8c50cba16 100644 --- a/lib/mapObjects/CArmedInstance.h +++ b/lib/mapObjects/CArmedInstance.h @@ -52,7 +52,7 @@ public: void serializeJsonOptions(JsonSerializeFormat & handler) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & static_cast(*this); diff --git a/lib/mapObjects/CBank.h b/lib/mapObjects/CBank.h index 1ac22869f..9377e83ed 100644 --- a/lib/mapObjects/CBank.h +++ b/lib/mapObjects/CBank.h @@ -43,7 +43,7 @@ public: std::vector getPopupComponents(PlayerColor player) const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & daycounter; diff --git a/lib/mapObjects/CGCreature.h b/lib/mapObjects/CGCreature.h index 7d293686b..d81e1bd8b 100644 --- a/lib/mapObjects/CGCreature.h +++ b/lib/mapObjects/CGCreature.h @@ -56,7 +56,7 @@ public: bool containsUpgradedStack() const; int getNumberOfStacks(const CGHeroInstance *hero) const; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & identifier; diff --git a/lib/mapObjects/CGDwelling.h b/lib/mapObjects/CGDwelling.h index 5f0b6388f..08d592227 100644 --- a/lib/mapObjects/CGDwelling.h +++ b/lib/mapObjects/CGDwelling.h @@ -61,7 +61,7 @@ private: void heroAcceptsCreatures(const CGHeroInstance *h) const; public: - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & creatures; diff --git a/lib/mapObjects/CGHeroInstance.h b/lib/mapObjects/CGHeroInstance.h index 1b938057a..c5352a73c 100644 --- a/lib/mapObjects/CGHeroInstance.h +++ b/lib/mapObjects/CGHeroInstance.h @@ -36,7 +36,7 @@ public: /// if this is placeholder by type, then hero type of desired hero std::optional heroType; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & powerRank; @@ -103,7 +103,7 @@ public: bool patrolling; int3 initialPos; ui32 patrolRadius; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & patrolling; h & initialPos; @@ -121,7 +121,7 @@ public: void resetMagicSchoolCounter(); void resetWisdomCounter(); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & magicSchoolCounter; h & wisdomCounter; @@ -321,7 +321,7 @@ public: void serializeJsonDefinition(JsonSerializeFormat & handler); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & static_cast(*this); diff --git a/lib/mapObjects/CGMarket.h b/lib/mapObjects/CGMarket.h index a316956d0..eb41e487e 100644 --- a/lib/mapObjects/CGMarket.h +++ b/lib/mapObjects/CGMarket.h @@ -36,7 +36,7 @@ public: int availableUnits(EMarketMode mode, int marketItemSerial) const override; //-1 if unlimited std::vector availableItemsIds(EMarketMode mode) const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & marketModes; @@ -56,7 +56,7 @@ public: void newTurn(CRandomGenerator & rand) const override; //reset artifacts for black market every month std::vector availableItemsIds(EMarketMode mode) const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & artifacts; @@ -73,7 +73,7 @@ public: std::vector availableItemsIds(EMarketMode mode) const override; void onHeroVisit(const CGHeroInstance * h) const override; //open window - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & skills; diff --git a/lib/mapObjects/CGObjectInstance.h b/lib/mapObjects/CGObjectInstance.h index 33ec31e98..b1e4f144e 100644 --- a/lib/mapObjects/CGObjectInstance.h +++ b/lib/mapObjects/CGObjectInstance.h @@ -137,14 +137,14 @@ public: virtual void afterRemoveFromMap(CMap * map); ///Entry point of binary (de-)serialization - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & instanceName; h & typeName; h & subTypeName; h & pos; h & ID; - subID.serializeIdentifier(h, ID, version); + subID.serializeIdentifier(h, ID); h & id; h & tempOwner; h & blockVisit; diff --git a/lib/mapObjects/CGPandoraBox.h b/lib/mapObjects/CGPandoraBox.h index 77cdf35bc..f739f1fb9 100644 --- a/lib/mapObjects/CGPandoraBox.h +++ b/lib/mapObjects/CGPandoraBox.h @@ -28,7 +28,7 @@ public: void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & message; @@ -50,7 +50,7 @@ public: bool computerActivate = false; //true if computer player can activate this event bool humanActivate = false; //true if human player can activate this event - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & removeAfterVisit; diff --git a/lib/mapObjects/CGTownBuilding.h b/lib/mapObjects/CGTownBuilding.h index d31b07622..9b620a6ac 100644 --- a/lib/mapObjects/CGTownBuilding.h +++ b/lib/mapObjects/CGTownBuilding.h @@ -54,7 +54,7 @@ public: int3 visitablePos() const override; int3 getPosition() const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & bID; h & indexOnTV; @@ -79,7 +79,7 @@ public: COPWBonus(const BuildingID & index, BuildingSubID::EBuildingSubID subId, CGTownInstance * TOWN); COPWBonus(IGameCallback *cb); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & visitors; @@ -98,7 +98,7 @@ public: CTownBonus(const BuildingID & index, BuildingSubID::EBuildingSubID subId, CGTownInstance * TOWN); CTownBonus(IGameCallback *cb); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & visitors; @@ -136,7 +136,7 @@ public: CTownRewardableBuilding(const BuildingID & index, BuildingSubID::EBuildingSubID subId, CGTownInstance * town, CRandomGenerator & rand); CTownRewardableBuilding(IGameCallback *cb); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & static_cast(*this); diff --git a/lib/mapObjects/CGTownInstance.h b/lib/mapObjects/CGTownInstance.h index d29edeac5..f8fd3f8e3 100644 --- a/lib/mapObjects/CGTownInstance.h +++ b/lib/mapObjects/CGTownInstance.h @@ -67,7 +67,7 @@ public: std::pair bonusValue;//var to store town bonuses (rampart = resources from mystic pond); ////////////////////////////////////////////////////////////////////////// - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & nameTextId; diff --git a/lib/mapObjects/CQuest.h b/lib/mapObjects/CQuest.h index eda83e454..d19694fca 100644 --- a/lib/mapObjects/CQuest.h +++ b/lib/mapObjects/CQuest.h @@ -69,7 +69,7 @@ public: return (quest.qid == qid); } - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & qid; h & isCompleted; @@ -106,7 +106,7 @@ public: virtual void getVisitText (MetaString &text, std::vector &components, bool FirstVisit, const CGHeroInstance * h = nullptr) const = 0; virtual bool checkQuest (const CGHeroInstance * h) const; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & quest; } @@ -142,7 +142,7 @@ public: void afterAddToMap(CMap * map) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & static_cast(*this); @@ -164,7 +164,7 @@ public: void onHeroVisit(const CGHeroInstance * h) const override; bool passableFor(PlayerColor color) const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); } @@ -182,7 +182,7 @@ public: std::string getObjectName() const override; //depending on color std::string getHoverText(PlayerColor player) const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); } @@ -196,7 +196,7 @@ public: bool wasVisited (PlayerColor player) const override; void onHeroVisit(const CGHeroInstance * h) const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); } @@ -217,7 +217,7 @@ public: void afterAddToMap(CMap * map) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & static_cast(*this); @@ -233,7 +233,7 @@ public: bool passableFor(PlayerColor color) const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); //need to serialize or object will be empty } diff --git a/lib/mapObjects/CRewardableObject.h b/lib/mapObjects/CRewardableObject.h index bdcff998c..47b8bfa65 100644 --- a/lib/mapObjects/CRewardableObject.h +++ b/lib/mapObjects/CRewardableObject.h @@ -78,7 +78,7 @@ public: std::vector getPopupComponents(PlayerColor player) const override; std::vector getPopupComponents(const CGHeroInstance * hero) const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & static_cast(*this); diff --git a/lib/mapObjects/IObjectInterface.h b/lib/mapObjects/IObjectInterface.h index baebb223e..8c5b94b8b 100644 --- a/lib/mapObjects/IObjectInterface.h +++ b/lib/mapObjects/IObjectInterface.h @@ -67,7 +67,7 @@ public: static void preInit(); //called before objs receive their initObj static void postInit();//called after objs receive their initObj - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { logGlobal->error("IObjectInterface serialized, unexpected, should not happen!"); } diff --git a/lib/mapObjects/MiscObjects.h b/lib/mapObjects/MiscObjects.h index 1a319a704..b75a31be7 100644 --- a/lib/mapObjects/MiscObjects.h +++ b/lib/mapObjects/MiscObjects.h @@ -33,7 +33,7 @@ public: bool wasVisited(const TeamID & team) const; void setPropertyDer(ObjProperty what, ObjPropertyID identifier) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & players; @@ -50,7 +50,7 @@ public: void onHeroVisit(const CGHeroInstance * h) const override; void initObj(CRandomGenerator & rand) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & message; @@ -71,7 +71,7 @@ public: void onHeroVisit(const CGHeroInstance * h) const override; void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & removableUnits; @@ -107,7 +107,7 @@ public: ArtifactID getArtifact() const; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & message; @@ -137,7 +137,7 @@ public: void collectRes(const PlayerColor & player) const; GameResID resourceID() const; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & amount; @@ -172,7 +172,7 @@ private: std::string getHoverText(PlayerColor player) const override; public: - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & producedResource; @@ -193,7 +193,7 @@ struct DLL_LINKAGE TeleportChannel std::vector exits; EPassability passability = EPassability::UNKNOWN; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & entrances; h & exits; @@ -232,7 +232,7 @@ public: static std::vector getPassableExits(CGameState * gs, const CGHeroInstance * h, std::vector exits); static bool isExitPassable(CGameState * gs, const CGHeroInstance * h, const CGObjectInstance * obj); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & type; h & channel; @@ -252,7 +252,7 @@ protected: public: using CGTeleport::CGTeleport; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); } @@ -268,7 +268,7 @@ public: static void postInit(IGameCallback * cb); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); } @@ -283,7 +283,7 @@ class DLL_LINKAGE CGWhirlpool : public CGMonolith public: using CGMonolith::CGMonolith; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); } @@ -298,7 +298,7 @@ public: std::string getHoverText(const CGHeroInstance * hero) const override; void initObj(CRandomGenerator & rand) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); } @@ -323,7 +323,7 @@ public: CGBoat(IGameCallback * cb); bool isCoastVisitable() const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & static_cast(*this); @@ -353,7 +353,7 @@ protected: public: using CGObjectInstance::CGObjectInstance; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & createdBoat; @@ -371,7 +371,7 @@ public: void initObj(CRandomGenerator & rand) override; void onHeroVisit(const CGHeroInstance * h) const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); } @@ -393,7 +393,7 @@ public: void initObj(CRandomGenerator & rand) override; std::string getHoverText(PlayerColor player) const override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); } @@ -409,7 +409,7 @@ public: void onHeroVisit(const CGHeroInstance * h) const override; void initObj(CRandomGenerator & rand) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); } @@ -443,7 +443,7 @@ protected: public: using CGObjectInstance::CGObjectInstance; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & static_cast(*this); h & upgradeCostPercentage; diff --git a/lib/mapObjects/ObjectTemplate.h b/lib/mapObjects/ObjectTemplate.h index 258e9aea0..0ceb409a2 100644 --- a/lib/mapObjects/ObjectTemplate.h +++ b/lib/mapObjects/ObjectTemplate.h @@ -156,7 +156,7 @@ private: void calculateTopVisibleOffset(); public: - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & usedTiles; h & allowedTerrains; @@ -164,7 +164,7 @@ public: h & animationFile; h & stringID; h & id; - subid.serializeIdentifier(h, id, version); + subid.serializeIdentifier(h, id); h & printPriority; h & visitDir; h & editorAnimationFile; diff --git a/lib/mapping/CMap.h b/lib/mapping/CMap.h index ca879f037..4dc4b7259 100644 --- a/lib/mapping/CMap.h +++ b/lib/mapping/CMap.h @@ -44,7 +44,7 @@ struct DLL_LINKAGE Rumor ~Rumor() = default; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & name; h & text; @@ -64,7 +64,7 @@ struct DLL_LINKAGE DisposedHero std::set players; /// Who can hire this hero (bitfield). template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & heroId; h & portrait; @@ -173,7 +173,7 @@ private: public: template - void serialize(Handler &h, const int formatVersion) + void serialize(Handler &h) { h & static_cast(*this); h & triggeredEvents; //from CMapHeader diff --git a/lib/mapping/CMapDefines.h b/lib/mapping/CMapDefines.h index 85a2da1a1..27ad56a32 100644 --- a/lib/mapping/CMapDefines.h +++ b/lib/mapping/CMapDefines.h @@ -43,7 +43,7 @@ public: ui32 nextOccurence; /// specifies after how many days the event will occur the next time; 0 if event occurs only one time template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & name; h & message; @@ -68,7 +68,7 @@ public: std::vector creatures; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & static_cast(*this); h & buildings; @@ -112,7 +112,7 @@ struct DLL_LINKAGE TerrainTile std::vector blockingObjects; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & terType; h & terView; diff --git a/lib/mapping/CMapHeader.h b/lib/mapping/CMapHeader.h index 324b7aa48..c343fcab7 100644 --- a/lib/mapping/CMapHeader.h +++ b/lib/mapping/CMapHeader.h @@ -32,7 +32,7 @@ struct DLL_LINKAGE SHeroName std::string heroName; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & heroId; h & heroName; @@ -76,7 +76,7 @@ struct DLL_LINKAGE PlayerInfo TeamID team; /// The default value NO_TEAM template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & hasRandomHero; h & mainCustomHeroId; @@ -128,7 +128,7 @@ struct DLL_LINKAGE EventCondition EWinLoseType condition; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & objectID; h & value; @@ -156,7 +156,7 @@ struct DLL_LINKAGE EventEffect MetaString toOtherMessage; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & type; h & toOtherMessage; @@ -181,7 +181,7 @@ struct DLL_LINKAGE TriggeredEvent EventEffect effect; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & identifier; h & trigger; @@ -245,7 +245,7 @@ public: void registerMapStrings(); template - void serialize(Handler & h, const int Version) + void serialize(Handler & h) { h & texts; h & version; diff --git a/lib/mapping/CMapInfo.cpp b/lib/mapping/CMapInfo.cpp index 39a0ee831..459cc4120 100644 --- a/lib/mapping/CMapInfo.cpp +++ b/lib/mapping/CMapInfo.cpp @@ -55,7 +55,7 @@ void CMapInfo::mapInit(const std::string & fname) void CMapInfo::saveInit(const ResourcePath & file) { - CLoadFile lf(*CResourceHandler::get()->getResourceName(file), MINIMAL_SERIALIZATION_VERSION); + CLoadFile lf(*CResourceHandler::get()->getResourceName(file), ESerializationVersion::MINIMAL); lf.checkMagicBytes(SAVEGAME_MAGIC); mapHeader = std::make_unique(); diff --git a/lib/mapping/CMapInfo.h b/lib/mapping/CMapInfo.h index b086a38af..40e05baee 100644 --- a/lib/mapping/CMapInfo.h +++ b/lib/mapping/CMapInfo.h @@ -58,7 +58,7 @@ public: int getMapSizeFormatIconId() const; std::string getMapSizeName() const; - template void serialize(Handler &h, const int Version) + template void serialize(Handler &h) { h & mapHeader; h & campaign; diff --git a/lib/modding/ActiveModsInSaveList.h b/lib/modding/ActiveModsInSaveList.h index 846b51af7..9798b1ac8 100644 --- a/lib/modding/ActiveModsInSaveList.h +++ b/lib/modding/ActiveModsInSaveList.h @@ -22,7 +22,7 @@ class ActiveModsInSaveList /// Checks whether provided mod list is compatible with current VLC and throws on failure void verifyActiveMods(const std::vector> & modList); public: - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { if(h.saving) { diff --git a/lib/modding/CModVersion.h b/lib/modding/CModVersion.h index 40197d340..2bee49153 100644 --- a/lib/modding/CModVersion.h +++ b/lib/modding/CModVersion.h @@ -38,7 +38,7 @@ struct DLL_LINKAGE CModVersion bool compatible(const CModVersion & other, bool checkMinor = false, bool checkPatch = false) const; bool isNull() const; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & major; h & minor; diff --git a/lib/modding/ModVerificationInfo.h b/lib/modding/ModVerificationInfo.h index e6652e40d..3737b0e97 100644 --- a/lib/modding/ModVerificationInfo.h +++ b/lib/modding/ModVerificationInfo.h @@ -31,7 +31,7 @@ struct ModVerificationInfo bool impactsGameplay = true; template - void serialize(Handler & h, const int v) + void serialize(Handler & h) { h & name; h & version; diff --git a/lib/networkPacks/ArtifactLocation.h b/lib/networkPacks/ArtifactLocation.h index d3acb2cdd..42739083f 100644 --- a/lib/networkPacks/ArtifactLocation.h +++ b/lib/networkPacks/ArtifactLocation.h @@ -38,7 +38,7 @@ struct ArtifactLocation { } - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & artHolder; h & slot; diff --git a/lib/networkPacks/BattleChanges.h b/lib/networkPacks/BattleChanges.h index 510505e23..92dca1d47 100644 --- a/lib/networkPacks/BattleChanges.h +++ b/lib/networkPacks/BattleChanges.h @@ -47,7 +47,7 @@ public: { } - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & id; h & healthDelta; @@ -69,7 +69,7 @@ public: { } - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & id; h & data; diff --git a/lib/networkPacks/Component.h b/lib/networkPacks/Component.h index 43ec61277..91170f10c 100644 --- a/lib/networkPacks/Component.h +++ b/lib/networkPacks/Component.h @@ -43,7 +43,7 @@ struct Component ComponentSubType subType; std::optional value; // + give; - take - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & type; h & subType; diff --git a/lib/networkPacks/EntityChanges.h b/lib/networkPacks/EntityChanges.h index 296148297..7d5aacf87 100644 --- a/lib/networkPacks/EntityChanges.h +++ b/lib/networkPacks/EntityChanges.h @@ -21,7 +21,7 @@ public: Metatype metatype = Metatype::UNKNOWN; int32_t entityIndex = 0; JsonNode data; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & metatype; h & entityIndex; diff --git a/lib/networkPacks/NetPacksBase.h b/lib/networkPacks/NetPacksBase.h index b77e92e94..9d765b0ff 100644 --- a/lib/networkPacks/NetPacksBase.h +++ b/lib/networkPacks/NetPacksBase.h @@ -27,7 +27,7 @@ struct DLL_LINKAGE CPack CPack() = default; virtual ~CPack() = default; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { logNetwork->error("CPack serialized... this should not happen!"); assert(false && "CPack serialized"); @@ -66,7 +66,7 @@ struct DLL_LINKAGE CPackForServer : public CPack mutable PlayerColor player = PlayerColor::NEUTRAL; mutable si32 requestID; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & player; h & requestID; diff --git a/lib/networkPacks/PacksForClient.h b/lib/networkPacks/PacksForClient.h index 971711a67..85e07e1bd 100644 --- a/lib/networkPacks/PacksForClient.h +++ b/lib/networkPacks/PacksForClient.h @@ -62,7 +62,7 @@ struct DLL_LINKAGE PackageApplied : public CPackForClient ui32 requestID = 0; //an ID given by client to the request that was applied PlayerColor player; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & result; h & packType; @@ -83,7 +83,7 @@ struct DLL_LINKAGE SystemMessage : public CPackForClient std::string text; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & text; } @@ -100,7 +100,7 @@ struct DLL_LINKAGE PlayerBlocked : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & reason; h & startOrEnd; @@ -118,7 +118,7 @@ struct DLL_LINKAGE PlayerCheated : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & player; h & losingCheatCode; @@ -133,7 +133,7 @@ struct DLL_LINKAGE TurnTimeUpdate : public CPackForClient PlayerColor player; TurnTimerInfo turnTimer; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & player; h & turnTimer; @@ -148,7 +148,7 @@ struct DLL_LINKAGE PlayerStartsTurn : public Query void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & queryID; h & player; @@ -164,7 +164,7 @@ struct DLL_LINKAGE DaysWithoutTown : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & player; h & daysWithoutCastle; @@ -179,7 +179,7 @@ struct DLL_LINKAGE EntitiesChanged : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & changes; } @@ -195,7 +195,7 @@ struct DLL_LINKAGE SetResources : public CPackForClient PlayerColor player; ResourceSet res; //res[resid] => res amount - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & abs; h & player; @@ -214,7 +214,7 @@ struct DLL_LINKAGE SetPrimSkill : public CPackForClient PrimarySkill which = PrimarySkill::ATTACK; si64 val = 0; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & abs; h & id; @@ -234,7 +234,7 @@ struct DLL_LINKAGE SetSecSkill : public CPackForClient SecondarySkill which; ui16 val = 0; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & abs; h & id; @@ -258,7 +258,7 @@ struct DLL_LINKAGE HeroVisitCastle : public CPackForClient return flags & 1; } - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & flags; h & tid; @@ -276,7 +276,7 @@ struct DLL_LINKAGE ChangeSpells : public CPackForClient ObjectInstanceID hid; std::set spells; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & learn; h & hid; @@ -294,7 +294,7 @@ struct DLL_LINKAGE SetMana : public CPackForClient si32 val = 0; bool absolute = true; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & val; h & hid; @@ -312,7 +312,7 @@ struct DLL_LINKAGE SetMovePoints : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & val; h & hid; @@ -331,7 +331,7 @@ struct DLL_LINKAGE FoWChange : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & tiles; h & player; @@ -357,7 +357,7 @@ struct DLL_LINKAGE SetAvailableHero : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & slotID; h & roleID; @@ -386,7 +386,7 @@ struct DLL_LINKAGE GiveBonus : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & bonus; h & id; @@ -409,7 +409,7 @@ struct DLL_LINKAGE ChangeObjPos : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & objid; h & nPos; @@ -425,7 +425,7 @@ struct DLL_LINKAGE PlayerEndsTurn : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & player; } @@ -440,7 +440,7 @@ struct DLL_LINKAGE PlayerEndsGame : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & player; h & victoryLossCheckResult; @@ -456,7 +456,7 @@ struct DLL_LINKAGE PlayerReinitInterface : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & players; h & playerConnectionId; @@ -484,7 +484,7 @@ struct DLL_LINKAGE RemoveBonus : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & source; h & id; @@ -508,7 +508,7 @@ struct DLL_LINKAGE SetCommanderProperty : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & heroid; h & which; @@ -527,7 +527,7 @@ struct DLL_LINKAGE AddQuest : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & player; h & quest; @@ -541,7 +541,7 @@ struct DLL_LINKAGE UpdateArtHandlerLists : public CPackForClient void applyGs(CGameState * gs) const; void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & allocatedArtifacts; } @@ -554,7 +554,7 @@ struct DLL_LINKAGE UpdateMapEvents : public CPackForClient void applyGs(CGameState * gs) const; void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & events; } @@ -568,7 +568,7 @@ struct DLL_LINKAGE UpdateCastleEvents : public CPackForClient void applyGs(CGameState * gs) const; void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & town; h & events; @@ -583,7 +583,7 @@ struct DLL_LINKAGE ChangeFormation : public CPackForClient void applyGs(CGameState * gs) const; void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & hid; h & formation; @@ -608,7 +608,7 @@ struct DLL_LINKAGE RemoveObject : public CPackForClient /// Player that initiated this action, if any PlayerColor initiator; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & objectID; h & initiator; @@ -644,7 +644,7 @@ struct DLL_LINKAGE TryMoveHero : public CPackForClient return result != SUCCESS && result != EMBARK && result != DISEMBARK && result != TELEPORTATION; } - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & id; h & result; @@ -666,7 +666,7 @@ struct DLL_LINKAGE NewStructures : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & tid; h & bid; @@ -684,7 +684,7 @@ struct DLL_LINKAGE RazeStructures : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & tid; h & bid; @@ -701,7 +701,7 @@ struct DLL_LINKAGE SetAvailableCreatures : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & tid; h & creatures; @@ -718,7 +718,7 @@ struct DLL_LINKAGE SetHeroesInTown : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & tid; h & visiting; @@ -738,7 +738,7 @@ struct DLL_LINKAGE HeroRecruited : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & hid; h & tid; @@ -758,7 +758,7 @@ struct DLL_LINKAGE GiveHero : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & id; h & boatId; @@ -774,7 +774,7 @@ struct DLL_LINKAGE OpenWindow : public Query void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & queryID; h & window; @@ -800,10 +800,10 @@ struct DLL_LINKAGE NewObject : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & ID; - subID.serializeIdentifier(h, ID, version); + subID.serializeIdentifier(h, ID); h & targetPos; h & initiator; } @@ -819,7 +819,7 @@ struct DLL_LINKAGE SetAvailableArtifacts : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & id; h & arts; @@ -841,7 +841,7 @@ struct DLL_LINKAGE ChangeStackCount : CGarrisonOperationPack void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & army; h & slot; @@ -860,7 +860,7 @@ struct DLL_LINKAGE SetStackType : CGarrisonOperationPack void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & army; h & slot; @@ -876,7 +876,7 @@ struct DLL_LINKAGE EraseStack : CGarrisonOperationPack void applyGs(CGameState * gs); void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & army; h & slot; @@ -893,7 +893,7 @@ struct DLL_LINKAGE SwapStacks : CGarrisonOperationPack void applyGs(CGameState * gs); void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & srcArmy; h & dstArmy; @@ -912,7 +912,7 @@ struct DLL_LINKAGE InsertNewStack : CGarrisonOperationPack void applyGs(CGameState * gs); void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & army; h & slot; @@ -934,7 +934,7 @@ struct DLL_LINKAGE RebalanceStacks : CGarrisonOperationPack void applyGs(CGameState * gs); void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & srcArmy; h & dstArmy; @@ -952,7 +952,7 @@ struct DLL_LINKAGE BulkRebalanceStacks : CGarrisonOperationPack void visitTyped(ICPackVisitor & visitor) override; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & moves; } @@ -967,7 +967,7 @@ struct DLL_LINKAGE BulkSmartRebalanceStacks : CGarrisonOperationPack void visitTyped(ICPackVisitor & visitor) override; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & moves; h & changes; @@ -993,7 +993,7 @@ struct DLL_LINKAGE PutArtifact : CArtifactOperationPack void applyGs(CGameState * gs); void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & al; h & askAssemble; @@ -1008,7 +1008,7 @@ struct DLL_LINKAGE NewArtifact : public CArtifactOperationPack void applyGs(CGameState * gs); void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & art; } @@ -1021,7 +1021,7 @@ struct DLL_LINKAGE EraseArtifact : CArtifactOperationPack void applyGs(CGameState * gs); void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & al; } @@ -1041,7 +1041,7 @@ struct DLL_LINKAGE MoveArtifact : CArtifactOperationPack void applyGs(CGameState * gs); void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & src; h & dst; @@ -1062,7 +1062,7 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack , dstPos(dstPos) { } - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & srcPos; h & dstPos; @@ -1102,7 +1102,7 @@ struct DLL_LINKAGE BulkMoveArtifacts : CArtifactOperationPack void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & artsPack0; h & artsPack1; @@ -1124,7 +1124,7 @@ struct DLL_LINKAGE AssembledArtifact : CArtifactOperationPack void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & al; h & builtArt; @@ -1139,7 +1139,7 @@ struct DLL_LINKAGE DisassembledArtifact : CArtifactOperationPack void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & al; } @@ -1157,7 +1157,7 @@ struct DLL_LINKAGE HeroVisit : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & player; h & heroId; @@ -1179,7 +1179,7 @@ struct DLL_LINKAGE NewTurn : public CPackForClient ObjectInstanceID id; //id is a general serial id ui32 move; ui32 mana; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & id; h & move; @@ -1197,7 +1197,7 @@ struct DLL_LINKAGE NewTurn : public CPackForClient NewTurn() = default; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & heroes; h & cres; @@ -1218,7 +1218,7 @@ struct DLL_LINKAGE InfoWindow : public CPackForClient //103 - displays simple i void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & type; h & text; @@ -1241,7 +1241,7 @@ struct DLL_LINKAGE SetObjectProperty : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & id; h & what; @@ -1276,7 +1276,7 @@ struct DLL_LINKAGE ChangeObjectVisitors : public CPackForClient { } - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & object; h & hero; @@ -1296,7 +1296,7 @@ struct DLL_LINKAGE HeroLevelUp : public Query void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & queryID; h & player; @@ -1317,7 +1317,7 @@ struct DLL_LINKAGE CommanderLevelUp : public Query void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & queryID; h & player; @@ -1356,7 +1356,7 @@ struct DLL_LINKAGE BlockingDialog : public Query void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & queryID; h & text; @@ -1375,7 +1375,7 @@ struct DLL_LINKAGE GarrisonDialog : public Query void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & queryID; h & objid; @@ -1393,7 +1393,7 @@ struct DLL_LINKAGE ExchangeDialog : public Query void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & queryID; h & player; @@ -1418,7 +1418,7 @@ struct DLL_LINKAGE TeleportDialog : public Query void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & queryID; h & hero; @@ -1438,7 +1438,7 @@ struct DLL_LINKAGE MapObjectSelectDialog : public Query void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & queryID; h & player; @@ -1453,7 +1453,7 @@ struct DLL_LINKAGE AdvmapSpellCast : public CPackForClient { ObjectInstanceID casterID; SpellID spellID; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & casterID; h & spellID; @@ -1470,7 +1470,7 @@ struct DLL_LINKAGE ShowWorldViewEx : public CPackForClient std::vector objectPositions; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & player; h & showTerrain; @@ -1494,7 +1494,7 @@ struct DLL_LINKAGE PlayerMessageClient : public CPackForClient PlayerColor player; std::string text; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & player; h & text; @@ -1509,7 +1509,7 @@ struct DLL_LINKAGE CenterView : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & pos; h & player; diff --git a/lib/networkPacks/PacksForClientBattle.h b/lib/networkPacks/PacksForClientBattle.h index 7578abcdc..239a248da 100644 --- a/lib/networkPacks/PacksForClientBattle.h +++ b/lib/networkPacks/PacksForClientBattle.h @@ -32,7 +32,7 @@ struct DLL_LINKAGE BattleStart : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & info; @@ -48,7 +48,7 @@ struct DLL_LINKAGE BattleNextRound : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; assert(battleID != BattleID::NONE); @@ -65,7 +65,7 @@ struct DLL_LINKAGE BattleSetActiveStack : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & stack; @@ -80,7 +80,7 @@ struct DLL_LINKAGE BattleCancelled: public CPackForClient BattleID battleID = BattleID::NONE; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; assert(battleID != BattleID::NONE); @@ -100,7 +100,7 @@ struct DLL_LINKAGE BattleResultAccepted : public CPackForClient CArmedInstance * army; TExpType exp; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & hero; h & army; @@ -112,7 +112,7 @@ struct DLL_LINKAGE BattleResultAccepted : public CPackForClient std::array heroResult; ui8 winnerSide; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & heroResult; @@ -134,7 +134,7 @@ struct DLL_LINKAGE BattleResult : public Query void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & queryID; @@ -158,7 +158,7 @@ struct DLL_LINKAGE BattleLogMessage : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & lines; @@ -179,7 +179,7 @@ struct DLL_LINKAGE BattleStackMoved : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & stack; @@ -200,7 +200,7 @@ struct DLL_LINKAGE BattleUnitsChanged : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & changedStacks; @@ -248,7 +248,7 @@ struct BattleStackAttacked return flags & FIRE_SHIELD; } - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & stackAttacked; @@ -315,7 +315,7 @@ struct DLL_LINKAGE BattleAttack : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & bsa; @@ -343,7 +343,7 @@ struct DLL_LINKAGE StartAction : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & ba; @@ -357,7 +357,7 @@ struct DLL_LINKAGE EndAction : public CPackForClient BattleID battleID = BattleID::NONE; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; } @@ -381,7 +381,7 @@ struct DLL_LINKAGE BattleSpellCast : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & side; @@ -408,7 +408,7 @@ struct DLL_LINKAGE StacksInjured : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & stacks; @@ -422,7 +422,7 @@ struct DLL_LINKAGE BattleResultsApplied : public CPackForClient PlayerColor player1, player2; void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & player1; @@ -441,7 +441,7 @@ struct DLL_LINKAGE BattleObstaclesChanged : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & changes; @@ -457,7 +457,7 @@ struct DLL_LINKAGE CatapultAttack : public CPackForClient EWallPart attackedPart; ui8 damageDealt; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & destinationTile; h & attackedPart; @@ -477,7 +477,7 @@ struct DLL_LINKAGE CatapultAttack : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & attackedParts; @@ -498,7 +498,7 @@ struct DLL_LINKAGE BattleSetStackProperty : public CPackForClient int val = 0; int absolute = 0; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & stackID; @@ -523,7 +523,7 @@ struct DLL_LINKAGE BattleTriggerEffect : public CPackForClient int val = 0; int additionalInfo = 0; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & stackID; @@ -543,7 +543,7 @@ struct DLL_LINKAGE BattleUpdateGateState : public CPackForClient BattleID battleID = BattleID::NONE; EGateState state = EGateState::NONE; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & state; diff --git a/lib/networkPacks/PacksForLobby.h b/lib/networkPacks/PacksForLobby.h index d5ef0b7b5..ff7c242f3 100644 --- a/lib/networkPacks/PacksForLobby.h +++ b/lib/networkPacks/PacksForLobby.h @@ -44,7 +44,7 @@ struct DLL_LINKAGE LobbyClientConnected : public CLobbyPackToPropagate void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & uuid; h & names; @@ -63,7 +63,7 @@ struct DLL_LINKAGE LobbyClientDisconnected : public CLobbyPackToPropagate void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & clientId; h & shutdownServer; @@ -77,7 +77,7 @@ struct DLL_LINKAGE LobbyChatMessage : public CLobbyPackToPropagate void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & playerName; h & message; @@ -93,7 +93,7 @@ struct DLL_LINKAGE LobbyGuiAction : public CLobbyPackToPropagate void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & action; } @@ -105,7 +105,7 @@ struct DLL_LINKAGE LobbyLoadProgress : public CLobbyPackToPropagate void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & progress; } @@ -118,7 +118,7 @@ struct DLL_LINKAGE LobbyEndGame : public CLobbyPackToPropagate void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & closeConnection; h & restart; @@ -134,7 +134,7 @@ struct DLL_LINKAGE LobbyStartGame : public CLobbyPackToPropagate void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & clientId; h & initializedStartInfo; @@ -151,7 +151,7 @@ struct DLL_LINKAGE LobbyChangeHost : public CLobbyPackToPropagate void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & newHostConnectionId; } @@ -164,7 +164,7 @@ struct DLL_LINKAGE LobbyUpdateState : public CLobbyPackToPropagate void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & state; } @@ -179,7 +179,7 @@ struct DLL_LINKAGE LobbySetMap : public CLobbyPackToServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & mapInfo; h & mapGenOpts; @@ -192,7 +192,7 @@ struct DLL_LINKAGE LobbySetCampaign : public CLobbyPackToServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & ourCampaign; } @@ -204,7 +204,7 @@ struct DLL_LINKAGE LobbySetCampaignMap : public CLobbyPackToServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & mapId; } @@ -216,7 +216,7 @@ struct DLL_LINKAGE LobbySetCampaignBonus : public CLobbyPackToServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & bonusId; } @@ -231,7 +231,7 @@ struct DLL_LINKAGE LobbyChangePlayerOption : public CLobbyPackToServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & what; h & value; @@ -245,7 +245,7 @@ struct DLL_LINKAGE LobbySetPlayer : public CLobbyPackToServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & clickedColor; } @@ -258,7 +258,7 @@ struct DLL_LINKAGE LobbySetPlayerName : public CLobbyPackToServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & color; h & name; @@ -271,7 +271,7 @@ struct DLL_LINKAGE LobbySetSimturns : public CLobbyPackToServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & simturnsInfo; } @@ -283,7 +283,7 @@ struct DLL_LINKAGE LobbySetTurnTime : public CLobbyPackToServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & turnTimerInfo; } @@ -295,7 +295,7 @@ struct DLL_LINKAGE LobbySetExtraOptions : public CLobbyPackToServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & extraOptionsInfo; } @@ -307,7 +307,7 @@ struct DLL_LINKAGE LobbySetDifficulty : public CLobbyPackToServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & difficulty; } @@ -320,7 +320,7 @@ struct DLL_LINKAGE LobbyForceSetPlayer : public CLobbyPackToServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & targetConnectedPlayer; h & targetPlayerColor; @@ -333,7 +333,7 @@ struct DLL_LINKAGE LobbyShowMessage : public CLobbyPackToPropagate void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & message; } diff --git a/lib/networkPacks/PacksForServer.h b/lib/networkPacks/PacksForServer.h index de1d7d613..ad41583a3 100644 --- a/lib/networkPacks/PacksForServer.h +++ b/lib/networkPacks/PacksForServer.h @@ -22,7 +22,7 @@ struct DLL_LINKAGE GamePause : public CPackForServer { void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); } @@ -32,7 +32,7 @@ struct DLL_LINKAGE EndTurn : public CPackForServer { void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); } @@ -49,7 +49,7 @@ struct DLL_LINKAGE DismissHero : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & hid; @@ -71,7 +71,7 @@ struct DLL_LINKAGE MoveHero : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & dest; @@ -95,7 +95,7 @@ struct DLL_LINKAGE CastleTeleportHero : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & dest; @@ -123,7 +123,7 @@ struct DLL_LINKAGE ArrangeStacks : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & what; @@ -153,7 +153,7 @@ struct DLL_LINKAGE BulkMoveArmy : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & static_cast(*this); h & srcSlot; @@ -180,7 +180,7 @@ struct DLL_LINKAGE BulkSplitStack : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & static_cast(*this); h & src; @@ -205,7 +205,7 @@ struct DLL_LINKAGE BulkMergeStacks : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & static_cast(*this); h & src; @@ -229,7 +229,7 @@ struct DLL_LINKAGE BulkSmartSplitStack : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & static_cast(*this); h & src; @@ -250,7 +250,7 @@ struct DLL_LINKAGE DisbandCreature : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & pos; @@ -271,7 +271,7 @@ struct DLL_LINKAGE BuildStructure : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & tid; @@ -303,7 +303,7 @@ struct DLL_LINKAGE RecruitCreatures : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & tid; @@ -329,7 +329,7 @@ struct DLL_LINKAGE UpgradeCreature : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & pos; @@ -349,7 +349,7 @@ struct DLL_LINKAGE GarrisonHeroSwap : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & tid; @@ -362,7 +362,7 @@ struct DLL_LINKAGE ExchangeArtifacts : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & src; @@ -390,7 +390,7 @@ struct DLL_LINKAGE BulkExchangeArtifacts : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & srcHero; @@ -418,7 +418,7 @@ struct DLL_LINKAGE AssembleArtifacts : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & heroID; @@ -439,7 +439,7 @@ struct DLL_LINKAGE EraseArtifactByClient : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & al; @@ -459,7 +459,7 @@ struct DLL_LINKAGE BuyArtifact : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & hid; @@ -479,7 +479,7 @@ struct DLL_LINKAGE TradeOnMarketplace : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & marketId; @@ -505,7 +505,7 @@ struct DLL_LINKAGE SetFormation : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & hid; @@ -527,7 +527,7 @@ struct DLL_LINKAGE HireHero : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & hid; @@ -542,7 +542,7 @@ struct DLL_LINKAGE BuildBoat : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & objid; @@ -563,7 +563,7 @@ struct DLL_LINKAGE QueryReply : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & qid; @@ -584,7 +584,7 @@ struct DLL_LINKAGE MakeAction : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & ba; @@ -598,7 +598,7 @@ struct DLL_LINKAGE DigWithHero : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & id; @@ -613,7 +613,7 @@ struct DLL_LINKAGE CastAdvSpell : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & hid; @@ -637,7 +637,7 @@ struct DLL_LINKAGE SaveGame : public CPackForServer void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & fname; @@ -660,7 +660,7 @@ struct DLL_LINKAGE PlayerMessage : public CPackForServer std::string text; ObjectInstanceID currObj; // optional parameter that specifies current object. For cheats :) - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & static_cast(*this); h & text; diff --git a/lib/networkPacks/SetStackEffect.h b/lib/networkPacks/SetStackEffect.h index f53b4cfe2..af6196353 100644 --- a/lib/networkPacks/SetStackEffect.h +++ b/lib/networkPacks/SetStackEffect.h @@ -29,7 +29,7 @@ struct DLL_LINKAGE SetStackEffect : public CPackForClient void visitTyped(ICPackVisitor & visitor) override; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & battleID; h & toAdd; diff --git a/lib/networkPacks/StackLocation.h b/lib/networkPacks/StackLocation.h index abb922d0f..a53255b8b 100644 --- a/lib/networkPacks/StackLocation.h +++ b/lib/networkPacks/StackLocation.h @@ -30,7 +30,7 @@ struct StackLocation } DLL_LINKAGE const CStackInstance * getStack(); - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & army; h & slot; diff --git a/lib/rewardable/Configuration.h b/lib/rewardable/Configuration.h index e7ce85dff..4e47d5217 100644 --- a/lib/rewardable/Configuration.h +++ b/lib/rewardable/Configuration.h @@ -68,7 +68,7 @@ struct DLL_LINKAGE ResetInfo void serializeJson(JsonSerializeFormat & handler); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & period; h & visitors; @@ -93,7 +93,7 @@ struct DLL_LINKAGE VisitInfo void serializeJson(JsonSerializeFormat & handler); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & limiter; h & reward; @@ -113,7 +113,7 @@ struct DLL_LINKAGE Variables void serializeJson(JsonSerializeFormat & handler); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & values; h & preset; @@ -173,7 +173,7 @@ struct DLL_LINKAGE Configuration void serializeJson(JsonSerializeFormat & handler); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & onSelect; h & description; diff --git a/lib/rewardable/Info.h b/lib/rewardable/Info.h index 7df4c17e9..3216d5f68 100644 --- a/lib/rewardable/Info.h +++ b/lib/rewardable/Info.h @@ -69,7 +69,7 @@ public: void init(const JsonNode & objectConfig, const std::string & objectTextID); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & parameters; } diff --git a/lib/rewardable/Interface.h b/lib/rewardable/Interface.h index ac85e6b72..3ff6980c9 100644 --- a/lib/rewardable/Interface.h +++ b/lib/rewardable/Interface.h @@ -44,7 +44,7 @@ public: void serializeJson(JsonSerializeFormat & handler); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & configuration; } diff --git a/lib/rewardable/Limiter.h b/lib/rewardable/Limiter.h index 407db0f24..969bcd576 100644 --- a/lib/rewardable/Limiter.h +++ b/lib/rewardable/Limiter.h @@ -92,7 +92,7 @@ struct DLL_LINKAGE Limiter final void loadComponents(std::vector & comps, const CGHeroInstance * h) const; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & dayOfWeek; h & daysPassed; diff --git a/lib/rewardable/Reward.h b/lib/rewardable/Reward.h index 5c4fd84a2..a7410a241 100644 --- a/lib/rewardable/Reward.h +++ b/lib/rewardable/Reward.h @@ -45,7 +45,7 @@ struct RewardRevealTiles void serializeJson(JsonSerializeFormat & handler); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & radius; h & scoreSurface; @@ -119,7 +119,7 @@ struct DLL_LINKAGE Reward final Reward(); ~Reward(); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & resources; h & extraComponents; diff --git a/lib/rmg/CMapGenOptions.h b/lib/rmg/CMapGenOptions.h index 6658c9057..47e33c797 100644 --- a/lib/rmg/CMapGenOptions.h +++ b/lib/rmg/CMapGenOptions.h @@ -67,14 +67,13 @@ public: public: template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & color; h & startingTown; h & playerType; - if(version >= 806) - h & team; - if (version >= 832) + h & team; + if (h.version >= Handler::Version::RELEASE_143) h & startingHero; else startingHero = HeroTypeID::RANDOM; @@ -186,7 +185,7 @@ private: public: template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & width; h & height; @@ -203,16 +202,13 @@ public: { templateName = mapTemplate->getId(); } - if(version >= 806) + h & templateName; + if(!h.saving) { - h & templateName; - if(!h.saving) - { - setMapTemplate(templateName); - } - - h & enabledRoads; + setMapTemplate(templateName); } + + h & enabledRoads; } }; diff --git a/lib/serializer/BinaryDeserializer.cpp b/lib/serializer/BinaryDeserializer.cpp index 0cb95f14a..5a82c58fe 100644 --- a/lib/serializer/BinaryDeserializer.cpp +++ b/lib/serializer/BinaryDeserializer.cpp @@ -16,7 +16,7 @@ VCMI_LIB_NAMESPACE_BEGIN BinaryDeserializer::BinaryDeserializer(IBinaryReader * r): CLoaderBase(r) { saving = false; - fileVersion = 0; + version = Version::NONE; smartPointerSerialization = true; reverseEndianess = false; diff --git a/lib/serializer/BinaryDeserializer.h b/lib/serializer/BinaryDeserializer.h index 911a04b05..c4ddc49c6 100644 --- a/lib/serializer/BinaryDeserializer.h +++ b/lib/serializer/BinaryDeserializer.h @@ -11,6 +11,7 @@ #include "CSerializer.h" #include "CTypeList.h" +#include "SerializerVersion.h" #include "../mapObjects/CGHeroInstance.h" VCMI_LIB_NAMESPACE_BEGIN @@ -135,8 +136,7 @@ class DLL_LINKAGE BinaryDeserializer : public CLoaderBase Type * ptr = ClassObjectCreator::invoke(cb); //does new npT or throws for abstract classes s.ptrAllocated(ptr, pid); - assert(s.fileVersion != 0); - ptr->serialize(s,s.fileVersion); + ptr->serialize(s); return static_cast(ptr); } @@ -147,8 +147,10 @@ class DLL_LINKAGE BinaryDeserializer : public CLoaderBase int write(const void * data, unsigned size); public: + using Version = ESerializationVersion; + bool reverseEndianess; //if source has different endianness than us, we reverse bytes - si32 fileVersion; + Version version; std::map loadedPointers; std::map> loadedSharedPointers; @@ -178,11 +180,10 @@ public: template < typename T, typename std::enable_if < is_serializeable::value, int >::type = 0 > void load(T &data) { - assert( fileVersion != 0 ); ////that const cast is evil because it allows to implicitly overwrite const objects when deserializing typedef typename std::remove_const::type nonConstT; auto & hlp = const_cast(data); - hlp.serialize(*this,fileVersion); + hlp.serialize(*this); } template < typename T, typename std::enable_if < std::is_array::value, int >::type = 0 > void load(T &data) diff --git a/lib/serializer/BinarySerializer.h b/lib/serializer/BinarySerializer.h index 922b5f6dd..36c0922f2 100644 --- a/lib/serializer/BinarySerializer.h +++ b/lib/serializer/BinarySerializer.h @@ -11,6 +11,7 @@ #include "CSerializer.h" #include "CTypeList.h" +#include "SerializerVersion.h" #include "../mapObjects/CArmedInstance.h" VCMI_LIB_NAMESPACE_BEGIN @@ -103,15 +104,18 @@ class DLL_LINKAGE BinarySerializer : public CSaverBase const T *ptr = static_cast(data); //T is most derived known type, it's time to call actual serialize - const_cast(ptr)->serialize(s, SERIALIZATION_VERSION); + const_cast(ptr)->serialize(s); } }; CApplier applier; public: + using Version = ESerializationVersion; + std::map savedPointers; + const Version version = Version::CURRENT; bool smartPointerSerialization; bool saving; @@ -238,7 +242,7 @@ public: template < typename T, typename std::enable_if < is_serializeable::value, int >::type = 0 > void save(const T &data) { - const_cast(data).serialize(*this, SERIALIZATION_VERSION); + const_cast(data).serialize(*this); } void save(const std::monostate & data) diff --git a/lib/serializer/CLoadFile.cpp b/lib/serializer/CLoadFile.cpp index cf5ea34d7..2e50fa6c1 100644 --- a/lib/serializer/CLoadFile.cpp +++ b/lib/serializer/CLoadFile.cpp @@ -12,7 +12,7 @@ VCMI_LIB_NAMESPACE_BEGIN -CLoadFile::CLoadFile(const boost::filesystem::path & fname, int minimalVersion) +CLoadFile::CLoadFile(const boost::filesystem::path & fname, ESerializationVersion minimalVersion) : serializer(this) { openNextFile(fname, minimalVersion); @@ -27,10 +27,10 @@ int CLoadFile::read(void * data, unsigned size) return size; } -void CLoadFile::openNextFile(const boost::filesystem::path & fname, int minimalVersion) +void CLoadFile::openNextFile(const boost::filesystem::path & fname, ESerializationVersion minimalVersion) { assert(!serializer.reverseEndianess); - assert(minimalVersion <= SERIALIZATION_VERSION); + assert(minimalVersion <= ESerializationVersion::CURRENT); try { @@ -47,19 +47,19 @@ void CLoadFile::openNextFile(const boost::filesystem::path & fname, int minimalV if(std::memcmp(buffer, "VCMI", 4) != 0) THROW_FORMAT("Error: not a VCMI file(%s)!", fName); - serializer & serializer.fileVersion; - if(serializer.fileVersion < minimalVersion) + serializer & serializer.version; + if(serializer.version < minimalVersion) THROW_FORMAT("Error: too old file format (%s)!", fName); - if(serializer.fileVersion > SERIALIZATION_VERSION) + if(serializer.version > ESerializationVersion::CURRENT) { - logGlobal->warn("Warning format version mismatch: found %d when current is %d! (file %s)\n", serializer.fileVersion, SERIALIZATION_VERSION , fName); + logGlobal->warn("Warning format version mismatch: found %d when current is %d! (file %s)\n", vstd::to_underlying(serializer.version), vstd::to_underlying(ESerializationVersion::CURRENT), fName); - auto * versionptr = reinterpret_cast(&serializer.fileVersion); + auto * versionptr = reinterpret_cast(&serializer.version); std::reverse(versionptr, versionptr + 4); - logGlobal->warn("Version number reversed is %x, checking...", serializer.fileVersion); + logGlobal->warn("Version number reversed is %x, checking...", vstd::to_underlying(serializer.version)); - if(serializer.fileVersion == SERIALIZATION_VERSION) + if(serializer.version == ESerializationVersion::CURRENT) { logGlobal->warn("%s seems to have different endianness! Entering reversing mode.", fname.string()); serializer.reverseEndianess = true; @@ -86,7 +86,7 @@ void CLoadFile::clear() { sfile = nullptr; fName.clear(); - serializer.fileVersion = 0; + serializer.version = ESerializationVersion::NONE; } void CLoadFile::checkMagicBytes(const std::string &text) diff --git a/lib/serializer/CLoadFile.h b/lib/serializer/CLoadFile.h index 8f9079bb9..00b5264b8 100644 --- a/lib/serializer/CLoadFile.h +++ b/lib/serializer/CLoadFile.h @@ -10,6 +10,7 @@ #pragma once #include "BinaryDeserializer.h" +#include "SerializerVersion.h" VCMI_LIB_NAMESPACE_BEGIN @@ -21,11 +22,11 @@ public: std::string fName; std::unique_ptr sfile; - CLoadFile(const boost::filesystem::path & fname, int minimalVersion = SERIALIZATION_VERSION); //throws! + CLoadFile(const boost::filesystem::path & fname, ESerializationVersion minimalVersion = ESerializationVersion::CURRENT); //throws! virtual ~CLoadFile(); int read(void * data, unsigned size) override; //throws! - void openNextFile(const boost::filesystem::path & fname, int minimalVersion); //throws! + void openNextFile(const boost::filesystem::path & fname, ESerializationVersion minimalVersion); //throws! void clear(); void reportState(vstd::CLoggerBase * out) override; diff --git a/lib/serializer/CMemorySerializer.cpp b/lib/serializer/CMemorySerializer.cpp index 797c10a6d..39a647335 100644 --- a/lib/serializer/CMemorySerializer.cpp +++ b/lib/serializer/CMemorySerializer.cpp @@ -32,7 +32,7 @@ int CMemorySerializer::write(const void * data, unsigned size) CMemorySerializer::CMemorySerializer(): iser(this), oser(this), readPos(0) { - iser.fileVersion = SERIALIZATION_VERSION; + iser.version = ESerializationVersion::CURRENT; } VCMI_LIB_NAMESPACE_END diff --git a/lib/serializer/CSaveFile.cpp b/lib/serializer/CSaveFile.cpp index 5f377aed6..e575a88a3 100644 --- a/lib/serializer/CSaveFile.cpp +++ b/lib/serializer/CSaveFile.cpp @@ -39,7 +39,7 @@ void CSaveFile::openNextFile(const boost::filesystem::path &fname) THROW_FORMAT("Error: cannot open to write %s!", fname); sfile->write("VCMI",4); //write magic identifier - serializer & SERIALIZATION_VERSION; //write format version + serializer & ESerializationVersion::CURRENT; //write format version } catch(...) { diff --git a/lib/serializer/CSerializer.h b/lib/serializer/CSerializer.h index 58914184c..491ad80cb 100644 --- a/lib/serializer/CSerializer.h +++ b/lib/serializer/CSerializer.h @@ -14,8 +14,6 @@ VCMI_LIB_NAMESPACE_BEGIN -const ui32 SERIALIZATION_VERSION = 832; -const ui32 MINIMAL_SERIALIZATION_VERSION = 831; const std::string SAVEGAME_MAGIC = "VCMISVG"; class CHero; @@ -138,10 +136,7 @@ struct is_serializeable using No = char (&)[2]; template - static Yes test(U * data, S* arg1 = 0, - typename std::enable_ifserialize(*arg1, int(0))) - >::value>::type * = 0); + static Yes test(U * data, S* arg1 = 0, typename std::enable_if_tserialize(*arg1))>> * = 0); static No test(...); static const bool value = sizeof(Yes) == sizeof(is_serializeable::test((typename std::remove_reference::type>::type*)0)); }; diff --git a/lib/serializer/Connection.cpp b/lib/serializer/Connection.cpp index cda305ff7..e17d57141 100644 --- a/lib/serializer/Connection.cpp +++ b/lib/serializer/Connection.cpp @@ -59,7 +59,7 @@ void CConnection::init() mutexRead = std::make_shared(); mutexWrite = std::make_shared(); - iser.fileVersion = SERIALIZATION_VERSION; + iser.version = ESerializationVersion::CURRENT; } CConnection::CConnection(const std::string & host, ui16 port, std::string Name, std::string UUID): diff --git a/lib/serializer/SerializerVersion.h b/lib/serializer/SerializerVersion.h new file mode 100644 index 000000000..1be8194e3 --- /dev/null +++ b/lib/serializer/SerializerVersion.h @@ -0,0 +1,39 @@ +/* + * ESerializationVersion.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 + +/// This is enumeration that controls save compatibility support +/// - 'MINIMAL' represents older supported version counter. Save can be loaded if its version is at least 'MINIMAL' +/// - 'CURRENT' represent current save version. All saves are created using 'CURRENT' version +/// +/// To add save-breaking change: +/// - change 'MINIMAL' to value higher than CURRENT +/// - remove all version enumerations inbetween +/// - change 'CURRENT' to 'CURRENT = MINIMAL' +/// +/// To add non-breaking change: +/// - add new enumeration value before 'CURRENT' +/// - change 'CURRENT' to 'CURRENT = NEW_TEST_KEY' +/// +/// To check for version in serialize() call use form +/// if (h.version >= Handler::Version::NEW_TEST_KEY) +/// h & newKey; // loading/saving save of a new version +/// else +/// newKey = saneDefaultValue; // loading of old save +enum class ESerializationVersion : int32_t +{ + NONE = 0, + + MINIMAL = 831, + RELEASE_143, // 832 + text container in campaigns, +starting hero in RMG options + HAS_EXTRA_OPTIONS, // 833 +extra options struct as part of startinfo + + CURRENT = HAS_EXTRA_OPTIONS +}; diff --git a/lib/spells/CSpellHandler.h b/lib/spells/CSpellHandler.h index 666e58b51..522e30d83 100644 --- a/lib/spells/CSpellHandler.h +++ b/lib/spells/CSpellHandler.h @@ -68,7 +68,7 @@ public: ///resource name AnimationPath resourceName; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & minimumAngle; h & resourceName; @@ -84,11 +84,10 @@ public: AnimationItem(); - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & resourceName; - if (version > 806) - h & effectName; + h & effectName; h & verticalPosition; h & pause; } @@ -112,7 +111,7 @@ public: ///use selectProjectile to access std::vector projectile; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & projectile; h & hit; @@ -141,7 +140,7 @@ public: JsonNode battleEffects; - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & cost; h & power; diff --git a/lib/spells/ViewSpellInt.h b/lib/spells/ViewSpellInt.h index 18447d43a..a4c589daa 100644 --- a/lib/spells/ViewSpellInt.h +++ b/lib/spells/ViewSpellInt.h @@ -26,7 +26,7 @@ VCMI_LIB_NAMESPACE_BEGIN ObjectPosInfo() = default; ObjectPosInfo(const CGObjectInstance * obj); - template void serialize(Handler & h, const int version) + template void serialize(Handler & h) { h & pos; h & id; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index b8f6cfaf6..0fc3dba9d 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1799,7 +1799,7 @@ bool CGameHandler::load(const std::string & filename) try { { - CLoadFile lf(*CResourceHandler::get()->getResourceName(ResourcePath(stem.to_string(), EResType::SAVEGAME)), MINIMAL_SERIALIZATION_VERSION); + CLoadFile lf(*CResourceHandler::get()->getResourceName(ResourcePath(stem.to_string(), EResType::SAVEGAME)), ESerializationVersion::MINIMAL); lf.serializer.cb = this; loadCommonState(lf); logGlobal->info("Loading server state"); diff --git a/server/CGameHandler.h b/server/CGameHandler.h index 152452d6a..45789bfcd 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -222,7 +222,7 @@ public: bool dig(const CGHeroInstance *h); void moveArmy(const CArmedInstance *src, const CArmedInstance *dst, bool allowMerging); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & QID; h & getRandomGenerator(); diff --git a/server/battles/BattleProcessor.h b/server/battles/BattleProcessor.h index c7423eeb2..952759fde 100644 --- a/server/battles/BattleProcessor.h +++ b/server/battles/BattleProcessor.h @@ -74,7 +74,7 @@ public: /// Applies results of a battle after potential levelup void battleAfterLevelUp(const BattleID & battleID, const BattleResult & result); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { } diff --git a/server/battles/BattleResultProcessor.h b/server/battles/BattleResultProcessor.h index 7616c1775..5160c55e4 100644 --- a/server/battles/BattleResultProcessor.h +++ b/server/battles/BattleResultProcessor.h @@ -50,7 +50,7 @@ struct FinishingBattleHelper int remainingBattleQueriesCount; - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { h & winnerHero; h & loserHero; diff --git a/server/processors/HeroPoolProcessor.h b/server/processors/HeroPoolProcessor.h index eed300a79..cd31175d3 100644 --- a/server/processors/HeroPoolProcessor.h +++ b/server/processors/HeroPoolProcessor.h @@ -62,7 +62,7 @@ public: /// Incoming net pack handling bool hireHero(const ObjectInstanceID & objectID, const HeroTypeID & hid, const PlayerColor & player); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { // h & gameHandler; // FIXME: make this work instead of using deserializationFix in gameHandler h & playerSeed; diff --git a/server/processors/PlayerMessageProcessor.h b/server/processors/PlayerMessageProcessor.h index b11e082a1..9d4fd36dc 100644 --- a/server/processors/PlayerMessageProcessor.h +++ b/server/processors/PlayerMessageProcessor.h @@ -60,7 +60,7 @@ public: /// Send message from specific player to all other players void broadcastMessage(PlayerColor playerSender, const std::string & message); - template void serialize(Handler &h, const int version) + template void serialize(Handler &h) { } }; diff --git a/server/processors/TurnOrderProcessor.h b/server/processors/TurnOrderProcessor.h index 2d3b87f2e..8be868599 100644 --- a/server/processors/TurnOrderProcessor.h +++ b/server/processors/TurnOrderProcessor.h @@ -28,7 +28,7 @@ class TurnOrderProcessor : boost::noncopyable } template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & a; h & b; @@ -92,7 +92,7 @@ public: void onGameStarted(); template - void serialize(Handler & h, const int version) + void serialize(Handler & h) { h & blockedContacts; h & awaitingPlayers; From cc7fc4a2c6f3dd84c35cfc8bcbc94277bca4b4d0 Mon Sep 17 00:00:00 2001 From: Andrii Danylchenko Date: Sun, 3 Dec 2023 18:39:25 +0200 Subject: [PATCH 21/54] Fix headless mode --- AI/Nullkiller/Engine/PriorityEvaluator.cpp | 2 ++ client/CMT.cpp | 4 +-- client/CServerHandler.cpp | 4 ++- client/Client.cpp | 4 +-- client/NetPacksClient.cpp | 29 +++++++++++++++------- 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/AI/Nullkiller/Engine/PriorityEvaluator.cpp b/AI/Nullkiller/Engine/PriorityEvaluator.cpp index 77411dac6..d01ea5e22 100644 --- a/AI/Nullkiller/Engine/PriorityEvaluator.cpp +++ b/AI/Nullkiller/Engine/PriorityEvaluator.cpp @@ -588,6 +588,8 @@ float RewardEvaluator::getSkillReward(const CGObjectInstance * target, const CGH case Obj::PANDORAS_BOX: //Can contains experience, spells, or skills (only on custom maps) return 2.5f; + case Obj::PYRAMID: + return 3.0f; case Obj::HERO: return ai->cb->getPlayerRelations(target->tempOwner, ai->playerID) == PlayerRelations::ENEMIES ? enemyHeroEliminationSkillRewardRatio * dynamic_cast(target)->level diff --git a/client/CMT.cpp b/client/CMT.cpp index e3b6780f9..8ad12ae73 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -462,9 +462,9 @@ static void mainLoop() { if(CSH->client) CSH->endGameplay(); - } - GH.windows().clear(); + GH.windows().clear(); + } CMM.reset(); diff --git a/client/CServerHandler.cpp b/client/CServerHandler.cpp index 4b3ef7adf..ee3f47164 100644 --- a/client/CServerHandler.cpp +++ b/client/CServerHandler.cpp @@ -617,7 +617,9 @@ bool CServerHandler::validateGameStart(bool allowOnlyAI) const void CServerHandler::sendStartGame(bool allowOnlyAI) const { verifyStateBeforeStart(allowOnlyAI ? true : settings["session"]["onlyai"].Bool()); - GH.windows().createAndPushWindow(); + + if(!settings["session"]["headless"].Bool()) + GH.windows().createAndPushWindow(); LobbyStartGame lsg; if(client) diff --git a/client/Client.cpp b/client/Client.cpp index 10c2b64e9..f5cba4024 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -411,7 +411,7 @@ void CClient::initPlayerEnvironments() hasHumanPlayer = true; } - if(!hasHumanPlayer) + if(!hasHumanPlayer && !settings["session"]["headless"].Bool()) { Settings session = settings.write["session"]; session["spectate"].Bool() = true; @@ -436,7 +436,7 @@ void CClient::initPlayerInterfaces() if(!vstd::contains(playerint, color)) { logNetwork->info("Preparing interface for player %s", color.toString()); - if(playerInfo.second.isControlledByAI()) + if(playerInfo.second.isControlledByAI() || settings["session"]["onlyai"].Bool()) { bool alliedToHuman = false; for(auto & allyInfo : gs->scenarioOps->playerInfos) diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index 1b7ab14c1..2d9e89eaf 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -157,6 +157,9 @@ void ApplyClientNetPackVisitor::visitSetMana(SetMana & pack) const CGHeroInstance *h = cl.getHero(pack.hid); callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroManaPointsChanged, h); + if(settings["session"]["headless"].Bool()) + return; + for (auto window : GH.windows().findWindows()) window->heroManaPointsChanged(h); } @@ -467,7 +470,8 @@ void ApplyFirstClientNetPackVisitor::visitRemoveObject(RemoveObject & pack) i->second->objectRemoved(o, pack.initiator); } - CGI->mh->waitForOngoingAnimations(); + if(CGI->mh) + CGI->mh->waitForOngoingAnimations(); } void ApplyClientNetPackVisitor::visitRemoveObject(RemoveObject & pack) @@ -553,9 +557,11 @@ void ApplyClientNetPackVisitor::visitNewStructures(NewStructures & pack) } // invalidate section of map view with our object and force an update - CGI->mh->onObjectInstantRemove(town, town->getOwner()); - CGI->mh->onObjectInstantAdd(town, town->getOwner()); - + if(CGI->mh) + { + CGI->mh->onObjectInstantRemove(town, town->getOwner()); + CGI->mh->onObjectInstantAdd(town, town->getOwner()); + } } void ApplyClientNetPackVisitor::visitRazeStructures(RazeStructures & pack) { @@ -566,8 +572,11 @@ void ApplyClientNetPackVisitor::visitRazeStructures(RazeStructures & pack) } // invalidate section of map view with our object and force an update - CGI->mh->onObjectInstantRemove(town, town->getOwner()); - CGI->mh->onObjectInstantAdd(town, town->getOwner()); + if(CGI->mh) + { + CGI->mh->onObjectInstantRemove(town, town->getOwner()); + CGI->mh->onObjectInstantAdd(town, town->getOwner()); + } } void ApplyClientNetPackVisitor::visitSetAvailableCreatures(SetAvailableCreatures & pack) @@ -651,7 +660,7 @@ void ApplyFirstClientNetPackVisitor::visitSetObjectProperty(SetObjectProperty & } // invalidate section of map view with our object and force an update with new flag color - if (pack.what == ObjProperty::OWNER) + if (pack.what == ObjProperty::OWNER && CGI->mh) { auto object = gs.getObjInstance(pack.id); CGI->mh->onObjectInstantRemove(object, object->getOwner()); @@ -668,7 +677,7 @@ void ApplyClientNetPackVisitor::visitSetObjectProperty(SetObjectProperty & pack) } // invalidate section of map view with our object and force an update with new flag color - if (pack.what == ObjProperty::OWNER) + if (pack.what == ObjProperty::OWNER && CGI->mh) { auto object = gs.getObjInstance(pack.id); CGI->mh->onObjectInstantAdd(object, object->getOwner()); @@ -1023,7 +1032,9 @@ void ApplyClientNetPackVisitor::visitNewObject(NewObject & pack) if(gs.isVisible(obj, i->first)) i->second->newObject(obj); } - CGI->mh->waitForOngoingAnimations(); + + if(CGI->mh) + CGI->mh->waitForOngoingAnimations(); } void ApplyClientNetPackVisitor::visitSetAvailableArtifacts(SetAvailableArtifacts & pack) From 36bc9ddcec15e019e4cf452d4b016455252d4e24 Mon Sep 17 00:00:00 2001 From: Andrii Danylchenko Date: Sun, 17 Dec 2023 10:11:05 +0200 Subject: [PATCH 22/54] NKAI: mutex for internal AI state --- AI/Nullkiller/AIGateway.cpp | 22 +++++++++++++++------- AI/Nullkiller/Engine/Nullkiller.cpp | 4 ++++ AI/Nullkiller/Engine/Nullkiller.h | 1 + 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/AI/Nullkiller/AIGateway.cpp b/AI/Nullkiller/AIGateway.cpp index ae58960af..74a152f2e 100644 --- a/AI/Nullkiller/AIGateway.cpp +++ b/AI/Nullkiller/AIGateway.cpp @@ -588,6 +588,8 @@ void AIGateway::heroGotLevel(const CGHeroInstance * hero, PrimarySkill pskill, s { if(hPtr.validAndSet()) { + std::unique_lock lockGuard(nullkiller->aiStateMutex); + nullkiller->heroManager->update(); answerQuery(queryID, nullkiller->heroManager->selectBestSkill(hPtr, skills)); } @@ -661,14 +663,18 @@ void AIGateway::showBlockingDialog(const std::string & text, const std::vector take the last one (they're indexed [1-size]) sel = components.size(); - // TODO: Find better way to understand it is Chest of Treasures - if(hero.validAndSet() - && components.size() == 2 - && components.front().type == ComponentType::RESOURCE - && (nullkiller->heroManager->getHeroRole(hero) != HeroRole::MAIN - || nullkiller->buildAnalyzer->getGoldPreasure() > MAX_GOLD_PEASURE)) { - sel = 1; // for now lets pick gold from a chest. + std::unique_lock(nullkiller->aiStateMutex); + + // TODO: Find better way to understand it is Chest of Treasures + if(hero.validAndSet() + && components.size() == 2 + && components.front().type == ComponentType::RESOURCE + && (nullkiller->heroManager->getHeroRole(hero) != HeroRole::MAIN + || nullkiller->buildAnalyzer->getGoldPreasure() > MAX_GOLD_PEASURE)) + { + sel = 1; // for now lets pick gold from a chest. + } } answerQuery(askID, sel); @@ -859,6 +865,8 @@ void AIGateway::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h { makePossibleUpgrades(h.get()); + std::unique_lock lockGuard(nullkiller->aiStateMutex); + if(!h->visitedTown->garrisonHero || !nullkiller->isHeroLocked(h->visitedTown->garrisonHero)) moveCreaturesToHero(h->visitedTown); diff --git a/AI/Nullkiller/Engine/Nullkiller.cpp b/AI/Nullkiller/Engine/Nullkiller.cpp index 79c21d1ab..de5222570 100644 --- a/AI/Nullkiller/Engine/Nullkiller.cpp +++ b/AI/Nullkiller/Engine/Nullkiller.cpp @@ -115,6 +115,8 @@ Goals::TTask Nullkiller::choseBestTask(Goals::TSubgoal behavior, int decompositi void Nullkiller::resetAiState() { + std::unique_lock lockGuard(aiStateMutex); + lockedResources = TResources(); scanDepth = ScanDepth::MAIN_FULL; playerID = ai->playerID; @@ -127,6 +129,8 @@ void Nullkiller::updateAiState(int pass, bool fast) { boost::this_thread::interruption_point(); + std::unique_lock lockGuard(aiStateMutex); + auto start = std::chrono::high_resolution_clock::now(); activeHero = nullptr; diff --git a/AI/Nullkiller/Engine/Nullkiller.h b/AI/Nullkiller/Engine/Nullkiller.h index 36f3504fd..b75465c73 100644 --- a/AI/Nullkiller/Engine/Nullkiller.h +++ b/AI/Nullkiller/Engine/Nullkiller.h @@ -73,6 +73,7 @@ public: std::unique_ptr armyFormation; PlayerColor playerID; std::shared_ptr cb; + std::mutex aiStateMutex; Nullkiller(); void init(std::shared_ptr cb, PlayerColor playerID); From 1db43a509eff4fdc127b7fd32d792fbe548de832 Mon Sep 17 00:00:00 2001 From: Andrii Danylchenko Date: Sat, 23 Dec 2023 15:53:30 +0200 Subject: [PATCH 23/54] NKAI: fix casting FLY several times during path calculation --- AI/Nullkiller/Engine/PriorityEvaluator.cpp | 16 ++++++++++++++-- AI/Nullkiller/Pathfinding/AINodeStorage.cpp | 6 ++++++ AI/Nullkiller/Pathfinding/AINodeStorage.h | 10 +++++++++- .../AdventureSpellCastMovementActions.cpp | 15 ++++++++------- .../Actions/AdventureSpellCastMovementActions.h | 3 ++- .../Pathfinding/Rules/AILayerTransitionRule.cpp | 12 ++++++++++++ 6 files changed, 51 insertions(+), 11 deletions(-) diff --git a/AI/Nullkiller/Engine/PriorityEvaluator.cpp b/AI/Nullkiller/Engine/PriorityEvaluator.cpp index d01ea5e22..f16b99e62 100644 --- a/AI/Nullkiller/Engine/PriorityEvaluator.cpp +++ b/AI/Nullkiller/Engine/PriorityEvaluator.cpp @@ -137,6 +137,18 @@ TResources getCreatureBankResources(const CGObjectInstance * target, const CGHer return sum > 1 ? result / sum : result; } +uint64_t getResourcesGoldReward(TResources & res) +{ + int nonGoldResources = res[EGameResID::GEMS] + + res[EGameResID::SULFUR] + + res[EGameResID::WOOD] + + res[EGameResID::ORE] + + res[EGameResID::CRYSTAL] + + res[EGameResID::MERCURY]; + + return res[EGameResID::GOLD] + 100 * nonGoldResources; +} + uint64_t getCreatureBankArmyReward(const CGObjectInstance * target, const CGHeroInstance * hero) { auto objectInfo = target->getObjectHandler()->getObjectInfo(target->appearance); @@ -491,7 +503,7 @@ float RewardEvaluator::getStrategicalValue(const CGObjectInstance * target) cons //Evaluate resources used for construction. Gold is evaluated separately. if (it->resType != EGameResID::GOLD) { - sum += 0.1f * getResourceRequirementStrength(it->resType); + sum += 0.1f * it->resVal * getResourceRequirementStrength(it->resType); } } return sum; @@ -662,7 +674,7 @@ int32_t RewardEvaluator::getGoldReward(const CGObjectInstance * target, const CG case Obj::WAGON: return 100; case Obj::CREATURE_BANK: - return getCreatureBankResources(target, hero)[EGameResID::GOLD]; + return getResourcesGoldReward(getCreatureBankResources(target, hero)); case Obj::CRYPT: case Obj::DERELICT_SHIP: return 3000; diff --git a/AI/Nullkiller/Pathfinding/AINodeStorage.cpp b/AI/Nullkiller/Pathfinding/AINodeStorage.cpp index 7e029fe64..9858f872b 100644 --- a/AI/Nullkiller/Pathfinding/AINodeStorage.cpp +++ b/AI/Nullkiller/Pathfinding/AINodeStorage.cpp @@ -234,6 +234,7 @@ void AINodeStorage::resetTile(const int3 & coord, EPathfindingLayer layer, EPath heroNode.specialAction.reset(); heroNode.armyLoss = 0; heroNode.chainOther = nullptr; + heroNode.dayFlags = DayFlags::NONE; heroNode.update(coord, layer, accessibility); } } @@ -295,6 +296,11 @@ void AINodeStorage::commit( { commitedTiles.insert(destination->coord); } + + if(destination->turns == source->turns) + { + destination->dayFlags = source->dayFlags; + } } std::vector AINodeStorage::calculateNeighbours( diff --git a/AI/Nullkiller/Pathfinding/AINodeStorage.h b/AI/Nullkiller/Pathfinding/AINodeStorage.h index 068304955..395e2b3a2 100644 --- a/AI/Nullkiller/Pathfinding/AINodeStorage.h +++ b/AI/Nullkiller/Pathfinding/AINodeStorage.h @@ -41,11 +41,19 @@ namespace AIPathfinding const int CHAIN_MAX_DEPTH = 4; } +enum DayFlags : ui8 +{ + NONE = 0, + FLY_CASTED = 1, + WATER_WALK_CASTED = 2 +}; + struct AIPathNode : public CGPathNode { uint64_t danger; uint64_t armyLoss; - int32_t manaCost; + int16_t manaCost; + DayFlags dayFlags; const AIPathNode * chainOther; std::shared_ptr specialAction; const ChainActor * actor; diff --git a/AI/Nullkiller/Pathfinding/Actions/AdventureSpellCastMovementActions.cpp b/AI/Nullkiller/Pathfinding/Actions/AdventureSpellCastMovementActions.cpp index ff4934b36..d5cb01397 100644 --- a/AI/Nullkiller/Pathfinding/Actions/AdventureSpellCastMovementActions.cpp +++ b/AI/Nullkiller/Pathfinding/Actions/AdventureSpellCastMovementActions.cpp @@ -22,18 +22,18 @@ namespace NKAI namespace AIPathfinding { - AdventureCastAction::AdventureCastAction(SpellID spellToCast, const CGHeroInstance * hero) - :spellToCast(spellToCast), hero(hero) + AdventureCastAction::AdventureCastAction(SpellID spellToCast, const CGHeroInstance * hero, DayFlags flagsToAdd) + :spellToCast(spellToCast), hero(hero), flagsToAdd(flagsToAdd) { manaCost = hero->getSpellCost(spellToCast.toSpell()); } WaterWalkingAction::WaterWalkingAction(const CGHeroInstance * hero) - :AdventureCastAction(SpellID::WATER_WALK, hero) + :AdventureCastAction(SpellID::WATER_WALK, hero, DayFlags::WATER_WALK_CASTED) { } AirWalkingAction::AirWalkingAction(const CGHeroInstance * hero) - : AdventureCastAction(SpellID::FLY, hero) + : AdventureCastAction(SpellID::FLY, hero, DayFlags::FLY_CASTED) { } @@ -41,11 +41,12 @@ namespace AIPathfinding const CGHeroInstance * hero, CDestinationNodeInfo & destination, const PathNodeInfo & source, - AIPathNode * dstMode, + AIPathNode * dstNode, const AIPathNode * srcNode) const { - dstMode->manaCost = srcNode->manaCost + manaCost; - dstMode->theNodeBefore = source.node; + dstNode->manaCost = srcNode->manaCost + manaCost; + dstNode->theNodeBefore = source.node; + dstNode->dayFlags = static_cast(dstNode->dayFlags | flagsToAdd); } void AdventureCastAction::execute(const CGHeroInstance * hero) const diff --git a/AI/Nullkiller/Pathfinding/Actions/AdventureSpellCastMovementActions.h b/AI/Nullkiller/Pathfinding/Actions/AdventureSpellCastMovementActions.h index 0667e400a..b7d596d26 100644 --- a/AI/Nullkiller/Pathfinding/Actions/AdventureSpellCastMovementActions.h +++ b/AI/Nullkiller/Pathfinding/Actions/AdventureSpellCastMovementActions.h @@ -24,9 +24,10 @@ namespace AIPathfinding SpellID spellToCast; const CGHeroInstance * hero; int manaCost; + DayFlags flagsToAdd; public: - AdventureCastAction(SpellID spellToCast, const CGHeroInstance * hero); + AdventureCastAction(SpellID spellToCast, const CGHeroInstance * hero, DayFlags flagsToAdd = DayFlags::NONE); virtual void execute(const CGHeroInstance * hero) const override; diff --git a/AI/Nullkiller/Pathfinding/Rules/AILayerTransitionRule.cpp b/AI/Nullkiller/Pathfinding/Rules/AILayerTransitionRule.cpp index a70826252..9d5350d16 100644 --- a/AI/Nullkiller/Pathfinding/Rules/AILayerTransitionRule.cpp +++ b/AI/Nullkiller/Pathfinding/Rules/AILayerTransitionRule.cpp @@ -61,6 +61,12 @@ namespace AIPathfinding if(source.node->layer == EPathfindingLayer::LAND && destination.node->layer == EPathfindingLayer::WATER) { + if(nodeStorage->getAINode(source.node)->dayFlags & DayFlags::WATER_WALK_CASTED) + { + destination.blocked = false; + return; + } + auto action = waterWalkingActions.find(nodeStorage->getHero(source.node)); if(action != waterWalkingActions.end() && tryUseSpecialAction(destination, source, action->second, EPathNodeAction::NORMAL)) @@ -73,6 +79,12 @@ namespace AIPathfinding if(source.node->layer == EPathfindingLayer::LAND && destination.node->layer == EPathfindingLayer::AIR) { + if(nodeStorage->getAINode(source.node)->dayFlags & DayFlags::FLY_CASTED) + { + destination.blocked = false; + return; + } + auto action = airWalkingActions.find(nodeStorage->getHero(source.node)); if(action != airWalkingActions.end() && tryUseSpecialAction(destination, source, action->second, EPathNodeAction::NORMAL)) From 0c1664dbe736749bb524b21ed954e805c81d6b87 Mon Sep 17 00:00:00 2001 From: Andrii Danylchenko Date: Sat, 23 Dec 2023 15:53:51 +0200 Subject: [PATCH 24/54] NKAI: various AI fixes after tests in headless --- AI/Nullkiller/AIGateway.cpp | 7 ++++++- AI/Nullkiller/Engine/PriorityEvaluator.cpp | 5 ++++- client/CMT.cpp | 21 ++++++++++----------- lib/pathfinder/PathfindingRules.cpp | 4 +--- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/AI/Nullkiller/AIGateway.cpp b/AI/Nullkiller/AIGateway.cpp index 74a152f2e..aaad0611f 100644 --- a/AI/Nullkiller/AIGateway.cpp +++ b/AI/Nullkiller/AIGateway.cpp @@ -586,13 +586,18 @@ void AIGateway::heroGotLevel(const CGHeroInstance * hero, PrimarySkill pskill, s requestActionASAP([=]() { + int sel = 0; + if(hPtr.validAndSet()) { std::unique_lock lockGuard(nullkiller->aiStateMutex); nullkiller->heroManager->update(); - answerQuery(queryID, nullkiller->heroManager->selectBestSkill(hPtr, skills)); + + sel = nullkiller->heroManager->selectBestSkill(hPtr, skills); } + + answerQuery(queryID, sel); }); } diff --git a/AI/Nullkiller/Engine/PriorityEvaluator.cpp b/AI/Nullkiller/Engine/PriorityEvaluator.cpp index f16b99e62..8564f52fc 100644 --- a/AI/Nullkiller/Engine/PriorityEvaluator.cpp +++ b/AI/Nullkiller/Engine/PriorityEvaluator.cpp @@ -137,7 +137,7 @@ TResources getCreatureBankResources(const CGObjectInstance * target, const CGHer return sum > 1 ? result / sum : result; } -uint64_t getResourcesGoldReward(TResources & res) +uint64_t getResourcesGoldReward(const TResources & res) { int nonGoldResources = res[EGameResID::GEMS] + res[EGameResID::SULFUR] @@ -541,6 +541,9 @@ float RewardEvaluator::getStrategicalValue(const CGObjectInstance * target) cons ? getEnemyHeroStrategicalValue(dynamic_cast(target)) : 0; + case Obj::KEYMASTER: + return 0.6f; + default: return 0; } diff --git a/client/CMT.cpp b/client/CMT.cpp index 8ad12ae73..a35d245f2 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -524,25 +524,24 @@ void handleQuit(bool ask) // FIXME: avoids crash if player attempts to close game while opening is still playing // use cursor handler as indicator that loading is not done yet // proper solution would be to abort init thread (or wait for it to finish) + if(!ask) + { + quitApplication(); + return; + } + if (!CCS->curh) { quitRequestedDuringOpeningPlayback = true; return; } - if(ask) - { - CCS->curh->set(Cursor::Map::POINTER); + CCS->curh->set(Cursor::Map::POINTER); - if (LOCPLINT) - LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[69], quitApplication, nullptr); - else - CInfoWindow::showYesNoDialog(CGI->generaltexth->allTexts[69], {}, quitApplication, {}, PlayerColor(1)); - } + if (LOCPLINT) + LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[69], quitApplication, nullptr); else - { - quitApplication(); - } + CInfoWindow::showYesNoDialog(CGI->generaltexth->allTexts[69], {}, quitApplication, {}, PlayerColor(1)); } void handleFatalError(const std::string & message, bool terminate) diff --git a/lib/pathfinder/PathfindingRules.cpp b/lib/pathfinder/PathfindingRules.cpp index 49de31ff7..2f13caca2 100644 --- a/lib/pathfinder/PathfindingRules.cpp +++ b/lib/pathfinder/PathfindingRules.cpp @@ -249,9 +249,7 @@ PathfinderBlockingRule::BlockingReason MovementAfterDestinationRule::getBlocking } case EPathNodeAction::BLOCKING_VISIT: - return destination.guarded - ? BlockingReason::DESTINATION_GUARDED - : BlockingReason::DESTINATION_BLOCKVIS; + return BlockingReason::DESTINATION_BLOCKVIS; case EPathNodeAction::NORMAL: return BlockingReason::NONE; From 9f3655c41bd86d1e80b542f325c323db27550ee1 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sat, 20 Jan 2024 23:26:04 +0200 Subject: [PATCH 25/54] Minor code cleanup --- cmake_modules/VCMI_lib.cmake | 2 +- lib/serializer/BinaryDeserializer.h | 2 +- lib/serializer/BinarySerializer.h | 2 +- lib/serializer/CLoadFile.h | 1 - lib/serializer/CSerializer.h | 4 ++-- ...alizerVersion.h => ESerializationVersion.h} | 18 +++++++++--------- 6 files changed, 14 insertions(+), 15 deletions(-) rename lib/serializer/{SerializerVersion.h => ESerializationVersion.h} (53%) diff --git a/cmake_modules/VCMI_lib.cmake b/cmake_modules/VCMI_lib.cmake index ff5ab40ab..39b8044f5 100644 --- a/cmake_modules/VCMI_lib.cmake +++ b/cmake_modules/VCMI_lib.cmake @@ -557,7 +557,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE) ${MAIN_LIB_DIR}/serializer/JsonSerializer.h ${MAIN_LIB_DIR}/serializer/JsonUpdater.h ${MAIN_LIB_DIR}/serializer/Cast.h - ${MAIN_LIB_DIR}/serializer/SerializerVersion.h + ${MAIN_LIB_DIR}/serializer/ESerializationVersion.h ${MAIN_LIB_DIR}/spells/AbilityCaster.h ${MAIN_LIB_DIR}/spells/AdventureSpellMechanics.h diff --git a/lib/serializer/BinaryDeserializer.h b/lib/serializer/BinaryDeserializer.h index c4ddc49c6..b34addee5 100644 --- a/lib/serializer/BinaryDeserializer.h +++ b/lib/serializer/BinaryDeserializer.h @@ -11,7 +11,7 @@ #include "CSerializer.h" #include "CTypeList.h" -#include "SerializerVersion.h" +#include "ESerializationVersion.h" #include "../mapObjects/CGHeroInstance.h" VCMI_LIB_NAMESPACE_BEGIN diff --git a/lib/serializer/BinarySerializer.h b/lib/serializer/BinarySerializer.h index 36c0922f2..9f465e539 100644 --- a/lib/serializer/BinarySerializer.h +++ b/lib/serializer/BinarySerializer.h @@ -11,7 +11,7 @@ #include "CSerializer.h" #include "CTypeList.h" -#include "SerializerVersion.h" +#include "ESerializationVersion.h" #include "../mapObjects/CArmedInstance.h" VCMI_LIB_NAMESPACE_BEGIN diff --git a/lib/serializer/CLoadFile.h b/lib/serializer/CLoadFile.h index 00b5264b8..405c1f99c 100644 --- a/lib/serializer/CLoadFile.h +++ b/lib/serializer/CLoadFile.h @@ -10,7 +10,6 @@ #pragma once #include "BinaryDeserializer.h" -#include "SerializerVersion.h" VCMI_LIB_NAMESPACE_BEGIN diff --git a/lib/serializer/CSerializer.h b/lib/serializer/CSerializer.h index 491ad80cb..6907c2008 100644 --- a/lib/serializer/CSerializer.h +++ b/lib/serializer/CSerializer.h @@ -136,9 +136,9 @@ struct is_serializeable using No = char (&)[2]; template - static Yes test(U * data, S* arg1 = 0, typename std::enable_if_tserialize(*arg1))>> * = 0); + static Yes test(U * data, S* arg1 = nullptr, typename std::enable_if_tserialize(*arg1))>> * = nullptr); static No test(...); - static const bool value = sizeof(Yes) == sizeof(is_serializeable::test((typename std::remove_reference::type>::type*)0)); + static const bool value = sizeof(Yes) == sizeof(is_serializeable::test((typename std::remove_reference::type>::type*)nullptr)); }; template //metafunction returning CGObjectInstance if T is its derivate or T elsewise diff --git a/lib/serializer/SerializerVersion.h b/lib/serializer/ESerializationVersion.h similarity index 53% rename from lib/serializer/SerializerVersion.h rename to lib/serializer/ESerializationVersion.h index 1be8194e3..bcbd1e77c 100644 --- a/lib/serializer/SerializerVersion.h +++ b/lib/serializer/ESerializationVersion.h @@ -9,18 +9,18 @@ */ #pragma once -/// This is enumeration that controls save compatibility support -/// - 'MINIMAL' represents older supported version counter. Save can be loaded if its version is at least 'MINIMAL' -/// - 'CURRENT' represent current save version. All saves are created using 'CURRENT' version +/// This enumeration controls save compatibility support. +/// - 'MINIMAL' represents the oldest supported version counter. A saved game can be loaded if its version is at least 'MINIMAL'. +/// - 'CURRENT' represents the current save version. Saved games are created using the 'CURRENT' version. /// -/// To add save-breaking change: -/// - change 'MINIMAL' to value higher than CURRENT -/// - remove all version enumerations inbetween +/// To make a save-breaking change: +/// - change 'MINIMAL' to a value higher than 'CURRENT' +/// - remove all keys in enumeration between 'MINIMAL' and 'CURRENT' as well as all their usage (will be detected by compiler) /// - change 'CURRENT' to 'CURRENT = MINIMAL' /// -/// To add non-breaking change: +/// To make a non-breaking change: /// - add new enumeration value before 'CURRENT' -/// - change 'CURRENT' to 'CURRENT = NEW_TEST_KEY' +/// - change 'CURRENT' to 'CURRENT = NEW_TEST_KEY'. /// /// To check for version in serialize() call use form /// if (h.version >= Handler::Version::NEW_TEST_KEY) @@ -32,7 +32,7 @@ enum class ESerializationVersion : int32_t NONE = 0, MINIMAL = 831, - RELEASE_143, // 832 + text container in campaigns, +starting hero in RMG options + RELEASE_143, // 832 +text container in campaigns, +starting hero in RMG options HAS_EXTRA_OPTIONS, // 833 +extra options struct as part of startinfo CURRENT = HAS_EXTRA_OPTIONS From cb297793e038402e4e0c0a8523c427b27971c583 Mon Sep 17 00:00:00 2001 From: Andrii Danylchenko Date: Sat, 20 Jan 2024 23:31:57 +0200 Subject: [PATCH 26/54] NKAI: fix lock --- AI/Nullkiller/AIGateway.cpp | 2 +- AI/Nullkiller/Pathfinding/AINodeStorage.h | 4 ++-- .../Pathfinding/Actions/AdventureSpellCastMovementActions.cpp | 4 ++-- AI/Nullkiller/Pathfinding/Rules/AILayerTransitionRule.cpp | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/AI/Nullkiller/AIGateway.cpp b/AI/Nullkiller/AIGateway.cpp index aaad0611f..e86e1f320 100644 --- a/AI/Nullkiller/AIGateway.cpp +++ b/AI/Nullkiller/AIGateway.cpp @@ -669,7 +669,7 @@ void AIGateway::showBlockingDialog(const std::string & text, const std::vector(nullkiller->aiStateMutex); + std::unique_lock mxLock(nullkiller->aiStateMutex); // TODO: Find better way to understand it is Chest of Treasures if(hero.validAndSet() diff --git a/AI/Nullkiller/Pathfinding/AINodeStorage.h b/AI/Nullkiller/Pathfinding/AINodeStorage.h index 395e2b3a2..b1d4dbf00 100644 --- a/AI/Nullkiller/Pathfinding/AINodeStorage.h +++ b/AI/Nullkiller/Pathfinding/AINodeStorage.h @@ -44,8 +44,8 @@ namespace AIPathfinding enum DayFlags : ui8 { NONE = 0, - FLY_CASTED = 1, - WATER_WALK_CASTED = 2 + FLY_CAST = 1, + WATER_WALK_CAST = 2 }; struct AIPathNode : public CGPathNode diff --git a/AI/Nullkiller/Pathfinding/Actions/AdventureSpellCastMovementActions.cpp b/AI/Nullkiller/Pathfinding/Actions/AdventureSpellCastMovementActions.cpp index d5cb01397..4da806986 100644 --- a/AI/Nullkiller/Pathfinding/Actions/AdventureSpellCastMovementActions.cpp +++ b/AI/Nullkiller/Pathfinding/Actions/AdventureSpellCastMovementActions.cpp @@ -29,11 +29,11 @@ namespace AIPathfinding } WaterWalkingAction::WaterWalkingAction(const CGHeroInstance * hero) - :AdventureCastAction(SpellID::WATER_WALK, hero, DayFlags::WATER_WALK_CASTED) + :AdventureCastAction(SpellID::WATER_WALK, hero, DayFlags::WATER_WALK_CAST) { } AirWalkingAction::AirWalkingAction(const CGHeroInstance * hero) - : AdventureCastAction(SpellID::FLY, hero, DayFlags::FLY_CASTED) + : AdventureCastAction(SpellID::FLY, hero, DayFlags::FLY_CAST) { } diff --git a/AI/Nullkiller/Pathfinding/Rules/AILayerTransitionRule.cpp b/AI/Nullkiller/Pathfinding/Rules/AILayerTransitionRule.cpp index 9d5350d16..a43f8f04e 100644 --- a/AI/Nullkiller/Pathfinding/Rules/AILayerTransitionRule.cpp +++ b/AI/Nullkiller/Pathfinding/Rules/AILayerTransitionRule.cpp @@ -61,7 +61,7 @@ namespace AIPathfinding if(source.node->layer == EPathfindingLayer::LAND && destination.node->layer == EPathfindingLayer::WATER) { - if(nodeStorage->getAINode(source.node)->dayFlags & DayFlags::WATER_WALK_CASTED) + if(nodeStorage->getAINode(source.node)->dayFlags & DayFlags::WATER_WALK_CAST) { destination.blocked = false; return; @@ -79,7 +79,7 @@ namespace AIPathfinding if(source.node->layer == EPathfindingLayer::LAND && destination.node->layer == EPathfindingLayer::AIR) { - if(nodeStorage->getAINode(source.node)->dayFlags & DayFlags::FLY_CASTED) + if(nodeStorage->getAINode(source.node)->dayFlags & DayFlags::FLY_CAST) { destination.blocked = false; return; From 708e0d11072f0ef88882e9df69314b96354b2cc9 Mon Sep 17 00:00:00 2001 From: Andrii Danylchenko Date: Sat, 20 Jan 2024 23:12:00 +0200 Subject: [PATCH 27/54] NKAI: avoid writing to commited tiles when calculating hero chain --- AI/Nullkiller/Pathfinding/AINodeStorage.cpp | 19 +++++++++++++++---- AI/Nullkiller/Pathfinding/AINodeStorage.h | 3 ++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/AI/Nullkiller/Pathfinding/AINodeStorage.cpp b/AI/Nullkiller/Pathfinding/AINodeStorage.cpp index 7e029fe64..d4fe74c0f 100644 --- a/AI/Nullkiller/Pathfinding/AINodeStorage.cpp +++ b/AI/Nullkiller/Pathfinding/AINodeStorage.cpp @@ -35,6 +35,8 @@ const uint64_t MIN_ARMY_STRENGTH_FOR_CHAIN = 5000; const uint64_t MIN_ARMY_STRENGTH_FOR_NEXT_ACTOR = 1000; const uint64_t CHAIN_MAX_DEPTH = 4; +const bool DO_NOT_SAVE_TO_COMMITED_TILES = false; + AISharedStorage::AISharedStorage(int3 sizes) { if(!shared){ @@ -265,7 +267,8 @@ void AINodeStorage::commit( EPathNodeAction action, int turn, int movementLeft, - float cost) const + float cost, + bool saveToCommited) const { destination->action = action; destination->setCost(cost); @@ -291,7 +294,7 @@ void AINodeStorage::commit( destination->actor->armyValue); #endif - if(destination->turns <= heroChainTurn) + if(saveToCommited && destination->turns <= heroChainTurn) { commitedTiles.insert(destination->coord); } @@ -778,7 +781,14 @@ void HeroChainCalculationTask::addHeroChain(const std::vector continue; } - storage.commit(exchangeNode, carrier, carrier->action, chainInfo.turns, chainInfo.moveRemains, chainInfo.getCost()); + storage.commit( + exchangeNode, + carrier, + carrier->action, + chainInfo.turns, + chainInfo.moveRemains, + chainInfo.getCost(), + DO_NOT_SAVE_TO_COMMITED_TILES); if(carrier->specialAction || carrier->chainOther) { @@ -1070,7 +1080,8 @@ struct TowmPortalFinder EPathNodeAction::TELEPORT_NORMAL, bestNode->turns, bestNode->moveRemains - movementNeeded, - movementCost); + movementCost, + DO_NOT_SAVE_TO_COMMITED_TILES); node->theNodeBefore = bestNode; node->addSpecialAction(std::make_shared(targetTown)); diff --git a/AI/Nullkiller/Pathfinding/AINodeStorage.h b/AI/Nullkiller/Pathfinding/AINodeStorage.h index 068304955..48e6074d1 100644 --- a/AI/Nullkiller/Pathfinding/AINodeStorage.h +++ b/AI/Nullkiller/Pathfinding/AINodeStorage.h @@ -200,7 +200,8 @@ public: EPathNodeAction action, int turn, int movementLeft, - float cost) const; + float cost, + bool saveToCommited = true) const; inline const AIPathNode * getAINode(const CGPathNode * node) const { From 0a4b5dbe100ac56db9073526d9ed48bcab8e9e51 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sun, 21 Jan 2024 18:12:46 +0100 Subject: [PATCH 28/54] code review --- client/lobby/OptionsTabBase.cpp | 4 ++-- client/windows/GUIClasses.cpp | 32 ++++++++++++------------- config/gameConfig.json | 2 +- lib/GameSettings.cpp | 2 +- lib/GameSettings.h | 2 +- server/processors/HeroPoolProcessor.cpp | 13 +++++----- 6 files changed, 28 insertions(+), 27 deletions(-) diff --git a/client/lobby/OptionsTabBase.cpp b/client/lobby/OptionsTabBase.cpp index aa1b97c9a..a89943dc8 100644 --- a/client/lobby/OptionsTabBase.cpp +++ b/client/lobby/OptionsTabBase.cpp @@ -409,12 +409,12 @@ void OptionsTabBase::recreate() if(auto buttonCheatAllowed = widget("buttonCheatAllowed")) { buttonCheatAllowed->setSelectedSilent(SEL->getStartInfo()->extraOptionsInfo.cheatsAllowed); - buttonCheatAllowed->setInputEnabled(SEL->screenType != ESelectionScreen::loadGame); + buttonCheatAllowed->block(SEL->screenType == ESelectionScreen::loadGame); } if(auto buttonUnlimitedReplay = widget("buttonUnlimitedReplay")) { buttonUnlimitedReplay->setSelectedSilent(SEL->getStartInfo()->extraOptionsInfo.unlimitedReplay); - buttonUnlimitedReplay->setInputEnabled(SEL->screenType != ESelectionScreen::loadGame); + buttonUnlimitedReplay->block(SEL->screenType == ESelectionScreen::loadGame); } } diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 3a10c2870..962a1828b 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -519,25 +519,25 @@ void CTavernWindow::addInvite() { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - if(VLC->settings()->getBoolean(EGameSettings::HEROES_INVITE)) + if(!VLC->settings()->getBoolean(EGameSettings::HEROES_TAVERN_INVITE)) + return; + + const auto & heroesPool = CSH->client->gameState()->heroesPool; + for(auto & elem : heroesPool->unusedHeroesFromPool()) { - const auto & heroesPool = CSH->client->gameState()->heroesPool; - for(auto & elem : heroesPool->unusedHeroesFromPool()) - { - bool heroAvailable = heroesPool->isHeroAvailableFor(elem.first, tavernObj->getOwner()); - if(heroAvailable) - inviteableHeroes[elem.first] = elem.second; - } + bool heroAvailable = heroesPool->isHeroAvailableFor(elem.first, tavernObj->getOwner()); + if(heroAvailable) + inviteableHeroes[elem.first] = elem.second; + } - if(inviteableHeroes.size() > 0) - { - if(!heroToInvite) - heroToInvite = (*RandomGeneratorUtil::nextItem(inviteableHeroes, CRandomGenerator::getDefault())).second; + if(inviteableHeroes.size() > 0) + { + if(!heroToInvite) + heroToInvite = (*RandomGeneratorUtil::nextItem(inviteableHeroes, CRandomGenerator::getDefault())).second; - inviteHero = std::make_shared(170, 444, EFonts::FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->translate("vcmi.tavernWindow.inviteHero")); - inviteHeroImage = std::make_shared(AnimationPath::builtin("PortraitsSmall"), (*CGI->heroh)[heroToInvite->getHeroType()]->imageIndex, 0, 245, 428); - inviteHeroImageArea = std::make_shared(Rect(245, 428, 48, 32), [&](){ GH.windows().createAndPushWindow(inviteableHeroes, [&](CGHeroInstance* h){ heroToInvite = h; addInvite(); }); }, [&](){ GH.windows().createAndPushWindow(std::make_shared(heroToInvite)); }); - } + inviteHero = std::make_shared(170, 444, EFonts::FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->translate("vcmi.tavernWindow.inviteHero")); + inviteHeroImage = std::make_shared(AnimationPath::builtin("PortraitsSmall"), (*CGI->heroh)[heroToInvite->getHeroType()]->imageIndex, 0, 245, 428); + inviteHeroImageArea = std::make_shared(Rect(245, 428, 48, 32), [&](){ GH.windows().createAndPushWindow(inviteableHeroes, [&](CGHeroInstance* h){ heroToInvite = h; addInvite(); }); }, [&](){ GH.windows().createAndPushWindow(std::make_shared(heroToInvite)); }); } } diff --git a/config/gameConfig.json b/config/gameConfig.json index 24e3c4580..b7d7bcd91 100644 --- a/config/gameConfig.json +++ b/config/gameConfig.json @@ -291,7 +291,7 @@ // number of artifacts that can fit in a backpack. -1 is unlimited. "backpackSize" : -1, // if heroes are invitable in tavern - "invite" : false + "tavernInvite" : false }, "towns": diff --git a/lib/GameSettings.cpp b/lib/GameSettings.cpp index 248300fea..1996fb62b 100644 --- a/lib/GameSettings.cpp +++ b/lib/GameSettings.cpp @@ -74,7 +74,7 @@ void GameSettings::load(const JsonNode & input) {EGameSettings::HEROES_RETREAT_ON_WIN_WITHOUT_TROOPS, "heroes", "retreatOnWinWithoutTroops" }, {EGameSettings::HEROES_STARTING_STACKS_CHANCES, "heroes", "startingStackChances" }, {EGameSettings::HEROES_BACKPACK_CAP, "heroes", "backpackSize" }, - {EGameSettings::HEROES_INVITE, "heroes", "invite" }, + {EGameSettings::HEROES_TAVERN_INVITE, "heroes", "tavernInvite" }, {EGameSettings::MAP_FORMAT_RESTORATION_OF_ERATHIA, "mapFormat", "restorationOfErathia" }, {EGameSettings::MAP_FORMAT_ARMAGEDDONS_BLADE, "mapFormat", "armageddonsBlade" }, {EGameSettings::MAP_FORMAT_SHADOW_OF_DEATH, "mapFormat", "shadowOfDeath" }, diff --git a/lib/GameSettings.h b/lib/GameSettings.h index a33581320..e1b76ef54 100644 --- a/lib/GameSettings.h +++ b/lib/GameSettings.h @@ -38,7 +38,7 @@ enum class EGameSettings HEROES_RETREAT_ON_WIN_WITHOUT_TROOPS, HEROES_STARTING_STACKS_CHANCES, HEROES_BACKPACK_CAP, - HEROES_INVITE, + HEROES_TAVERN_INVITE, MARKETS_BLACK_MARKET_RESTOCK_PERIOD, BANKS_SHOW_GUARDS_COMPOSITION, MODULE_COMMANDERS, diff --git a/server/processors/HeroPoolProcessor.cpp b/server/processors/HeroPoolProcessor.cpp index 789775804..bdc2b21c1 100644 --- a/server/processors/HeroPoolProcessor.cpp +++ b/server/processors/HeroPoolProcessor.cpp @@ -112,11 +112,7 @@ void HeroPoolProcessor::selectNewHeroForSlot(const PlayerColor & color, TavernHe sah.slotID = slot; sah.replenishPoints = true; - CGHeroInstance *newHero = pickHeroFor(needNativeHero, color); - - const auto & heroesPool = gameHandler->gameState()->heroesPool; - if(VLC->settings()->getBoolean(EGameSettings::HEROES_INVITE) && heroesPool->unusedHeroesFromPool().count(nextHero) && heroesPool->isHeroAvailableFor(nextHero, color)) - newHero = heroesPool->unusedHeroesFromPool()[nextHero]; + CGHeroInstance *newHero = (nextHero == HeroTypeID::NONE) ? pickHeroFor(needNativeHero, color) : gameHandler->gameState()->heroesPool->unusedHeroesFromPool()[nextHero]; if (newHero) { @@ -155,6 +151,7 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy const PlayerState * playerState = gameHandler->getPlayerState(player); const CGObjectInstance * mapObject = gameHandler->getObj(objectID); const CGTownInstance * town = gameHandler->getTown(objectID); + const auto & heroesPool = gameHandler->gameState()->heroesPool; if (!mapObject && gameHandler->complain("Invalid map object!")) return false; @@ -171,6 +168,10 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy if (gameHandler->getHeroCount(player, true) >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_TOTAL_CAP) && gameHandler->complain("Cannot hire hero, too many heroes garrizoned and wandering already!")) return false; + if(VLC->settings()->getBoolean(EGameSettings::HEROES_TAVERN_INVITE) && nextHero != HeroTypeID::NONE) + if(!heroesPool->unusedHeroesFromPool().count(nextHero) && !heroesPool->isHeroAvailableFor(nextHero, player) && gameHandler->complain("Cannot set next hero!")) + return false; + if(town) //tavern in town { if(gameHandler->getPlayerRelations(mapObject->tempOwner, player) == PlayerRelations::ENEMIES && gameHandler->complain("Can't buy hero in enemy town!")) @@ -197,7 +198,7 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy return false; } - auto recruitableHeroes = gameHandler->gameState()->heroesPool->getHeroesFor(player); + auto recruitableHeroes = heroesPool->getHeroesFor(player); const CGHeroInstance * recruitedHero = nullptr; From dd004f0f6e82fc0c2c239b4cb801ebf3856380e1 Mon Sep 17 00:00:00 2001 From: godric3 Date: Sun, 21 Jan 2024 21:07:06 +0100 Subject: [PATCH 29/54] Fix inspector using wrong editor for some values --- mapeditor/inspector/inspector.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/mapeditor/inspector/inspector.h b/mapeditor/inspector/inspector.h index 432e40ab0..94c2b80c2 100644 --- a/mapeditor/inspector/inspector.h +++ b/mapeditor/inspector/inspector.h @@ -128,7 +128,6 @@ protected: { itemKey = keyItems[key]; table->setItem(table->row(itemKey), 1, itemValue); - if(delegate) table->setItemDelegateForRow(table->row(itemKey), delegate); } else @@ -139,7 +138,6 @@ protected: table->setRowCount(row + 1); table->setItem(row, 0, itemKey); table->setItem(row, 1, itemValue); - if(delegate) table->setItemDelegateForRow(row, delegate); ++row; } From b3adb9e5545f22fdb2113e94a113ad137b0d5083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zieli=C5=84ski?= Date: Mon, 22 Jan 2024 09:27:30 +0100 Subject: [PATCH 30/54] Do not place zone guards adjacent to 3rd zone --- lib/rmg/modificators/ConnectionsPlacer.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/rmg/modificators/ConnectionsPlacer.cpp b/lib/rmg/modificators/ConnectionsPlacer.cpp index d2c1ddada..89689c932 100644 --- a/lib/rmg/modificators/ConnectionsPlacer.cpp +++ b/lib/rmg/modificators/ConnectionsPlacer.cpp @@ -177,6 +177,21 @@ void ConnectionsPlacer::selfSideDirectConnection(const rmg::ZoneConnection & con int3 potentialPos = zone.areaPossible().nearest(borderPos); assert(borderPos != potentialPos); + //Check if guard pos doesn't touch any 3rd zone. This would create unwanted passage to 3rd zone + bool adjacentZone = false; + map.foreach_neighbour(potentialPos, [this, &adjacentZone, otherZoneId](int3 & pos) + { + auto zoneId = map.getZoneID(pos); + if (zoneId != zone.getId() && zoneId != otherZoneId) + { + adjacentZone = true; + } + }); + if (adjacentZone) + { + continue; + } + //Take into account distance to objects from both sides float dist = std::min(map.getTileInfo(potentialPos).getNearestObjectDistance(), map.getTileInfo(borderPos).getNearestObjectDistance()); From 9b2908d46457761443258c05de12143527a56994 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Mon, 22 Jan 2024 20:19:49 +0100 Subject: [PATCH 31/54] Apply suggestions from code review Co-authored-by: Ivan Savenko --- client/windows/GUIClasses.cpp | 10 +++++----- server/processors/HeroPoolProcessor.cpp | 11 +++++++++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 962a1828b..153edd8b4 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -463,8 +463,8 @@ CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj, const std::func oldSelected = -1; - h1 = std::make_shared(selected, 0, 72, 299, h[0], [&]() { if(!recruit->isBlocked()) recruitb(); }); - h2 = std::make_shared(selected, 1, 162, 299, h[1], [&]() { if(!recruit->isBlocked()) recruitb(); }); + h1 = std::make_shared(selected, 0, 72, 299, h[0], [this]() { if(!recruit->isBlocked()) recruitb(); }); + h2 = std::make_shared(selected, 1, 162, 299, h[1], [this]() { if(!recruit->isBlocked()) recruitb(); }); title = std::make_shared(197, 32, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[37]); cost = std::make_shared(320, 328, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, std::to_string(GameConstants::HERO_GOLD_COST)); @@ -530,14 +530,14 @@ void CTavernWindow::addInvite() inviteableHeroes[elem.first] = elem.second; } - if(inviteableHeroes.size() > 0) + if(!inviteableHeroes.empty()) { if(!heroToInvite) heroToInvite = (*RandomGeneratorUtil::nextItem(inviteableHeroes, CRandomGenerator::getDefault())).second; inviteHero = std::make_shared(170, 444, EFonts::FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->translate("vcmi.tavernWindow.inviteHero")); inviteHeroImage = std::make_shared(AnimationPath::builtin("PortraitsSmall"), (*CGI->heroh)[heroToInvite->getHeroType()]->imageIndex, 0, 245, 428); - inviteHeroImageArea = std::make_shared(Rect(245, 428, 48, 32), [&](){ GH.windows().createAndPushWindow(inviteableHeroes, [&](CGHeroInstance* h){ heroToInvite = h; addInvite(); }); }, [&](){ GH.windows().createAndPushWindow(std::make_shared(heroToInvite)); }); + inviteHeroImageArea = std::make_shared(Rect(245, 428, 48, 32), [&](){ GH.windows().createAndPushWindow(inviteableHeroes, [this](CGHeroInstance* h){ heroToInvite = h; addInvite(); }); }, [this](){ GH.windows().createAndPushWindow(std::make_shared(heroToInvite)); }); } } @@ -667,7 +667,7 @@ CTavernWindow::HeroSelector::HeroSelector(std::map for(auto & h : inviteableHeroes) { portraits.push_back(std::make_shared(AnimationPath::builtin("PortraitsSmall"), (*CGI->heroh)[h.first]->imageIndex, 0, x * 48, y * 32)); - portraitAreas.push_back(std::make_shared(Rect(x * 48, y * 32, 48, 32), [&](){ close(); onChoose(inviteableHeroes[h.first]); }, [&](){ GH.windows().createAndPushWindow(std::make_shared(inviteableHeroes[h.first])); })); + portraitAreas.push_back(std::make_shared(Rect(x * 48, y * 32, 48, 32), [this](){ close(); onChoose(inviteableHeroes[h.first]); }, [this](){ GH.windows().createAndPushWindow(std::make_shared(inviteableHeroes[h.first])); })); if(x > 0 && x % 15 == 0) { diff --git a/server/processors/HeroPoolProcessor.cpp b/server/processors/HeroPoolProcessor.cpp index bdc2b21c1..65b7acd46 100644 --- a/server/processors/HeroPoolProcessor.cpp +++ b/server/processors/HeroPoolProcessor.cpp @@ -168,8 +168,15 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy if (gameHandler->getHeroCount(player, true) >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_TOTAL_CAP) && gameHandler->complain("Cannot hire hero, too many heroes garrizoned and wandering already!")) return false; - if(VLC->settings()->getBoolean(EGameSettings::HEROES_TAVERN_INVITE) && nextHero != HeroTypeID::NONE) - if(!heroesPool->unusedHeroesFromPool().count(nextHero) && !heroesPool->isHeroAvailableFor(nextHero, player) && gameHandler->complain("Cannot set next hero!")) + if (nextHero != HeroTypeID::NONE) // player attempts to invite next hero + { + if(!VLC->settings()->getBoolean(EGameSettings::HEROES_TAVERN_INVITE) && gameHandler->complain("Inviting heroes not allowed!")) + return false; + + if(!heroesPool->unusedHeroesFromPool().count(nextHero) && gameHandler->complain("Cannot invite specified hero!")) + return false; + + if(!heroesPool->isHeroAvailableFor(nextHero, player) && gameHandler->complain("Cannot invite specified hero!")) return false; if(town) //tavern in town From 7857673ca93feb67ba94a2e4dbda760369ebc895 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Mon, 22 Jan 2024 20:22:15 +0100 Subject: [PATCH 32/54] missing bracket --- server/processors/HeroPoolProcessor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/server/processors/HeroPoolProcessor.cpp b/server/processors/HeroPoolProcessor.cpp index 65b7acd46..d6bb4e104 100644 --- a/server/processors/HeroPoolProcessor.cpp +++ b/server/processors/HeroPoolProcessor.cpp @@ -178,6 +178,7 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy if(!heroesPool->isHeroAvailableFor(nextHero, player) && gameHandler->complain("Cannot invite specified hero!")) return false; + } if(town) //tavern in town { From 6a42494b125f6d1888b2c8d46ec36e4623c2bdf6 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 22 Jan 2024 21:48:03 +0200 Subject: [PATCH 33/54] Merge CKeyboardFocusListener and IFocusListener into CFocusable --- client/widgets/TextControls.cpp | 33 +++++++++--------------------- client/widgets/TextControls.h | 36 ++++++--------------------------- 2 files changed, 16 insertions(+), 53 deletions(-) diff --git a/client/widgets/TextControls.cpp b/client/widgets/TextControls.cpp index 344d20757..6fbab6605 100644 --- a/client/widgets/TextControls.cpp +++ b/client/widgets/TextControls.cpp @@ -553,8 +553,7 @@ Point CGStatusBar::getBorderSize() CTextInput::CTextInput(const Rect & Pos, EFonts font, const CFunctionList & CB, bool giveFocusToInput) : CLabel(Pos.x, Pos.y, font, ETextAlignment::CENTER), - cb(CB), - CFocusable(std::make_shared(this)) + cb(CB) { setRedrawParent(true); pos.h = Pos.h; @@ -570,7 +569,7 @@ CTextInput::CTextInput(const Rect & Pos, EFonts font, const CFunctionList & CB) - :cb(CB), CFocusable(std::make_shared(this)) + :cb(CB) { pos += Pos.topLeft(); pos.h = Pos.h; @@ -587,7 +586,6 @@ CTextInput::CTextInput(const Rect & Pos, const Point & bgOffset, const ImagePath } CTextInput::CTextInput(const Rect & Pos, std::shared_ptr srf) - :CFocusable(std::make_shared(this)) { pos += Pos.topLeft(); OBJ_CONSTRUCTION; @@ -603,20 +601,15 @@ CTextInput::CTextInput(const Rect & Pos, std::shared_ptr srf) #endif } -std::atomic CKeyboardFocusListener::usageIndex(0); +std::atomic CFocusable::usageIndex(0); -CKeyboardFocusListener::CKeyboardFocusListener(CTextInput * textInput) - :textInput(textInput) +void CFocusable::focusGot() { -} - -void CKeyboardFocusListener::focusGot() -{ - GH.startTextInput(textInput->pos); + GH.startTextInput(pos); usageIndex++; } -void CKeyboardFocusListener::focusLost() +void CFocusable::focusLost() { if(0 == --usageIndex) { @@ -769,12 +762,6 @@ void CTextInput::numberFilter(std::string & text, const std::string & oldText, i } CFocusable::CFocusable() - :CFocusable(std::make_shared()) -{ -} - -CFocusable::CFocusable(std::shared_ptr focusListener) - : focusListener(focusListener) { focus = false; focusables.push_back(this); @@ -785,7 +772,7 @@ CFocusable::~CFocusable() if(hasFocus()) { inputWithFocus = nullptr; - focusListener->focusLost(); + focusLost(); } focusables -= this; @@ -799,13 +786,13 @@ bool CFocusable::hasFocus() const void CFocusable::giveFocus() { focus = true; - focusListener->focusGot(); + focusGot(); redraw(); if(inputWithFocus) { inputWithFocus->focus = false; - inputWithFocus->focusListener->focusLost(); + inputWithFocus->focusLost(); inputWithFocus->redraw(); } @@ -837,7 +824,7 @@ void CFocusable::removeFocus() if(this == inputWithFocus) { focus = false; - focusListener->focusLost(); + focusLost(); redraw(); inputWithFocus = nullptr; diff --git a/client/widgets/TextControls.h b/client/widgets/TextControls.h index 7c6b5266b..d922d0f87 100644 --- a/client/widgets/TextControls.h +++ b/client/widgets/TextControls.h @@ -163,25 +163,12 @@ public: void clear() override; void setEnteringMode(bool on) override; void setEnteredText(const std::string & text) override; - -}; - -class CFocusable; - -class IFocusListener -{ -public: - virtual void focusGot() {}; - virtual void focusLost() {}; - virtual ~IFocusListener() = default; }; /// UIElement which can get input focus class CFocusable : public virtual CIntObject { -private: - std::shared_ptr focusListener; - + static std::atomic usageIndex; public: bool focus; //only one focusable control can have focus at one moment @@ -190,38 +177,27 @@ public: void removeFocus(); //remove focus bool hasFocus() const; + void focusGot(); + void focusLost(); + static std::list focusables; //all existing objs static CFocusable * inputWithFocus; //who has focus now CFocusable(); - CFocusable(std::shared_ptr focusListener); ~CFocusable(); }; -class CTextInput; -class CKeyboardFocusListener : public IFocusListener -{ -private: - static std::atomic usageIndex; - CTextInput * textInput; - -public: - CKeyboardFocusListener(CTextInput * textInput); - void focusGot() override; - void focusLost() override; -}; - /// Text input box where players can enter text class CTextInput : public CLabel, public CFocusable { std::string newText; std::string helpBox; //for right-click help - + protected: std::string visibleText() override; public: - + CFunctionList cb; CFunctionList filters; void setText(const std::string & nText) override; From 7d1553bc298ce87147faeac3166c9411962bf7b2 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Mon, 22 Jan 2024 20:56:35 +0100 Subject: [PATCH 34/54] fix build --- client/windows/GUIClasses.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 153edd8b4..4298719cb 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -667,7 +667,7 @@ CTavernWindow::HeroSelector::HeroSelector(std::map for(auto & h : inviteableHeroes) { portraits.push_back(std::make_shared(AnimationPath::builtin("PortraitsSmall"), (*CGI->heroh)[h.first]->imageIndex, 0, x * 48, y * 32)); - portraitAreas.push_back(std::make_shared(Rect(x * 48, y * 32, 48, 32), [this](){ close(); onChoose(inviteableHeroes[h.first]); }, [this](){ GH.windows().createAndPushWindow(std::make_shared(inviteableHeroes[h.first])); })); + portraitAreas.push_back(std::make_shared(Rect(x * 48, y * 32, 48, 32), [this, h](){ close(); onChoose(inviteableHeroes[h.first]); }, [this, h](){ GH.windows().createAndPushWindow(std::make_shared(inviteableHeroes[h.first])); })); if(x > 0 && x % 15 == 0) { From ea439ad17580a0c639621f7fbc337f0d395ce505 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 22 Jan 2024 22:19:52 +0200 Subject: [PATCH 35/54] Dispatch text input SDL calls in main thread on all platforms --- client/eventsSDL/InputSourceText.cpp | 43 +++++++++------------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/client/eventsSDL/InputSourceText.cpp b/client/eventsSDL/InputSourceText.cpp index 72afc978d..96edf5fe1 100644 --- a/client/eventsSDL/InputSourceText.cpp +++ b/client/eventsSDL/InputSourceText.cpp @@ -21,10 +21,6 @@ #include -#ifdef VCMI_APPLE -# include -#endif - void InputSourceText::handleEventTextInput(const SDL_TextInputEvent & text) { GH.events().dispatchTextInput(text.text); @@ -37,38 +33,27 @@ void InputSourceText::handleEventTextEditing(const SDL_TextEditingEvent & text) void InputSourceText::startTextInput(const Rect & whereInput) { - -#ifdef VCMI_APPLE - dispatch_async(dispatch_get_main_queue(), ^{ -#endif - - Rect rectInScreenCoordinates = GH.screenHandler().convertLogicalPointsToWindow(whereInput); - SDL_Rect textInputRect = CSDL_Ext::toSDL(rectInScreenCoordinates); - - SDL_SetTextInputRect(&textInputRect); - - if (SDL_IsTextInputActive() == SDL_FALSE) + GH.dispatchMainThread([whereInput]() { - SDL_StartTextInput(); - } + Rect rectInScreenCoordinates = GH.screenHandler().convertLogicalPointsToWindow(whereInput); + SDL_Rect textInputRect = CSDL_Ext::toSDL(rectInScreenCoordinates); -#ifdef VCMI_APPLE + SDL_SetTextInputRect(&textInputRect); + + if (SDL_IsTextInputActive() == SDL_FALSE) + { + SDL_StartTextInput(); + } }); -#endif } void InputSourceText::stopTextInput() { -#ifdef VCMI_APPLE - dispatch_async(dispatch_get_main_queue(), ^{ -#endif - - if (SDL_IsTextInputActive() == SDL_TRUE) + GH.dispatchMainThread([]() { - SDL_StopTextInput(); - } - -#ifdef VCMI_APPLE + if (SDL_IsTextInputActive() == SDL_TRUE) + { + SDL_StopTextInput(); + } }); -#endif } From f83a004b54c097d901bcc1b1e26a13749a26ed34 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 23 Jan 2024 00:49:18 +0200 Subject: [PATCH 36/54] Added workaround to prevent multithreaded access to bonus system in RMG --- lib/bonuses/CBonusSystemNode.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/bonuses/CBonusSystemNode.cpp b/lib/bonuses/CBonusSystemNode.cpp index 8306e3ae1..92634975d 100644 --- a/lib/bonuses/CBonusSystemNode.cpp +++ b/lib/bonuses/CBonusSystemNode.cpp @@ -273,6 +273,10 @@ CBonusSystemNode::~CBonusSystemNode() void CBonusSystemNode::attachTo(CBonusSystemNode & parent) { + // quick workaround to prevent multithreaded access to bonus system in RMG + static boost::mutex attachMutex; + boost::lock_guard lock(attachMutex); + assert(!vstd::contains(parents, &parent)); parents.push_back(&parent); @@ -646,4 +650,4 @@ int64_t CBonusSystemNode::getTreeVersion() const return treeChanged; } -VCMI_LIB_NAMESPACE_END \ No newline at end of file +VCMI_LIB_NAMESPACE_END From 81c333919907a96b8f5992319bebc128694e3fc3 Mon Sep 17 00:00:00 2001 From: Alexander Wilms Date: Mon, 22 Jan 2024 23:25:23 +0000 Subject: [PATCH 37/54] Add second workaround for CPack issue on macOS --- .github/workflows/github.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github.yml b/.github/workflows/github.yml index 0ea0ab0fc..1b9d9279a 100644 --- a/.github/workflows/github.yml +++ b/.github/workflows/github.yml @@ -268,6 +268,13 @@ jobs: run: | ctest --preset ${{matrix.preset}} + - name: Kill XProtect to work around CPack issue on macOS + if: runner.os == 'macOS' + run: | + # Cf. https://github.com/actions/runner-images/issues/7522#issuecomment-1556766641 + echo Killing...; sudo pkill -9 XProtect >/dev/null || true; + echo Waiting...; while pgrep XProtect; do sleep 3; done; + - name: Pack id: cpack if: ${{ matrix.pack == 1 }} @@ -279,7 +286,7 @@ jobs: && '${{github.workspace}}/CI/${{matrix.platform}}/post_pack.sh' '${{github.workspace}}' "$(ls '${{ env.VCMI_PACKAGE_FILE_NAME }}'.*)" rm -rf _CPack_Packages - - name: Create android package + - name: Create Android package if: ${{ startsWith(matrix.platform, 'android') }} run: | cd android @@ -414,7 +421,7 @@ jobs: name: Android JNI android-64 path: ${{ github.workspace }}/android/vcmi-app/src/main/jniLibs/ - - name: Create android package + - name: Create Android package run: | cd android ./gradlew bundleRelease --info From 334020b077f32ad8b4dbb39cba82bc31a1c79103 Mon Sep 17 00:00:00 2001 From: Asirome <66029412+macomarivas@users.noreply.github.com> Date: Tue, 23 Jan 2024 11:11:35 +0100 Subject: [PATCH 38/54] Updated spanish.ts translation --- launcher/translation/spanish.ts | 147 +++++++++++++++++--------------- 1 file changed, 80 insertions(+), 67 deletions(-) diff --git a/launcher/translation/spanish.ts b/launcher/translation/spanish.ts index ec1903015..2dd41b3a0 100644 --- a/launcher/translation/spanish.ts +++ b/launcher/translation/spanish.ts @@ -6,84 +6,84 @@ VCMI on Discord - VCMI en Discord + VCMI en Discord Have a question? Found a bug? Want to help? Join us! - ¿Tienes alguna pregunta? ¿Encontraste algún error? ¿Quieres ayudar? ¡Únete a nosotros! + ¿Tienes alguna pregunta? ¿Encontraste algún error? ¿Quieres ayudar? ¡Únete a nosotros! VCMI on Github - VCMI en Github + VCMI en Github Our Community - + Nuestra comunidad VCMI on Slack - VCMI en Slack + VCMI en Slack Build Information - + Información de la versión User data directory - Directorio de datos del usuario + Directorio de datos del usuario Open - Abrir + Abrir Check for updates - + Comprobar actualizaciones Game version - + Versión del juego Log files directory - Directorio de archivos de registro + Directorio de archivos de registro Data Directories - Directorios de datos + Directorios de datos Game data directory - + Directorio de los datos del juego Operating System - + Sistema operativo Project homepage - + Página web del proyecto Report a bug - + Informar de un error @@ -121,7 +121,7 @@ Maps - + Mapas @@ -180,7 +180,7 @@ Compatibility - Compatibilidad + Compatibilidad @@ -319,7 +319,7 @@ Size - + Tamaño @@ -410,12 +410,12 @@ Downloading %s%. %p% (%v MB out of %m MB) finished - + Descargando %s%. %p% (%v MB de %m MB) completado Download failed - + Descarga fallida @@ -424,30 +424,37 @@ Encountered errors: - + No se han podido descargar todos los ficheros. + +Errores encontrados: + + Install successfully downloaded? - + + +Instalar lo correctamente descargado? Installing mod %1 - + Instalando mod %1 Operation failed - + Operación fallida Encountered errors: - + Errores encontrados: + @@ -482,94 +489,94 @@ Install successfully downloaded? Interface Scaling - + Escala de la interfaz Neutral AI in battles - + IA neutral en batallas Enemy AI in battles - + IA enemiga en batallas Additional repository - + Repositorio adicional Adventure Map Allies - + Aliados en el Mapa de aventuras Adventure Map Enemies - + Enemigos en el Mapa de aventuras Windowed - + Ventana Borderless fullscreen - + Ventana completa sin bordes Exclusive fullscreen - + Pantalla completa Autosave limit (0 = off) - + Límite de autosaves (0 = sin límite) Friendly AI in battles - + IA amistosa en batallas Framerate Limit - + Límite de fotogramas Autosave prefix - + Prefijo autoguardado empty = map name prefix - + Vacio = prefijo del mapa Refresh now - + Actualizar Default repository - + Repositorio por defecto Renderer - + Render On - Encendido + Activado @@ -584,7 +591,7 @@ Install successfully downloaded? Reserved screen area - + Área de pantalla reservada @@ -614,7 +621,7 @@ Install successfully downloaded? VSync - + Sincronización vertical @@ -640,7 +647,13 @@ Windowed - game will run inside a window that covers part of your screen Borderless Windowed Mode - game will run in a window that covers entirely of your screen, using same resolution as your screen. Fullscreen Exclusive Mode - game will cover entirety of your screen and will use selected resolution. - + Selecciona el modo de visualización del juego + +En ventana - el juego se ejecutará dentro de una ventana que forma parte de tu pantalla. + +Ventana sin bordes - el juego se ejecutará en una ventana que cubre completamente tu pantalla, usando la misma resolución. + +Pantalla completa - el juego cubrirá la totalidad de la pantalla y utilizará la resolución seleccionada. @@ -698,27 +711,27 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use Form - + Formulario Users in lobby - + Usuarios en la sala Global chat - + Chat general type you message - + Escribe tu mensaje send - + Enviar @@ -792,12 +805,12 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use Interface Improvements - + Mejora de la interfaz Install mod that provides various interface improvements, such as better interface for random maps and selectable actions in battles - + Instalar mod que proporciona varias mejoras en la interfaz, como mejor interacción en los mapas aleatorios y más opciones en las batallas @@ -910,12 +923,12 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Heroes III installation found! - + Instalación de Heroes III encontrada! Copy data to VCMI folder? - + Copiar datos a la carpeta VCMI? @@ -931,7 +944,7 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Czech - + Czech (Checo) @@ -946,7 +959,7 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Finnish - + Finnish (Finlandés) @@ -961,12 +974,12 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Hungarian - + Hungarian (Húngaro) Italian - + Italian (Italiano) @@ -981,7 +994,7 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Portuguese - + Portuguese (Portugués) @@ -996,12 +1009,12 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Swedish - + Swedish (Sueco) Turkish - + Turkish (Turco) @@ -1011,7 +1024,7 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Vietnamese - + Vietnamese (Vietnamita) @@ -1021,12 +1034,12 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Other (Cyrillic Script) - + Otro (Escritura cirílica) Other (West European) - + Otro (Europa del Este) @@ -1161,7 +1174,7 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Help - + Ayuda From be47c66c575d2c312c4e2336864511f1335524aa Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 23 Jan 2024 12:57:38 +0200 Subject: [PATCH 39/54] Ignore hidden mods when checking mod dependencies --- launcher/modManager/cmodlist.cpp | 3 +++ launcher/modManager/cmodlistview_moc.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/launcher/modManager/cmodlist.cpp b/launcher/modManager/cmodlist.cpp index b36d4b198..6facca796 100644 --- a/launcher/modManager/cmodlist.cpp +++ b/launcher/modManager/cmodlist.cpp @@ -38,6 +38,9 @@ bool CModEntry::isEnabled() const if(!isInstalled()) return false; + if (!isVisible()) + return false; + return modSettings["active"].toBool(); } diff --git a/launcher/modManager/cmodlistview_moc.cpp b/launcher/modManager/cmodlistview_moc.cpp index f27573aef..556b7945b 100644 --- a/launcher/modManager/cmodlistview_moc.cpp +++ b/launcher/modManager/cmodlistview_moc.cpp @@ -521,7 +521,7 @@ QStringList CModListView::findDependentMods(QString mod, bool excludeDisabled) { auto current = modModel->getMod(modName); - if(!current.isInstalled()) + if(!current.isInstalled() || !current.isVisible()) continue; if(current.getDependencies().contains(mod, Qt::CaseInsensitive)) From 5836e390f1711c293b25420167723d17e4df9339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zieli=C5=84ski?= Date: Mon, 22 Jan 2024 09:27:30 +0100 Subject: [PATCH 40/54] Do not place zone guards adjacent to 3rd zone --- lib/rmg/modificators/ConnectionsPlacer.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/rmg/modificators/ConnectionsPlacer.cpp b/lib/rmg/modificators/ConnectionsPlacer.cpp index 73e9b5837..f765eeb00 100644 --- a/lib/rmg/modificators/ConnectionsPlacer.cpp +++ b/lib/rmg/modificators/ConnectionsPlacer.cpp @@ -177,6 +177,21 @@ void ConnectionsPlacer::selfSideDirectConnection(const rmg::ZoneConnection & con int3 potentialPos = zone.areaPossible().nearest(borderPos); assert(borderPos != potentialPos); + //Check if guard pos doesn't touch any 3rd zone. This would create unwanted passage to 3rd zone + bool adjacentZone = false; + map.foreach_neighbour(potentialPos, [this, &adjacentZone, otherZoneId](int3 & pos) + { + auto zoneId = map.getZoneID(pos); + if (zoneId != zone.getId() && zoneId != otherZoneId) + { + adjacentZone = true; + } + }); + if (adjacentZone) + { + continue; + } + //Take into account distance to objects from both sides float dist = std::min(map.getTileInfo(potentialPos).getNearestObjectDistance(), map.getTileInfo(borderPos).getNearestObjectDistance()); From ccc8d28043329f7f860a2b3a1b08c562ce0644c1 Mon Sep 17 00:00:00 2001 From: godric3 Date: Sun, 21 Jan 2024 21:07:06 +0100 Subject: [PATCH 41/54] Fix inspector using wrong editor for some values --- mapeditor/inspector/inspector.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/mapeditor/inspector/inspector.h b/mapeditor/inspector/inspector.h index 432e40ab0..94c2b80c2 100644 --- a/mapeditor/inspector/inspector.h +++ b/mapeditor/inspector/inspector.h @@ -128,7 +128,6 @@ protected: { itemKey = keyItems[key]; table->setItem(table->row(itemKey), 1, itemValue); - if(delegate) table->setItemDelegateForRow(table->row(itemKey), delegate); } else @@ -139,7 +138,6 @@ protected: table->setRowCount(row + 1); table->setItem(row, 0, itemKey); table->setItem(row, 1, itemValue); - if(delegate) table->setItemDelegateForRow(row, delegate); ++row; } From 183612d32b645a9433ec4dc36af8d1b943fb9fdd Mon Sep 17 00:00:00 2001 From: Asirome <66029412+macomarivas@users.noreply.github.com> Date: Tue, 23 Jan 2024 11:11:35 +0100 Subject: [PATCH 42/54] Updated spanish.ts translation --- launcher/translation/spanish.ts | 143 +++++++++++++++++--------------- 1 file changed, 78 insertions(+), 65 deletions(-) diff --git a/launcher/translation/spanish.ts b/launcher/translation/spanish.ts index 10c94498e..ae2c67cbf 100644 --- a/launcher/translation/spanish.ts +++ b/launcher/translation/spanish.ts @@ -6,84 +6,84 @@ VCMI on Discord - VCMI en Discord + VCMI en Discord Have a question? Found a bug? Want to help? Join us! - ¿Tienes alguna pregunta? ¿Encontraste algún error? ¿Quieres ayudar? ¡Únete a nosotros! + ¿Tienes alguna pregunta? ¿Encontraste algún error? ¿Quieres ayudar? ¡Únete a nosotros! VCMI on Github - VCMI en Github + VCMI en Github Our Community - + Nuestra comunidad VCMI on Slack - VCMI en Slack + VCMI en Slack Build Information - + Información de la versión User data directory - Directorio de datos del usuario + Directorio de datos del usuario Open - Abrir + Abrir Check for updates - + Comprobar actualizaciones Game version - + Versión del juego Log files directory - Directorio de archivos de registro + Directorio de archivos de registro Data Directories - Directorios de datos + Directorios de datos Game data directory - + Directorio de los datos del juego Operating System - + Sistema operativo Project homepage - + Página web del proyecto Report a bug - + Informar de un error @@ -121,7 +121,7 @@ Maps - + Mapas @@ -180,7 +180,7 @@ Compatibility - Compatibilidad + Compatibilidad @@ -319,7 +319,7 @@ Size - + Tamaño @@ -410,12 +410,12 @@ Downloading %s%. %p% (%v MB out of %m MB) finished - + Descargando %s%. %p% (%v MB de %m MB) completado Download failed - + Descarga fallida @@ -424,30 +424,37 @@ Encountered errors: - + No se han podido descargar todos los ficheros. + +Errores encontrados: + + Install successfully downloaded? - + + +Instalar lo correctamente descargado? Installing mod %1 - + Instalando mod %1 Operation failed - + Operación fallida Encountered errors: - + Errores encontrados: + @@ -482,94 +489,94 @@ Install successfully downloaded? Interface Scaling - + Escala de la interfaz Neutral AI in battles - + IA neutral en batallas Enemy AI in battles - + IA enemiga en batallas Additional repository - + Repositorio adicional Adventure Map Allies - + Aliados en el Mapa de aventuras Adventure Map Enemies - + Enemigos en el Mapa de aventuras Windowed - + Ventana Borderless fullscreen - + Ventana completa sin bordes Exclusive fullscreen - + Pantalla completa Autosave limit (0 = off) - + Límite de autosaves (0 = sin límite) Friendly AI in battles - + IA amistosa en batallas Framerate Limit - + Límite de fotogramas Autosave prefix - + Prefijo autoguardado empty = map name prefix - + Vacio = prefijo del mapa Refresh now - + Actualizar Default repository - + Repositorio por defecto Renderer - + Render On - Encendido + Activado @@ -584,7 +591,7 @@ Install successfully downloaded? Reserved screen area - + Área de pantalla reservada @@ -614,7 +621,7 @@ Install successfully downloaded? VSync - + Sincronización vertical @@ -640,7 +647,13 @@ Windowed - game will run inside a window that covers part of your screen Borderless Windowed Mode - game will run in a window that covers entirely of your screen, using same resolution as your screen. Fullscreen Exclusive Mode - game will cover entirety of your screen and will use selected resolution. - + Selecciona el modo de visualización del juego + +En ventana - el juego se ejecutará dentro de una ventana que forma parte de tu pantalla. + +Ventana sin bordes - el juego se ejecutará en una ventana que cubre completamente tu pantalla, usando la misma resolución. + +Pantalla completa - el juego cubrirá la totalidad de la pantalla y utilizará la resolución seleccionada. @@ -698,27 +711,27 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use Form - + Formulario Users in lobby - + Usuarios en la sala Global chat - + Chat general type you message - + Escribe tu mensaje send - + Enviar @@ -792,12 +805,12 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use Interface Improvements - + Mejora de la interfaz Install mod that provides various interface improvements, such as better interface for random maps and selectable actions in battles - + Instalar mod que proporciona varias mejoras en la interfaz, como mejor interacción en los mapas aleatorios y más opciones en las batallas @@ -921,7 +934,7 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Czech - + Czech (Checo) @@ -936,7 +949,7 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Finnish - + Finnish (Finlandés) @@ -951,12 +964,12 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Hungarian - + Hungarian (Húngaro) Italian - + Italian (Italiano) @@ -971,7 +984,7 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Portuguese - + Portuguese (Portugués) @@ -986,12 +999,12 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Swedish - + Swedish (Sueco) Turkish - + Turkish (Turco) @@ -1001,7 +1014,7 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Vietnamese - + Vietnamese (Vietnamita) @@ -1011,12 +1024,12 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Other (Cyrillic Script) - + Otro (Escritura cirílica) Other (West European) - + Otro (Europa del Este) @@ -1151,7 +1164,7 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi Help - + Ayuda From aff9fddd030e1d3462842ea8367eea4539c8793b Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 23 Jan 2024 13:56:28 +0200 Subject: [PATCH 43/54] Version bump to 1.4.5 --- ChangeLog.md | 19 +++++++++++++++++++ android/vcmi-app/build.gradle | 4 ++-- cmake_modules/VersionDefinition.cmake | 2 +- debian/changelog | 6 ++++++ launcher/eu.vcmi.VCMI.metainfo.xml | 1 + 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 20db36fee..cd7468304 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,3 +1,22 @@ +# 1.4.4 -> 1.4.5 + +### Stability +* Fixed crash on creature spellcasting +* Fixed crash on unit entering magical obstacles such as quicksands +* Fixed freeze on map loading on some systems + +### Random Maps Generator +* Fixed placement of guards sometimes resulting into open connection into third zone +* Fixed rare crash on multithreaded access during placement of artifacts or wandering monsters + +### Map Editor +* Fixed inspector using wrong editor for some values + +# 1.4.3 -> 1.4.4 + +### General +* Fixed crash on generation of random maps + # 1.4.2 -> 1.4.3 ### General diff --git a/android/vcmi-app/build.gradle b/android/vcmi-app/build.gradle index 7a88a69fd..b8ab1c6ef 100644 --- a/android/vcmi-app/build.gradle +++ b/android/vcmi-app/build.gradle @@ -10,8 +10,8 @@ android { applicationId "is.xyz.vcmi" minSdk 19 targetSdk 33 - versionCode 1441 - versionName "1.4.4" + versionCode 1450 + versionName "1.4.5" setProperty("archivesBaseName", "vcmi") } diff --git a/cmake_modules/VersionDefinition.cmake b/cmake_modules/VersionDefinition.cmake index 14867224a..1e8c6240a 100644 --- a/cmake_modules/VersionDefinition.cmake +++ b/cmake_modules/VersionDefinition.cmake @@ -1,6 +1,6 @@ set(VCMI_VERSION_MAJOR 1) set(VCMI_VERSION_MINOR 4) -set(VCMI_VERSION_PATCH 4) +set(VCMI_VERSION_PATCH 5) add_definitions( -DVCMI_VERSION_MAJOR=${VCMI_VERSION_MAJOR} -DVCMI_VERSION_MINOR=${VCMI_VERSION_MINOR} diff --git a/debian/changelog b/debian/changelog index 144b17e94..a2ad89bfa 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +vcmi (1.4.5) jammy; urgency=medium + + * New upstream release + + -- Ivan Savenko Tue, 23 Jan 2024 12:00:00 +0200 + vcmi (1.4.4) jammy; urgency=medium * New upstream release diff --git a/launcher/eu.vcmi.VCMI.metainfo.xml b/launcher/eu.vcmi.VCMI.metainfo.xml index c043968f3..d1e30f3ad 100644 --- a/launcher/eu.vcmi.VCMI.metainfo.xml +++ b/launcher/eu.vcmi.VCMI.metainfo.xml @@ -76,6 +76,7 @@ + From d937d26b80429a3a85c34d94d8611bcd27b7e174 Mon Sep 17 00:00:00 2001 From: Alexander Wilms Date: Tue, 23 Jan 2024 10:42:24 +0000 Subject: [PATCH 44/54] CPack isn't used for iOS builds, so only kill XProtect if we're building for macOS Also wait at most 10 s for XProtect to be killed --- .github/workflows/github.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github.yml b/.github/workflows/github.yml index 1b9d9279a..e54a027b2 100644 --- a/.github/workflows/github.yml +++ b/.github/workflows/github.yml @@ -269,11 +269,12 @@ jobs: ctest --preset ${{matrix.preset}} - name: Kill XProtect to work around CPack issue on macOS - if: runner.os == 'macOS' + if: ${{ startsWith(matrix.platform, 'mac') }} run: | # Cf. https://github.com/actions/runner-images/issues/7522#issuecomment-1556766641 echo Killing...; sudo pkill -9 XProtect >/dev/null || true; - echo Waiting...; while pgrep XProtect; do sleep 3; done; + echo "Waiting..."; counter=0; while pgrep XProtect && ((counter < 20)); do sleep 3; ((counter++)); done + pgrep XProtect || true - name: Pack id: cpack From 1975a08a3c12e6c7639ffcaa70d468a0011fd860 Mon Sep 17 00:00:00 2001 From: Alexander Wilms Date: Tue, 23 Jan 2024 13:07:32 +0000 Subject: [PATCH 45/54] Retry cpack until it succeeds --- .github/workflows/github.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github.yml b/.github/workflows/github.yml index e54a027b2..592e15321 100644 --- a/.github/workflows/github.yml +++ b/.github/workflows/github.yml @@ -282,7 +282,7 @@ jobs: run: | cd '${{github.workspace}}/out/build/${{matrix.preset}}' CPACK_PATH=`which -a cpack | grep -m1 -v -i chocolatey` - "$CPACK_PATH" -C ${{matrix.pack_type}} ${{ matrix.cpack_args }} + counter=0; until "$CPACK_PATH" -C ${{matrix.pack_type}} ${{ matrix.cpack_args }} || ((counter > 20)); do sleep 3; ((counter++)); done test -f '${{github.workspace}}/CI/${{matrix.platform}}/post_pack.sh' \ && '${{github.workspace}}/CI/${{matrix.platform}}/post_pack.sh' '${{github.workspace}}' "$(ls '${{ env.VCMI_PACKAGE_FILE_NAME }}'.*)" rm -rf _CPack_Packages From 0df4f9bda53804913ebb989b4655d413fa12474e Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Tue, 23 Jan 2024 23:45:31 +0100 Subject: [PATCH 46/54] video button --- client/lobby/CBonusSelection.cpp | 4 ++++ client/lobby/CBonusSelection.h | 1 + client/mainmenu/CPrologEpilogVideo.cpp | 3 ++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/client/lobby/CBonusSelection.cpp b/client/lobby/CBonusSelection.cpp index 33775dfa9..22a9106ef 100644 --- a/client/lobby/CBonusSelection.cpp +++ b/client/lobby/CBonusSelection.cpp @@ -72,6 +72,7 @@ CBonusSelection::CBonusSelection() 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); + buttonVideo = std::make_shared(Point(705, 214), AnimationPath::builtin("CBVIDEB.DEF"), CButton::tooltip(), [this](){ GH.windows().createAndPushWindow(getCampaign()->scenario(CSH->campaignMap).prolog, nullptr); }); 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()); @@ -309,6 +310,7 @@ void CBonusSelection::updateAfterStateChange() if(CSH->state != EClientState::GAMEPLAY) { buttonRestart->disable(); + buttonVideo->disable(); buttonStart->enable(); if(!getCampaign()->conqueredScenarios().empty()) buttonBack->block(true); @@ -319,6 +321,7 @@ void CBonusSelection::updateAfterStateChange() { buttonStart->disable(); buttonRestart->enable(); + buttonVideo->enable(); buttonBack->block(false); if(buttonDifficultyLeft) buttonDifficultyLeft->disable(); @@ -401,6 +404,7 @@ void CBonusSelection::startMap() //block buttons immediately buttonStart->block(true); buttonRestart->block(true); + buttonVideo->block(true); buttonBack->block(true); if(LOCPLINT) // we're currently ingame, so ask for starting new map and end game diff --git a/client/lobby/CBonusSelection.h b/client/lobby/CBonusSelection.h index 78289bb02..394c3b81b 100644 --- a/client/lobby/CBonusSelection.h +++ b/client/lobby/CBonusSelection.h @@ -65,6 +65,7 @@ public: std::shared_ptr buttonStart; std::shared_ptr buttonRestart; std::shared_ptr buttonBack; + std::shared_ptr buttonVideo; std::shared_ptr campaignName; std::shared_ptr labelCampaignDescription; std::shared_ptr campaignDescription; diff --git a/client/mainmenu/CPrologEpilogVideo.cpp b/client/mainmenu/CPrologEpilogVideo.cpp index d81bd07e7..22e7ad7cc 100644 --- a/client/mainmenu/CPrologEpilogVideo.cpp +++ b/client/mainmenu/CPrologEpilogVideo.cpp @@ -64,5 +64,6 @@ void CPrologEpilogVideo::clickPressed(const Point & cursorPosition) close(); CCS->soundh->stopSound(voiceSoundHandle); CCS->soundh->stopSound(videoSoundHandle); - exitCb(); + if(exitCb) + exitCb(); } From 56db0e06cf527a09d4c62661e17353d79488b3d4 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Wed, 24 Jan 2024 00:04:56 +0100 Subject: [PATCH 47/54] fix render artefacts remaining after video playback --- client/lobby/CBonusSelection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/lobby/CBonusSelection.cpp b/client/lobby/CBonusSelection.cpp index 22a9106ef..0939e776b 100644 --- a/client/lobby/CBonusSelection.cpp +++ b/client/lobby/CBonusSelection.cpp @@ -72,7 +72,7 @@ CBonusSelection::CBonusSelection() 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); - buttonVideo = std::make_shared(Point(705, 214), AnimationPath::builtin("CBVIDEB.DEF"), CButton::tooltip(), [this](){ GH.windows().createAndPushWindow(getCampaign()->scenario(CSH->campaignMap).prolog, nullptr); }); + buttonVideo = std::make_shared(Point(705, 214), AnimationPath::builtin("CBVIDEB.DEF"), CButton::tooltip(), [this](){ GH.windows().createAndPushWindow(getCampaign()->scenario(CSH->campaignMap).prolog, [this](){ redraw(); }); }); 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()); From dbf53d78badacc6c8691af0251d3103f8d3a189d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zieli=C5=84ski?= Date: Wed, 24 Jan 2024 06:20:46 +0100 Subject: [PATCH 48/54] Fix invalid logic which made AI not attack guards --- lib/pathfinder/PathfindingRules.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pathfinder/PathfindingRules.cpp b/lib/pathfinder/PathfindingRules.cpp index 2f13caca2..1be7fe660 100644 --- a/lib/pathfinder/PathfindingRules.cpp +++ b/lib/pathfinder/PathfindingRules.cpp @@ -271,9 +271,9 @@ PathfinderBlockingRule::BlockingReason MovementAfterDestinationRule::getBlocking if(destination.guarded) { if (pathfinderHelper->options.ignoreGuards) - return BlockingReason::DESTINATION_GUARDED; - else return BlockingReason::NONE; + else + return BlockingReason::DESTINATION_GUARDED; } break; From b7662c5ec670756be122505b32ed19be1f7c2663 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 24 Jan 2024 13:43:16 +0200 Subject: [PATCH 49/54] Android build ID bump --- android/vcmi-app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/vcmi-app/build.gradle b/android/vcmi-app/build.gradle index b8ab1c6ef..538fc9a4c 100644 --- a/android/vcmi-app/build.gradle +++ b/android/vcmi-app/build.gradle @@ -10,7 +10,7 @@ android { applicationId "is.xyz.vcmi" minSdk 19 targetSdk 33 - versionCode 1450 + versionCode 1451 versionName "1.4.5" setProperty("archivesBaseName", "vcmi") } From 702fc8077dcf5320f0dd7042364e17a0d2f8d372 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 24 Jan 2024 13:43:35 +0200 Subject: [PATCH 50/54] Fix possible crash on invalid spell --- lib/CBonusTypeHandler.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/CBonusTypeHandler.cpp b/lib/CBonusTypeHandler.cpp index 7244c62d2..ba86a2d8e 100644 --- a/lib/CBonusTypeHandler.cpp +++ b/lib/CBonusTypeHandler.cpp @@ -76,10 +76,10 @@ std::string CBonusTypeHandler::bonusToString(const std::shared_ptr & bonu if (text.find("${val}") != std::string::npos) boost::algorithm::replace_all(text, "${val}", std::to_string(bearer->valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype)))); - if (text.find("${subtype.creature}") != std::string::npos && bonus->subtype.as() != CreatureID::NONE) + if (text.find("${subtype.creature}") != std::string::npos && bonus->subtype.as().hasValue()) boost::algorithm::replace_all(text, "${subtype.creature}", bonus->subtype.as().toCreature()->getNamePluralTranslated()); - if (text.find("${subtype.spell}") != std::string::npos && bonus->subtype.as() != SpellID::NONE) + if (text.find("${subtype.spell}") != std::string::npos && bonus->subtype.as().hasValue()) boost::algorithm::replace_all(text, "${subtype.spell}", bonus->subtype.as().toSpell()->getNameTranslated()); return text; @@ -95,8 +95,11 @@ ImagePath CBonusTypeHandler::bonusToGraphics(const std::shared_ptr & bonu case BonusType::SPELL_IMMUNITY: { fullPath = true; - const CSpell * sp = bonus->subtype.as().toSpell(); - fileName = sp->getIconImmune(); + if (bonus->subtype.as().hasValue()) + { + const CSpell * sp = bonus->subtype.as().toSpell(); + fileName = sp->getIconImmune(); + } break; } case BonusType::SPELL_DAMAGE_REDUCTION: //Spell damage reduction for all schools From 2f5bf6434004ac44e24460660b868517583aae22 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 24 Jan 2024 13:44:22 +0200 Subject: [PATCH 51/54] Do not crash on attempt to load campaign with unsupported maps --- Mods/vcmi/config/vcmi/english.json | 1 + client/lobby/CLobbyScreen.cpp | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Mods/vcmi/config/vcmi/english.json b/Mods/vcmi/config/vcmi/english.json index 690e34700..010c2429d 100644 --- a/Mods/vcmi/config/vcmi/english.json +++ b/Mods/vcmi/config/vcmi/english.json @@ -72,6 +72,7 @@ "vcmi.lobby.noUnderground" : "no underground", "vcmi.lobby.sortDate" : "Sorts maps by change date", + "vcmi.client.errors.invalidMap" : "{Invalid map or campaign}\n\nFailed to start game! Selected map or campaign might be invalid or corrupted. Reason:\n%s", "vcmi.client.errors.missingCampaigns" : "{Missing data files}\n\nCampaigns data files were not found! You may be using incomplete or corrupted Heroes 3 data files. Please reinstall game data.", "vcmi.server.errors.existingProcess" : "Another VCMI server process is running. Please terminate it before starting a new game.", "vcmi.server.errors.modsToEnable" : "{Following mods are required}", diff --git a/client/lobby/CLobbyScreen.cpp b/client/lobby/CLobbyScreen.cpp index 0c5a6670e..730f5e2ee 100644 --- a/client/lobby/CLobbyScreen.cpp +++ b/client/lobby/CLobbyScreen.cpp @@ -127,11 +127,23 @@ void CLobbyScreen::toggleTab(std::shared_ptr tab) void CLobbyScreen::startCampaign() { - if(CSH->mi) - { + if(!CSH->mi) + return; + + try { auto ourCampaign = CampaignHandler::getCampaign(CSH->mi->fileURI); CSH->setCampaignState(ourCampaign); } + catch (const std::runtime_error &e) + { + // handle possible exception on map loading. For example campaign that contains map in unsupported format + // for example, wog campaigns or hota campaigns without hota map support mod + MetaString message; + message.appendTextID("vcmi.client.errors.invalidMap"); + message.replaceRawString(e.what()); + + CInfoWindow::showInfoDialog(message.toString(), {}); + } } void CLobbyScreen::startScenario(bool allowOnlyAI) From a2e0742ffb038a82d4bd04d29375f24b47494d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zieli=C5=84ski?= Date: Wed, 24 Jan 2024 06:20:46 +0100 Subject: [PATCH 52/54] Fix invalid logic which made AI not attack guards --- lib/pathfinder/PathfindingRules.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pathfinder/PathfindingRules.cpp b/lib/pathfinder/PathfindingRules.cpp index 49de31ff7..ca71db460 100644 --- a/lib/pathfinder/PathfindingRules.cpp +++ b/lib/pathfinder/PathfindingRules.cpp @@ -273,9 +273,9 @@ PathfinderBlockingRule::BlockingReason MovementAfterDestinationRule::getBlocking if(destination.guarded) { if (pathfinderHelper->options.ignoreGuards) - return BlockingReason::DESTINATION_GUARDED; - else return BlockingReason::NONE; + else + return BlockingReason::DESTINATION_GUARDED; } break; From d69e0b23e897c166329271389def64e57c4f4e0a Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 24 Jan 2024 14:09:40 +0200 Subject: [PATCH 53/54] Update changelog --- ChangeLog.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index cd7468304..78379b875 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -4,6 +4,8 @@ * Fixed crash on creature spellcasting * Fixed crash on unit entering magical obstacles such as quicksands * Fixed freeze on map loading on some systems +* Fixed crash on attempt to start campaign with unsupported map +* Fixed crash on opening creature information window with invalid SPELL_IMMUNITY bonus ### Random Maps Generator * Fixed placement of guards sometimes resulting into open connection into third zone @@ -12,6 +14,10 @@ ### Map Editor * Fixed inspector using wrong editor for some values +### AI +* Fixed bug leading to AI not attacking wandering monsters in some cases +* Fixed crash on using StupidAI for autocombat or for enemy players + # 1.4.3 -> 1.4.4 ### General From e434d5c0b7270c53f1f2a464b0887fd6f8545a3c Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Thu, 25 Jan 2024 20:35:30 +0100 Subject: [PATCH 54/54] Apply suggestions from code review Co-authored-by: Ivan Savenko --- client/windows/GUIClasses.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 4298719cb..e77d1dcc7 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -537,7 +537,7 @@ void CTavernWindow::addInvite() inviteHero = std::make_shared(170, 444, EFonts::FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->translate("vcmi.tavernWindow.inviteHero")); inviteHeroImage = std::make_shared(AnimationPath::builtin("PortraitsSmall"), (*CGI->heroh)[heroToInvite->getHeroType()]->imageIndex, 0, 245, 428); - inviteHeroImageArea = std::make_shared(Rect(245, 428, 48, 32), [&](){ GH.windows().createAndPushWindow(inviteableHeroes, [this](CGHeroInstance* h){ heroToInvite = h; addInvite(); }); }, [this](){ GH.windows().createAndPushWindow(std::make_shared(heroToInvite)); }); + inviteHeroImageArea = std::make_shared(Rect(245, 428, 48, 32), [this](){ GH.windows().createAndPushWindow(inviteableHeroes, [this](CGHeroInstance* h){ heroToInvite = h; addInvite(); }); }, [this](){ GH.windows().createAndPushWindow(std::make_shared(heroToInvite)); }); } } @@ -663,7 +663,8 @@ CTavernWindow::HeroSelector::HeroSelector(std::map pos = Rect(0, 0, 16 * 48, (inviteableHeroes.size() / 16 + (inviteableHeroes.size() % 16 != 0)) * 32); background = std::make_shared(ImagePath::builtin("DIBOXBCK"), Rect(0, 0, pos.w, pos.h)); - int x = 0, y = 0; + int x = 0; + int y = 0; for(auto & h : inviteableHeroes) { portraits.push_back(std::make_shared(AnimationPath::builtin("PortraitsSmall"), (*CGI->heroh)[h.first]->imageIndex, 0, x * 48, y * 32));