mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
Nullkiller: fix priorities after refactoring
This commit is contained in:
parent
1349eff201
commit
cebb5b296b
@ -36,9 +36,9 @@ extern const int GOLD_RESERVE;
|
||||
|
||||
enum HeroRole
|
||||
{
|
||||
SCOUT,
|
||||
SCOUT = 0,
|
||||
|
||||
MAIN
|
||||
MAIN = 1
|
||||
};
|
||||
|
||||
//provisional class for AI to store a reference to an owned hero object
|
||||
|
@ -363,12 +363,12 @@ ArmyUpgradeInfo ArmyManager::calculateCreateresUpgrade(
|
||||
{
|
||||
SlotInfo upgradedArmy;
|
||||
|
||||
upgradedArmy.creature = upgrade.upgradedCreature;
|
||||
upgradedArmy.creature = upgrade.upgradedCreature.toCreature();
|
||||
upgradedArmy.count = upgrade.count;
|
||||
upgradedArmy.power = evaluateStackPower(upgradedArmy.creature, upgradedArmy.count);
|
||||
|
||||
auto slotToReplace = std::find_if(result.resultingArmy.begin(), result.resultingArmy.end(), [&](const SlotInfo & slot) -> bool {
|
||||
return slot.count == upgradedArmy.count && slot.creature == upgrade.initialCreature;
|
||||
return slot.count == upgradedArmy.count && slot.creature->idNumber == upgrade.initialCreature;
|
||||
});
|
||||
|
||||
resourcesLeft -= upgrade.cost;
|
||||
|
@ -129,10 +129,12 @@ TGoalVec CompleteQuest::missionArt() const
|
||||
if(!solutions.empty())
|
||||
return solutions;
|
||||
|
||||
/*for(auto art : q.quest->m5arts)
|
||||
CaptureObjectsBehavior findArts;
|
||||
|
||||
for(auto art : q.quest->m5arts)
|
||||
{
|
||||
solutions.push_back(sptr(GetArtOfType(art))); //TODO: transport?
|
||||
}*/
|
||||
solutions.push_back(sptr(CaptureObjectsBehavior().ofType(Obj::ARTIFACT, art)));
|
||||
}
|
||||
|
||||
return solutions;
|
||||
}
|
||||
@ -223,21 +225,18 @@ TGoalVec CompleteQuest::missionDestroyObj() const
|
||||
if(!obj)
|
||||
return CaptureObjectsBehavior(q.obj).decompose();
|
||||
|
||||
if(obj->ID == Obj::HERO)
|
||||
auto relations = cb->getPlayerRelations(ai->playerID, obj->tempOwner);
|
||||
|
||||
//if(relations == PlayerRelations::SAME_PLAYER)
|
||||
//{
|
||||
// auto heroToProtect = cb->getHero(obj->id);
|
||||
|
||||
// //solutions.push_back(sptr(GatherArmy().sethero(heroToProtect)));
|
||||
//}
|
||||
//else
|
||||
if(relations == PlayerRelations::ENEMIES)
|
||||
{
|
||||
auto relations = cb->getPlayerRelations(ai->playerID, obj->tempOwner);
|
||||
|
||||
//if(relations == PlayerRelations::SAME_PLAYER)
|
||||
//{
|
||||
// auto heroToProtect = cb->getHero(obj->id);
|
||||
|
||||
// //solutions.push_back(sptr(GatherArmy().sethero(heroToProtect)));
|
||||
//}
|
||||
//else
|
||||
if(relations == PlayerRelations::ENEMIES)
|
||||
{
|
||||
return CaptureObjectsBehavior(obj).decompose();
|
||||
}
|
||||
return CaptureObjectsBehavior(obj).decompose();
|
||||
}
|
||||
|
||||
return TGoalVec();
|
||||
|
@ -35,14 +35,9 @@ Goals::TGoalVec DefenceBehavior::decompose() const
|
||||
{
|
||||
Goals::TGoalVec tasks;
|
||||
|
||||
auto heroes = cb->getHeroesInfo();
|
||||
|
||||
if(heroes.size())
|
||||
for(auto town : cb->getTownsInfo())
|
||||
{
|
||||
for(auto town : cb->getTownsInfo())
|
||||
{
|
||||
evaluateDefence(tasks, town);
|
||||
}
|
||||
evaluateDefence(tasks, town);
|
||||
}
|
||||
|
||||
return tasks;
|
||||
|
@ -474,7 +474,7 @@ public:
|
||||
auto army = path.heroArmy;
|
||||
|
||||
vstd::amax(evaluationContext.armyLossPersentage, path.getTotalArmyLoss() / (double)path.getHeroStrength());
|
||||
vstd::amax(evaluationContext.heroRole, ai->ah->getHeroRole(heroPtr));
|
||||
evaluationContext.heroRole = ai->ah->getHeroRole(heroPtr);
|
||||
evaluationContext.goldReward += getGoldReward(target, hero);
|
||||
evaluationContext.armyReward += getArmyReward(target, hero, army, checkGold);
|
||||
evaluationContext.skillReward += getSkillReward(target, hero, evaluationContext.heroRole);
|
||||
@ -604,17 +604,18 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task)
|
||||
}
|
||||
assert(result >= 0);
|
||||
|
||||
#ifdef VCMI_TRACE_PATHFINDER
|
||||
logAi->trace("Evaluated %s, loss: %f, turns main: %f, scout: %f, gold: %d, cost: %d, army gain: %d, danger: %d, role: %s, strategical value: %f, cwr: %f, result %f",
|
||||
#ifdef AI_TRACE_LEVEL >= 1
|
||||
logAi->trace("Evaluated %s, loss: %f, turn: %d, turns main: %f, scout: %f, gold: %d, cost: %d, army gain: %d, danger: %d, role: %s, strategical value: %f, cwr: %f, result %f",
|
||||
task->toString(),
|
||||
evaluationContext.armyLossPersentage,
|
||||
(int)evaluationContext.turn,
|
||||
evaluationContext.movementCostByRole[HeroRole::MAIN],
|
||||
evaluationContext.movementCostByRole[HeroRole::SCOUT],
|
||||
evaluationContext.goldReward,
|
||||
evaluationContext.goldCost,
|
||||
evaluationContext.armyReward,
|
||||
evaluationContext.danger,
|
||||
evaluationContext.heroRole ? "scout" : "main",
|
||||
evaluationContext.heroRole == HeroRole::MAIN ? "main" : "scout",
|
||||
evaluationContext.strategicalValue,
|
||||
evaluationContext.closestWayRatio,
|
||||
result);
|
||||
|
@ -214,7 +214,7 @@ void AINodeStorage::commit(
|
||||
destination->theNodeBefore = source->theNodeBefore;
|
||||
destination->chainOther = nullptr;
|
||||
|
||||
#if AI_TRACE_LEVEL >= 2
|
||||
#if PATHFINDER_TRACE_LEVEL >= 2
|
||||
logAi->trace(
|
||||
"Commited %s -> %s, cost: %f, turn: %s, mp: %d, hero: %s, mask: %x, army: %lld",
|
||||
source->coord.toString(),
|
||||
@ -422,7 +422,7 @@ void AINodeStorage::calculateHeroChain(
|
||||
|| (node->action == CGPathNode::ENodeAction::UNKNOWN && node->actor->hero)
|
||||
|| (node->actor->chainMask & srcNode->actor->chainMask) != 0)
|
||||
{
|
||||
#if AI_TRACE_LEVEL >= 2
|
||||
#if PATHFINDER_TRACE_LEVEL >= 2
|
||||
logAi->trace(
|
||||
"Skip exchange %s[%x] -> %s[%x] at %s because of %s",
|
||||
node->actor->toString(),
|
||||
@ -439,7 +439,7 @@ void AINodeStorage::calculateHeroChain(
|
||||
continue;
|
||||
}
|
||||
|
||||
#if AI_TRACE_LEVEL >= 2
|
||||
#if PATHFINDER_TRACE_LEVEL >= 2
|
||||
logAi->trace(
|
||||
"Thy exchange %s[%x] -> %s[%x] at %s",
|
||||
node->actor->toString(),
|
||||
@ -464,7 +464,7 @@ void AINodeStorage::calculateHeroChain(
|
||||
&& (other->armyLoss == 0 || other->armyLoss < other->actor->armyValue)
|
||||
&& carrier->actor->canExchange(other->actor))
|
||||
{
|
||||
#if AI_TRACE_LEVEL >= 2
|
||||
#if PATHFINDER_TRACE_LEVEL >= 2
|
||||
logAi->trace(
|
||||
"Exchange allowed %s[%x] -> %s[%x] at %s",
|
||||
other->actor->toString(),
|
||||
@ -481,7 +481,7 @@ void AINodeStorage::calculateHeroChain(
|
||||
|
||||
if(hasLessMp && hasLessExperience)
|
||||
{
|
||||
#if AI_TRACE_LEVEL >= 2
|
||||
#if PATHFINDER_TRACE_LEVEL >= 2
|
||||
logAi->trace("Exchange at %s is ineficient. Blocked.", carrier->coord.toString());
|
||||
#endif
|
||||
return;
|
||||
@ -505,7 +505,7 @@ void AINodeStorage::addHeroChain(const std::vector<ExchangeCandidate> & result)
|
||||
|
||||
if(!chainNodeOptional)
|
||||
{
|
||||
#if AI_TRACE_LEVEL >= 2
|
||||
#if PATHFINDER_TRACE_LEVEL >= 2
|
||||
logAi->trace("Exchange at %s can not allocate node. Blocked.", carrier->coord.toString());
|
||||
#endif
|
||||
continue;
|
||||
@ -515,7 +515,7 @@ void AINodeStorage::addHeroChain(const std::vector<ExchangeCandidate> & result)
|
||||
|
||||
if(exchangeNode->action != CGPathNode::ENodeAction::UNKNOWN)
|
||||
{
|
||||
#if AI_TRACE_LEVEL >= 2
|
||||
#if PATHFINDER_TRACE_LEVEL >= 2
|
||||
logAi->trace("Exchange at %s node is already in use. Blocked.", carrier->coord.toString());
|
||||
#endif
|
||||
continue;
|
||||
@ -523,7 +523,7 @@ void AINodeStorage::addHeroChain(const std::vector<ExchangeCandidate> & result)
|
||||
|
||||
if(exchangeNode->turns != 0xFF && exchangeNode->cost < chainInfo.cost)
|
||||
{
|
||||
#if AI_TRACE_LEVEL >= 2
|
||||
#if PATHFINDER_TRACE_LEVEL >= 2
|
||||
logAi->trace(
|
||||
"Exchange at %s is is not effective enough. %f < %f",
|
||||
exchangeNode->coord.toString(),
|
||||
@ -544,7 +544,7 @@ void AINodeStorage::addHeroChain(const std::vector<ExchangeCandidate> & result)
|
||||
exchangeNode->chainOther = other;
|
||||
exchangeNode->armyLoss = chainInfo.armyLoss;
|
||||
|
||||
#if AI_TRACE_LEVEL >= 2
|
||||
#if PATHFINDER_TRACE_LEVEL >= 2
|
||||
logAi->trace(
|
||||
"Chain accepted at %s %s -> %s, mask %x, cost %f, turn: %s, mp: %d, army %i",
|
||||
exchangeNode->coord.toString(),
|
||||
@ -858,7 +858,7 @@ void AINodeStorage::calculateTownPortalTeleportations(std::vector<CGPathNode *>
|
||||
|
||||
if(nodeOptional)
|
||||
{
|
||||
#if AI_TRACE_LEVEL >= 1
|
||||
#if PATHFINDER_TRACE_LEVEL >= 1
|
||||
logAi->trace("Adding town portal node at %s", targetTown->name);
|
||||
#endif
|
||||
initialNodes.push_back(nodeOptional.get());
|
||||
@ -897,7 +897,7 @@ bool AINodeStorage::hasBetterChain(
|
||||
{
|
||||
if(node.cost < candidateNode->cost)
|
||||
{
|
||||
#if AI_TRACE_LEVEL >= 2
|
||||
#if PATHFINDER_TRACE_LEVEL >= 2
|
||||
logAi->trace(
|
||||
"Block ineficient battle move %s->%s, hero: %s[%X], army %lld, mp diff: %i",
|
||||
source->coord.toString(),
|
||||
@ -921,7 +921,7 @@ bool AINodeStorage::hasBetterChain(
|
||||
if(nodeArmyValue > candidateArmyValue
|
||||
&& node.cost <= candidateNode->cost)
|
||||
{
|
||||
#if AI_TRACE_LEVEL >= 2
|
||||
#if PATHFINDER_TRACE_LEVEL >= 2
|
||||
logAi->trace(
|
||||
"Block ineficient move because of stronger army %s->%s, hero: %s[%X], army %lld, mp diff: %i",
|
||||
source->coord.toString(),
|
||||
|
@ -10,8 +10,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define VCMI_TRACE_PATHFINDER 1
|
||||
#define AI_TRACE_LEVEL 1
|
||||
#define PATHFINDER_TRACE_LEVEL 1
|
||||
#define AI_TRACE_LEVEL 2
|
||||
|
||||
#include "../../../lib/CPathfinder.h"
|
||||
#include "../../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
@ -36,7 +36,8 @@ namespace AIPathfinding
|
||||
return dynamic_cast<const IQuestObject *>(questInfo.obj)->checkQuest(node->actor->hero);
|
||||
}
|
||||
|
||||
return questInfo.quest->checkQuest(node->actor->hero);
|
||||
return questInfo.quest->progress == CQuest::NOT_ACTIVE
|
||||
|| questInfo.quest->checkQuest(node->actor->hero);
|
||||
}
|
||||
|
||||
Goals::TSubgoal QuestAction::decompose(const CGHeroInstance * hero) const
|
||||
|
@ -172,7 +172,7 @@ bool HeroExchangeMap::canExchange(const ChainActor * other)
|
||||
if(!resources.canAfford(actor->armyCost + other->armyCost))
|
||||
{
|
||||
result = false;
|
||||
#if AI_TRACE_LEVEL >= 2
|
||||
#if PATHFINDER_TRACE_LEVEL >= 2
|
||||
logAi->trace(
|
||||
"Can not afford exchange because of total cost %s but we have %s",
|
||||
(actor->armyCost + other->armyCost).toString(),
|
||||
@ -191,7 +191,7 @@ bool HeroExchangeMap::canExchange(const ChainActor * other)
|
||||
if(other->creatureSet->Slots().size())
|
||||
reinforcment += ai->ah->howManyReinforcementsCanGet(actor->creatureSet, other->creatureSet);
|
||||
|
||||
#if AI_TRACE_LEVEL >= 2
|
||||
#if PATHFINDER_TRACE_LEVEL >= 2
|
||||
logAi->trace(
|
||||
"Exchange %s->%s reinforcement: %d, %f%%",
|
||||
actor->toString(),
|
||||
|
@ -37,7 +37,7 @@ namespace AIPathfinding
|
||||
|
||||
if(virtualBoat && tryEmbarkVirtualBoat(destination, source, virtualBoat))
|
||||
{
|
||||
#ifdef VCMI_TRACE_PATHFINDER
|
||||
#if PATHFINDER_TRACE_LEVEL >= 1
|
||||
logAi->trace("Embarking to virtual boat while moving %s -> %s!", source.coord.toString(), destination.coord.toString());
|
||||
#endif
|
||||
}
|
||||
@ -138,7 +138,7 @@ namespace AIPathfinding
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef VCMI_TRACE_PATHFINDER
|
||||
#if PATHFINDER_TRACE_LEVEL >= 1
|
||||
logAi->trace(
|
||||
"Special transition node already allocated. Blocked moving %s -> %s",
|
||||
source.coord.toString(),
|
||||
|
@ -102,6 +102,11 @@ namespace AIPathfinding
|
||||
auto questObj = dynamic_cast<const IQuestObject *>(destination.nodeObject);
|
||||
auto nodeHero = pathfinderHelper->hero;
|
||||
|
||||
if(destination.nodeObject->ID == Obj::QUEST_GUARD && questObj->quest->missionType == CQuest::MISSION_NONE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!destination.nodeObject->wasVisited(nodeHero->tempOwner)
|
||||
|| !questObj->checkQuest(nodeHero))
|
||||
{
|
||||
@ -154,7 +159,7 @@ namespace AIPathfinding
|
||||
|
||||
if(guardsAlreadyBypassed && srcNode->actor->allowBattle)
|
||||
{
|
||||
#ifdef VCMI_TRACE_PATHFINDER
|
||||
#if PATHFINDER_TRACE_LEVEL >= 1
|
||||
logAi->trace(
|
||||
"Bypass guard at destination while moving %s -> %s",
|
||||
source.coord.toString(),
|
||||
@ -182,7 +187,7 @@ namespace AIPathfinding
|
||||
|
||||
if(!battleNodeOptional)
|
||||
{
|
||||
#ifdef VCMI_TRACE_PATHFINDER
|
||||
#if PATHFINDER_TRACE_LEVEL >= 1
|
||||
logAi->trace(
|
||||
"Can not allocate battle node while moving %s -> %s",
|
||||
source.coord.toString(),
|
||||
@ -195,7 +200,7 @@ namespace AIPathfinding
|
||||
|
||||
if(battleNode->locked)
|
||||
{
|
||||
#ifdef VCMI_TRACE_PATHFINDER
|
||||
#if PATHFINDER_TRACE_LEVEL >= 1
|
||||
logAi->trace(
|
||||
"Block bypass guard at destination while moving %s -> %s",
|
||||
source.coord.toString(),
|
||||
@ -222,7 +227,7 @@ namespace AIPathfinding
|
||||
|
||||
battleNode->specialAction = std::make_shared<BattleAction>(destination.coord);
|
||||
|
||||
#ifdef VCMI_TRACE_PATHFINDER
|
||||
#if PATHFINDER_TRACE_LEVEL >= 1
|
||||
logAi->trace(
|
||||
"Begin bypass guard at destination with danger %s while moving %s -> %s",
|
||||
std::to_string(danger),
|
||||
|
@ -37,7 +37,7 @@ namespace AIPathfinding
|
||||
|
||||
if(blocker == BlockingReason::SOURCE_GUARDED && nodeStorage->getAINode(source.node)->actor->allowBattle)
|
||||
{
|
||||
#ifdef VCMI_TRACE_PATHFINDER
|
||||
#if PATHFINDER_TRACE_LEVEL >= 1
|
||||
logAi->trace(
|
||||
"Bypass src guard while moving from %s to %s",
|
||||
source.coord.toString(),
|
||||
|
@ -27,7 +27,8 @@ namespace AIPathfinding
|
||||
{
|
||||
// we can not directly bypass objects, we need to interact with them first
|
||||
destination.node->theNodeBefore = source.node;
|
||||
#ifdef VCMI_TRACE_PATHFINDER
|
||||
|
||||
#if PATHFINDER_TRACE_LEVEL >= 1
|
||||
logAi->trace(
|
||||
"Link src node %s to destination node %s while bypassing visitable obj",
|
||||
source.coord.toString(),
|
||||
|
@ -569,12 +569,11 @@ void VCAI::showBlockingDialog(const std::string & text, const std::vector<Compon
|
||||
{
|
||||
LOG_TRACE_PARAMS(logAi, "text '%s', askID '%i', soundID '%i', selection '%i', cancel '%i'", text % askID % soundID % selection % cancel);
|
||||
NET_EVENT_HANDLER;
|
||||
int sel = 0;
|
||||
status.addQuery(askID, boost::str(boost::format("Blocking dialog query with %d components - %s")
|
||||
% components.size() % text));
|
||||
|
||||
if(selection) //select from multiple components -> take the last one (they're indexed [1-size])
|
||||
sel = components.size();
|
||||
auto hero = nullkiller->getActiveHero();
|
||||
auto target = nullkiller->getTargetTile();
|
||||
|
||||
if(!selection && cancel)
|
||||
{
|
||||
@ -582,8 +581,6 @@ void VCAI::showBlockingDialog(const std::string & text, const std::vector<Compon
|
||||
{
|
||||
//yes&no -> always answer yes, we are a brave AI :)
|
||||
auto answer = 1;
|
||||
auto hero = nullkiller->getActiveHero();
|
||||
auto target = nullkiller->getTargetTile();
|
||||
auto objects = cb->getVisitableObjs(target);
|
||||
|
||||
if(hero.validAndSet() && target.valid() && objects.size())
|
||||
@ -608,14 +605,21 @@ void VCAI::showBlockingDialog(const std::string & text, const std::vector<Compon
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Find better way to understand it is Chest of Treasures
|
||||
if(components.size() == 2 && components.front().id == Component::RESOURCE)
|
||||
{
|
||||
sel = 1; // for now lets pick gold from a chest.
|
||||
}
|
||||
|
||||
requestActionASAP([=]()
|
||||
{
|
||||
int sel = 0;
|
||||
|
||||
if(selection) //select from multiple components -> take the last one (they're indexed [1-size])
|
||||
sel = components.size();
|
||||
|
||||
// TODO: Find better way to understand it is Chest of Treasures
|
||||
if(components.size() == 2
|
||||
&& components.front().id == Component::RESOURCE
|
||||
&& ah->getHeroRole(hero) != HeroRole::MAIN)
|
||||
{
|
||||
sel = 1; // for now lets pick gold from a chest.
|
||||
}
|
||||
|
||||
answerQuery(askID, sel);
|
||||
});
|
||||
}
|
||||
@ -2026,6 +2030,9 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj)
|
||||
break;
|
||||
case Obj::TREE_OF_KNOWLEDGE:
|
||||
{
|
||||
if(ai->ah->getHeroRole(h) == HeroRole::SCOUT)
|
||||
return false;
|
||||
|
||||
TResources myRes = cb->getResourceAmount();
|
||||
if(myRes[Res::GOLD] < 2000 || myRes[Res::GEMS] < 10)
|
||||
return false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user