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/CRmgTemplateStorage.cpp
|
||||
rmg/CRmgTemplateZone.cpp
|
||||
rmg/CZoneGraphGenerator.cpp
|
||||
rmg/CZonePlacer.cpp
|
||||
|
||||
serializer/BinaryDeserializer.cpp
|
||||
@ -292,7 +291,6 @@ set(lib_HEADERS
|
||||
rmg/CRmgTemplate.h
|
||||
rmg/CRmgTemplateStorage.h
|
||||
rmg/CRmgTemplateZone.h
|
||||
rmg/CZoneGraphGenerator.h
|
||||
rmg/CZonePlacer.h
|
||||
rmg/float3.h
|
||||
|
||||
|
@ -255,6 +255,7 @@ void ObjectTemplate::readJson(const JsonNode &node, const bool withTerrain)
|
||||
allowedTerrains.insert(ETerrainType((si32)i));
|
||||
|
||||
allowedTerrains.erase(ETerrainType::ROCK);
|
||||
allowedTerrains.erase(ETerrainType::WATER);
|
||||
}
|
||||
|
||||
if(withTerrain && allowedTerrains.empty())
|
||||
@ -327,8 +328,8 @@ void ObjectTemplate::writeJson(JsonNode & node, const bool withTerrain) const
|
||||
|
||||
if(withTerrain)
|
||||
{
|
||||
//assumed that ROCK terrain not included
|
||||
if(allowedTerrains.size() < (GameConstants::TERRAIN_TYPES - 1))
|
||||
//assumed that ROCK and WATER terrains are not included
|
||||
if(allowedTerrains.size() < (GameConstants::TERRAIN_TYPES - 2))
|
||||
{
|
||||
JsonVector & data = node["allowedTerrains"].Vector();
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "../mapping/CMap.h"
|
||||
#include "CRmgTemplateStorage.h"
|
||||
#include "CRmgTemplate.h"
|
||||
#include "CRandomGenerator.h"
|
||||
#include "../VCMI_Lib.h"
|
||||
#include "../CTownHandler.h"
|
||||
|
||||
@ -390,9 +391,39 @@ bool CMapGenOptions::checkOptions() const
|
||||
const CRmgTemplate * CMapGenOptions::getPossibleTemplate(CRandomGenerator & rand) const
|
||||
{
|
||||
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
|
||||
if(templates.empty())
|
||||
return nullptr;
|
||||
|
@ -11,9 +11,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "../GameConstants.h"
|
||||
#include "../CRandomGenerator.h"
|
||||
|
||||
class CRmgTemplate;
|
||||
class CRandomGenerator;
|
||||
|
||||
namespace EWaterContent
|
||||
{
|
||||
|
@ -285,17 +285,41 @@ void CMapGenerator::genZones()
|
||||
for(const auto & option : tmpl->getZones())
|
||||
{
|
||||
auto zone = std::make_shared<CRmgTemplateZone>(this);
|
||||
zone->setOptions(option.second.get());
|
||||
zone->setOptions(*option.second.get());
|
||||
zones[zone->getId()] = zone;
|
||||
}
|
||||
|
||||
CZonePlacer placer(this);
|
||||
placer.placeZones(&rand);
|
||||
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");
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
//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
|
||||
//place main town in the middle
|
||||
for (auto it : zones)
|
||||
for(auto it : zones)
|
||||
it.second->initTownType();
|
||||
|
||||
//make sure there are some free tiles in the zone
|
||||
for (auto it : zones)
|
||||
for(auto it : zones)
|
||||
it.second->initFreeTiles();
|
||||
|
||||
createDirectConnections(); //direct
|
||||
|
||||
//make sure all connections are passable before creating borders
|
||||
for (auto it : zones)
|
||||
for(auto it : zones)
|
||||
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
|
||||
|
||||
for(auto it : zones)
|
||||
zoneWater.second->waterConnection(*it.second);
|
||||
|
||||
createWaterTreasures();
|
||||
zoneWater.second->initFreeTiles();
|
||||
zoneWater.second->fill();
|
||||
|
||||
std::vector<std::shared_ptr<CRmgTemplateZone>> treasureZones;
|
||||
for (auto it : zones)
|
||||
for(auto it : zones)
|
||||
{
|
||||
it.second->fill();
|
||||
if (it.second->getType() == ETemplateZoneType::TREASURE)
|
||||
treasureZones.push_back(it.second);
|
||||
}
|
||||
|
||||
#ifdef _BETA
|
||||
dump(false);
|
||||
#endif
|
||||
|
||||
//set apriopriate free/occupied tiles, including blocked underground rock
|
||||
createObstaclesCommon1();
|
||||
//set back original terrain for underground zones
|
||||
for (auto it : zones)
|
||||
for(auto it : zones)
|
||||
it.second->createObstacles1();
|
||||
|
||||
createObstaclesCommon2();
|
||||
//place actual obstacles matching zone terrain
|
||||
for (auto it : zones)
|
||||
{
|
||||
for(auto it : zones)
|
||||
it.second->createObstacles2();
|
||||
}
|
||||
|
||||
zoneWater.second->createObstacles2();
|
||||
|
||||
#ifdef _BETA
|
||||
dump(false);
|
||||
#endif
|
||||
|
||||
#define PRINT_MAP_BEFORE_ROADS false
|
||||
if (PRINT_MAP_BEFORE_ROADS) //enable to debug
|
||||
@ -379,15 +429,15 @@ void CMapGenerator::fillZones()
|
||||
out << std::endl;
|
||||
}
|
||||
|
||||
for (auto it : zones)
|
||||
for(auto it : zones)
|
||||
{
|
||||
it.second->connectRoads(); //draw roads after everything else has been placed
|
||||
}
|
||||
|
||||
//find place for Grail
|
||||
if (treasureZones.empty())
|
||||
if(treasureZones.empty())
|
||||
{
|
||||
for (auto it : zones)
|
||||
for(auto it : zones)
|
||||
treasureZones.push_back(it.second);
|
||||
}
|
||||
auto grailZone = *RandomGeneratorUtil::nextItem(treasureZones, rand);
|
||||
@ -503,30 +553,29 @@ void CMapGenerator::findZonesForQuestArts()
|
||||
|
||||
void CMapGenerator::createDirectConnections()
|
||||
{
|
||||
bool waterMode = getMapGenOptions().getWaterContent() != EWaterContent::NONE;
|
||||
|
||||
for (auto connection : mapGenOptions.getMapTemplate()->getConnections())
|
||||
{
|
||||
auto zoneA = zones[connection.getZoneA()];
|
||||
auto zoneB = zones[connection.getZoneB()];
|
||||
|
||||
//rearrange tiles in random order
|
||||
auto tilesCopy = zoneA->getTileInfo();
|
||||
std::vector<int3> tiles(tilesCopy.begin(), tilesCopy.end());
|
||||
const auto & tiles = zoneA->getTileInfo();
|
||||
|
||||
int3 guardPos(-1,-1,-1);
|
||||
|
||||
auto otherZoneTiles = zoneB->getTileInfo();
|
||||
|
||||
int3 posA = zoneA->getPos();
|
||||
int3 posB = zoneB->getPos();
|
||||
// auto zoneAid = zoneA->getId();
|
||||
auto zoneBid = zoneB->getId();
|
||||
|
||||
|
||||
if (posA.z == posB.z)
|
||||
{
|
||||
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;
|
||||
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())
|
||||
{
|
||||
//zones can make paths only in their own area
|
||||
zoneA->connectWithCenter(guardPos, true);
|
||||
zoneB->connectWithCenter(guardPos, true);
|
||||
zoneA->connectWithCenter(guardPos, true, true);
|
||||
zoneB->connectWithCenter(guardPos, true, true);
|
||||
|
||||
bool monsterPresent = zoneA->addMonster(guardPos, connection.getGuardStrength(), false, true);
|
||||
zoneB->updateDistances(guardPos); //place next objects away from guard in both zones
|
||||
@ -575,9 +624,12 @@ void CMapGenerator::createDirectConnections()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
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 CTileInfo;
|
||||
|
||||
//#define _BETA
|
||||
|
||||
typedef std::vector<JsonNode> JsonVector;
|
||||
|
||||
class rmgException : public std::exception
|
||||
@ -96,18 +98,26 @@ public:
|
||||
void registerZone (TFaction faction);
|
||||
ui32 getZoneCount(TFaction faction);
|
||||
ui32 getTotalZoneCount() const;
|
||||
|
||||
Zones::value_type getZoneWater() const;
|
||||
void createWaterTreasures();
|
||||
void prepareWaterTiles();
|
||||
|
||||
TRmgTemplateZoneId getZoneID(const int3& tile) const;
|
||||
void setZoneID(const int3& tile, TRmgTemplateZoneId zid);
|
||||
|
||||
void dump(bool zoneId);
|
||||
|
||||
private:
|
||||
int randomSeed;
|
||||
CMapGenOptions& mapGenOptions;
|
||||
|
||||
std::list<rmg::ZoneConnection> connectionsLeft;
|
||||
std::vector<rmg::ZoneConnection> connectionsLeft;
|
||||
Zones zones;
|
||||
std::map<TFaction, ui32> zonesPerFaction;
|
||||
ui32 zonesTotal; //zones that have their main town only
|
||||
|
||||
std::pair<Zones::key_type, Zones::mapped_type> zoneWater;
|
||||
|
||||
CTileInfo*** tiles;
|
||||
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
|
||||
{
|
||||
return (min == other.min) && (max == other.max) && (density == other.density);
|
||||
@ -196,6 +202,11 @@ ETemplateZoneType::ETemplateZoneType ZoneOptions::getType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
void ZoneOptions::setType(ETemplateZoneType::ETemplateZoneType value)
|
||||
{
|
||||
type = value;
|
||||
}
|
||||
|
||||
int ZoneOptions::getSize() const
|
||||
{
|
||||
@ -264,6 +275,11 @@ void ZoneOptions::setTreasureInfo(const std::vector<CTreasureInfo> & value)
|
||||
{
|
||||
treasureInfo = value;
|
||||
}
|
||||
|
||||
void ZoneOptions::addTreasureInfo(const CTreasureInfo & value)
|
||||
{
|
||||
treasureInfo.push_back(value);
|
||||
}
|
||||
|
||||
const std::vector<CTreasureInfo> & ZoneOptions::getTreasureInfo() const
|
||||
{
|
||||
@ -302,7 +318,8 @@ void ZoneOptions::serializeJson(JsonSerializeFormat & handler)
|
||||
"playerStart",
|
||||
"cpuStart",
|
||||
"treasure",
|
||||
"junction"
|
||||
"junction",
|
||||
"water"
|
||||
};
|
||||
|
||||
handler.serializeEnum("type", type, zoneTypes);
|
||||
@ -421,6 +438,11 @@ bool CRmgTemplate::matchesSize(const int3 & value) const
|
||||
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)
|
||||
{
|
||||
id = value;
|
||||
@ -623,6 +645,14 @@ void CRmgTemplate::afterLoad()
|
||||
zone1->addConnection(id2);
|
||||
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)
|
||||
|
@ -24,7 +24,8 @@ namespace ETemplateZoneType
|
||||
PLAYER_START,
|
||||
CPU_START,
|
||||
TREASURE,
|
||||
JUNCTION
|
||||
JUNCTION,
|
||||
WATER
|
||||
};
|
||||
}
|
||||
|
||||
@ -35,6 +36,7 @@ public:
|
||||
ui32 max;
|
||||
ui16 density;
|
||||
CTreasureInfo();
|
||||
CTreasureInfo(ui32 min, ui32 max, ui16 density);
|
||||
|
||||
bool operator ==(const CTreasureInfo & other) const;
|
||||
|
||||
@ -93,6 +95,8 @@ public:
|
||||
void setId(TRmgTemplateZoneId value);
|
||||
|
||||
ETemplateZoneType::ETemplateZoneType getType() const;
|
||||
void setType(ETemplateZoneType::ETemplateZoneType value);
|
||||
|
||||
int getSize() const;
|
||||
void setSize(int value);
|
||||
boost::optional<int> getOwner() const;
|
||||
@ -110,6 +114,7 @@ public:
|
||||
std::map<TResource, ui16> getMinesInfo() const;
|
||||
|
||||
void setTreasureInfo(const std::vector<CTreasureInfo> & value);
|
||||
void addTreasureInfo(const CTreasureInfo & value);
|
||||
const std::vector<CTreasureInfo> & getTreasureInfo() const;
|
||||
|
||||
TRmgTemplateZoneId getMinesLikeZone() const;
|
||||
@ -175,6 +180,7 @@ public:
|
||||
~CRmgTemplate();
|
||||
|
||||
bool matchesSize(const int3 & value) const;
|
||||
bool isWaterContentAllowed(EWaterContent::EWaterContent waterContent) const;
|
||||
|
||||
void setId(const std::string & value);
|
||||
const std::string & getName() const;
|
||||
@ -195,6 +201,7 @@ private:
|
||||
CPlayerCountRange players, cpuPlayers;
|
||||
Zones zones;
|
||||
std::vector<rmg::ZoneConnection> connections;
|
||||
std::set<EWaterContent::EWaterContent> allowedWaterContent;
|
||||
|
||||
void afterLoad();
|
||||
void serializeSize(JsonSerializeFormat & handler, int3 & value, const std::string & fieldName);
|
||||
|
@ -68,36 +68,3 @@ std::vector<const CRmgTemplate *> CRmgTemplateStorage::getTemplates() const
|
||||
}
|
||||
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, 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 int3& filterSize, si8 filterPlayers, si8 filterHumanPlayers, si8 filterCpuPlayers) const;
|
||||
|
||||
private:
|
||||
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:
|
||||
CRmgTemplateZone(CMapGenerator * Gen);
|
||||
|
||||
void setOptions(const rmg::ZoneOptions * options);
|
||||
void setOptions(const rmg::ZoneOptions & options);
|
||||
bool isUnderground() const;
|
||||
|
||||
float3 getCenter() const;
|
||||
void setCenter(const float3 &f);
|
||||
int3 getPos() const;
|
||||
void setPos(const int3 &pos);
|
||||
bool isAccessibleFromAnywhere(ObjectTemplate &appearance, int3 &tile) const;
|
||||
int3 getAccessibleOffset(ObjectTemplate &appearance, int3 &tile) const;
|
||||
bool isAccessibleFromSomewhere(ObjectTemplate & appearance, const 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 ();
|
||||
std::set<int3> getTileInfo() const;
|
||||
std::set<int3> getPossibleTiles() const;
|
||||
void discardDistantTiles (float distance);
|
||||
std::set<int3> collectDistantTiles (float distance) const;
|
||||
void clearTiles();
|
||||
|
||||
void addRequiredObject(CGObjectInstance * obj, si32 guardStrength=0);
|
||||
void addCloseObject(CGObjectInstance * obj, si32 guardStrength = 0);
|
||||
void addNearbyObject(CGObjectInstance * obj, CGObjectInstance * nearbyTarget);
|
||||
void addObjectAtPosition(CGObjectInstance * obj, const int3 & position, si32 guardStrength=0);
|
||||
|
||||
void addToConnectLater(const int3& src);
|
||||
bool addMonster(int3 &pos, si32 strength, bool clearSurroundingTiles = true, bool zoneGuard = false);
|
||||
bool createTreasurePile(int3 &pos, float minDistance, const CTreasureInfo& treasureInfo);
|
||||
@ -123,21 +126,35 @@ public:
|
||||
void createBorder();
|
||||
void fractalize();
|
||||
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 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 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 createObstacles2();
|
||||
bool crunchPath(const int3 &src, const int3 &dst, bool onlyStraight, std::set<int3>* clearedTiles = nullptr);
|
||||
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);
|
||||
|
||||
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);
|
||||
std::set<int3>* getFreePaths();
|
||||
void addFreePath(const int3 &);
|
||||
|
||||
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();
|
||||
|
||||
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;
|
||||
|
||||
//template info
|
||||
|
||||
si32 townType;
|
||||
ETerrainType terrainType;
|
||||
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
|
||||
std::vector<std::pair<CGObjectInstance*, ui32>> requiredObjects;
|
||||
std::vector<std::pair<CGObjectInstance*, ui32>> closeObjects;
|
||||
std::vector<std::pair<CGObjectInstance*, int3>> instantObjects;
|
||||
std::vector<std::pair<CGObjectInstance*, CGObjectInstance*>> nearbyObjects;
|
||||
std::vector<CGObjectInstance*> objects;
|
||||
std::map<CGObjectInstance*, int3> requestedPositions;
|
||||
|
||||
//placement info
|
||||
int3 pos;
|
||||
@ -182,11 +212,14 @@ private:
|
||||
std::set<int3> tileinfo; //irregular area assined to zone
|
||||
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> coastTiles; //tiles bordered to water
|
||||
|
||||
std::set<int3> roadNodes; //tiles to be connected with roads
|
||||
std::set<int3> roads; //all tiles with roads
|
||||
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);
|
||||
void drawRoads(); //actually updates tiles
|
||||
|
||||
@ -197,4 +230,6 @@ private:
|
||||
bool canObstacleBePlacedHere(ObjectTemplate &temp, int3 &pos);
|
||||
void setTemplateForObject(CGObjectInstance* obj);
|
||||
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 "CRmgTemplateZone.h"
|
||||
#include "../mapping/CMap.h"
|
||||
|
||||
#include "CZoneGraphGenerator.h"
|
||||
#include "../mapping/CMapEditManager.h"
|
||||
|
||||
class CRandomGenerator;
|
||||
|
||||
@ -557,7 +556,11 @@ void CZonePlacer::assignZones()
|
||||
if (zone.second->isUnderground())
|
||||
{
|
||||
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
|
||||
//FIXME: reorder actions?
|
||||
|
Loading…
Reference in New Issue
Block a user