From 7707adc44f29c802b7a62e36d461261b75ef5fb2 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sat, 28 Sep 2024 01:18:10 +0200 Subject: [PATCH] checks on server --- lib/mapObjects/CGTownInstance.cpp | 3 ++- lib/mapObjects/CGTownInstance.h | 4 ++++ lib/serializer/ESerializationVersion.h | 3 ++- server/CGameHandler.cpp | 18 ++++++++++++++++++ server/NetPacksServer.cpp | 3 +++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index 2c040da6b..500ce19b0 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -268,7 +268,8 @@ CGTownInstance::CGTownInstance(IGameCallback *cb): built(0), destroyed(0), identifier(0), - alignmentToPlayer(PlayerColor::NEUTRAL) + alignmentToPlayer(PlayerColor::NEUTRAL), + lastSpellResearchDay(0) { this->setNodeType(CBonusSystemNode::TOWN); } diff --git a/lib/mapObjects/CGTownInstance.h b/lib/mapObjects/CGTownInstance.h index fab98714e..e14802fd4 100644 --- a/lib/mapObjects/CGTownInstance.h +++ b/lib/mapObjects/CGTownInstance.h @@ -73,6 +73,7 @@ public: std::vector > spells; //spells[level] -> vector of spells, first will be available in guild std::vector events; std::pair bonusValue;//var to store town bonuses (rampart = resources from mystic pond, factory = save debts); + int lastSpellResearchDay; ////////////////////////////////////////////////////////////////////////// template void serialize(Handler &h) @@ -93,6 +94,9 @@ public: h & spells; h & events; + if (h.version >= Handler::Version::SPELL_RESEARCH) + h & lastSpellResearchDay; + if (h.version >= Handler::Version::NEW_TOWN_BUILDINGS) { h & rewardableBuildings; diff --git a/lib/serializer/ESerializationVersion.h b/lib/serializer/ESerializationVersion.h index dd0deb6b0..b4be54223 100644 --- a/lib/serializer/ESerializationVersion.h +++ b/lib/serializer/ESerializationVersion.h @@ -61,6 +61,7 @@ enum class ESerializationVersion : int32_t CAMPAIGN_OUTRO_SUPPORT, // 862 - support for campaign outro video REWARDABLE_BANKS, // 863 - team state contains list of scouted objects, coast visitable rewardable objects REGION_LABEL, // 864 - labels for campaign regions + SPELL_RESEARCH, // 865 - spell research - CURRENT = REGION_LABEL + CURRENT = SPELL_RESEARCH }; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 607fdf620..fb9625012 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -2256,6 +2256,24 @@ bool CGameHandler::spellResearch(ObjectInstanceID tid, SpellID spellAtSlot) if(level == -1 && complain("Spell for replacement not found!")) return false; + + int daysSinceLastResearch = gs->getDate(Date::DAY) - t->lastSpellResearchDay; + if(!daysSinceLastResearch && complain("Already researched today!")) + return false; + + TResources cost; + cost[EGameResID::GOLD] = 1000; + cost[EGameResID::MERCURY] = (level + 1) * 2; + cost[EGameResID::SULFUR] = (level + 1) * 2; + cost[EGameResID::CRYSTAL] = (level + 1) * 2; + cost[EGameResID::GEMS] = (level + 1) * 2; + + if(!getPlayerState(t->getOwner())->resources.canAfford(cost) && complain("Spell replacement cannot be afforded!")) + return false; + + giveResources(t->getOwner(), -cost); + + t->lastSpellResearchDay = gs->getDate(Date::DAY); auto spells = t->spells.at(level); diff --git a/server/NetPacksServer.cpp b/server/NetPacksServer.cpp index b8f71167b..b4227f1ea 100644 --- a/server/NetPacksServer.cpp +++ b/server/NetPacksServer.cpp @@ -140,6 +140,9 @@ void ApplyGhNetPackVisitor::visitBuildStructure(BuildStructure & pack) void ApplyGhNetPackVisitor::visitSpellResearch(SpellResearch & pack) { + gh.throwIfWrongOwner(&pack, pack.tid); + gh.throwIfPlayerNotActive(&pack); + result = gh.spellResearch(pack.tid, pack.spellAtSlot); }