1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-12-01 23:12:49 +02:00

Nullkiller: update / fix build, core changes required for Nullkiller AI

This commit is contained in:
Andrii Danylchenko
2021-05-16 20:53:11 +03:00
committed by Andrii Danylchenko
parent b4241670ba
commit 3fa7e0976f
28 changed files with 379 additions and 233 deletions

View File

@@ -1,12 +1,12 @@
/*
* CommonConstructors.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
*
*/
* CommonConstructors.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 "CommonConstructors.h"
@@ -29,7 +29,7 @@ bool CObstacleConstructor::isStaticObject()
return true;
}
CTownInstanceConstructor::CTownInstanceConstructor():
CTownInstanceConstructor::CTownInstanceConstructor() :
faction(nullptr)
{
}
@@ -47,7 +47,7 @@ void CTownInstanceConstructor::initTypeData(const JsonNode & input)
void CTownInstanceConstructor::afterLoadFinalization()
{
assert(faction);
for (auto entry : filtersJson.Struct())
for(auto entry : filtersJson.Struct())
{
filters[entry.first] = LogicalExpression<BuildingID>(entry.second, [this](const JsonNode & node)
{
@@ -79,7 +79,7 @@ CGObjectInstance * CTownInstanceConstructor::create(const ObjectTemplate & tmpl)
void CTownInstanceConstructor::configureObject(CGObjectInstance * object, CRandomGenerator & rng) const
{
auto templ = getOverride(object->cb->getTile(object->pos)->terType, object);
if (templ)
if(templ)
object->appearance = templ.get();
}
@@ -91,15 +91,17 @@ CHeroInstanceConstructor::CHeroInstanceConstructor()
void CHeroInstanceConstructor::initTypeData(const JsonNode & input)
{
VLC->modh->identifiers.requestIdentifier("heroClass", input["heroClass"],
[&](si32 index) { heroClass = VLC->heroh->classes[index]; });
VLC->modh->identifiers.requestIdentifier(
"heroClass",
input["heroClass"],
[&](si32 index) { heroClass = VLC->heroh->classes[index]; });
filtersJson = input["filters"];
}
void CHeroInstanceConstructor::afterLoadFinalization()
{
for (auto entry : filtersJson.Struct())
for(auto entry : filtersJson.Struct())
{
filters[entry.first] = LogicalExpression<HeroTypeID>(entry.second, [](const JsonNode & node)
{
@@ -117,7 +119,7 @@ bool CHeroInstanceConstructor::objectFilter(const CGObjectInstance * object, con
return hero->type->ID == id;
};
if (filters.count(templ.stringID))
if(filters.count(templ.stringID))
{
return filters.at(templ.stringID).test(heroTest);
}
@@ -175,9 +177,9 @@ CGObjectInstance * CDwellingInstanceConstructor::create(const ObjectTemplate & t
CGDwelling * obj = createTyped(tmpl);
obj->creatures.resize(availableCreatures.size());
for (auto & entry : availableCreatures)
for(auto & entry : availableCreatures)
{
for (const CCreature * cre : entry)
for(const CCreature * cre : entry)
obj->creatures.back().second.push_back(cre->idNumber);
}
return obj;
@@ -190,34 +192,34 @@ void CDwellingInstanceConstructor::configureObject(CGObjectInstance * object, CR
dwelling->creatures.clear();
dwelling->creatures.reserve(availableCreatures.size());
for (auto & entry : availableCreatures)
for(auto & entry : availableCreatures)
{
dwelling->creatures.resize(dwelling->creatures.size() + 1);
for (const CCreature * cre : entry)
for(const CCreature * cre : entry)
dwelling->creatures.back().second.push_back(cre->idNumber);
}
bool guarded = false; //TODO: serialize for sanity
if (guards.getType() == JsonNode::JsonType::DATA_BOOL) //simple switch
if(guards.getType() == JsonNode::JsonType::DATA_BOOL) //simple switch
{
if (guards.Bool())
if(guards.Bool())
{
guarded = true;
}
}
else if (guards.getType() == JsonNode::JsonType::DATA_VECTOR) //custom guards (eg. Elemental Conflux)
else if(guards.getType() == JsonNode::JsonType::DATA_VECTOR) //custom guards (eg. Elemental Conflux)
{
for (auto & stack : JsonRandom::loadCreatures(guards, rng))
for(auto & stack : JsonRandom::loadCreatures(guards, rng))
{
dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(stack.type->idNumber, stack.count));
}
}
else //default condition - creatures are of level 5 or higher
{
for (auto creatureEntry : availableCreatures)
for(auto creatureEntry : availableCreatures)
{
if (creatureEntry.at(0)->level >= 5)
if(creatureEntry.at(0)->level >= 5)
{
guarded = true;
break;
@@ -225,22 +227,22 @@ void CDwellingInstanceConstructor::configureObject(CGObjectInstance * object, CR
}
}
if (guarded)
if(guarded)
{
for (auto creatureEntry : availableCreatures)
for(auto creatureEntry : availableCreatures)
{
const CCreature * crea = creatureEntry.at(0);
dwelling->putStack (SlotID(dwelling->stacksCount()), new CStackInstance(crea->idNumber, crea->growth * 3));
dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(crea->idNumber, crea->growth * 3));
}
}
}
bool CDwellingInstanceConstructor::producesCreature(const CCreature * crea) const
{
for (auto & entry : availableCreatures)
for(auto & entry : availableCreatures)
{
for (const CCreature * cre : entry)
if (crea == cre)
for(const CCreature * cre : entry)
if(crea == cre)
return true;
}
return false;
@@ -249,9 +251,9 @@ bool CDwellingInstanceConstructor::producesCreature(const CCreature * crea) cons
std::vector<const CCreature *> CDwellingInstanceConstructor::getProducedCreatures() const
{
std::vector<const CCreature *> creatures; //no idea why it's 2D, to be honest
for (auto & entry : availableCreatures)
for(auto & entry : availableCreatures)
{
for (const CCreature * cre : entry)
for(const CCreature * cre : entry)
creatures.push_back(cre);
}
return creatures;
@@ -292,7 +294,7 @@ BankConfig CBankInstanceConstructor::generateConfig(const JsonNode & level, CRan
bc.resources = Res::ResourceSet(level["reward"]["resources"]);
bc.creatures = JsonRandom::loadCreatures(level["reward"]["creatures"], rng);
bc.artifacts = JsonRandom::loadArtifacts(level["reward"]["artifacts"], rng);
bc.spells = JsonRandom::loadSpells(level["reward"]["spells"], rng, spells);
bc.spells = JsonRandom::loadSpells(level["reward"]["spells"], rng, spells);
bc.value = static_cast<ui32>(level["value"].Float());
@@ -314,18 +316,18 @@ void CBankInstanceConstructor::configureObject(CGObjectInstance * object, CRando
si32 selectedChance = rng.nextInt(totalChance - 1);
int cumulativeChance = 0;
for (auto & node : levels)
for(auto & node : levels)
{
cumulativeChance += static_cast<int>(node["chance"].Float());
if (selectedChance < cumulativeChance)
if(selectedChance < cumulativeChance)
{
bank->setConfig(generateConfig(node, rng));
break;
bank->setConfig(generateConfig(node, rng));
break;
}
}
}
CBankInfo::CBankInfo(const JsonVector & Config):
CBankInfo::CBankInfo(const JsonVector & Config) :
config(Config)
{
assert(!Config.empty());
@@ -336,28 +338,28 @@ static void addStackToArmy(IObjectInfo::CArmyStructure & army, const CCreature *
army.totalStrength += crea->fightValue * amount;
bool walker = true;
if (crea->hasBonusOfType(Bonus::SHOOTER))
if(crea->hasBonusOfType(Bonus::SHOOTER))
{
army.shootersStrength += crea->fightValue * amount;
walker = false;
}
if (crea->hasBonusOfType(Bonus::FLYING))
if(crea->hasBonusOfType(Bonus::FLYING))
{
army.flyersStrength += crea->fightValue * amount;
walker = false;
}
if (walker)
if(walker)
army.walkersStrength += crea->fightValue * amount;
}
IObjectInfo::CArmyStructure CBankInfo::minGuards() const
{
std::vector<IObjectInfo::CArmyStructure> armies;
for (auto configEntry : config)
for(auto configEntry : config)
{
auto stacks = JsonRandom::evaluateCreatures(configEntry["guards"]);
IObjectInfo::CArmyStructure army;
for (auto & stack : stacks)
for(auto & stack : stacks)
{
assert(!stack.allowedCreatures.empty());
auto weakest = boost::range::min_element(stack.allowedCreatures, [](const CCreature * a, const CCreature * b)
@@ -374,11 +376,11 @@ IObjectInfo::CArmyStructure CBankInfo::minGuards() const
IObjectInfo::CArmyStructure CBankInfo::maxGuards() const
{
std::vector<IObjectInfo::CArmyStructure> armies;
for (auto configEntry : config)
for(auto configEntry : config)
{
auto stacks = JsonRandom::evaluateCreatures(configEntry["guards"]);
IObjectInfo::CArmyStructure army;
for (auto & stack : stacks)
for(auto & stack : stacks)
{
assert(!stack.allowedCreatures.empty());
auto strongest = boost::range::max_element(stack.allowedCreatures, [](const CCreature * a, const CCreature * b)
@@ -396,14 +398,14 @@ TPossibleGuards CBankInfo::getPossibleGuards() const
{
TPossibleGuards out;
for (const JsonNode & configEntry : config)
for(const JsonNode & configEntry : config)
{
const JsonNode & guardsInfo = configEntry["guards"];
auto stacks = JsonRandom::evaluateCreatures(guardsInfo);
IObjectInfo::CArmyStructure army;
for (auto stack : stacks)
for(auto stack : stacks)
{
army.totalStrength += stack.allowedCreatures.front()->AIValue * (stack.minAmount + stack.maxAmount) / 2;
//TODO: add fields for flyers, walkers etc...
@@ -415,34 +417,78 @@ TPossibleGuards CBankInfo::getPossibleGuards() const
return out;
}
std::vector<PossibleReward<TResources>> CBankInfo::getPossibleResourcesReward() const
{
std::vector<PossibleReward<TResources>> result;
for(const JsonNode & configEntry : config)
{
const JsonNode & resourcesInfo = configEntry["reward"]["resources"];
if(!resourcesInfo.isNull())
{
result.push_back(
PossibleReward<TResources>(
configEntry["chance"].Integer(),
TResources(resourcesInfo)
));
}
}
return result;
}
std::vector<PossibleReward<CStackBasicDescriptor>> CBankInfo::getPossibleCreaturesReward() const
{
std::vector<PossibleReward<CStackBasicDescriptor>> aproximateReward;
for(const JsonNode & configEntry : config)
{
const JsonNode & guardsInfo = configEntry["reward"]["creatures"];
auto stacks = JsonRandom::evaluateCreatures(guardsInfo);
for(auto stack : stacks)
{
auto creature = stack.allowedCreatures.front();
aproximateReward.push_back(
PossibleReward<CStackBasicDescriptor>(
configEntry["chance"].Integer(),
CStackBasicDescriptor(creature, (stack.minAmount + stack.maxAmount) / 2)));
}
}
return aproximateReward;
}
bool CBankInfo::givesResources() const
{
for (const JsonNode & node : config)
if (!node["reward"]["resources"].isNull())
for(const JsonNode & node : config)
if(!node["reward"]["resources"].isNull())
return true;
return false;
}
bool CBankInfo::givesArtifacts() const
{
for (const JsonNode & node : config)
if (!node["reward"]["artifacts"].isNull())
for(const JsonNode & node : config)
if(!node["reward"]["artifacts"].isNull())
return true;
return false;
}
bool CBankInfo::givesCreatures() const
{
for (const JsonNode & node : config)
if (!node["reward"]["creatures"].isNull())
for(const JsonNode & node : config)
if(!node["reward"]["creatures"].isNull())
return true;
return false;
}
bool CBankInfo::givesSpells() const
{
for (const JsonNode & node : config)
if (!node["reward"]["spells"].isNull())
for(const JsonNode & node : config)
if(!node["reward"]["spells"].isNull())
return true;
return false;
}