mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Rmg water support (#745)
* RMG: water support and refactoring * Fix seers hut bug
This commit is contained in:
parent
b698f32557
commit
5c1a66ab69
@ -86,7 +86,6 @@ set(lib_SRCS
|
|||||||
rmg/CRmgTemplate.cpp
|
rmg/CRmgTemplate.cpp
|
||||||
rmg/CRmgTemplateStorage.cpp
|
rmg/CRmgTemplateStorage.cpp
|
||||||
rmg/CRmgTemplateZone.cpp
|
rmg/CRmgTemplateZone.cpp
|
||||||
rmg/CZoneGraphGenerator.cpp
|
|
||||||
rmg/CZonePlacer.cpp
|
rmg/CZonePlacer.cpp
|
||||||
|
|
||||||
serializer/BinaryDeserializer.cpp
|
serializer/BinaryDeserializer.cpp
|
||||||
@ -292,7 +291,6 @@ set(lib_HEADERS
|
|||||||
rmg/CRmgTemplate.h
|
rmg/CRmgTemplate.h
|
||||||
rmg/CRmgTemplateStorage.h
|
rmg/CRmgTemplateStorage.h
|
||||||
rmg/CRmgTemplateZone.h
|
rmg/CRmgTemplateZone.h
|
||||||
rmg/CZoneGraphGenerator.h
|
|
||||||
rmg/CZonePlacer.h
|
rmg/CZonePlacer.h
|
||||||
rmg/float3.h
|
rmg/float3.h
|
||||||
|
|
||||||
|
@ -255,6 +255,7 @@ void ObjectTemplate::readJson(const JsonNode &node, const bool withTerrain)
|
|||||||
allowedTerrains.insert(ETerrainType((si32)i));
|
allowedTerrains.insert(ETerrainType((si32)i));
|
||||||
|
|
||||||
allowedTerrains.erase(ETerrainType::ROCK);
|
allowedTerrains.erase(ETerrainType::ROCK);
|
||||||
|
allowedTerrains.erase(ETerrainType::WATER);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(withTerrain && allowedTerrains.empty())
|
if(withTerrain && allowedTerrains.empty())
|
||||||
@ -327,8 +328,8 @@ void ObjectTemplate::writeJson(JsonNode & node, const bool withTerrain) const
|
|||||||
|
|
||||||
if(withTerrain)
|
if(withTerrain)
|
||||||
{
|
{
|
||||||
//assumed that ROCK terrain not included
|
//assumed that ROCK and WATER terrains are not included
|
||||||
if(allowedTerrains.size() < (GameConstants::TERRAIN_TYPES - 1))
|
if(allowedTerrains.size() < (GameConstants::TERRAIN_TYPES - 2))
|
||||||
{
|
{
|
||||||
JsonVector & data = node["allowedTerrains"].Vector();
|
JsonVector & data = node["allowedTerrains"].Vector();
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "../mapping/CMap.h"
|
#include "../mapping/CMap.h"
|
||||||
#include "CRmgTemplateStorage.h"
|
#include "CRmgTemplateStorage.h"
|
||||||
#include "CRmgTemplate.h"
|
#include "CRmgTemplate.h"
|
||||||
|
#include "CRandomGenerator.h"
|
||||||
#include "../VCMI_Lib.h"
|
#include "../VCMI_Lib.h"
|
||||||
#include "../CTownHandler.h"
|
#include "../CTownHandler.h"
|
||||||
|
|
||||||
@ -390,9 +391,39 @@ bool CMapGenOptions::checkOptions() const
|
|||||||
const CRmgTemplate * CMapGenOptions::getPossibleTemplate(CRandomGenerator & rand) const
|
const CRmgTemplate * CMapGenOptions::getPossibleTemplate(CRandomGenerator & rand) const
|
||||||
{
|
{
|
||||||
int3 tplSize(width, height, (hasTwoLevels ? 2 : 1));
|
int3 tplSize(width, height, (hasTwoLevels ? 2 : 1));
|
||||||
|
auto humanPlayers = countHumanPlayers();
|
||||||
|
|
||||||
|
auto templates = VLC->tplh->getTemplates();
|
||||||
|
|
||||||
|
vstd::erase_if(templates, [this, &tplSize, humanPlayers](const CRmgTemplate * tmpl)
|
||||||
|
{
|
||||||
|
if(!tmpl->matchesSize(tplSize))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(!tmpl->isWaterContentAllowed(getWaterContent()))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(getPlayerCount() != -1)
|
||||||
|
{
|
||||||
|
if (!tmpl->getPlayers().isInRange(getPlayerCount()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Human players shouldn't be banned when playing with random player count
|
||||||
|
if(humanPlayers > *boost::min_element(tmpl->getPlayers().getNumbers()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(compOnlyPlayerCount != -1)
|
||||||
|
{
|
||||||
|
if (!tmpl->getCpuPlayers().isInRange(compOnlyPlayerCount))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
auto templates = VLC->tplh->getTemplates(tplSize, getPlayerCount(), countHumanPlayers(), compOnlyPlayerCount);
|
|
||||||
|
|
||||||
// Select tpl
|
// Select tpl
|
||||||
if(templates.empty())
|
if(templates.empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -11,9 +11,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../GameConstants.h"
|
#include "../GameConstants.h"
|
||||||
#include "../CRandomGenerator.h"
|
|
||||||
|
|
||||||
class CRmgTemplate;
|
class CRmgTemplate;
|
||||||
|
class CRandomGenerator;
|
||||||
|
|
||||||
namespace EWaterContent
|
namespace EWaterContent
|
||||||
{
|
{
|
||||||
|
@ -285,17 +285,41 @@ void CMapGenerator::genZones()
|
|||||||
for(const auto & option : tmpl->getZones())
|
for(const auto & option : tmpl->getZones())
|
||||||
{
|
{
|
||||||
auto zone = std::make_shared<CRmgTemplateZone>(this);
|
auto zone = std::make_shared<CRmgTemplateZone>(this);
|
||||||
zone->setOptions(option.second.get());
|
zone->setOptions(*option.second.get());
|
||||||
zones[zone->getId()] = zone;
|
zones[zone->getId()] = zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
CZonePlacer placer(this);
|
CZonePlacer placer(this);
|
||||||
placer.placeZones(&rand);
|
placer.placeZones(&rand);
|
||||||
placer.assignZones();
|
placer.assignZones();
|
||||||
|
|
||||||
|
//add special zone for water
|
||||||
|
zoneWater.first = zones.size() + 1;
|
||||||
|
zoneWater.second = std::make_shared<CRmgTemplateZone>(this);
|
||||||
|
{
|
||||||
|
rmg::ZoneOptions options;
|
||||||
|
options.setId(zoneWater.first);
|
||||||
|
options.setType(ETemplateZoneType::WATER);
|
||||||
|
zoneWater.second->setOptions(options);
|
||||||
|
}
|
||||||
|
|
||||||
logGlobal->info("Zones generated successfully");
|
logGlobal->info("Zones generated successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMapGenerator::createWaterTreasures()
|
||||||
|
{
|
||||||
|
//add treasures on water
|
||||||
|
getZoneWater().second->addTreasureInfo(CTreasureInfo{100, 1000, 5});
|
||||||
|
getZoneWater().second->addTreasureInfo(CTreasureInfo{2000, 6000, 1});
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMapGenerator::prepareWaterTiles()
|
||||||
|
{
|
||||||
|
for(auto & t : zoneWater.second->getTileInfo())
|
||||||
|
if(shouldBeBlocked(t))
|
||||||
|
setOccupied(t, ETileType::POSSIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
void CMapGenerator::fillZones()
|
void CMapGenerator::fillZones()
|
||||||
{
|
{
|
||||||
//init native town count with 0
|
//init native town count with 0
|
||||||
@ -308,41 +332,67 @@ void CMapGenerator::fillZones()
|
|||||||
|
|
||||||
//we need info about all town types to evaluate dwellings and pandoras with creatures properly
|
//we need info about all town types to evaluate dwellings and pandoras with creatures properly
|
||||||
//place main town in the middle
|
//place main town in the middle
|
||||||
for (auto it : zones)
|
for(auto it : zones)
|
||||||
it.second->initTownType();
|
it.second->initTownType();
|
||||||
|
|
||||||
//make sure there are some free tiles in the zone
|
//make sure there are some free tiles in the zone
|
||||||
for (auto it : zones)
|
for(auto it : zones)
|
||||||
it.second->initFreeTiles();
|
it.second->initFreeTiles();
|
||||||
|
|
||||||
createDirectConnections(); //direct
|
for(auto it : zones)
|
||||||
|
|
||||||
//make sure all connections are passable before creating borders
|
|
||||||
for (auto it : zones)
|
|
||||||
it.second->createBorder(); //once direct connections are done
|
it.second->createBorder(); //once direct connections are done
|
||||||
|
|
||||||
|
#ifdef _BETA
|
||||||
|
dump(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(auto it : zones)
|
||||||
|
it.second->createWater(getMapGenOptions().getWaterContent());
|
||||||
|
|
||||||
|
zoneWater.second->waterInitFreeTiles();
|
||||||
|
|
||||||
|
#ifdef _BETA
|
||||||
|
dump(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
createDirectConnections(); //direct
|
||||||
createConnections2(); //subterranean gates and monoliths
|
createConnections2(); //subterranean gates and monoliths
|
||||||
|
|
||||||
|
for(auto it : zones)
|
||||||
|
zoneWater.second->waterConnection(*it.second);
|
||||||
|
|
||||||
|
createWaterTreasures();
|
||||||
|
zoneWater.second->initFreeTiles();
|
||||||
|
zoneWater.second->fill();
|
||||||
|
|
||||||
std::vector<std::shared_ptr<CRmgTemplateZone>> treasureZones;
|
std::vector<std::shared_ptr<CRmgTemplateZone>> treasureZones;
|
||||||
for (auto it : zones)
|
for(auto it : zones)
|
||||||
{
|
{
|
||||||
it.second->fill();
|
it.second->fill();
|
||||||
if (it.second->getType() == ETemplateZoneType::TREASURE)
|
if (it.second->getType() == ETemplateZoneType::TREASURE)
|
||||||
treasureZones.push_back(it.second);
|
treasureZones.push_back(it.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _BETA
|
||||||
|
dump(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
//set apriopriate free/occupied tiles, including blocked underground rock
|
//set apriopriate free/occupied tiles, including blocked underground rock
|
||||||
createObstaclesCommon1();
|
createObstaclesCommon1();
|
||||||
//set back original terrain for underground zones
|
//set back original terrain for underground zones
|
||||||
for (auto it : zones)
|
for(auto it : zones)
|
||||||
it.second->createObstacles1();
|
it.second->createObstacles1();
|
||||||
|
|
||||||
createObstaclesCommon2();
|
createObstaclesCommon2();
|
||||||
//place actual obstacles matching zone terrain
|
//place actual obstacles matching zone terrain
|
||||||
for (auto it : zones)
|
for(auto it : zones)
|
||||||
{
|
|
||||||
it.second->createObstacles2();
|
it.second->createObstacles2();
|
||||||
}
|
|
||||||
|
zoneWater.second->createObstacles2();
|
||||||
|
|
||||||
|
#ifdef _BETA
|
||||||
|
dump(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PRINT_MAP_BEFORE_ROADS false
|
#define PRINT_MAP_BEFORE_ROADS false
|
||||||
if (PRINT_MAP_BEFORE_ROADS) //enable to debug
|
if (PRINT_MAP_BEFORE_ROADS) //enable to debug
|
||||||
@ -379,15 +429,15 @@ void CMapGenerator::fillZones()
|
|||||||
out << std::endl;
|
out << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it : zones)
|
for(auto it : zones)
|
||||||
{
|
{
|
||||||
it.second->connectRoads(); //draw roads after everything else has been placed
|
it.second->connectRoads(); //draw roads after everything else has been placed
|
||||||
}
|
}
|
||||||
|
|
||||||
//find place for Grail
|
//find place for Grail
|
||||||
if (treasureZones.empty())
|
if(treasureZones.empty())
|
||||||
{
|
{
|
||||||
for (auto it : zones)
|
for(auto it : zones)
|
||||||
treasureZones.push_back(it.second);
|
treasureZones.push_back(it.second);
|
||||||
}
|
}
|
||||||
auto grailZone = *RandomGeneratorUtil::nextItem(treasureZones, rand);
|
auto grailZone = *RandomGeneratorUtil::nextItem(treasureZones, rand);
|
||||||
@ -503,30 +553,29 @@ void CMapGenerator::findZonesForQuestArts()
|
|||||||
|
|
||||||
void CMapGenerator::createDirectConnections()
|
void CMapGenerator::createDirectConnections()
|
||||||
{
|
{
|
||||||
|
bool waterMode = getMapGenOptions().getWaterContent() != EWaterContent::NONE;
|
||||||
|
|
||||||
for (auto connection : mapGenOptions.getMapTemplate()->getConnections())
|
for (auto connection : mapGenOptions.getMapTemplate()->getConnections())
|
||||||
{
|
{
|
||||||
auto zoneA = zones[connection.getZoneA()];
|
auto zoneA = zones[connection.getZoneA()];
|
||||||
auto zoneB = zones[connection.getZoneB()];
|
auto zoneB = zones[connection.getZoneB()];
|
||||||
|
|
||||||
//rearrange tiles in random order
|
//rearrange tiles in random order
|
||||||
auto tilesCopy = zoneA->getTileInfo();
|
const auto & tiles = zoneA->getTileInfo();
|
||||||
std::vector<int3> tiles(tilesCopy.begin(), tilesCopy.end());
|
|
||||||
|
|
||||||
int3 guardPos(-1,-1,-1);
|
int3 guardPos(-1,-1,-1);
|
||||||
|
|
||||||
auto otherZoneTiles = zoneB->getTileInfo();
|
|
||||||
|
|
||||||
int3 posA = zoneA->getPos();
|
int3 posA = zoneA->getPos();
|
||||||
int3 posB = zoneB->getPos();
|
int3 posB = zoneB->getPos();
|
||||||
// auto zoneAid = zoneA->getId();
|
// auto zoneAid = zoneA->getId();
|
||||||
auto zoneBid = zoneB->getId();
|
auto zoneBid = zoneB->getId();
|
||||||
|
|
||||||
if (posA.z == posB.z)
|
if (posA.z == posB.z)
|
||||||
{
|
{
|
||||||
std::vector<int3> middleTiles;
|
std::vector<int3> middleTiles;
|
||||||
for (auto tile : tilesCopy)
|
for (const auto& tile : tiles)
|
||||||
{
|
{
|
||||||
if (isBlocked(tile)) //tiles may be occupied by subterranean gates already placed
|
if (isUsed(tile) || getZoneID(tile)==zoneWater.first) //tiles may be occupied by towns or water
|
||||||
continue;
|
continue;
|
||||||
foreachDirectNeighbour(tile, [tile, &middleTiles, this, zoneBid](int3 & pos) //must be direct since paths also also generated between direct neighbours
|
foreachDirectNeighbour(tile, [tile, &middleTiles, this, zoneBid](int3 & pos) //must be direct since paths also also generated between direct neighbours
|
||||||
{
|
{
|
||||||
@ -559,8 +608,8 @@ void CMapGenerator::createDirectConnections()
|
|||||||
if (guardPos.valid())
|
if (guardPos.valid())
|
||||||
{
|
{
|
||||||
//zones can make paths only in their own area
|
//zones can make paths only in their own area
|
||||||
zoneA->connectWithCenter(guardPos, true);
|
zoneA->connectWithCenter(guardPos, true, true);
|
||||||
zoneB->connectWithCenter(guardPos, true);
|
zoneB->connectWithCenter(guardPos, true, true);
|
||||||
|
|
||||||
bool monsterPresent = zoneA->addMonster(guardPos, connection.getGuardStrength(), false, true);
|
bool monsterPresent = zoneA->addMonster(guardPos, connection.getGuardStrength(), false, true);
|
||||||
zoneB->updateDistances(guardPos); //place next objects away from guard in both zones
|
zoneB->updateDistances(guardPos); //place next objects away from guard in both zones
|
||||||
@ -575,9 +624,12 @@ void CMapGenerator::createDirectConnections()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!guardPos.valid())
|
if (!guardPos.valid())
|
||||||
connectionsLeft.push_back(connection);
|
{
|
||||||
|
if(!waterMode || posA.z != posB.z || !zoneWater.second->waterKeepConnection(connection.getZoneA(), connection.getZoneB()))
|
||||||
|
connectionsLeft.push_back(connection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,3 +917,48 @@ ui32 CMapGenerator::getTotalZoneCount() const
|
|||||||
{
|
{
|
||||||
return zonesTotal;
|
return zonesTotal;
|
||||||
}
|
}
|
||||||
|
CMapGenerator::Zones::value_type CMapGenerator::getZoneWater() const
|
||||||
|
{
|
||||||
|
return zoneWater;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMapGenerator::dump(bool zoneId)
|
||||||
|
{
|
||||||
|
static int id = 0;
|
||||||
|
std::ofstream out(boost::to_string(boost::format("zone_%d.txt") % id++));
|
||||||
|
int levels = map->twoLevel ? 2 : 1;
|
||||||
|
int width = map->width;
|
||||||
|
int height = map->height;
|
||||||
|
for (int k = 0; k < levels; k++)
|
||||||
|
{
|
||||||
|
for(int j=0; j<height; j++)
|
||||||
|
{
|
||||||
|
for (int i=0; i<width; i++)
|
||||||
|
{
|
||||||
|
if(zoneId)
|
||||||
|
{
|
||||||
|
out << getZoneID(int3(i, j, k));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char t = '?';
|
||||||
|
switch (getTile(int3(i, j, k)).getTileType())
|
||||||
|
{
|
||||||
|
case ETileType::FREE:
|
||||||
|
t = ' '; break;
|
||||||
|
case ETileType::BLOCKED:
|
||||||
|
t = '#'; break;
|
||||||
|
case ETileType::POSSIBLE:
|
||||||
|
t = '-'; break;
|
||||||
|
case ETileType::USED:
|
||||||
|
t = 'O'; break;
|
||||||
|
}
|
||||||
|
out << t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out << std::endl;
|
||||||
|
}
|
||||||
|
out << std::endl;
|
||||||
|
}
|
||||||
|
out << std::endl;
|
||||||
|
}
|
||||||
|
@ -26,6 +26,8 @@ class JsonNode;
|
|||||||
class CMapGenerator;
|
class CMapGenerator;
|
||||||
class CTileInfo;
|
class CTileInfo;
|
||||||
|
|
||||||
|
//#define _BETA
|
||||||
|
|
||||||
typedef std::vector<JsonNode> JsonVector;
|
typedef std::vector<JsonNode> JsonVector;
|
||||||
|
|
||||||
class rmgException : public std::exception
|
class rmgException : public std::exception
|
||||||
@ -96,18 +98,26 @@ public:
|
|||||||
void registerZone (TFaction faction);
|
void registerZone (TFaction faction);
|
||||||
ui32 getZoneCount(TFaction faction);
|
ui32 getZoneCount(TFaction faction);
|
||||||
ui32 getTotalZoneCount() const;
|
ui32 getTotalZoneCount() const;
|
||||||
|
|
||||||
|
Zones::value_type getZoneWater() const;
|
||||||
|
void createWaterTreasures();
|
||||||
|
void prepareWaterTiles();
|
||||||
|
|
||||||
TRmgTemplateZoneId getZoneID(const int3& tile) const;
|
TRmgTemplateZoneId getZoneID(const int3& tile) const;
|
||||||
void setZoneID(const int3& tile, TRmgTemplateZoneId zid);
|
void setZoneID(const int3& tile, TRmgTemplateZoneId zid);
|
||||||
|
|
||||||
|
void dump(bool zoneId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int randomSeed;
|
int randomSeed;
|
||||||
CMapGenOptions& mapGenOptions;
|
CMapGenOptions& mapGenOptions;
|
||||||
|
|
||||||
std::list<rmg::ZoneConnection> connectionsLeft;
|
std::vector<rmg::ZoneConnection> connectionsLeft;
|
||||||
Zones zones;
|
Zones zones;
|
||||||
std::map<TFaction, ui32> zonesPerFaction;
|
std::map<TFaction, ui32> zonesPerFaction;
|
||||||
ui32 zonesTotal; //zones that have their main town only
|
ui32 zonesTotal; //zones that have their main town only
|
||||||
|
|
||||||
|
std::pair<Zones::key_type, Zones::mapped_type> zoneWater;
|
||||||
|
|
||||||
CTileInfo*** tiles;
|
CTileInfo*** tiles;
|
||||||
boost::multi_array<TRmgTemplateZoneId, 3> zoneColouring; //[z][x][y]
|
boost::multi_array<TRmgTemplateZoneId, 3> zoneColouring; //[z][x][y]
|
||||||
|
@ -39,6 +39,12 @@ CTreasureInfo::CTreasureInfo()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CTreasureInfo::CTreasureInfo(ui32 imin, ui32 imax, ui16 idensity)
|
||||||
|
: min(imin), max(imax), density(idensity)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool CTreasureInfo::operator==(const CTreasureInfo & other) const
|
bool CTreasureInfo::operator==(const CTreasureInfo & other) const
|
||||||
{
|
{
|
||||||
return (min == other.min) && (max == other.max) && (density == other.density);
|
return (min == other.min) && (max == other.max) && (density == other.density);
|
||||||
@ -196,6 +202,11 @@ ETemplateZoneType::ETemplateZoneType ZoneOptions::getType() const
|
|||||||
{
|
{
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZoneOptions::setType(ETemplateZoneType::ETemplateZoneType value)
|
||||||
|
{
|
||||||
|
type = value;
|
||||||
|
}
|
||||||
|
|
||||||
int ZoneOptions::getSize() const
|
int ZoneOptions::getSize() const
|
||||||
{
|
{
|
||||||
@ -264,6 +275,11 @@ void ZoneOptions::setTreasureInfo(const std::vector<CTreasureInfo> & value)
|
|||||||
{
|
{
|
||||||
treasureInfo = value;
|
treasureInfo = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZoneOptions::addTreasureInfo(const CTreasureInfo & value)
|
||||||
|
{
|
||||||
|
treasureInfo.push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<CTreasureInfo> & ZoneOptions::getTreasureInfo() const
|
const std::vector<CTreasureInfo> & ZoneOptions::getTreasureInfo() const
|
||||||
{
|
{
|
||||||
@ -302,7 +318,8 @@ void ZoneOptions::serializeJson(JsonSerializeFormat & handler)
|
|||||||
"playerStart",
|
"playerStart",
|
||||||
"cpuStart",
|
"cpuStart",
|
||||||
"treasure",
|
"treasure",
|
||||||
"junction"
|
"junction",
|
||||||
|
"water"
|
||||||
};
|
};
|
||||||
|
|
||||||
handler.serializeEnum("type", type, zoneTypes);
|
handler.serializeEnum("type", type, zoneTypes);
|
||||||
@ -421,6 +438,11 @@ bool CRmgTemplate::matchesSize(const int3 & value) const
|
|||||||
return minSquare <= square && square <= maxSquare;
|
return minSquare <= square && square <= maxSquare;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CRmgTemplate::isWaterContentAllowed(EWaterContent::EWaterContent waterContent) const
|
||||||
|
{
|
||||||
|
return waterContent == EWaterContent::EWaterContent::RANDOM || allowedWaterContent.count(waterContent);
|
||||||
|
}
|
||||||
|
|
||||||
void CRmgTemplate::setId(const std::string & value)
|
void CRmgTemplate::setId(const std::string & value)
|
||||||
{
|
{
|
||||||
id = value;
|
id = value;
|
||||||
@ -623,6 +645,14 @@ void CRmgTemplate::afterLoad()
|
|||||||
zone1->addConnection(id2);
|
zone1->addConnection(id2);
|
||||||
zone2->addConnection(id1);
|
zone2->addConnection(id1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(allowedWaterContent.empty() || allowedWaterContent.count(EWaterContent::EWaterContent::RANDOM))
|
||||||
|
{
|
||||||
|
allowedWaterContent.insert(EWaterContent::EWaterContent::NONE);
|
||||||
|
allowedWaterContent.insert(EWaterContent::EWaterContent::NORMAL);
|
||||||
|
allowedWaterContent.insert(EWaterContent::EWaterContent::ISLANDS);
|
||||||
|
}
|
||||||
|
allowedWaterContent.erase(EWaterContent::EWaterContent::RANDOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRmgTemplate::serializeSize(JsonSerializeFormat & handler, int3 & value, const std::string & fieldName)
|
void CRmgTemplate::serializeSize(JsonSerializeFormat & handler, int3 & value, const std::string & fieldName)
|
||||||
|
@ -24,7 +24,8 @@ namespace ETemplateZoneType
|
|||||||
PLAYER_START,
|
PLAYER_START,
|
||||||
CPU_START,
|
CPU_START,
|
||||||
TREASURE,
|
TREASURE,
|
||||||
JUNCTION
|
JUNCTION,
|
||||||
|
WATER
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +36,7 @@ public:
|
|||||||
ui32 max;
|
ui32 max;
|
||||||
ui16 density;
|
ui16 density;
|
||||||
CTreasureInfo();
|
CTreasureInfo();
|
||||||
|
CTreasureInfo(ui32 min, ui32 max, ui16 density);
|
||||||
|
|
||||||
bool operator ==(const CTreasureInfo & other) const;
|
bool operator ==(const CTreasureInfo & other) const;
|
||||||
|
|
||||||
@ -93,6 +95,8 @@ public:
|
|||||||
void setId(TRmgTemplateZoneId value);
|
void setId(TRmgTemplateZoneId value);
|
||||||
|
|
||||||
ETemplateZoneType::ETemplateZoneType getType() const;
|
ETemplateZoneType::ETemplateZoneType getType() const;
|
||||||
|
void setType(ETemplateZoneType::ETemplateZoneType value);
|
||||||
|
|
||||||
int getSize() const;
|
int getSize() const;
|
||||||
void setSize(int value);
|
void setSize(int value);
|
||||||
boost::optional<int> getOwner() const;
|
boost::optional<int> getOwner() const;
|
||||||
@ -110,6 +114,7 @@ public:
|
|||||||
std::map<TResource, ui16> getMinesInfo() const;
|
std::map<TResource, ui16> getMinesInfo() const;
|
||||||
|
|
||||||
void setTreasureInfo(const std::vector<CTreasureInfo> & value);
|
void setTreasureInfo(const std::vector<CTreasureInfo> & value);
|
||||||
|
void addTreasureInfo(const CTreasureInfo & value);
|
||||||
const std::vector<CTreasureInfo> & getTreasureInfo() const;
|
const std::vector<CTreasureInfo> & getTreasureInfo() const;
|
||||||
|
|
||||||
TRmgTemplateZoneId getMinesLikeZone() const;
|
TRmgTemplateZoneId getMinesLikeZone() const;
|
||||||
@ -175,6 +180,7 @@ public:
|
|||||||
~CRmgTemplate();
|
~CRmgTemplate();
|
||||||
|
|
||||||
bool matchesSize(const int3 & value) const;
|
bool matchesSize(const int3 & value) const;
|
||||||
|
bool isWaterContentAllowed(EWaterContent::EWaterContent waterContent) const;
|
||||||
|
|
||||||
void setId(const std::string & value);
|
void setId(const std::string & value);
|
||||||
const std::string & getName() const;
|
const std::string & getName() const;
|
||||||
@ -195,6 +201,7 @@ private:
|
|||||||
CPlayerCountRange players, cpuPlayers;
|
CPlayerCountRange players, cpuPlayers;
|
||||||
Zones zones;
|
Zones zones;
|
||||||
std::vector<rmg::ZoneConnection> connections;
|
std::vector<rmg::ZoneConnection> connections;
|
||||||
|
std::set<EWaterContent::EWaterContent> allowedWaterContent;
|
||||||
|
|
||||||
void afterLoad();
|
void afterLoad();
|
||||||
void serializeSize(JsonSerializeFormat & handler, int3 & value, const std::string & fieldName);
|
void serializeSize(JsonSerializeFormat & handler, int3 & value, const std::string & fieldName);
|
||||||
|
@ -68,36 +68,3 @@ std::vector<const CRmgTemplate *> CRmgTemplateStorage::getTemplates() const
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const CRmgTemplate *> CRmgTemplateStorage::getTemplates(const int3& filterSize, si8 filterPlayers, si8 filterHumanPlayers, si8 filterCpuPlayers) const
|
|
||||||
{
|
|
||||||
std::vector<const CRmgTemplate *> result;
|
|
||||||
for(auto i=templates.cbegin(); i!=templates.cend(); ++i)
|
|
||||||
{
|
|
||||||
auto& tmpl = i->second;
|
|
||||||
|
|
||||||
if (!tmpl.matchesSize(filterSize))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (filterPlayers != -1)
|
|
||||||
{
|
|
||||||
if (!tmpl.getPlayers().isInRange(filterPlayers))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Human players shouldn't be banned when playing with random player count
|
|
||||||
if (filterHumanPlayers > *boost::min_element(tmpl.getPlayers().getNumbers()))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(filterCpuPlayers != -1)
|
|
||||||
{
|
|
||||||
if (!tmpl.getCpuPlayers().isInRange(filterCpuPlayers))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.push_back(&i->second);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
@ -29,9 +29,8 @@ public:
|
|||||||
virtual void loadObject(std::string scope, std::string name, const JsonNode & data) override;
|
virtual void loadObject(std::string scope, std::string name, const JsonNode & data) override;
|
||||||
virtual void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
|
virtual void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
|
||||||
|
|
||||||
const CRmgTemplate * getTemplate(const std::string & templateName) const;
|
const CRmgTemplate* getTemplate(const std::string & templateName) const;
|
||||||
std::vector<const CRmgTemplate *> getTemplates() const;
|
std::vector<const CRmgTemplate *> getTemplates() const;
|
||||||
std::vector<const CRmgTemplate *> getTemplates(const int3& filterSize, si8 filterPlayers, si8 filterHumanPlayers, si8 filterCpuPlayers) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, CRmgTemplate> templates;
|
std::map<std::string, CRmgTemplate> templates;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -91,26 +91,29 @@ class DLL_LINKAGE CRmgTemplateZone : public rmg::ZoneOptions
|
|||||||
public:
|
public:
|
||||||
CRmgTemplateZone(CMapGenerator * Gen);
|
CRmgTemplateZone(CMapGenerator * Gen);
|
||||||
|
|
||||||
void setOptions(const rmg::ZoneOptions * options);
|
void setOptions(const rmg::ZoneOptions & options);
|
||||||
bool isUnderground() const;
|
bool isUnderground() const;
|
||||||
|
|
||||||
float3 getCenter() const;
|
float3 getCenter() const;
|
||||||
void setCenter(const float3 &f);
|
void setCenter(const float3 &f);
|
||||||
int3 getPos() const;
|
int3 getPos() const;
|
||||||
void setPos(const int3 &pos);
|
void setPos(const int3 &pos);
|
||||||
bool isAccessibleFromAnywhere(ObjectTemplate &appearance, int3 &tile) const;
|
bool isAccessibleFromSomewhere(ObjectTemplate & appearance, const int3 & tile) const;
|
||||||
int3 getAccessibleOffset(ObjectTemplate &appearance, int3 &tile) const;
|
int3 getAccessibleOffset(ObjectTemplate & appearance, const int3 & tile) const;
|
||||||
|
|
||||||
void addTile (const int3 &pos);
|
void addTile (const int3 & pos);
|
||||||
|
void removeTile(const int3 & pos);
|
||||||
void initFreeTiles ();
|
void initFreeTiles ();
|
||||||
std::set<int3> getTileInfo() const;
|
std::set<int3> getTileInfo() const;
|
||||||
std::set<int3> getPossibleTiles() const;
|
std::set<int3> getPossibleTiles() const;
|
||||||
void discardDistantTiles (float distance);
|
std::set<int3> collectDistantTiles (float distance) const;
|
||||||
void clearTiles();
|
void clearTiles();
|
||||||
|
|
||||||
void addRequiredObject(CGObjectInstance * obj, si32 guardStrength=0);
|
void addRequiredObject(CGObjectInstance * obj, si32 guardStrength=0);
|
||||||
void addCloseObject(CGObjectInstance * obj, si32 guardStrength = 0);
|
void addCloseObject(CGObjectInstance * obj, si32 guardStrength = 0);
|
||||||
void addNearbyObject(CGObjectInstance * obj, CGObjectInstance * nearbyTarget);
|
void addNearbyObject(CGObjectInstance * obj, CGObjectInstance * nearbyTarget);
|
||||||
|
void addObjectAtPosition(CGObjectInstance * obj, const int3 & position, si32 guardStrength=0);
|
||||||
|
|
||||||
void addToConnectLater(const int3& src);
|
void addToConnectLater(const int3& src);
|
||||||
bool addMonster(int3 &pos, si32 strength, bool clearSurroundingTiles = true, bool zoneGuard = false);
|
bool addMonster(int3 &pos, si32 strength, bool clearSurroundingTiles = true, bool zoneGuard = false);
|
||||||
bool createTreasurePile(int3 &pos, float minDistance, const CTreasureInfo& treasureInfo);
|
bool createTreasurePile(int3 &pos, float minDistance, const CTreasureInfo& treasureInfo);
|
||||||
@ -123,21 +126,35 @@ public:
|
|||||||
void createBorder();
|
void createBorder();
|
||||||
void fractalize();
|
void fractalize();
|
||||||
void connectLater();
|
void connectLater();
|
||||||
EObjectPlacingResult::EObjectPlacingResult tryToPlaceObjectAndConnectToPath(CGObjectInstance *obj, int3 &pos); //return true if the position cna be connected
|
EObjectPlacingResult::EObjectPlacingResult tryToPlaceObjectAndConnectToPath(CGObjectInstance * obj, const int3 & pos); //return true if the position can be connected
|
||||||
bool createRequiredObjects();
|
bool createRequiredObjects();
|
||||||
|
bool createShipyard(const int3 & pos, si32 guardStrength=0);
|
||||||
|
int3 createShipyard(const std::set<int3> & lake, si32 guardStrength=0);
|
||||||
|
bool makeBoat(TRmgTemplateZoneId land, const int3 & coast);
|
||||||
|
int3 makeBoat(TRmgTemplateZoneId land, const std::set<int3> & lake);
|
||||||
void createTreasures();
|
void createTreasures();
|
||||||
|
|
||||||
|
void createWater(EWaterContent::EWaterContent waterContent, bool debug=false);
|
||||||
|
void waterInitFreeTiles();
|
||||||
|
void waterConnection(CRmgTemplateZone& dst);
|
||||||
|
bool waterKeepConnection(TRmgTemplateZoneId zoneA, TRmgTemplateZoneId zoneB);
|
||||||
|
const std::set<int3>& getCoastTiles() const;
|
||||||
|
bool isWaterConnected(TRmgTemplateZoneId zone, const int3 & tile) const;
|
||||||
|
//void computeCoastTiles();
|
||||||
|
|
||||||
void createObstacles1();
|
void createObstacles1();
|
||||||
void createObstacles2();
|
void createObstacles2();
|
||||||
bool crunchPath(const int3 &src, const int3 &dst, bool onlyStraight, std::set<int3>* clearedTiles = nullptr);
|
bool crunchPath(const int3 &src, const int3 &dst, bool onlyStraight, std::set<int3>* clearedTiles = nullptr);
|
||||||
bool connectPath(const int3& src, bool onlyStraight);
|
bool connectPath(const int3& src, bool onlyStraight);
|
||||||
bool connectWithCenter(const int3& src, bool onlyStraight);
|
bool connectWithCenter(const int3& src, bool onlyStraight, bool passTroughBlocked = false);
|
||||||
void updateDistances(const int3 & pos);
|
void updateDistances(const int3 & pos);
|
||||||
|
|
||||||
std::vector<int3> getAccessibleOffsets (const CGObjectInstance* object);
|
std::vector<int3> getAccessibleOffsets (const CGObjectInstance* object);
|
||||||
bool areAllTilesAvailable(CGObjectInstance* obj, int3& tile, std::set<int3>& tilesBlockedByObject) const;
|
bool areAllTilesAvailable(CGObjectInstance* obj, int3& tile, const std::set<int3>& tilesBlockedByObject) const;
|
||||||
|
|
||||||
void setQuestArtZone(std::shared_ptr<CRmgTemplateZone> otherZone);
|
void setQuestArtZone(std::shared_ptr<CRmgTemplateZone> otherZone);
|
||||||
std::set<int3>* getFreePaths();
|
std::set<int3>* getFreePaths();
|
||||||
|
void addFreePath(const int3 &);
|
||||||
|
|
||||||
ObjectInfo getRandomObject (CTreasurePileInfo &info, ui32 desiredValue, ui32 maxValue, ui32 currentValue);
|
ObjectInfo getRandomObject (CTreasurePileInfo &info, ui32 desiredValue, ui32 maxValue, ui32 currentValue);
|
||||||
|
|
||||||
@ -160,9 +177,20 @@ public:
|
|||||||
boost::heap::priority_queue<TDistance, boost::heap::compare<NodeComparer>> createPriorityQueue();
|
boost::heap::priority_queue<TDistance, boost::heap::compare<NodeComparer>> createPriorityQueue();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
//subclass to store disconnected parts of water zone
|
||||||
|
struct Lake
|
||||||
|
{
|
||||||
|
std::set<int3> tiles;
|
||||||
|
std::set<int3> coast;
|
||||||
|
std::map<int3, int> distance;
|
||||||
|
std::set<TRmgTemplateZoneId> connectedZones;
|
||||||
|
std::set<TRmgTemplateZoneId> keepConnections;
|
||||||
|
};
|
||||||
|
|
||||||
CMapGenerator * gen;
|
CMapGenerator * gen;
|
||||||
|
|
||||||
//template info
|
//template info
|
||||||
|
|
||||||
si32 townType;
|
si32 townType;
|
||||||
ETerrainType terrainType;
|
ETerrainType terrainType;
|
||||||
std::weak_ptr<CRmgTemplateZone> questArtZone; //artifacts required for Seer Huts will be placed here - or not if null
|
std::weak_ptr<CRmgTemplateZone> questArtZone; //artifacts required for Seer Huts will be placed here - or not if null
|
||||||
@ -173,8 +201,10 @@ private:
|
|||||||
//content info
|
//content info
|
||||||
std::vector<std::pair<CGObjectInstance*, ui32>> requiredObjects;
|
std::vector<std::pair<CGObjectInstance*, ui32>> requiredObjects;
|
||||||
std::vector<std::pair<CGObjectInstance*, ui32>> closeObjects;
|
std::vector<std::pair<CGObjectInstance*, ui32>> closeObjects;
|
||||||
|
std::vector<std::pair<CGObjectInstance*, int3>> instantObjects;
|
||||||
std::vector<std::pair<CGObjectInstance*, CGObjectInstance*>> nearbyObjects;
|
std::vector<std::pair<CGObjectInstance*, CGObjectInstance*>> nearbyObjects;
|
||||||
std::vector<CGObjectInstance*> objects;
|
std::vector<CGObjectInstance*> objects;
|
||||||
|
std::map<CGObjectInstance*, int3> requestedPositions;
|
||||||
|
|
||||||
//placement info
|
//placement info
|
||||||
int3 pos;
|
int3 pos;
|
||||||
@ -182,11 +212,14 @@ private:
|
|||||||
std::set<int3> tileinfo; //irregular area assined to zone
|
std::set<int3> tileinfo; //irregular area assined to zone
|
||||||
std::set<int3> possibleTiles; //optimization purposes for treasure generation
|
std::set<int3> possibleTiles; //optimization purposes for treasure generation
|
||||||
std::set<int3> freePaths; //core paths of free tiles that all other objects will be linked to
|
std::set<int3> freePaths; //core paths of free tiles that all other objects will be linked to
|
||||||
|
std::set<int3> coastTiles; //tiles bordered to water
|
||||||
|
|
||||||
std::set<int3> roadNodes; //tiles to be connected with roads
|
std::set<int3> roadNodes; //tiles to be connected with roads
|
||||||
std::set<int3> roads; //all tiles with roads
|
std::set<int3> roads; //all tiles with roads
|
||||||
std::set<int3> tilesToConnectLater; //will be connected after paths are fractalized
|
std::set<int3> tilesToConnectLater; //will be connected after paths are fractalized
|
||||||
|
std::vector<Lake> lakes; //disconnected parts of zone. Used to work with water zones
|
||||||
|
std::map<int3, int> lakeMap; //map tile on lakeId which is position of lake in lakes array +1
|
||||||
|
|
||||||
bool createRoad(const int3 &src, const int3 &dst);
|
bool createRoad(const int3 &src, const int3 &dst);
|
||||||
void drawRoads(); //actually updates tiles
|
void drawRoads(); //actually updates tiles
|
||||||
|
|
||||||
@ -197,4 +230,6 @@ private:
|
|||||||
bool canObstacleBePlacedHere(ObjectTemplate &temp, int3 &pos);
|
bool canObstacleBePlacedHere(ObjectTemplate &temp, int3 &pos);
|
||||||
void setTemplateForObject(CGObjectInstance* obj);
|
void setTemplateForObject(CGObjectInstance* obj);
|
||||||
void checkAndPlaceObject(CGObjectInstance* object, const int3 &pos);
|
void checkAndPlaceObject(CGObjectInstance* object, const int3 &pos);
|
||||||
|
|
||||||
|
bool isGuardNeededForTreasure(int value);
|
||||||
};
|
};
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* CZoneGraphGenerator.cpp, part of VCMI engine
|
|
||||||
*
|
|
||||||
* Authors: listed in file AUTHORS in main folder
|
|
||||||
*
|
|
||||||
* License: GNU General Public License v2.0 or later
|
|
||||||
* Full text of license available in license.txt file, in main folder
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "StdInc.h"
|
|
||||||
#include "CZoneGraphGenerator.h"
|
|
||||||
|
|
||||||
CZoneCell::CZoneCell(const CRmgTemplateZone * zone)// : zone(zone)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CZoneGraph::CZoneGraph()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
CZoneGraphGenerator::CZoneGraphGenerator()// : gen(nullptr)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<CZoneGraph> CZoneGraphGenerator::generate(const CMapGenOptions & options, CRandomGenerator * gen)
|
|
||||||
{
|
|
||||||
return make_unique<CZoneGraph>();
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* CZoneGraphGenerator.h, part of VCMI engine
|
|
||||||
*
|
|
||||||
* Authors: listed in file AUTHORS in main folder
|
|
||||||
*
|
|
||||||
* License: GNU General Public License v2.0 or later
|
|
||||||
* Full text of license available in license.txt file, in main folder
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
class CRmgTemplateZone;
|
|
||||||
class CRandomGenerator;
|
|
||||||
class CMapGenOptions;
|
|
||||||
|
|
||||||
class CZoneCell
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit CZoneCell(const CRmgTemplateZone * zone);
|
|
||||||
|
|
||||||
private:
|
|
||||||
//const CRmgTemplateZone * zone;
|
|
||||||
|
|
||||||
//TODO additional data
|
|
||||||
};
|
|
||||||
|
|
||||||
class CZoneGraph
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CZoneGraph();
|
|
||||||
|
|
||||||
private:
|
|
||||||
//TODO zone graph storage
|
|
||||||
};
|
|
||||||
|
|
||||||
class CZoneGraphGenerator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CZoneGraphGenerator();
|
|
||||||
|
|
||||||
std::unique_ptr<CZoneGraph> generate(const CMapGenOptions & options, CRandomGenerator * gen);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<CZoneGraph> graph;
|
|
||||||
//CRandomGenerator * gen;
|
|
||||||
};
|
|
@ -13,8 +13,7 @@
|
|||||||
#include "CZonePlacer.h"
|
#include "CZonePlacer.h"
|
||||||
#include "CRmgTemplateZone.h"
|
#include "CRmgTemplateZone.h"
|
||||||
#include "../mapping/CMap.h"
|
#include "../mapping/CMap.h"
|
||||||
|
#include "../mapping/CMapEditManager.h"
|
||||||
#include "CZoneGraphGenerator.h"
|
|
||||||
|
|
||||||
class CRandomGenerator;
|
class CRandomGenerator;
|
||||||
|
|
||||||
@ -557,7 +556,11 @@ void CZonePlacer::assignZones()
|
|||||||
if (zone.second->isUnderground())
|
if (zone.second->isUnderground())
|
||||||
{
|
{
|
||||||
if (!CREATE_FULL_UNDERGROUND)
|
if (!CREATE_FULL_UNDERGROUND)
|
||||||
zone.second->discardDistantTiles((float)(zone.second->getSize() + 1));
|
{
|
||||||
|
auto discardTile = zone.second->collectDistantTiles((float)(zone.second->getSize() + 1));
|
||||||
|
for(auto& t : discardTile)
|
||||||
|
zone.second->removeTile(t);
|
||||||
|
}
|
||||||
|
|
||||||
//make sure that terrain inside zone is not a rock
|
//make sure that terrain inside zone is not a rock
|
||||||
//FIXME: reorder actions?
|
//FIXME: reorder actions?
|
||||||
|
Loading…
Reference in New Issue
Block a user