mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Somewhat better gate placement, attempt to add rocky tiles to underground zones.
This commit is contained in:
parent
d118fbffe8
commit
ab748ae221
@ -265,29 +265,50 @@ void CMapGenerator::createConnections()
|
||||
}
|
||||
else //create subterranean gates between two zones
|
||||
{
|
||||
//find point just in the middle
|
||||
//find point on the path between zones
|
||||
int3 posA = zoneA->getPos();
|
||||
int3 posB = zoneB->getPos();
|
||||
float3 offset (posB.x - posA.x, posB.y - posA.y, 0);
|
||||
|
||||
offset /= posB.dist2d(posA); //get unit vector
|
||||
float distance = posB.dist2d(posA);
|
||||
offset /= distance; //get unit vector
|
||||
float3 vec (0, 0, 0);
|
||||
//use reduced size of underground zone - make sure gate does not stand on rock
|
||||
offset *= ((posA.z ? zoneA->getSize() : zoneB->getSize()) - 2);
|
||||
int3 tile = posA + int3(offset.x, offset.y, 0);
|
||||
int3 tile = posA;
|
||||
int3 otherTile = tile;
|
||||
otherTile.z = posB.z;
|
||||
|
||||
if (vstd::contains(tiles, tile) && vstd::contains(otherZoneTiles, otherTile))
|
||||
bool stop = false;
|
||||
while (!stop)
|
||||
{
|
||||
auto gate1 = new CGTeleport;
|
||||
gate1->ID = Obj::SUBTERRANEAN_GATE;
|
||||
gate1->subID = 0;
|
||||
zoneA->placeAndGuardObject(this, gate1, tile, connection.getGuardStrength());
|
||||
auto gate2 = new CGTeleport(*gate1);
|
||||
zoneB->placeAndGuardObject(this, gate2, otherTile, connection.getGuardStrength());
|
||||
vec += offset;
|
||||
tile = posA + int3(vec.x, vec.y, 0);
|
||||
float distanceFromA = posA.dist2d(tile);
|
||||
float distanceFromB = posB.dist2d(tile);
|
||||
if (distanceFromA >= distance)
|
||||
break;
|
||||
|
||||
continue; //we are done, go to next connection
|
||||
//if zone is underground, gate must lay withing its (reduced) radius
|
||||
if (distanceFromA > 3 && (!posA.z || distanceFromA < zoneA->getSize() - 2)
|
||||
&& distanceFromB > 3 && (!posB.z ||distanceFromB < zoneB->getSize() - 2))
|
||||
{
|
||||
otherTile = tile;
|
||||
otherTile.z = posB.z;
|
||||
|
||||
if (vstd::contains(tiles, tile) && vstd::contains(otherZoneTiles, otherTile))
|
||||
{
|
||||
auto gate1 = new CGTeleport;
|
||||
gate1->ID = Obj::SUBTERRANEAN_GATE;
|
||||
gate1->subID = 0;
|
||||
zoneA->placeAndGuardObject(this, gate1, tile, connection.getGuardStrength());
|
||||
auto gate2 = new CGTeleport(*gate1);
|
||||
zoneB->placeAndGuardObject(this, gate2, otherTile, connection.getGuardStrength());
|
||||
|
||||
stop = true; //we are done, go to next connection
|
||||
}
|
||||
}
|
||||
}
|
||||
if (stop)
|
||||
continue;
|
||||
}
|
||||
if (!guardPos.valid())
|
||||
{
|
||||
@ -348,6 +369,13 @@ bool CMapGenerator::isFree(const int3 &tile) const
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].isFree();
|
||||
}
|
||||
bool CMapGenerator::isUsed(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].isUsed();
|
||||
}
|
||||
void CMapGenerator::setOccupied(const int3 &tile, ETileType::ETileType state)
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
|
@ -70,6 +70,7 @@ public:
|
||||
bool shouldBeBlocked(const int3 &tile) const;
|
||||
bool isPossible(const int3 &tile) const;
|
||||
bool isFree(const int3 &tile) const;
|
||||
bool isUsed(const int3 &tile) const;
|
||||
void setOccupied(const int3 &tile, ETileType::ETileType state);
|
||||
CTileInfo getTile(const int3 & tile) const;
|
||||
|
||||
|
@ -109,6 +109,10 @@ bool CTileInfo::isFree() const
|
||||
{
|
||||
return occupied == ETileType::FREE;
|
||||
}
|
||||
bool CTileInfo::isUsed() const
|
||||
{
|
||||
return occupied == ETileType::USED;
|
||||
}
|
||||
void CTileInfo::setOccupied(ETileType::ETileType value)
|
||||
{
|
||||
occupied = value;
|
||||
@ -359,7 +363,10 @@ void CRmgTemplateZone::discardDistantTiles (CMapGenerator* gen, int distance)
|
||||
for (auto tile : tileinfo)
|
||||
{
|
||||
if (tile.dist2d(this->pos) > distance)
|
||||
{
|
||||
gen->setOccupied(tile, ETileType::USED);
|
||||
//gen->setOccupied(tile, ETileType::BLOCKED); //fixme: crash at rendering?
|
||||
}
|
||||
}
|
||||
vstd::erase_if (tileinfo, [distance, this](const int3 &tile) -> bool
|
||||
{
|
||||
@ -935,7 +942,40 @@ void CRmgTemplateZone::createTreasures(CMapGenerator* gen)
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::createObstacles(CMapGenerator* gen)
|
||||
{
|
||||
{
|
||||
if (pos.z) //underground
|
||||
{
|
||||
std::vector<int3> rockTiles;
|
||||
|
||||
for (auto tile : tileinfo)
|
||||
{
|
||||
bool placeRock = true;
|
||||
if (gen->shouldBeBlocked(tile))
|
||||
{
|
||||
gen->foreach_neighbour (tile, [gen, &placeRock](int3 &pos)
|
||||
{
|
||||
if (!(gen->shouldBeBlocked(pos) || gen->isPossible(pos)))
|
||||
placeRock = false;
|
||||
});
|
||||
if (placeRock)
|
||||
{
|
||||
rockTiles.push_back(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
gen->editManager->getTerrainSelection().setSelection(rockTiles);
|
||||
gen->editManager->drawTerrain(ETerrainType::ROCK, &gen->rand);
|
||||
//for (auto tile : rockTiles)
|
||||
//{
|
||||
// gen->setOccupied (tile, ETileType::USED);
|
||||
// gen->foreach_neighbour (tile, [gen](int3 &pos)
|
||||
// {
|
||||
// if (!gen->isUsed(pos))
|
||||
// gen->setOccupied (pos, ETileType::BLOCKED);
|
||||
// });
|
||||
//}
|
||||
}
|
||||
|
||||
//get all possible obstacles for this terrain
|
||||
for (auto primaryID : VLC->objtypeh->knownObjects())
|
||||
{
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
bool shouldBeBlocked() const;
|
||||
bool isPossible() const;
|
||||
bool isFree() const;
|
||||
bool isUsed() const;
|
||||
void setOccupied(ETileType::ETileType value);
|
||||
ETerrainType getTerrainType() const;
|
||||
void setTerrainType(ETerrainType value);
|
||||
|
Loading…
Reference in New Issue
Block a user