From e5e01ab35d440761b28f6dcbb0b7a29ce244558f Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 20 Nov 2023 14:38:57 +0200 Subject: [PATCH 1/5] Disable spectator mode in single player to avoid confusing players --- client/lobby/CLobbyScreen.cpp | 4 ++-- client/lobby/OptionsTab.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/lobby/CLobbyScreen.cpp b/client/lobby/CLobbyScreen.cpp index 135e0d078..95623b02f 100644 --- a/client/lobby/CLobbyScreen.cpp +++ b/client/lobby/CLobbyScreen.cpp @@ -76,7 +76,7 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType) card->iconDifficulty->addCallback(std::bind(&IServerAPI::setDifficulty, CSH, _1)); - buttonStart = std::make_shared(Point(411, 535), AnimationPath::builtin("SCNRBEG.DEF"), CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, true), EShortcut::LOBBY_BEGIN_GAME); + buttonStart = std::make_shared(Point(411, 535), AnimationPath::builtin("SCNRBEG.DEF"), CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, false), EShortcut::LOBBY_BEGIN_GAME); initLobby(); break; } @@ -84,7 +84,7 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType) { tabOpt = std::make_shared(); tabTurnOptions = std::make_shared(); - buttonStart = std::make_shared(Point(411, 535), AnimationPath::builtin("SCNRLOD.DEF"), CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, true), EShortcut::LOBBY_LOAD_GAME); + buttonStart = std::make_shared(Point(411, 535), AnimationPath::builtin("SCNRLOD.DEF"), CGI->generaltexth->zelp[103], std::bind(&CLobbyScreen::startScenario, this, false), EShortcut::LOBBY_LOAD_GAME); initLobby(); break; } diff --git a/client/lobby/OptionsTab.cpp b/client/lobby/OptionsTab.cpp index f9a211c25..65d5cead3 100644 --- a/client/lobby/OptionsTab.cpp +++ b/client/lobby/OptionsTab.cpp @@ -959,7 +959,7 @@ void OptionsTab::PlayerOptionsEntry::updateName() { void OptionsTab::onSetPlayerClicked(const PlayerSettings & ps) const { - if(ps.isControlledByAI() || humanPlayers > 0) + if(ps.isControlledByAI() || humanPlayers > 1) CSH->setPlayer(ps.color); } From 845a259619cb63147adfc63f672f7b071e7ba15f Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 20 Nov 2023 14:39:19 +0200 Subject: [PATCH 2/5] Disable quick combat by default to avoid confusing players --- config/schemas/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/schemas/settings.json b/config/schemas/settings.json index d0dedb7fe..5e7e5956d 100644 --- a/config/schemas/settings.json +++ b/config/schemas/settings.json @@ -255,7 +255,7 @@ }, "quickCombat" : { "type" : "boolean", - "default" : true + "default" : false }, "objectAnimation" : { "type" : "boolean", From 71825fcc4eeed0f616661ec4f309df48af78b440 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 20 Nov 2023 19:56:55 +0200 Subject: [PATCH 3/5] Fix crash on artifact movement --- lib/mapObjects/CGHeroInstance.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp index 0ea8bb52d..11698ea0b 100644 --- a/lib/mapObjects/CGHeroInstance.cpp +++ b/lib/mapObjects/CGHeroInstance.cpp @@ -329,7 +329,6 @@ void CGHeroInstance::initHero(CRandomGenerator & rand) if(!getArt(ArtifactPosition::SPELLBOOK) && type->haveSpellBook) { auto artifact = ArtifactUtils::createNewArtifactInstance(ArtifactID::SPELLBOOK); - cb->gameState()->map->addNewArtifactInstance(artifact); putArtifact(ArtifactPosition::SPELLBOOK, artifact); } } @@ -339,7 +338,6 @@ void CGHeroInstance::initHero(CRandomGenerator & rand) if(!getArt(ArtifactPosition::MACH4)) { auto artifact = ArtifactUtils::createNewArtifactInstance(ArtifactID::CATAPULT); - cb->gameState()->map->addNewArtifactInstance(artifact); putArtifact(ArtifactPosition::MACH4, artifact); //everyone has a catapult } @@ -458,7 +456,6 @@ void CGHeroInstance::initArmy(CRandomGenerator & rand, IArmyDescriptor * dst) if(!getArt(slot)) { auto artifact = ArtifactUtils::createNewArtifactInstance(aid); - cb->gameState()->map->addNewArtifactInstance(artifact); putArtifact(slot, artifact); } else From 842d66afbcbcfb9b041fed4453a9418d80a17a47 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 20 Nov 2023 19:57:07 +0200 Subject: [PATCH 4/5] Fix crash on battlefield deserialization --- lib/constants/EntityIdentifiers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/constants/EntityIdentifiers.cpp b/lib/constants/EntityIdentifiers.cpp index d119c0f76..60cf811c2 100644 --- a/lib/constants/EntityIdentifiers.cpp +++ b/lib/constants/EntityIdentifiers.cpp @@ -371,7 +371,7 @@ si32 BattleField::decode(const std::string & identifier) std::string BattleField::encode(const si32 index) { - return VLC->spells()->getByIndex(index)->getJsonKey(); + return VLC->battlefields()->getByIndex(index)->getJsonKey(); } std::string SpellID::entityType() From a4d5c4917b61c78a5459585906cc3f0efd75e3a3 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 20 Nov 2023 20:50:37 +0200 Subject: [PATCH 5/5] Limit resources to 1000 000 000 to prevent overflow --- lib/constants/NumericConstants.h | 1 + lib/networkPacks/NetPacksLib.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/lib/constants/NumericConstants.h b/lib/constants/NumericConstants.h index 9d61935ff..fcc3da876 100644 --- a/lib/constants/NumericConstants.h +++ b/lib/constants/NumericConstants.h @@ -50,6 +50,7 @@ namespace GameConstants constexpr int CREATURES_COUNT = 197; constexpr ui32 BASE_MOVEMENT_COST = 100; //default cost for non-diagonal movement + constexpr int64_t PLAYER_RESOURCES_CAP = 1000 * 1000 * 1000; } VCMI_LIB_NAMESPACE_END diff --git a/lib/networkPacks/NetPacksLib.cpp b/lib/networkPacks/NetPacksLib.cpp index 8faa7044a..20ebdd086 100644 --- a/lib/networkPacks/NetPacksLib.cpp +++ b/lib/networkPacks/NetPacksLib.cpp @@ -797,6 +797,7 @@ void SetResources::applyGs(CGameState * gs) const gs->getPlayerState(player)->resources = res; else gs->getPlayerState(player)->resources += res; + gs->getPlayerState(player)->resources.amin(GameConstants::PLAYER_RESOURCES_CAP); //just ensure that player resources are not negative //server is responsible to check if player can afford deal @@ -2022,6 +2023,7 @@ void NewTurn::applyGs(CGameState *gs) { assert(re.first.isValidPlayer()); gs->getPlayerState(re.first)->resources = re.second; + gs->getPlayerState(re.first)->resources.amin(GameConstants::PLAYER_RESOURCES_CAP); } for(const auto & creatureSet : cres) //set available creatures in towns