mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Correct placement of subterranean gates.
This commit is contained in:
parent
60a5c764b8
commit
d118fbffe8
@ -8,7 +8,7 @@
|
||||
{
|
||||
"1" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 1, "owner" : 1,
|
||||
"type" : "playerStart", "size" : 2, "owner" : 1,
|
||||
"playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true,
|
||||
"monsters" : "normal",
|
||||
"mines" : {"wood" : 1, "ore" : 1, "gems" : 1, "crystal" : 1, "sulfur" : 1, "mercury" : 1},
|
||||
@ -19,7 +19,7 @@
|
||||
},
|
||||
"2" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 1, "owner" : 2,
|
||||
"type" : "playerStart", "size" : 2, "owner" : 2,
|
||||
"playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true,
|
||||
"monsters" : "normal",
|
||||
"minesLikeZone" : 1,
|
||||
@ -27,7 +27,7 @@
|
||||
},
|
||||
"3" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 1, "owner" : 3,
|
||||
"type" : "playerStart", "size" : 2, "owner" : 3,
|
||||
"playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true,
|
||||
"monsters" : "normal",
|
||||
"minesLikeZone" : 1,
|
||||
@ -35,7 +35,7 @@
|
||||
},
|
||||
"4" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 1, "owner" : 4,
|
||||
"type" : "playerStart", "size" : 2, "owner" : 4,
|
||||
"playerTowns" : { "castles" : 1 }, "neutralTowns" : { "towns" : 1 }, "townsAreSameType" : true,
|
||||
"monsters" : "normal",
|
||||
"minesLikeZone" : 1,
|
||||
@ -43,7 +43,7 @@
|
||||
},
|
||||
"5" :
|
||||
{
|
||||
"type" : "treasure", "size" : 2, "terrainTypes" : [ "sand" ], "matchTerrainToTown" : false,
|
||||
"type" : "treasure", "size" : 3, "terrainTypes" : [ "sand" ], "matchTerrainToTown" : false,
|
||||
"neutralTowns" : { "castles" : 1 },
|
||||
"monsters" : "strong",
|
||||
"mines" : {"gold" : 2},
|
||||
@ -132,7 +132,7 @@
|
||||
{
|
||||
"1" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 3, "owner" : 1,
|
||||
"type" : "playerStart", "size" : 2, "owner" : 1,
|
||||
"playerTowns" : { "castles" : 1 },
|
||||
"monsters" : "normal",
|
||||
"mines" : {"wood" : 1, "ore" : 1},
|
||||
@ -143,7 +143,7 @@
|
||||
},
|
||||
"2" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 3, "owner" : 2,
|
||||
"type" : "playerStart", "size" : 2, "owner" : 2,
|
||||
"playerTowns" : { "castles" : 1 },
|
||||
"monsters" : "normal",
|
||||
"minesLikeZone" : 1,
|
||||
@ -151,7 +151,7 @@
|
||||
},
|
||||
"3" :
|
||||
{
|
||||
"type" : "playerStart", "size" : 3, "owner" : 3,
|
||||
"type" : "playerStart", "size" : 2, "owner" : 3,
|
||||
"playerTowns" : { "castles" : 1 },
|
||||
"monsters" : "normal",
|
||||
"minesLikeZone" : 1,
|
||||
|
@ -241,21 +241,52 @@ void CMapGenerator::createConnections()
|
||||
auto otherZoneTiles = zoneB->getTileInfo();
|
||||
//auto otherZoneCenter = zoneB->getPos();
|
||||
|
||||
for (auto tile : tiles)
|
||||
if (zoneA->getPos().z == zoneB->getPos().z)
|
||||
{
|
||||
foreach_neighbour (tile, [&guardPos, tile, &otherZoneTiles](int3 &pos)
|
||||
for (auto tile : tiles)
|
||||
{
|
||||
if (vstd::contains(otherZoneTiles, pos))
|
||||
guardPos = tile;
|
||||
});
|
||||
if (guardPos.valid())
|
||||
if (isBlocked(tile)) //tiles may be occupied by subterranean gates already placed
|
||||
continue;
|
||||
foreach_neighbour (tile, [&guardPos, tile, &otherZoneTiles, this](int3 &pos)
|
||||
{
|
||||
if (vstd::contains(otherZoneTiles, pos) && !this->isBlocked(pos))
|
||||
guardPos = tile;
|
||||
});
|
||||
if (guardPos.valid())
|
||||
{
|
||||
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(), 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
|
||||
}
|
||||
}
|
||||
}
|
||||
else //create subterranean gates between two zones
|
||||
{
|
||||
//find point just in the middle
|
||||
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
|
||||
//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 otherTile = tile;
|
||||
otherTile.z = posB.z;
|
||||
|
||||
if (vstd::contains(tiles, tile) && vstd::contains(otherZoneTiles, otherTile))
|
||||
{
|
||||
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(), 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
|
||||
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());
|
||||
|
||||
continue; //we are done, go to next connection
|
||||
}
|
||||
}
|
||||
if (!guardPos.valid())
|
||||
|
@ -354,8 +354,13 @@ std::set<int3> CRmgTemplateZone::getTileInfo () const
|
||||
return tileinfo;
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::discardDistantTiles (int distance)
|
||||
void CRmgTemplateZone::discardDistantTiles (CMapGenerator* gen, int distance)
|
||||
{
|
||||
for (auto tile : tileinfo)
|
||||
{
|
||||
if (tile.dist2d(this->pos) > distance)
|
||||
gen->setOccupied(tile, ETileType::USED);
|
||||
}
|
||||
vstd::erase_if (tileinfo, [distance, this](const int3 &tile) -> bool
|
||||
{
|
||||
return tile.dist2d(this->pos) > distance;
|
||||
@ -828,6 +833,12 @@ void CRmgTemplateZone::initTerrainType (CMapGenerator* gen)
|
||||
terrainType = *RandomGeneratorUtil::nextItem(terrainTypes, gen->rand);
|
||||
|
||||
//paint zone with matching terrain
|
||||
|
||||
paintZoneTerrain (gen, terrainType);
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::paintZoneTerrain (CMapGenerator* gen, ETerrainType terrainType)
|
||||
{
|
||||
std::vector<int3> tiles;
|
||||
for (auto tile : tileinfo)
|
||||
{
|
||||
@ -1132,9 +1143,10 @@ void CRmgTemplateZone::checkAndPlaceObject(CMapGenerator* gen, CGObjectInstance*
|
||||
|
||||
if (object->appearance.id == Obj::NO_OBJ)
|
||||
{
|
||||
auto templates = VLC->objtypeh->getHandlerFor(object->ID, object->subID)->getTemplates(gen->map->getTile(pos).terType);
|
||||
auto terrainType = gen->map->getTile(pos).terType;
|
||||
auto templates = VLC->objtypeh->getHandlerFor(object->ID, object->subID)->getTemplates(terrainType);
|
||||
if (templates.empty())
|
||||
throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s") %object->ID %object->subID %pos));
|
||||
throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") %object->ID %object->subID %pos %terrainType));
|
||||
|
||||
object->appearance = templates.front();
|
||||
}
|
||||
@ -1168,6 +1180,12 @@ void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object,
|
||||
}
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::placeAndGuardObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, si32 str)
|
||||
{
|
||||
placeObject(gen, object, pos);
|
||||
guardObject(gen, object, str);
|
||||
}
|
||||
|
||||
std::vector<int3> CRmgTemplateZone::getAccessibleOffsets (CMapGenerator* gen, CGObjectInstance* object)
|
||||
{
|
||||
//get all tiles from which this object can be accessed
|
||||
|
@ -128,7 +128,7 @@ public:
|
||||
|
||||
void addTile (const int3 &pos);
|
||||
std::set<int3> getTileInfo () const;
|
||||
void discardDistantTiles (int distance);
|
||||
void discardDistantTiles (CMapGenerator* gen, int distance);
|
||||
|
||||
void addRequiredObject(CGObjectInstance * obj, si32 guardStrength=0);
|
||||
bool addMonster(CMapGenerator* gen, int3 &pos, si32 strength);
|
||||
@ -136,6 +136,7 @@ public:
|
||||
bool fill (CMapGenerator* gen);
|
||||
bool placeMines (CMapGenerator* gen);
|
||||
void initTownType (CMapGenerator* gen);
|
||||
void paintZoneTerrain (CMapGenerator* gen, ETerrainType terrainType);
|
||||
void initTerrainType (CMapGenerator* gen);
|
||||
void createBorder(CMapGenerator* gen);
|
||||
void fractalize(CMapGenerator* gen);
|
||||
@ -155,6 +156,8 @@ public:
|
||||
|
||||
ObjectInfo getRandomObject (CMapGenerator* gen, ui32 value);
|
||||
|
||||
void placeAndGuardObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, si32 str);
|
||||
|
||||
private:
|
||||
//template info
|
||||
TRmgTemplateZoneId id;
|
||||
|
@ -247,7 +247,13 @@ void CZonePlacer::assignZones(shared_ptr<CMapGenOptions> mapGenOptions)
|
||||
|
||||
//TODO: similiar for islands
|
||||
if (zone.second->getPos().z)
|
||||
zone.second->discardDistantTiles(zone.second->getSize());
|
||||
{
|
||||
zone.second->discardDistantTiles(gen, zone.second->getSize());
|
||||
|
||||
//make sure that terrain inside zone is not a rock
|
||||
//FIXME: reorder actions?
|
||||
zone.second->paintZoneTerrain (gen, ETerrainType::SUBTERRANEAN);
|
||||
}
|
||||
}
|
||||
logGlobal->infoStream() << "Finished zone colouring";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user