mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
More experiments WIP.
This commit is contained in:
parent
eb60d9737f
commit
76193c4c5c
@ -433,8 +433,11 @@ void CMapGenerator::createConnections()
|
||||
setOccupied (guardPos, ETileType::FREE); //just in case monster is too weak to spawn
|
||||
zoneA->addMonster (this, guardPos, connection.getGuardStrength(), false, true);
|
||||
//zones can make paths only in their own area
|
||||
zoneA->crunchRoad(this, guardPos, posA, zoneA->getFreePaths()); //make connection towards our zone center
|
||||
zoneB->crunchRoad(this, guardPos, posB, zoneB->getFreePaths()); //make connection towards other zone center
|
||||
zoneA->crunchPath(this, guardPos, posA, zoneA->getFreePaths()); //make connection towards our zone center
|
||||
zoneB->crunchPath(this, guardPos, posB, zoneB->getFreePaths()); //make connection towards other zone center
|
||||
|
||||
zoneA->addRoadNode(guardPos);
|
||||
zoneB->addRoadNode(guardPos);
|
||||
break; //we're done with this connection
|
||||
}
|
||||
}
|
||||
@ -528,6 +531,13 @@ void CMapGenerator::addHeaderInfo()
|
||||
addPlayerInfo();
|
||||
}
|
||||
|
||||
void CMapGenerator::checkIsOnMap(const int3& tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
}
|
||||
|
||||
|
||||
std::map<TRmgTemplateZoneId, CRmgTemplateZone*> CMapGenerator::getZones() const
|
||||
{
|
||||
return zones;
|
||||
@ -535,67 +545,74 @@ std::map<TRmgTemplateZoneId, CRmgTemplateZone*> CMapGenerator::getZones() const
|
||||
|
||||
bool CMapGenerator::isBlocked(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
checkIsOnMap(tile);
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].isBlocked();
|
||||
}
|
||||
bool CMapGenerator::shouldBeBlocked(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
checkIsOnMap(tile);
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].shouldBeBlocked();
|
||||
}
|
||||
bool CMapGenerator::isPossible(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
checkIsOnMap(tile);
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].isPossible();
|
||||
}
|
||||
bool CMapGenerator::isFree(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
checkIsOnMap(tile);
|
||||
|
||||
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));
|
||||
checkIsOnMap(tile);
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].isUsed();
|
||||
}
|
||||
|
||||
bool CMapGenerator::isRoad(const int3& tile) const
|
||||
{
|
||||
checkIsOnMap(tile);
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].isRoad();
|
||||
}
|
||||
|
||||
void CMapGenerator::setOccupied(const int3 &tile, ETileType::ETileType state)
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
checkIsOnMap(tile);
|
||||
|
||||
tiles[tile.x][tile.y][tile.z].setOccupied(state);
|
||||
}
|
||||
|
||||
CTileInfo CMapGenerator::getTile(const int3& tile) const
|
||||
void CMapGenerator::setRoad(const int3& tile, ERoadType::ERoadType roadType)
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
checkIsOnMap(tile);
|
||||
|
||||
tiles[tile.x][tile.y][tile.z].setRoadType(roadType);
|
||||
}
|
||||
|
||||
|
||||
CTileInfo CMapGenerator::getTile(const int3& tile) const
|
||||
{
|
||||
checkIsOnMap(tile);
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z];
|
||||
}
|
||||
|
||||
void CMapGenerator::setNearestObjectDistance(int3 &tile, float value)
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
checkIsOnMap(tile);
|
||||
|
||||
tiles[tile.x][tile.y][tile.z].setNearestObjectDistance(value);
|
||||
}
|
||||
|
||||
float CMapGenerator::getNearestObjectDistance(const int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
checkIsOnMap(tile);
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].getNearestObjectDistance();
|
||||
}
|
||||
|
@ -73,7 +73,11 @@ public:
|
||||
bool isPossible(const int3 &tile) const;
|
||||
bool isFree(const int3 &tile) const;
|
||||
bool isUsed(const int3 &tile) const;
|
||||
bool isRoad(const int3 &tile) const;
|
||||
|
||||
void setOccupied(const int3 &tile, ETileType::ETileType state);
|
||||
void setRoad(const int3 &tile, ERoadType::ERoadType roadType);
|
||||
|
||||
CTileInfo getTile(const int3 & tile) const;
|
||||
|
||||
float getNearestObjectDistance(const int3 &tile) const;
|
||||
@ -100,6 +104,7 @@ private:
|
||||
//int questArtsRemaining;
|
||||
int monolithIndex;
|
||||
std::vector<ArtifactID> questArtifacts;
|
||||
void checkIsOnMap(const int3 &tile) const; //throws
|
||||
|
||||
/// Generation methods
|
||||
std::string getMapDescription() const;
|
||||
|
@ -33,6 +33,11 @@ CRmgTemplateZone::CTownInfo::CTownInfo() : townCount(0), castleCount(0), townDen
|
||||
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::addRoadNode(const int3& node)
|
||||
{
|
||||
roadNodes.insert(node);
|
||||
}
|
||||
|
||||
int CRmgTemplateZone::CTownInfo::getTownCount() const
|
||||
{
|
||||
return townCount;
|
||||
@ -111,6 +116,12 @@ bool CTileInfo::isFree() const
|
||||
{
|
||||
return occupied == ETileType::FREE;
|
||||
}
|
||||
|
||||
bool CTileInfo::isRoad() const
|
||||
{
|
||||
return roadType != ERoadType::NO_ROAD;
|
||||
}
|
||||
|
||||
bool CTileInfo::isUsed() const
|
||||
{
|
||||
return occupied == ETileType::USED;
|
||||
@ -692,6 +703,8 @@ bool CRmgTemplateZone::crunchRoad(CMapGenerator* gen, const int3& src, const int
|
||||
if(crunchPath(gen, src, dst, ¤tClearedTiles, true))
|
||||
{
|
||||
roads.insert(std::begin(currentClearedTiles), std::end(currentClearedTiles));
|
||||
roads.insert(src);
|
||||
roads.insert(dst);
|
||||
|
||||
if(nullptr != clearedTiles)
|
||||
clearedTiles->insert(std::begin(currentClearedTiles), std::end(currentClearedTiles));
|
||||
@ -700,7 +713,8 @@ bool CRmgTemplateZone::crunchRoad(CMapGenerator* gen, const int3& src, const int
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
logGlobal->warnStream() << boost::format("Failed to crunch road from %s to %s") %src %dst;
|
||||
return crunchPath(gen, src, dst, clearedTiles, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1265,6 +1279,7 @@ bool CRmgTemplateZone::placeMines (CMapGenerator* gen)
|
||||
bool CRmgTemplateZone::createRequiredObjects(CMapGenerator* gen)
|
||||
{
|
||||
logGlobal->traceStream() << "Creating required objects";
|
||||
|
||||
for(const auto &obj : requiredObjects)
|
||||
{
|
||||
int3 pos;
|
||||
@ -1275,24 +1290,9 @@ bool CRmgTemplateZone::createRequiredObjects(CMapGenerator* gen)
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (obj.first->ID)
|
||||
{
|
||||
case Obj::TOWN:
|
||||
case Obj::MONOLITH_TWO_WAY:
|
||||
case Obj::SUBTERRANEAN_GATE:
|
||||
{
|
||||
crunchRoad(gen, this->pos, pos + obj.first->getVisitableOffset(), &freePaths);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
placeObject (gen, obj.first, pos);
|
||||
guardObject (gen, obj.first, obj.second, (obj.first->ID == Obj::MONOLITH_TWO_WAY), true);
|
||||
//paths to required objects constitute main paths of zone. otherwise they just may lead to middle and create dead zones
|
||||
//paths to required objects constitute main paths of zone. otherwise they just may lead to middle and create dead zones
|
||||
}
|
||||
|
||||
for (const auto &obj : closeObjects)
|
||||
@ -1481,18 +1481,45 @@ void CRmgTemplateZone::createObstacles2(CMapGenerator* gen)
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::drawRoads(CMapGenerator* gen)
|
||||
{
|
||||
|
||||
auto doDrawRoad = []()
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
while(!roadNodes.empty())
|
||||
{
|
||||
int3 node = *roadNodes.begin();
|
||||
roadNodes.erase(node);
|
||||
if(roads.empty())
|
||||
{
|
||||
//start road network
|
||||
roads.insert(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
int3 cross = *RandomGeneratorUtil::nextItem(roads, gen->rand);
|
||||
|
||||
crunchRoad(gen, node, cross, &freePaths);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::buildRoads(CMapGenerator* gen)
|
||||
{
|
||||
std::vector<int3> tiles;
|
||||
for (auto tile : roads)
|
||||
{
|
||||
tiles.push_back (tile);
|
||||
if(gen->map->isInTheMap(tile))
|
||||
tiles.push_back (tile);
|
||||
}
|
||||
gen->editManager->getTerrainSelection().setSelection(tiles);
|
||||
gen->editManager->drawRoad(ERoadType::COBBLESTONE_ROAD, &gen->rand);
|
||||
gen->editManager->drawRoad(ERoadType::COBBLESTONE_ROAD, &gen->rand);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CRmgTemplateZone::fill(CMapGenerator* gen)
|
||||
{
|
||||
initTerrainType(gen);
|
||||
@ -1503,11 +1530,11 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
|
||||
|
||||
placeMines(gen);
|
||||
createRequiredObjects(gen);
|
||||
drawRoads(gen);
|
||||
buildRoads(gen);
|
||||
fractalize(gen); //after required objects are created and linked with their own paths
|
||||
createTreasures(gen);
|
||||
|
||||
drawRoads(gen);
|
||||
|
||||
logGlobal->infoStream() << boost::format ("Zone %d filled successfully") %id;
|
||||
return true;
|
||||
}
|
||||
@ -1718,6 +1745,24 @@ void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object,
|
||||
auto artid = sh->quest->m5arts.front();
|
||||
logGlobal->warnStream() << boost::format("Placed Seer Hut at %s, quest artifact %d is %s") % object->pos % artid % VLC->arth->artifacts[artid]->Name();
|
||||
}
|
||||
|
||||
|
||||
switch (object->ID)
|
||||
{
|
||||
case Obj::TOWN:
|
||||
case Obj::RANDOM_TOWN:
|
||||
case Obj::MONOLITH_TWO_WAY:
|
||||
case Obj::MONOLITH_ONE_WAY_ENTRANCE:
|
||||
case Obj::MONOLITH_ONE_WAY_EXIT:
|
||||
case Obj::SUBTERRANEAN_GATE:
|
||||
{
|
||||
roadNodes.insert(pos + object->getVisitableOffset());
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::placeAndGuardObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, si32 str, bool zoneGuard)
|
||||
|
@ -47,10 +47,12 @@ public:
|
||||
bool isPossible() const;
|
||||
bool isFree() const;
|
||||
bool isUsed() const;
|
||||
bool isRoad() const;
|
||||
void setOccupied(ETileType::ETileType value);
|
||||
ETerrainType getTerrainType() const;
|
||||
ETileType::ETileType getTileType() const;
|
||||
void setTerrainType(ETerrainType value);
|
||||
|
||||
void setRoadType(ERoadType::ERoadType value);
|
||||
private:
|
||||
float nearestObjectDistance;
|
||||
@ -168,7 +170,7 @@ public:
|
||||
void createObstacles1(CMapGenerator* gen);
|
||||
void createObstacles2(CMapGenerator* gen);
|
||||
bool crunchPath(CMapGenerator* gen, const int3 &src, const int3 &dst, std::set<int3>* clearedTiles = nullptr, bool forRoad = false);
|
||||
bool crunchRoad(CMapGenerator* gen, const int3 &src, const int3 &dst, std::set<int3>* clearedTiles = nullptr);
|
||||
|
||||
std::vector<int3> getAccessibleOffsets (CMapGenerator* gen, CGObjectInstance* object);
|
||||
|
||||
void addConnection(TRmgTemplateZoneId otherZone);
|
||||
@ -181,7 +183,7 @@ public:
|
||||
ObjectInfo getRandomObject (CMapGenerator* gen, CTreasurePileInfo &info, ui32 desiredValue, ui32 maxValue, ui32 currentValue);
|
||||
|
||||
void placeAndGuardObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, si32 str, bool zoneGuard = false);
|
||||
|
||||
void addRoadNode(const int3 & node);
|
||||
private:
|
||||
//template info
|
||||
TRmgTemplateZoneId id;
|
||||
@ -218,9 +220,11 @@ private:
|
||||
std::vector<TRmgTemplateZoneId> connections; //list of adjacent zones
|
||||
std::set<int3> freePaths; //core paths of free tiles that all other objects will be linked to
|
||||
|
||||
std::set<int3> roads;
|
||||
std::set<int3> roadNodes; //tiles to be connected with roads
|
||||
std::set<int3> roads; //all tiles with roads
|
||||
|
||||
void drawRoads(CMapGenerator* gen);
|
||||
void drawRoads(CMapGenerator* gen); //fills "roads" according to "roadNodes"
|
||||
void buildRoads(CMapGenerator* gen); //actually updates tiles
|
||||
|
||||
bool pointIsIn(int x, int y);
|
||||
void addAllPossibleObjects (CMapGenerator* gen); //add objects, including zone-specific, to possibleObjects
|
||||
@ -233,4 +237,6 @@ private:
|
||||
void checkAndPlaceObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos);
|
||||
void placeObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, bool updateDistance = true);
|
||||
bool guardObject(CMapGenerator* gen, CGObjectInstance* object, si32 str, bool zoneGuard = false, bool addToFreePaths = false);
|
||||
//TODO:replace with A*-based algorithm on whole road network
|
||||
bool crunchRoad(CMapGenerator* gen, const int3 &src, const int3 &dst, std::set<int3>* clearedTiles = nullptr);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user