mirror of
https://github.com/vcmi/vcmi.git
synced 2025-09-16 09:26:28 +02:00
refactoring with guardingCreaturePosition
This commit is contained in:
@@ -791,7 +791,7 @@ bool CGameInfoCallback::isTeleportEntrancePassable(const CGTeleport * obj, Playe
|
|||||||
return obj && obj->isEntrance() && !isTeleportChannelImpassable(obj->channel, player);
|
return obj && obj->isEntrance() && !isTeleportChannelImpassable(obj->channel, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameInfoCallback::getFreeTiles(std::vector<int3> & tiles, bool skipIfNearbyBlocked) const
|
void CGameInfoCallback::getFreeTiles(std::vector<int3> & tiles, bool skipIfNearbyGuarded) const
|
||||||
{
|
{
|
||||||
std::vector<int> floors;
|
std::vector<int> floors;
|
||||||
floors.reserve(gameState().getMap().levels());
|
floors.reserve(gameState().getMap().levels());
|
||||||
@@ -809,36 +809,19 @@ void CGameInfoCallback::getFreeTiles(std::vector<int3> & tiles, bool skipIfNearb
|
|||||||
tinfo = getTile(int3 (xd,yd,zd));
|
tinfo = getTile(int3 (xd,yd,zd));
|
||||||
if (tinfo->isLand() && tinfo->getTerrain()->isPassable() && !tinfo->blocked()) //land and free
|
if (tinfo->isLand() && tinfo->getTerrain()->isPassable() && !tinfo->blocked()) //land and free
|
||||||
{
|
{
|
||||||
bool nearbyMonsterOrBlocked = false;
|
|
||||||
if (skipIfNearbyBlocked)
|
|
||||||
{
|
|
||||||
FowTilesType nearbyTiles;
|
|
||||||
getTilesInRange( nearbyTiles, int3 (xd,yd,zd), 1, ETileVisibility::REVEALED);
|
|
||||||
|
|
||||||
for (auto & nearbyTile : nearbyTiles)
|
|
||||||
{
|
|
||||||
auto nearbyTileInfo = getTile(nearbyTile);
|
|
||||||
if (nearbyTileInfo->isLand() && nearbyTileInfo->getTerrain()->isPassable() && !nearbyTileInfo->blocked())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
#if NKAI_TRACE_LEVEL >= 2
|
|
||||||
std::ostringstream tPos;
|
|
||||||
tPos << "(" << xd << "," << yd << "," << zd << ")";
|
|
||||||
std::ostringstream nearbyTPos;
|
|
||||||
nearbyTPos << "(" << nearbyTile.x << "," << nearbyTile.y << "," << nearbyTile.z << ")";
|
|
||||||
logGlobal->trace("Skipping free tile %d because nearby tile %s is blocked", tPos.str(), nearbyTPos.str());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nearbyMonsterOrBlocked = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure that CGameHandler::spawnWanderingMonsters won't set a random monster next to another monster
|
// Ensure that CGameHandler::spawnWanderingMonsters won't set a random monster next to another monster
|
||||||
// because Nullkiller AI is not able to go to one monster without falling into the attack range of the nearby one
|
// because Nullkiller AI is not able to go to one monster without falling into the attack range of the nearby one
|
||||||
// See GraphPaths::addChainInfo if(node.linkDanger > 0) (no link between random monsters and map monsters)
|
// See GraphPaths::addChainInfo if(node.linkDanger > 0) (no link between random monsters and map monsters)
|
||||||
if (!nearbyMonsterOrBlocked)
|
// Ivan: When new monster spawns, AI should receive AIGateway::newObject call for each object visible to AI. Probably you need to invalidate
|
||||||
tiles.emplace_back(xd, yd, zd);
|
// that data for AI & force recalculation on next turn. New queries to gamestate, like getGuardingCreaturePosition that are done either
|
||||||
|
// from AIGateway::newObject method or at any point later should correctly include newly spawned monsters
|
||||||
|
// TODO: Ensure this linking issue is properly fixed, not just with the workaround below
|
||||||
|
if (skipIfNearbyGuarded && guardingCreaturePosition(int3 (xd,yd,zd)).isValid())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles.emplace_back(xd, yd, zd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -102,7 +102,7 @@ public:
|
|||||||
bool isTeleportEntrancePassable(const CGTeleport * obj, PlayerColor player) const override;
|
bool isTeleportEntrancePassable(const CGTeleport * obj, PlayerColor player) const override;
|
||||||
|
|
||||||
//used for random spawns
|
//used for random spawns
|
||||||
void getFreeTiles(std::vector<int3> &tiles, bool skipIfNearbyBlocked) const;
|
void getFreeTiles(std::vector<int3> &tiles, bool skipIfNearbyGuarded) const;
|
||||||
void getTilesInRange(FowTilesType & tiles, const int3 & pos, int radius, ETileVisibility mode, std::optional<PlayerColor> player = std::optional<PlayerColor>(), int3::EDistanceFormula formula = int3::DIST_2D) const override;
|
void getTilesInRange(FowTilesType & tiles, const int3 & pos, int radius, ETileVisibility mode, std::optional<PlayerColor> player = std::optional<PlayerColor>(), int3::EDistanceFormula formula = int3::DIST_2D) const override;
|
||||||
void getAllTiles(FowTilesType &tiles, std::optional<PlayerColor> player, int level, const std::function<bool(const TerrainTile *)> & filter) const override;
|
void getAllTiles(FowTilesType &tiles, std::optional<PlayerColor> player, int level, const std::function<bool(const TerrainTile *)> & filter) const override;
|
||||||
|
|
||||||
|
@@ -3996,7 +3996,7 @@ void CGameHandler::spawnWanderingMonsters(CreatureID creatureID)
|
|||||||
std::vector<int3>::iterator tile;
|
std::vector<int3>::iterator tile;
|
||||||
std::vector<int3> tiles;
|
std::vector<int3> tiles;
|
||||||
gameState().getFreeTiles(tiles, true);
|
gameState().getFreeTiles(tiles, true);
|
||||||
ui32 amount = tiles.size() / 10; //Chance is 10% for each free tile. Higher than 0.5% because there are way fewer with nearby unblocked
|
ui32 amount = tiles.size() / 100; //Chance is 1% for each tile. Higher than the original 0.5% because there are fewer with nearby unguarded
|
||||||
|
|
||||||
RandomGeneratorUtil::randomShuffle(tiles, getRandomGenerator());
|
RandomGeneratorUtil::randomShuffle(tiles, getRandomGenerator());
|
||||||
logGlobal->trace("Spawning wandering monsters. Found %d free tiles. Creature type: %d", tiles.size(), creatureID.num);
|
logGlobal->trace("Spawning wandering monsters. Found %d free tiles. Creature type: %d", tiles.size(), creatureID.num);
|
||||||
|
Reference in New Issue
Block a user