Browse Source

checks on server

Laserlicht 1 year ago
parent
commit
7707adc44f

+ 2 - 1
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);
 }

+ 4 - 0
lib/mapObjects/CGTownInstance.h

@@ -73,6 +73,7 @@ public:
 	std::vector<std::vector<SpellID> > spells; //spells[level] -> vector of spells, first will be available in guild
 	std::vector<CCastleEvent> events;
 	std::pair<si32, si32> bonusValue;//var to store town bonuses (rampart = resources from mystic pond, factory = save debts);
+	int lastSpellResearchDay;
 
 	//////////////////////////////////////////////////////////////////////////
 	template <typename Handler> 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;

+ 2 - 1
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
 };

+ 18 - 0
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);
 

+ 3 - 0
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);
 }