mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Ground connections between adjacent zones.
This commit is contained in:
parent
8ab2a8df86
commit
8e8b27087a
@ -350,6 +350,21 @@ std::set<int3> CGObjectInstance::getBlockedPos() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::set<int3> CGObjectInstance::getBlockedOffsets() const
|
||||
{
|
||||
std::set<int3> ret;
|
||||
for(int w=0; w<getWidth(); ++w)
|
||||
{
|
||||
for(int h=0; h<getHeight(); ++h)
|
||||
{
|
||||
if (appearance.isBlockedAt(w, h))
|
||||
ret.insert(int3(-w, -h, 0));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool CGObjectInstance::operator<(const CGObjectInstance & cmp) const //screen printing priority comparing
|
||||
{
|
||||
if (appearance.printPriority != cmp.appearance.printPriority)
|
||||
|
@ -227,6 +227,7 @@ public:
|
||||
bool blockingAt(int x, int y) const; //returns true if object is blocking location (x, y) (h3m pos)
|
||||
bool coveringAt(int x, int y) const; //returns true if object covers with picture location (x, y) (h3m pos)
|
||||
std::set<int3> getBlockedPos() const; //returns set of positions blocked by this object
|
||||
std::set<int3> getBlockedOffsets() const; //returns set of relative positions blocked by this object
|
||||
bool isVisitable() const; //returns true if object is visitable
|
||||
bool operator<(const CGObjectInstance & cmp) const; //screen printing priority comparing
|
||||
void hideTiles(PlayerColor ourplayer, int radius) const;
|
||||
|
@ -207,14 +207,6 @@ void CMapGenerator::genZones()
|
||||
for(auto const it : zones)
|
||||
{
|
||||
CRmgTemplateZone * zone = it.second;
|
||||
std::vector<int3> shape;
|
||||
int left = part_w*(i%player_per_side);
|
||||
int top = part_h*(i/player_per_side);
|
||||
shape.push_back(int3(left, top, 0));
|
||||
shape.push_back(int3(left + part_w, top, 0));
|
||||
shape.push_back(int3(left + part_w, top + part_h, 0));
|
||||
shape.push_back(int3(left, top + part_h, 0));
|
||||
zone->setShape(shape);
|
||||
zone->setType(i < pcnt ? ETemplateZoneType::PLAYER_START : ETemplateZoneType::TREASURE);
|
||||
this->zones[it.first] = zone;
|
||||
++i;
|
||||
@ -225,8 +217,14 @@ void CMapGenerator::genZones()
|
||||
void CMapGenerator::fillZones()
|
||||
{
|
||||
logGlobal->infoStream() << "Started filling zones";
|
||||
for(auto it : zones)
|
||||
|
||||
for (auto it : zones)
|
||||
{
|
||||
it.second->createConnections(this);
|
||||
}
|
||||
for (auto it : zones)
|
||||
{
|
||||
//make sure all connections are passable before creating borders
|
||||
it.second->createBorder(this);
|
||||
it.second->fill(this);
|
||||
}
|
||||
|
@ -297,11 +297,6 @@ bool CRmgTemplateZone::pointIsIn(int x, int y)
|
||||
return true;
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::setShape(std::vector<int3> shape)
|
||||
{
|
||||
this->shape = shape;
|
||||
}
|
||||
|
||||
int3 CRmgTemplateZone::getPos() const
|
||||
{
|
||||
return pos;
|
||||
@ -316,6 +311,44 @@ void CRmgTemplateZone::addTile (const int3 &pos)
|
||||
tileinfo.insert(pos);
|
||||
}
|
||||
|
||||
std::set<int3> CRmgTemplateZone::getTileInfo () const
|
||||
{
|
||||
return tileinfo;
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::createConnections(CMapGenerator* gen)
|
||||
{
|
||||
for (auto connection : connections)
|
||||
{
|
||||
if (getId() > connection) //only one connection between each pair
|
||||
continue;
|
||||
|
||||
int3 guardPos(-1,-1,-1);
|
||||
|
||||
auto otherZoneTiles = gen->getZones()[connection]->getTileInfo();
|
||||
auto otherZoneCenter = gen->getZones()[connection]->getPos();
|
||||
|
||||
for (auto tile : tileinfo)
|
||||
{
|
||||
gen->foreach_neighbour (tile, [&guardPos, tile, &otherZoneTiles](int3 &pos)
|
||||
{
|
||||
if (vstd::contains(otherZoneTiles, pos))
|
||||
guardPos = tile;
|
||||
});
|
||||
if (guardPos.valid())
|
||||
{
|
||||
gen->setOccupied (pos, ETileType::FREE); //TODO: place monster here
|
||||
//zones can make paths only in their own area
|
||||
this->crunchPath (gen, guardPos, this->getPos(), this->getId()); //make connection towards our zone center
|
||||
gen->getZones()[connection]->crunchPath (gen, guardPos, otherZoneCenter, connection); //make connection towards other zone center
|
||||
break; //we're done with this connection
|
||||
}
|
||||
}
|
||||
if (!guardPos.valid())
|
||||
logGlobal->warnStream() << boost::format ("Did not find connection between zones %d and %d") %getId() %connection;
|
||||
}
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::createBorder(CMapGenerator* gen)
|
||||
{
|
||||
for (auto tile : tileinfo)
|
||||
@ -323,11 +356,78 @@ void CRmgTemplateZone::createBorder(CMapGenerator* gen)
|
||||
gen->foreach_neighbour (tile, [this, gen](int3 &pos)
|
||||
{
|
||||
if (!vstd::contains(this->tileinfo, pos))
|
||||
gen->setOccupied (pos, ETileType::BLOCKED);
|
||||
{
|
||||
gen->foreach_neighbour (pos, [this, gen](int3 &pos)
|
||||
{
|
||||
if (gen->isPossible(pos))
|
||||
gen->setOccupied (pos, ETileType::BLOCKED);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool CRmgTemplateZone::crunchPath (CMapGenerator* gen, int3 &src, int3 &dst, TRmgTemplateZoneId zone)
|
||||
{
|
||||
/*
|
||||
make shortest path with free tiles, reachning dst or closest already free tile. Avoid blocks.
|
||||
do not leave zone border
|
||||
*/
|
||||
bool result = false;
|
||||
bool end = false;
|
||||
|
||||
int3 currentPos = src;
|
||||
float distance = currentPos.dist2dSQ (dst);
|
||||
|
||||
while (!end)
|
||||
{
|
||||
if (currentPos == dst)
|
||||
break;
|
||||
|
||||
auto lastDistance = distance;
|
||||
gen->foreach_neighbour (currentPos, [this, gen, ¤tPos, dst, &distance, &result, &end](int3 &pos)
|
||||
{
|
||||
if (!result) //not sure if lambda is worth it...
|
||||
{
|
||||
if (pos == dst)
|
||||
{
|
||||
result = true;
|
||||
end = true;
|
||||
}
|
||||
if (pos.dist2dSQ (dst) < distance)
|
||||
{
|
||||
if (!gen->isBlocked(pos))
|
||||
{
|
||||
if (vstd::contains (tileinfo, pos))
|
||||
{
|
||||
if (gen->isPossible(pos))
|
||||
{
|
||||
gen->setOccupied (pos, ETileType::FREE);
|
||||
currentPos = pos;
|
||||
distance = currentPos.dist2dSQ (dst);
|
||||
}
|
||||
else if (gen->isFree(pos))
|
||||
{
|
||||
end = true;
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s of uknown type found on path") % pos()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!(result || distance < lastDistance)) //we do not advance, use more avdnaced pathfinding algorithm?
|
||||
{
|
||||
logGlobal->warnStream() << boost::format ("No tile closer than %s found on path from %s to %s") %currentPos %src %dst;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CRmgTemplateZone::fill(CMapGenerator* gen)
|
||||
{
|
||||
std::vector<CGObjectInstance*> required_objects;
|
||||
@ -486,12 +586,27 @@ bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance*
|
||||
continue;
|
||||
if (gen->isPossible(tile) && (dist >= min_dist) && (dist > best_distance))
|
||||
{
|
||||
best_distance = dist;
|
||||
pos = tile;
|
||||
gen->setOccupied(pos, ETileType::BLOCKED);
|
||||
result = true;
|
||||
bool allTilesAvailable = true;
|
||||
for (auto blockingTile : obj->getBlockedOffsets())
|
||||
{
|
||||
if (!gen->isPossible(pos + blockingTile))
|
||||
{
|
||||
allTilesAvailable = false; //if at least one tile is not possible, object can't be placed here
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allTilesAvailable)
|
||||
{
|
||||
best_distance = dist;
|
||||
pos = tile;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result)
|
||||
{
|
||||
gen->setOccupied(pos, ETileType::BLOCKED); //block that tile
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -110,9 +110,12 @@ public:
|
||||
void setPos(const int3 &pos);
|
||||
|
||||
void addTile (const int3 &pos);
|
||||
void setShape(std::vector<int3> shape);
|
||||
std::set<int3> getTileInfo () const;
|
||||
|
||||
bool fill(CMapGenerator* gen);
|
||||
void createConnections(CMapGenerator* gen);
|
||||
void createBorder(CMapGenerator* gen);
|
||||
bool crunchPath (CMapGenerator* gen, int3 &src, int3 &dst, TRmgTemplateZoneId zone);
|
||||
|
||||
void addConnection(TRmgTemplateZoneId otherZone);
|
||||
std::vector<TRmgTemplateZoneId> getConnections() const;
|
||||
|
Loading…
Reference in New Issue
Block a user