1
0
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:
AlexVinS 2015-01-18 16:19:00 +03:00
parent eb60d9737f
commit 76193c4c5c
4 changed files with 120 additions and 47 deletions

View File

@ -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();
}

View File

@ -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;

View File

@ -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, &currentClearedTiles, 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)

View File

@ -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);
};