1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-17 01:32:21 +02:00

checks on server

This commit is contained in:
Laserlicht
2024-09-28 01:18:10 +02:00
parent 5b2aa4dc71
commit 7707adc44f
5 changed files with 29 additions and 2 deletions

View File

@ -268,7 +268,8 @@ CGTownInstance::CGTownInstance(IGameCallback *cb):
built(0), built(0),
destroyed(0), destroyed(0),
identifier(0), identifier(0),
alignmentToPlayer(PlayerColor::NEUTRAL) alignmentToPlayer(PlayerColor::NEUTRAL),
lastSpellResearchDay(0)
{ {
this->setNodeType(CBonusSystemNode::TOWN); this->setNodeType(CBonusSystemNode::TOWN);
} }

View File

@ -73,6 +73,7 @@ public:
std::vector<std::vector<SpellID> > spells; //spells[level] -> vector of spells, first will be available in guild std::vector<std::vector<SpellID> > spells; //spells[level] -> vector of spells, first will be available in guild
std::vector<CCastleEvent> events; std::vector<CCastleEvent> events;
std::pair<si32, si32> bonusValue;//var to store town bonuses (rampart = resources from mystic pond, factory = save debts); 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) template <typename Handler> void serialize(Handler &h)
@ -93,6 +94,9 @@ public:
h & spells; h & spells;
h & events; h & events;
if (h.version >= Handler::Version::SPELL_RESEARCH)
h & lastSpellResearchDay;
if (h.version >= Handler::Version::NEW_TOWN_BUILDINGS) if (h.version >= Handler::Version::NEW_TOWN_BUILDINGS)
{ {
h & rewardableBuildings; h & rewardableBuildings;

View File

@ -61,6 +61,7 @@ enum class ESerializationVersion : int32_t
CAMPAIGN_OUTRO_SUPPORT, // 862 - support for campaign outro video CAMPAIGN_OUTRO_SUPPORT, // 862 - support for campaign outro video
REWARDABLE_BANKS, // 863 - team state contains list of scouted objects, coast visitable rewardable objects REWARDABLE_BANKS, // 863 - team state contains list of scouted objects, coast visitable rewardable objects
REGION_LABEL, // 864 - labels for campaign regions REGION_LABEL, // 864 - labels for campaign regions
SPELL_RESEARCH, // 865 - spell research
CURRENT = REGION_LABEL CURRENT = SPELL_RESEARCH
}; };

View File

@ -2257,6 +2257,24 @@ bool CGameHandler::spellResearch(ObjectInstanceID tid, SpellID spellAtSlot)
if(level == -1 && complain("Spell for replacement not found!")) if(level == -1 && complain("Spell for replacement not found!"))
return false; 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); auto spells = t->spells.at(level);
std::swap(spells.at(t->spellsAtLevel(level, false)), spells.at(vstd::find_pos(spells, spellAtSlot))); std::swap(spells.at(t->spellsAtLevel(level, false)), spells.at(vstd::find_pos(spells, spellAtSlot)));

View File

@ -140,6 +140,9 @@ void ApplyGhNetPackVisitor::visitBuildStructure(BuildStructure & pack)
void ApplyGhNetPackVisitor::visitSpellResearch(SpellResearch & pack) void ApplyGhNetPackVisitor::visitSpellResearch(SpellResearch & pack)
{ {
gh.throwIfWrongOwner(&pack, pack.tid);
gh.throwIfPlayerNotActive(&pack);
result = gh.spellResearch(pack.tid, pack.spellAtSlot); result = gh.spellResearch(pack.tid, pack.spellAtSlot);
} }