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:
parent
60df94a3f5
commit
f84e25fa78
20
lib/int3.h
20
lib/int3.h
@ -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;
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user