1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-15 20:03:15 +02:00

CCreatureHandler: load old stack exp as global effects

It is more robust and more logical.
This commit is contained in:
Konstantin
2023-04-06 19:56:48 +03:00
parent 0f5f4c69ec
commit 9f8dcfc736
4 changed files with 21 additions and 74 deletions

View File

@@ -426,13 +426,6 @@ CCreatureHandler::CCreatureHandler()
: expAfterUpgrade(0)
{
VLC->creh = this;
allCreatures.setDescription("All creatures");
allCreatures.setNodeType(CBonusSystemNode::ENodeTypes::ALL_CREATURES);
creaturesOfLevel[0].setDescription("Creatures of unnormalized tier");
for(int i = 1; i < ARRAY_COUNT(creaturesOfLevel); i++)
creaturesOfLevel[i].setDescription("Creatures of tier " + std::to_string(i));
loadCommanders();
}
@@ -697,10 +690,24 @@ std::vector<bool> CCreatureHandler::getDefaultAllowed() const
return ret;
}
void CCreatureHandler::loadCrExpBon()
void CCreatureHandler::loadCrExpBon(CBonusSystemNode & globalEffects)
{
if (VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE)) //reading default stack experience bonuses
{
logGlobal->debug("\tLoading stack experience bonuses");
auto addBonusForAllCreatures = [&](std::shared_ptr<Bonus> b) {
auto limiter = std::make_shared<CreatureLevelLimiter>();
b->addLimiter(limiter);
globalEffects.addNewBonus(b);
};
auto addBonusForTier = [&](int tier, std::shared_ptr<Bonus> b) {
assert(vstd::iswithin(tier, 1, 7));
//bonuses from level 7 are given to high-level creatures too
auto max = tier == GameConstants::CREATURES_PER_TOWN ? std::numeric_limits<int>::max() : tier + 1;
auto limiter = std::make_shared<CreatureLevelLimiter>(tier, max);
b->addLimiter(limiter);
globalEffects.addNewBonus(b);
};
CLegacyConfigParser parser("DATA/CREXPBON.TXT");
Bonus b; //prototype with some default properties
@@ -738,10 +745,7 @@ void CCreatureHandler::loadCrExpBon()
bl.clear();
loadStackExp(b, bl, parser);
for(const auto & b : bl)
{
addBonusForTier(7, b);
creaturesOfLevel[0].addNewBonus(b); //bonuses from level 7 are given to high-level creatures
}
parser.endLine();
}
do //parse everything that's left
@@ -1357,12 +1361,10 @@ CreatureID CCreatureHandler::pickRandomMonster(CRandomGenerator & rand, int tier
{
assert(vstd::iswithin(tier, 1, 7));
std::vector<CreatureID> allowed;
for(const CBonusSystemNode *b : creaturesOfLevel[tier].getChildrenNodes())
for(const auto & creature : objects)
{
assert(b->getNodeType() == CBonusSystemNode::CREATURE);
const auto * crea = dynamic_cast<const CCreature *>(b);
if(crea && !crea->special)
allowed.push_back(crea->getId());
if(!creature->special && creature->level == tier)
allowed.push_back(creature->getId());
}
if(allowed.empty())
@@ -1377,49 +1379,10 @@ CreatureID CCreatureHandler::pickRandomMonster(CRandomGenerator & rand, int tier
return CreatureID(r);
}
void CCreatureHandler::addBonusForTier(int tier, const std::shared_ptr<Bonus> & b)
{
assert(vstd::iswithin(tier, 1, 7));
creaturesOfLevel[tier].addNewBonus(b);
}
void CCreatureHandler::addBonusForAllCreatures(const std::shared_ptr<Bonus> & b)
{
const auto & exportedBonuses = allCreatures.getExportedBonusList();
for(const auto & bonus : exportedBonuses)
{
if(bonus->type == b->type && bonus->subtype == b->subtype)
return;
}
allCreatures.addNewBonus(b);
}
void CCreatureHandler::removeBonusesFromAllCreatures()
{
allCreatures.removeBonuses(Selector::all);
}
void CCreatureHandler::buildBonusTreeForTiers()
{
for(CCreature * c : objects)
{
if(vstd::isbetween(c->level, 0, ARRAY_COUNT(creaturesOfLevel)))
c->attachTo(creaturesOfLevel[c->level]);
else
c->attachTo(creaturesOfLevel[0]);
}
for(CBonusSystemNode &b : creaturesOfLevel)
b.attachTo(allCreatures);
}
void CCreatureHandler::afterLoadFinalization()
{
}
void CCreatureHandler::deserializationFix()
{
buildBonusTreeForTiers();
}
VCMI_LIB_NAMESPACE_END

View File

@@ -263,9 +263,6 @@ private:
class DLL_LINKAGE CCreatureHandler : public CHandlerBase<CreatureID, Creature, CCreature, CreatureService>
{
private:
CBonusSystemNode allCreatures;
CBonusSystemNode creaturesOfLevel[GameConstants::CREATURES_PER_TOWN + 1];//index 0 is used for creatures of unknown tier or outside <1-7> range
void loadJsonAnimation(CCreature * creature, const JsonNode & graphics) const;
void loadStackExperience(CCreature * creature, const JsonNode & input) const;
void loadCreatureJson(CCreature * creature, const JsonNode & config) const;
@@ -305,19 +302,13 @@ public:
const CCreature * getCreature(const std::string & scope, const std::string & identifier) const;
void deserializationFix();
CreatureID pickRandomMonster(CRandomGenerator & rand, int tier = -1) const; //tier <1 - CREATURES_PER_TOWN> or -1 for any
void addBonusForTier(int tier, const std::shared_ptr<Bonus> & b); //tier must be <1-7>
void addBonusForAllCreatures(const std::shared_ptr<Bonus> & b); //due to CBonusSystem::addNewBonus(const std::shared_ptr<Bonus>& b);
void removeBonusesFromAllCreatures();
CCreatureHandler();
~CCreatureHandler();
/// load all creatures from H3 files
void loadCrExpBon();
/// generates tier-specific bonus tree entries
void buildBonusTreeForTiers();
/// load all stack experience bonuses from H3 files
void loadCrExpBon(CBonusSystemNode & globalEffects);
void afterLoadFinalization() override;
@@ -336,9 +327,6 @@ public:
h & skillLevels;
h & skillRequirements;
h & commanderLevelPremy;
h & allCreatures;
h & creaturesOfLevel;
BONUS_TREE_DESERIALIZATION_FIX
}
};

View File

@@ -958,6 +958,7 @@ void CGameState::initGlobalBonuses()
bonus->sid = -1; //there is one global object
globalEffects.addNewBonus(bonus);
}
VLC->creh->loadCrExpBon(globalEffects);
}
void CGameState::initGrailPosition()
@@ -1869,7 +1870,6 @@ void CGameState::initTowns()
void CGameState::initMapObjects()
{
logGlobal->debug("\tObject initialization");
VLC->creh->removeBonusesFromAllCreatures();
// objCaller->preInit();
for(CGObjectInstance *obj : map->objects)

View File

@@ -1170,10 +1170,6 @@ void CModHandler::load()
allMods[modName].validation = CModInfo::FAILED;
logMod->info("\tLoading mod data: %d ms", timer.getDiff());
VLC->creh->loadCrExpBon();
VLC->creh->buildBonusTreeForTiers(); //do that after all new creatures are loaded
identifiers.finalize();
logMod->info("\tResolving identifiers: %d ms", timer.getDiff());