1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Somewhat better algorithm for paths, helps balance object distribution.

This commit is contained in:
DjWarmonger 2014-06-18 09:57:36 +02:00
parent 60df94a3f5
commit f84e25fa78
4 changed files with 31 additions and 6 deletions

View File

@ -155,4 +155,22 @@ struct ShashInt3
};
static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) };
int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) };
//FIXME: make sure it's <int3> container and not just any
template<typename Container>
int3 findClosestTile (Container & container, int3 dest)
{
int3 result(-1,-1,-1);
ui32 distance = std::numeric_limits<ui32>::max();
for (int3 tile : container)
{
ui32 currentDistance = dest.dist2dSQ(tile);
if (currentDistance < distance)
{
result = tile;
distance = currentDistance;
}
}
return result;
}

View File

@ -253,8 +253,8 @@ void CMapGenerator::createConnections()
setOccupied (guardPos, ETileType::FREE); //just in case monster is too weak to spawn
zoneA->addMonster (this, guardPos, connection.getGuardStrength()); //TODO: set value according to template
//zones can make paths only in their own area
zoneA->crunchPath (this, guardPos, zoneA->getPos(), zoneA->getId()); //make connection towards our zone center
zoneB->crunchPath (this, guardPos, zoneB->getPos(), zoneB->getId()); //make connection towards other zone center
zoneA->crunchPath (this, guardPos, zoneA->getPos(), zoneA->getId(), zoneA->getFreePaths()); //make connection towards our zone center
zoneB->crunchPath (this, guardPos, zoneB->getPos(), zoneB->getId(), zoneB->getFreePaths()); //make connection towards other zone center
break; //we're done with this connection
}
}

View File

@ -313,7 +313,6 @@ void CRmgTemplateZone::setCenter(const float3 &f)
center = float3 (std::min(std::max(f.x, 0.f), 1.f), std::min(std::max(f.y, 0.f), 1.f), f.z);
}
bool CRmgTemplateZone::pointIsIn(int x, int y)
{
return true;
@ -338,6 +337,11 @@ std::set<int3> CRmgTemplateZone::getTileInfo () const
return tileinfo;
}
std::set<int3>* CRmgTemplateZone::getFreePaths()
{
return &freePaths;
}
void CRmgTemplateZone::createBorder(CMapGenerator* gen)
{
for (auto tile : tileinfo)
@ -651,6 +655,7 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos)
int3 zoneCenter = getPos();
int3 closestTile = int3(-1,-1,-1);
float minDistance = 1e10;
for (auto treasure : treasures)
{
if (zoneCenter.dist2d(treasure.first) < minDistance)
@ -1180,8 +1185,9 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object,
for (auto tile : tiles)
{
//crunching path may fail if center of teh zone is dirrectly over wide object
if (crunchPath (gen, tile, getPos(), id)) //make sure object is accessible before surrounding it with blocked tiles
if (crunchPath (gen, tile, findClosestTile(freePaths, tile), id, &freePaths)) //required objects will contitute our core free paths
{
//make sure object is accessible before surrounding it with blocked tiles
guardTile = tile;
break;
}

View File

@ -149,6 +149,7 @@ public:
std::vector<TRmgTemplateZoneId> getConnections() const;
void addTreasureInfo(CTreasureInfo & info);
std::vector<CTreasureInfo> getTreasureInfo();
std::set<int3>* getFreePaths();
ObjectInfo getRandomObject (CMapGenerator* gen, ui32 value);
@ -182,7 +183,7 @@ private:
float3 center;
std::set<int3> tileinfo; //irregular area assined to zone
std::vector<TRmgTemplateZoneId> connections; //list of adjacent zones
std::map<TRmgTemplateZoneId, bool> alreadyConnected; //TODO: allow multiple connections between two zones?
std::set<int3> freePaths; //core paths of free tiles that all other objects will be linked to
bool pointIsIn(int x, int y);
void addAllPossibleObjects (CMapGenerator* gen); //add objects, including zone-specific, to possibleObjects