mirror of
https://github.com/vcmi/vcmi.git
synced 2026-06-19 22:57:37 +02:00
Nullkiller: various fixes for town portal and other
This commit is contained in:
committed by
Andrii Danylchenko
parent
1a69a43f09
commit
e95ccda5de
@@ -258,6 +258,29 @@ bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isObjectPassable(const CGObjectInstance * obj)
|
||||
{
|
||||
return isObjectPassable(obj, ai->playerID, cb->getPlayerRelations(obj->tempOwner, ai->playerID));
|
||||
}
|
||||
|
||||
// Pathfinder internal helper
|
||||
bool isObjectPassable(const CGObjectInstance * obj, PlayerColor playerColor, PlayerRelations::PlayerRelations objectRelations)
|
||||
{
|
||||
if((obj->ID == Obj::GARRISON || obj->ID == Obj::GARRISON2)
|
||||
&& objectRelations != PlayerRelations::ENEMIES)
|
||||
return true;
|
||||
|
||||
if(obj->ID == Obj::BORDER_GATE)
|
||||
{
|
||||
auto quest = dynamic_cast<const CGKeys *>(obj);
|
||||
|
||||
if(quest->passableFor(playerColor))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isBlockedBorderGate(int3 tileToHit) //TODO: is that function needed? should be handled by pathfinder
|
||||
{
|
||||
if(cb->getTile(tileToHit)->topVisitableId() != Obj::BORDER_GATE)
|
||||
|
||||
@@ -167,7 +167,9 @@ void foreach_neighbour(const int3 & pos, std::function<void(const int3 & pos)> f
|
||||
void foreach_neighbour(CCallback * cbp, const int3 & pos, std::function<void(CCallback * cbp, const int3 & pos)> foo); // avoid costly retrieval of thread-specific pointer
|
||||
|
||||
bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater);
|
||||
bool isBlockedBorderGate(int3 tileToHit);
|
||||
//bool isBlockedBorderGate(int3 tileToHit);
|
||||
bool isObjectPassable(const CGObjectInstance * obj);
|
||||
bool isObjectPassable(const CGObjectInstance * obj, PlayerColor playerColor, PlayerRelations::PlayerRelations objectRelations);
|
||||
bool isBlockVisitObj(const int3 & pos);
|
||||
|
||||
bool isWeeklyRevisitable(const CGObjectInstance * obj);
|
||||
|
||||
@@ -113,7 +113,8 @@ const CGObjectInstance * ObjectClusterizer::getBlocker(const AIPath & path) cons
|
||||
|| blocker->ID == Obj::QUEST_GUARD
|
||||
|| blocker->ID == Obj::BORDER_GATE)
|
||||
{
|
||||
return blocker;
|
||||
if(!isObjectPassable(blocker))
|
||||
return blocker;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ Goals::TGoalVec ClusterBehavior::decomposeCluster(std::shared_ptr<ObjectCluster>
|
||||
{
|
||||
blockerPaths.back().nodes.insert(blockerPaths.back().nodes.begin(), *node);
|
||||
|
||||
if(node->coord == blockerPos)
|
||||
if(node->coord == blockerPos || cb->getGuardingCreaturePosition(node->coord) == blockerPos)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
#include "../../../lib/PathfinderUtil.h"
|
||||
#include "../../../lib/CPlayerState.h"
|
||||
|
||||
/// 1-3 - position on map, 4 - layer (air, water, land), 5 - chain (normal, battle, spellcast and combinations)
|
||||
boost::multi_array<AIPathNode, 5> nodes;
|
||||
|
||||
AINodeStorage::AINodeStorage(const int3 & Sizes)
|
||||
: sizes(Sizes)
|
||||
{
|
||||
@@ -827,6 +830,14 @@ void AINodeStorage::calculateTownPortalTeleportations(std::vector<CGPathNode *>
|
||||
actorsOfInitial.insert(aiNode->actor->baseActor);
|
||||
}
|
||||
|
||||
std::map<const CGHeroInstance *, int> maskMap;
|
||||
|
||||
for(std::shared_ptr<ChainActor> basicActor : actors)
|
||||
{
|
||||
if(basicActor->hero)
|
||||
maskMap[basicActor->hero] = basicActor->chainMask;
|
||||
}
|
||||
|
||||
for(const ChainActor * actor : actorsOfInitial)
|
||||
{
|
||||
if(!actor->hero)
|
||||
@@ -851,8 +862,15 @@ void AINodeStorage::calculateTownPortalTeleportations(std::vector<CGPathNode *>
|
||||
for(const CGTownInstance * targetTown : towns)
|
||||
{
|
||||
// TODO: allow to hide visiting hero in garrison
|
||||
if(targetTown->visitingHero && targetTown->visitingHero != actor->hero)
|
||||
continue;
|
||||
if(targetTown->visitingHero)
|
||||
{
|
||||
auto basicMask = maskMap[targetTown->visitingHero.get()];
|
||||
bool heroIsInChain = (actor->chainMask & basicMask) != 0;
|
||||
bool sameActorInTown = actor->chainMask == basicMask;
|
||||
|
||||
if(sameActorInTown || !heroIsInChain)
|
||||
continue;
|
||||
}
|
||||
|
||||
auto nodeOptional = townPortalFinder.createTownPortalNode(targetTown);
|
||||
|
||||
|
||||
@@ -106,8 +106,6 @@ class AINodeStorage : public INodeStorage
|
||||
private:
|
||||
int3 sizes;
|
||||
|
||||
/// 1-3 - position on map, 4 - layer (air, water, land), 5 - chain (normal, battle, spellcast and combinations)
|
||||
boost::multi_array<AIPathNode, 5> nodes;
|
||||
const CPlayerSpecificInfoCallback * cb;
|
||||
const VCAI * ai;
|
||||
std::unique_ptr<FuzzyHelper> dangerEvaluator;
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace AIPathfinding
|
||||
AIPathNode * dstMode,
|
||||
const AIPathNode * srcNode) const override;
|
||||
|
||||
virtual bool canAct(const AIPathNode * source) const;
|
||||
virtual bool canAct(const AIPathNode * source) const override;
|
||||
|
||||
virtual const ChainActor * getActor(const ChainActor * sourceActor) const override;
|
||||
|
||||
|
||||
@@ -26,20 +26,12 @@ namespace AIPathfinding
|
||||
if(source.node->action == CGPathNode::ENodeAction::BLOCKING_VISIT
|
||||
|| source.node->action == CGPathNode::ENodeAction::VISIT)
|
||||
{
|
||||
if(source.nodeObject)
|
||||
if(source.nodeObject
|
||||
&& isObjectPassable(source.nodeObject, pathfinderHelper->hero->tempOwner, source.objectRelations))
|
||||
{
|
||||
if((source.nodeObject->ID == Obj::GARRISON || source.nodeObject->ID == Obj::GARRISON2)
|
||||
&& source.heroRelations != PlayerRelations::ENEMIES)
|
||||
return;
|
||||
|
||||
if(source.nodeObject->ID == Obj::BORDER_GATE)
|
||||
{
|
||||
auto quest = dynamic_cast<const CGBorderGate *>(source.nodeObject);
|
||||
|
||||
if(quest->wasMyColorVisited(pathfinderHelper->hero->tempOwner))
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// we can not directly bypass objects, we need to interact with them first
|
||||
destination.node->theNodeBefore = source.node;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ extern FuzzyHelper * fh;
|
||||
|
||||
class CGVisitableOPW;
|
||||
|
||||
const float SAFE_ATTACK_CONSTANT = 1.5;
|
||||
const float SAFE_ATTACK_CONSTANT = 1.2;
|
||||
|
||||
//one thread may be turn of AI and another will be handling a side effect for AI2
|
||||
boost::thread_specific_ptr<CCallback> cb;
|
||||
@@ -758,13 +758,12 @@ void VCAI::makeTurn()
|
||||
boost::shared_lock<boost::shared_mutex> gsLock(CGameState::mutex);
|
||||
setThreadName("VCAI::makeTurn");
|
||||
|
||||
switch(cb->getDate(Date::DAY_OF_WEEK))
|
||||
{
|
||||
case 1:
|
||||
if(cb->getDate(Date::DAY_OF_WEEK) == 1)
|
||||
{
|
||||
townVisitsThisWeek.clear();
|
||||
std::vector<const CGObjectInstance *> objs;
|
||||
retrieveVisitableObjs(objs, true);
|
||||
|
||||
for(const CGObjectInstance * obj : objs)
|
||||
{
|
||||
if(isWeeklyRevisitable(obj))
|
||||
@@ -773,15 +772,15 @@ void VCAI::makeTurn()
|
||||
vstd::erase_if_present(alreadyVisited, obj);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
markHeroAbleToExplore(primaryHero());
|
||||
visitedHeroes.clear();
|
||||
|
||||
if(cb->getDate(Date::DAY) == 1)
|
||||
{
|
||||
retrieveVisitableObjs();
|
||||
cb->sendMessage("vcmieagles");
|
||||
}
|
||||
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user