/* * Limiter.cpp, 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 * */ #include "StdInc.h" #include "Limiter.h" #include "../IGameCallback.h" #include "../CPlayerState.h" #include "../mapObjects/CGHeroInstance.h" #include "../serializer/JsonSerializeFormat.h" #include "../constants/StringConstants.h" #include "../CSkillHandler.h" VCMI_LIB_NAMESPACE_BEGIN Rewardable::Limiter::Limiter() : dayOfWeek(0) , daysPassed(0) , heroExperience(0) , heroLevel(0) , manaPercentage(0) , manaPoints(0) , primary(GameConstants::PRIMARY_SKILLS, 0) { } Rewardable::Limiter::~Limiter() = default; bool Rewardable::Limiter::heroAllowed(const CGHeroInstance * hero) const { if(dayOfWeek != 0) { if (IObjectInterface::cb->getDate(Date::DAY_OF_WEEK) != dayOfWeek) return false; } if(daysPassed != 0) { if (IObjectInterface::cb->getDate(Date::DAY) < daysPassed) return false; } for(const auto & reqStack : creatures) { size_t count = 0; for(const auto & slot : hero->Slots()) { const CStackInstance * heroStack = slot.second; if (heroStack->type == reqStack.type) count += heroStack->count; } if (count < reqStack.count) //not enough creatures of this kind return false; } if(!IObjectInterface::cb->getPlayerState(hero->tempOwner)->resources.canAfford(resources)) return false; if(heroLevel > static_cast(hero->level)) return false; if(static_cast(heroExperience) > hero->exp) return false; if(manaPoints > hero->mana) return false; if(manaPercentage > 100 * hero->mana / hero->manaLimit()) return false; for(size_t i=0; i hero->getPrimSkillLevel(static_cast(i))) return false; } for(const auto & skill : secondary) { if (skill.second > hero->getSecSkillLevel(skill.first)) return false; } for(const auto & spell : spells) { if (!hero->spellbookContainsSpell(spell)) return false; } for(const auto & art : artifacts) { if (!hero->hasArt(art)) return false; } for(const auto & sublimiter : noneOf) { if (sublimiter->heroAllowed(hero)) return false; } for(const auto & sublimiter : allOf) { if (!sublimiter->heroAllowed(hero)) return false; } if(anyOf.empty()) return true; for(const auto & sublimiter : anyOf) { if (sublimiter->heroAllowed(hero)) return true; } return false; } void Rewardable::Limiter::serializeJson(JsonSerializeFormat & handler) { handler.serializeInt("dayOfWeek", dayOfWeek); handler.serializeInt("daysPassed", daysPassed); resources.serializeJson(handler, "resources"); handler.serializeInt("manaPercentage", manaPercentage); handler.serializeInt("heroExperience", heroExperience); handler.serializeInt("heroLevel", heroLevel); handler.serializeInt("manaPoints", manaPoints); handler.serializeIdArray("artifacts", artifacts); handler.enterArray("creatures").serializeStruct(creatures); handler.enterArray("primary").serializeArray(primary); { auto a = handler.enterArray("secondary"); std::vector> fieldValue(secondary.begin(), secondary.end()); a.serializeStruct>(fieldValue, [](JsonSerializeFormat & h, std::pair & e) { h.serializeId("skill", e.first, SecondarySkill{}, VLC->skillh->decodeSkill, VLC->skillh->encodeSkill); h.serializeId("level", e.second, 0, [](const std::string & i){return vstd::find_pos(NSecondarySkill::levels, i);}, [](si32 i){return NSecondarySkill::levels.at(i);}); }); a.syncSize(fieldValue); secondary = std::map(fieldValue.begin(), fieldValue.end()); } //sublimiters auto serializeSublimitersList = [&handler](const std::string & field, LimitersList & container) { auto a = handler.enterArray(field); a.syncSize(container); for(int i = 0; i < container.size(); ++i) { if(!handler.saving) container[i] = std::make_shared(); auto e = a.enterStruct(i); container[i]->serializeJson(handler); } }; serializeSublimitersList("allOf", allOf); serializeSublimitersList("anyOf", anyOf); serializeSublimitersList("noneOf", noneOf); } VCMI_LIB_NAMESPACE_END