2019-01-15 06:00:00 +03:00
|
|
|
/*
|
|
|
|
* PathfinderUtil.h, 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
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
|
2023-06-21 13:46:09 +03:00
|
|
|
#include "../TerrainHandler.h"
|
|
|
|
#include "../mapObjects/CGObjectInstance.h"
|
|
|
|
#include "../mapping/CMapDefines.h"
|
2023-06-23 18:02:48 +03:00
|
|
|
#include "../gameState/CGameState.h"
|
2023-06-21 15:38:57 +03:00
|
|
|
#include "CGPathNode.h"
|
2019-01-15 06:00:00 +03:00
|
|
|
|
2022-07-26 16:07:42 +03:00
|
|
|
VCMI_LIB_NAMESPACE_BEGIN
|
|
|
|
|
2019-01-15 06:00:00 +03:00
|
|
|
namespace PathfinderUtil
|
|
|
|
{
|
2024-05-07 19:17:05 +00:00
|
|
|
using FoW = boost::multi_array<ui8, 3>;
|
2019-01-15 06:00:00 +03:00
|
|
|
using ELayer = EPathfindingLayer;
|
|
|
|
|
2023-08-20 00:22:31 +03:00
|
|
|
template<EPathfindingLayer::Type layer>
|
2023-11-13 12:09:55 +02:00
|
|
|
EPathAccessibility evaluateAccessibility(const int3 & pos, const TerrainTile & tinfo, const FoW & fow, const PlayerColor player, const CGameState * gs)
|
2019-01-15 06:00:00 +03:00
|
|
|
{
|
2024-05-07 19:17:05 +00:00
|
|
|
if(!fow[pos.z][pos.x][pos.y])
|
2023-06-21 15:38:57 +03:00
|
|
|
return EPathAccessibility::BLOCKED;
|
2019-01-15 06:00:00 +03:00
|
|
|
|
|
|
|
switch(layer)
|
|
|
|
{
|
|
|
|
case ELayer::LAND:
|
|
|
|
case ELayer::SAIL:
|
2024-07-13 18:37:13 +00:00
|
|
|
if(tinfo.visitable())
|
2019-01-15 06:00:00 +03:00
|
|
|
{
|
2025-03-19 14:40:45 +00:00
|
|
|
auto frontVisitable = gs->getObjInstance(tinfo.visitableObjects.front());
|
|
|
|
auto backVisitable = gs->getObjInstance(tinfo.visitableObjects.front());
|
|
|
|
|
|
|
|
if(frontVisitable->ID == Obj::SANCTUARY && backVisitable->ID == Obj::HERO && backVisitable->getOwner() != player) //non-owned hero stands on Sanctuary
|
2019-01-15 06:00:00 +03:00
|
|
|
{
|
2023-06-21 15:38:57 +03:00
|
|
|
return EPathAccessibility::BLOCKED;
|
2019-01-15 06:00:00 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2025-02-06 14:18:18 +00:00
|
|
|
bool hasBlockedVisitable = false;
|
|
|
|
bool hasVisitable = false;
|
|
|
|
|
2025-03-19 14:40:45 +00:00
|
|
|
for(const auto objID : tinfo.visitableObjects)
|
2019-01-15 06:00:00 +03:00
|
|
|
{
|
2025-03-19 14:40:45 +00:00
|
|
|
auto obj = gs->getObjInstance(objID);
|
|
|
|
|
2023-06-21 16:49:44 +03:00
|
|
|
if(obj->isBlockedVisitable())
|
2025-02-06 14:18:18 +00:00
|
|
|
hasBlockedVisitable = true;
|
|
|
|
else if(!obj->passableFor(player) && obj->ID != Obj::EVENT)
|
|
|
|
hasVisitable = true;
|
2019-01-15 06:00:00 +03:00
|
|
|
}
|
2025-02-06 14:18:18 +00:00
|
|
|
|
|
|
|
if(hasBlockedVisitable)
|
|
|
|
return EPathAccessibility::BLOCKVIS;
|
|
|
|
if(hasVisitable)
|
|
|
|
return EPathAccessibility::VISITABLE;
|
|
|
|
|
|
|
|
return EPathAccessibility::ACCESSIBLE;
|
2019-01-15 06:00:00 +03:00
|
|
|
}
|
|
|
|
}
|
2024-07-13 18:37:13 +00:00
|
|
|
else if(tinfo.blocked())
|
2019-01-15 06:00:00 +03:00
|
|
|
{
|
2023-06-21 15:38:57 +03:00
|
|
|
return EPathAccessibility::BLOCKED;
|
2019-01-15 06:00:00 +03:00
|
|
|
}
|
2025-02-28 19:56:43 +00:00
|
|
|
else if(gs->guardingCreaturePosition(pos).isValid())
|
2019-01-15 06:00:00 +03:00
|
|
|
{
|
|
|
|
// Monster close by; blocked visit for battle
|
2024-05-23 18:46:03 +00:00
|
|
|
return EPathAccessibility::GUARDED;
|
2019-01-15 06:00:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ELayer::WATER:
|
2024-07-13 18:37:13 +00:00
|
|
|
if(tinfo.blocked() || tinfo.isLand())
|
2023-06-21 15:38:57 +03:00
|
|
|
return EPathAccessibility::BLOCKED;
|
2019-01-15 06:00:00 +03:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ELayer::AIR:
|
2023-06-21 17:29:28 +03:00
|
|
|
return EPathAccessibility::FLYABLE;
|
2019-01-15 06:00:00 +03:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-06-21 15:38:57 +03:00
|
|
|
return EPathAccessibility::ACCESSIBLE;
|
2019-01-15 06:00:00 +03:00
|
|
|
}
|
|
|
|
}
|
2022-07-26 16:07:42 +03:00
|
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_END
|