mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-20 20:23:03 +02:00
vcmi: modernize lib/rmg
This commit is contained in:
parent
c5dd8b17d7
commit
7bfb37df4d
@ -138,7 +138,7 @@ void CMapGenOptions::resetPlayersMap()
|
|||||||
std::map<PlayerColor, TFaction> rememberTownTypes;
|
std::map<PlayerColor, TFaction> rememberTownTypes;
|
||||||
std::map<PlayerColor, TeamID> rememberTeam;
|
std::map<PlayerColor, TeamID> rememberTeam;
|
||||||
|
|
||||||
for (auto p : players)
|
for(const auto & p : players)
|
||||||
{
|
{
|
||||||
auto town = p.second.getStartingTown();
|
auto town = p.second.getStartingTown();
|
||||||
if (town != RANDOM_SIZE)
|
if (town != RANDOM_SIZE)
|
||||||
@ -184,14 +184,14 @@ const std::map<PlayerColor, CMapGenOptions::CPlayerSettings> & CMapGenOptions::g
|
|||||||
return players;
|
return players;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapGenOptions::setStartingTownForPlayer(PlayerColor color, si32 town)
|
void CMapGenOptions::setStartingTownForPlayer(const PlayerColor & color, si32 town)
|
||||||
{
|
{
|
||||||
auto it = players.find(color);
|
auto it = players.find(color);
|
||||||
if(it == players.end()) assert(0);
|
if(it == players.end()) assert(0);
|
||||||
it->second.setStartingTown(town);
|
it->second.setStartingTown(town);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapGenOptions::setPlayerTypeForStandardPlayer(PlayerColor color, EPlayerType::EPlayerType playerType)
|
void CMapGenOptions::setPlayerTypeForStandardPlayer(const PlayerColor & color, EPlayerType::EPlayerType playerType)
|
||||||
{
|
{
|
||||||
assert(playerType != EPlayerType::COMP_ONLY);
|
assert(playerType != EPlayerType::COMP_ONLY);
|
||||||
auto it = players.find(color);
|
auto it = players.find(color);
|
||||||
@ -246,7 +246,7 @@ bool CMapGenOptions::isRoadEnabled(const std::string & roadName) const
|
|||||||
return !disabledRoads.count(roadName);
|
return !disabledRoads.count(roadName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapGenOptions::setPlayerTeam(PlayerColor color, TeamID team)
|
void CMapGenOptions::setPlayerTeam(const PlayerColor & color, const TeamID & team)
|
||||||
{
|
{
|
||||||
auto it = players.find(color);
|
auto it = players.find(color);
|
||||||
if(it == players.end()) assert(0);
|
if(it == players.end()) assert(0);
|
||||||
@ -298,7 +298,7 @@ void CMapGenOptions::finalize(CRandomGenerator & rand)
|
|||||||
{
|
{
|
||||||
auto allowedContent = mapTemplate->getWaterContentAllowed();
|
auto allowedContent = mapTemplate->getWaterContentAllowed();
|
||||||
|
|
||||||
if(allowedContent.size())
|
if(!allowedContent.empty())
|
||||||
{
|
{
|
||||||
waterContent = *RandomGeneratorUtil::nextItem(mapTemplate->getWaterContentAllowed(), rand);
|
waterContent = *RandomGeneratorUtil::nextItem(mapTemplate->getWaterContentAllowed(), rand);
|
||||||
}
|
}
|
||||||
@ -323,7 +323,7 @@ void CMapGenOptions::finalize(CRandomGenerator & rand)
|
|||||||
|
|
||||||
logGlobal->trace("Player config:");
|
logGlobal->trace("Player config:");
|
||||||
int cpuOnlyPlayers = 0;
|
int cpuOnlyPlayers = 0;
|
||||||
for (auto player : players)
|
for(const auto & player : players)
|
||||||
{
|
{
|
||||||
std::string playerType;
|
std::string playerType;
|
||||||
switch (player.second.getPlayerType())
|
switch (player.second.getPlayerType())
|
||||||
@ -344,7 +344,7 @@ void CMapGenOptions::finalize(CRandomGenerator & rand)
|
|||||||
logGlobal->trace("Player %d: %s", player.second.getColor(), playerType);
|
logGlobal->trace("Player %d: %s", player.second.getColor(), playerType);
|
||||||
}
|
}
|
||||||
setCompOnlyPlayerCount(cpuOnlyPlayers); //human players are set automaticlaly (?)
|
setCompOnlyPlayerCount(cpuOnlyPlayers); //human players are set automaticlaly (?)
|
||||||
logGlobal->info("Final player config: %d total, %d cpu-only", players.size(), (int)getCompOnlyPlayerCount());
|
logGlobal->info("Final player config: %d total, %d cpu-only", players.size(), static_cast<int>(getCompOnlyPlayerCount()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapGenOptions::updatePlayers()
|
void CMapGenOptions::updatePlayers()
|
||||||
@ -504,7 +504,7 @@ PlayerColor CMapGenOptions::CPlayerSettings::getColor() const
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapGenOptions::CPlayerSettings::setColor(PlayerColor value)
|
void CMapGenOptions::CPlayerSettings::setColor(const PlayerColor & value)
|
||||||
{
|
{
|
||||||
assert(value >= PlayerColor(0) && value < PlayerColor::PLAYER_LIMIT);
|
assert(value >= PlayerColor(0) && value < PlayerColor::PLAYER_LIMIT);
|
||||||
color = value;
|
color = value;
|
||||||
@ -541,7 +541,7 @@ TeamID CMapGenOptions::CPlayerSettings::getTeam() const
|
|||||||
return team;
|
return team;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapGenOptions::CPlayerSettings::setTeam(TeamID value)
|
void CMapGenOptions::CPlayerSettings::setTeam(const TeamID & value)
|
||||||
{
|
{
|
||||||
team = value;
|
team = value;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ public:
|
|||||||
/// The color of the player ranging from 0 to PlayerColor::PLAYER_LIMIT - 1.
|
/// The color of the player ranging from 0 to PlayerColor::PLAYER_LIMIT - 1.
|
||||||
/// The default value is 0.
|
/// The default value is 0.
|
||||||
PlayerColor getColor() const;
|
PlayerColor getColor() const;
|
||||||
void setColor(PlayerColor value);
|
void setColor(const PlayerColor & value);
|
||||||
|
|
||||||
/// The starting town of the player ranging from 0 to town max count or RANDOM_TOWN.
|
/// The starting town of the player ranging from 0 to town max count or RANDOM_TOWN.
|
||||||
/// The default value is RANDOM_TOWN.
|
/// The default value is RANDOM_TOWN.
|
||||||
@ -54,7 +54,7 @@ public:
|
|||||||
|
|
||||||
/// Team id for this player. TeamID::NO_TEAM by default - team will be randomly assigned
|
/// Team id for this player. TeamID::NO_TEAM by default - team will be randomly assigned
|
||||||
TeamID getTeam() const;
|
TeamID getTeam() const;
|
||||||
void setTeam(TeamID value);
|
void setTeam(const TeamID & value);
|
||||||
|
|
||||||
/// Constant for a random town selection.
|
/// Constant for a random town selection.
|
||||||
static const si32 RANDOM_TOWN = -1;
|
static const si32 RANDOM_TOWN = -1;
|
||||||
@ -119,12 +119,12 @@ public:
|
|||||||
/// The first player colors belong to standard players and the last player colors belong to comp only players.
|
/// The first player colors belong to standard players and the last player colors belong to comp only players.
|
||||||
/// All standard players are by default of type EPlayerType::AI.
|
/// All standard players are by default of type EPlayerType::AI.
|
||||||
const std::map<PlayerColor, CPlayerSettings> & getPlayersSettings() const;
|
const std::map<PlayerColor, CPlayerSettings> & getPlayersSettings() const;
|
||||||
void setStartingTownForPlayer(PlayerColor color, si32 town);
|
void setStartingTownForPlayer(const PlayerColor & color, si32 town);
|
||||||
/// Sets a player type for a standard player. A standard player is the opposite of a computer only player. The
|
/// Sets a player type for a standard player. A standard player is the opposite of a computer only player. The
|
||||||
/// values which can be chosen for the player type are EPlayerType::AI or EPlayerType::HUMAN.
|
/// values which can be chosen for the player type are EPlayerType::AI or EPlayerType::HUMAN.
|
||||||
void setPlayerTypeForStandardPlayer(PlayerColor color, EPlayerType::EPlayerType playerType);
|
void setPlayerTypeForStandardPlayer(const PlayerColor & color, EPlayerType::EPlayerType playerType);
|
||||||
|
|
||||||
void setPlayerTeam(PlayerColor color, TeamID team = TeamID::NO_TEAM);
|
void setPlayerTeam(const PlayerColor & color, const TeamID & team = TeamID::NO_TEAM);
|
||||||
|
|
||||||
/// The random map template to generate the map with or empty/not set if the template should be chosen randomly.
|
/// The random map template to generate the map with or empty/not set if the template should be chosen randomly.
|
||||||
/// Default: Not set/random.
|
/// Default: Not set/random.
|
||||||
|
@ -88,9 +88,8 @@ const CMapGenerator::Config & CMapGenerator::getConfig() const
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
CMapGenerator::~CMapGenerator()
|
//must be instantiated in .cpp file for access to complete types of all member fields
|
||||||
{
|
CMapGenerator::~CMapGenerator() = default;
|
||||||
}
|
|
||||||
|
|
||||||
const CMapGenOptions& CMapGenerator::getMapGenOptions() const
|
const CMapGenOptions& CMapGenerator::getMapGenOptions() const
|
||||||
{
|
{
|
||||||
@ -281,7 +280,7 @@ void CMapGenerator::createWaterTreasures()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
//add treasures on water
|
//add treasures on water
|
||||||
for(auto & treasureInfo : getConfig().waterTreasure)
|
for(const auto & treasureInfo : getConfig().waterTreasure)
|
||||||
{
|
{
|
||||||
getZoneWater()->addTreasureInfo(treasureInfo);
|
getZoneWater()->addTreasureInfo(treasureInfo);
|
||||||
}
|
}
|
||||||
@ -297,7 +296,7 @@ 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
|
||||||
Load::Progress::setupStepsTill(map->getZones().size(), 50);
|
Load::Progress::setupStepsTill(map->getZones().size(), 50);
|
||||||
for(auto it : map->getZones())
|
for(const auto & it : map->getZones())
|
||||||
{
|
{
|
||||||
it.second->initFreeTiles();
|
it.second->initFreeTiles();
|
||||||
it.second->initModificators();
|
it.second->initModificators();
|
||||||
@ -306,7 +305,7 @@ void CMapGenerator::fillZones()
|
|||||||
|
|
||||||
Load::Progress::setupStepsTill(map->getZones().size(), 240);
|
Load::Progress::setupStepsTill(map->getZones().size(), 240);
|
||||||
std::vector<std::shared_ptr<Zone>> treasureZones;
|
std::vector<std::shared_ptr<Zone>> treasureZones;
|
||||||
for(auto it : map->getZones())
|
for(const auto & it : map->getZones())
|
||||||
{
|
{
|
||||||
it.second->processModificators();
|
it.second->processModificators();
|
||||||
|
|
||||||
@ -319,7 +318,7 @@ void CMapGenerator::fillZones()
|
|||||||
//find place for Grail
|
//find place for Grail
|
||||||
if(treasureZones.empty())
|
if(treasureZones.empty())
|
||||||
{
|
{
|
||||||
for(auto it : map->getZones())
|
for(const auto & it : map->getZones())
|
||||||
if(it.second->getType() != ETemplateZoneType::WATER)
|
if(it.second->getType() != ETemplateZoneType::WATER)
|
||||||
treasureZones.push_back(it.second);
|
treasureZones.push_back(it.second);
|
||||||
}
|
}
|
||||||
@ -389,7 +388,7 @@ const std::vector<ArtifactID> & CMapGenerator::getQuestArtsRemaning() const
|
|||||||
return questArtifacts;
|
return questArtifacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapGenerator::banQuestArt(ArtifactID id)
|
void CMapGenerator::banQuestArt(const ArtifactID & id)
|
||||||
{
|
{
|
||||||
map->map().allowedArtifact[id] = false;
|
map->map().allowedArtifact[id] = false;
|
||||||
vstd::erase_if_present(questArtifacts, id);
|
vstd::erase_if_present(questArtifacts, id);
|
||||||
|
@ -65,8 +65,8 @@ public:
|
|||||||
int getPrisonsRemaning() const;
|
int getPrisonsRemaning() const;
|
||||||
void decreasePrisonsRemaining();
|
void decreasePrisonsRemaining();
|
||||||
const std::vector<ArtifactID> & getQuestArtsRemaning() const;
|
const std::vector<ArtifactID> & getQuestArtsRemaning() const;
|
||||||
void banQuestArt(ArtifactID id);
|
void banQuestArt(const ArtifactID & id);
|
||||||
|
|
||||||
Zone * getZoneWater() const;
|
Zone * getZoneWater() const;
|
||||||
void createWaterTreasures();
|
void createWaterTreasures();
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ namespace
|
|||||||
|
|
||||||
std::string encodeZoneId(si32 id)
|
std::string encodeZoneId(si32 id)
|
||||||
{
|
{
|
||||||
return boost::lexical_cast<std::string>(id);
|
return std::to_string(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ class TerrainEncoder
|
|||||||
public:
|
public:
|
||||||
static si32 decode(const std::string & identifier)
|
static si32 decode(const std::string & identifier)
|
||||||
{
|
{
|
||||||
return *VLC->modh->identifiers.getIdentifier(VLC->modh->scopeGame(), "terrain", identifier);
|
return *VLC->modh->identifiers.getIdentifier(CModHandler::scopeGame(), "terrain", identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string encode(const si32 index)
|
static std::string encode(const si32 index)
|
||||||
@ -84,12 +84,12 @@ class ZoneEncoder
|
|||||||
public:
|
public:
|
||||||
static si32 decode(const std::string & json)
|
static si32 decode(const std::string & json)
|
||||||
{
|
{
|
||||||
return boost::lexical_cast<si32>(json);
|
return std::stoi(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string encode(si32 id)
|
static std::string encode(si32 id)
|
||||||
{
|
{
|
||||||
return boost::lexical_cast<std::string>(id);
|
return std::to_string(id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -132,22 +132,14 @@ void ZoneOptions::CTownInfo::serializeJson(JsonSerializeFormat & handler)
|
|||||||
handler.serializeInt("castleDensity", castleDensity, 0);
|
handler.serializeInt("castleDensity", castleDensity, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZoneOptions::ZoneOptions():
|
||||||
ZoneOptions::ZoneOptions()
|
id(0),
|
||||||
: id(0),
|
|
||||||
type(ETemplateZoneType::PLAYER_START),
|
type(ETemplateZoneType::PLAYER_START),
|
||||||
size(1),
|
size(1),
|
||||||
owner(boost::none),
|
owner(boost::none),
|
||||||
playerTowns(),
|
|
||||||
neutralTowns(),
|
|
||||||
matchTerrainToTown(true),
|
matchTerrainToTown(true),
|
||||||
townsAreSameType(false),
|
townsAreSameType(false),
|
||||||
townTypes(),
|
|
||||||
monsterTypes(),
|
|
||||||
zoneMonsterStrength(EMonsterStrength::ZONE_NORMAL),
|
zoneMonsterStrength(EMonsterStrength::ZONE_NORMAL),
|
||||||
mines(),
|
|
||||||
treasureInfo(),
|
|
||||||
connections(),
|
|
||||||
minesLikeZone(NO_ZONE),
|
minesLikeZone(NO_ZONE),
|
||||||
terrainTypeLikeZone(NO_ZONE),
|
terrainTypeLikeZone(NO_ZONE),
|
||||||
treasureLikeZone(NO_ZONE)
|
treasureLikeZone(NO_ZONE)
|
||||||
@ -157,29 +149,6 @@ ZoneOptions::ZoneOptions()
|
|||||||
terrainTypes.insert(terr->getId());
|
terrainTypes.insert(terr->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoneOptions & ZoneOptions::operator=(const ZoneOptions & other)
|
|
||||||
{
|
|
||||||
id = other.id;
|
|
||||||
type = other.type;
|
|
||||||
size = other.size;
|
|
||||||
owner = other.owner;
|
|
||||||
playerTowns = other.playerTowns;
|
|
||||||
neutralTowns = other.neutralTowns;
|
|
||||||
matchTerrainToTown = other.matchTerrainToTown;
|
|
||||||
terrainTypes = other.terrainTypes;
|
|
||||||
townsAreSameType = other.townsAreSameType;
|
|
||||||
townTypes = other.townTypes;
|
|
||||||
monsterTypes = other.monsterTypes;
|
|
||||||
zoneMonsterStrength = other.zoneMonsterStrength;
|
|
||||||
mines = other.mines;
|
|
||||||
treasureInfo = other.treasureInfo;
|
|
||||||
connections = other.connections;
|
|
||||||
minesLikeZone = other.minesLikeZone;
|
|
||||||
terrainTypeLikeZone = other.terrainTypeLikeZone;
|
|
||||||
treasureLikeZone = other.treasureLikeZone;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRmgTemplateZoneId ZoneOptions::getId() const
|
TRmgTemplateZoneId ZoneOptions::getId() const
|
||||||
{
|
{
|
||||||
return id;
|
return id;
|
||||||
@ -362,7 +331,7 @@ void ZoneOptions::serializeJson(JsonSerializeFormat & handler)
|
|||||||
if(handler.saving)
|
if(handler.saving)
|
||||||
{
|
{
|
||||||
node.setType(JsonNode::JsonType::DATA_VECTOR);
|
node.setType(JsonNode::JsonType::DATA_VECTOR);
|
||||||
for(auto & ttype : terrainTypes)
|
for(const auto & ttype : terrainTypes)
|
||||||
{
|
{
|
||||||
JsonNode n;
|
JsonNode n;
|
||||||
n.String() = VLC->terrainTypeHandler->getById(ttype)->getJsonKey();
|
n.String() = VLC->terrainTypeHandler->getById(ttype)->getJsonKey();
|
||||||
@ -375,7 +344,7 @@ void ZoneOptions::serializeJson(JsonSerializeFormat & handler)
|
|||||||
if(!node.Vector().empty())
|
if(!node.Vector().empty())
|
||||||
{
|
{
|
||||||
terrainTypes.clear();
|
terrainTypes.clear();
|
||||||
for(auto ttype : node.Vector())
|
for(const auto & ttype : node.Vector())
|
||||||
{
|
{
|
||||||
VLC->modh->identifiers.requestIdentifier("terrain", ttype, [this](int32_t identifier)
|
VLC->modh->identifiers.requestIdentifier("terrain", ttype, [this](int32_t identifier)
|
||||||
{
|
{
|
||||||
@ -476,10 +445,6 @@ CRmgTemplate::CRmgTemplate()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CRmgTemplate::~CRmgTemplate()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CRmgTemplate::matchesSize(const int3 & value) const
|
bool CRmgTemplate::matchesSize(const int3 & value) const
|
||||||
{
|
{
|
||||||
const int64_t square = value.x * value.y * value.z;
|
const int64_t square = value.x * value.y * value.z;
|
||||||
@ -551,12 +516,12 @@ std::pair<int3, int3> CRmgTemplate::getMapSizes() const
|
|||||||
|
|
||||||
void CRmgTemplate::CPlayerCountRange::addRange(int lower, int upper)
|
void CRmgTemplate::CPlayerCountRange::addRange(int lower, int upper)
|
||||||
{
|
{
|
||||||
range.push_back(std::make_pair(lower, upper));
|
range.emplace_back(lower, upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRmgTemplate::CPlayerCountRange::addNumber(int value)
|
void CRmgTemplate::CPlayerCountRange::addNumber(int value)
|
||||||
{
|
{
|
||||||
range.push_back(std::make_pair(value, value));
|
range.emplace_back(value, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CRmgTemplate::CPlayerCountRange::isInRange(int count) const
|
bool CRmgTemplate::CPlayerCountRange::isInRange(int count) const
|
||||||
@ -591,7 +556,7 @@ std::string CRmgTemplate::CPlayerCountRange::toString() const
|
|||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
for(auto & p : range)
|
for(const auto & p : range)
|
||||||
{
|
{
|
||||||
if(!first)
|
if(!first)
|
||||||
ret +=",";
|
ret +=",";
|
||||||
@ -600,7 +565,7 @@ std::string CRmgTemplate::CPlayerCountRange::toString() const
|
|||||||
|
|
||||||
if(p.first == p.second)
|
if(p.first == p.second)
|
||||||
{
|
{
|
||||||
ret += boost::lexical_cast<std::string>(p.first);
|
ret += std::to_string(p.first);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -683,7 +648,7 @@ void CRmgTemplate::serializeJson(JsonSerializeFormat & handler)
|
|||||||
|
|
||||||
{
|
{
|
||||||
auto zonesData = handler.enterStruct("zones");
|
auto zonesData = handler.enterStruct("zones");
|
||||||
if(handler.saving)
|
if(handler.saving)
|
||||||
{
|
{
|
||||||
for(auto & idAndZone : zones)
|
for(auto & idAndZone : zones)
|
||||||
{
|
{
|
||||||
@ -693,7 +658,7 @@ void CRmgTemplate::serializeJson(JsonSerializeFormat & handler)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(auto & idAndZone : zonesData->getCurrent().Struct())
|
for(const auto & idAndZone : zonesData->getCurrent().Struct())
|
||||||
{
|
{
|
||||||
auto guard = handler.enterStruct(idAndZone.first);
|
auto guard = handler.enterStruct(idAndZone.first);
|
||||||
auto zone = std::make_shared<ZoneOptions>();
|
auto zone = std::make_shared<ZoneOptions>();
|
||||||
|
@ -116,8 +116,6 @@ public:
|
|||||||
|
|
||||||
ZoneOptions();
|
ZoneOptions();
|
||||||
|
|
||||||
ZoneOptions & operator=(const ZoneOptions & other);
|
|
||||||
|
|
||||||
TRmgTemplateZoneId getId() const;
|
TRmgTemplateZoneId getId() const;
|
||||||
void setId(TRmgTemplateZoneId value);
|
void setId(TRmgTemplateZoneId value);
|
||||||
|
|
||||||
@ -210,7 +208,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
CRmgTemplate();
|
CRmgTemplate();
|
||||||
~CRmgTemplate();
|
|
||||||
|
|
||||||
bool matchesSize(const int3 & value) const;
|
bool matchesSize(const int3 & value) const;
|
||||||
bool isWaterContentAllowed(EWaterContent::EWaterContent waterContent) const;
|
bool isWaterContentAllowed(EWaterContent::EWaterContent waterContent) const;
|
||||||
|
@ -66,9 +66,10 @@ const CRmgTemplate * CRmgTemplateStorage::getTemplate(const std::string & templa
|
|||||||
std::vector<const CRmgTemplate *> CRmgTemplateStorage::getTemplates() const
|
std::vector<const CRmgTemplate *> CRmgTemplateStorage::getTemplates() const
|
||||||
{
|
{
|
||||||
std::vector<const CRmgTemplate *> result;
|
std::vector<const CRmgTemplate *> result;
|
||||||
for(auto i=templates.cbegin(); i!=templates.cend(); ++i)
|
result.reserve(templates.size());
|
||||||
|
for(const auto & i : templates)
|
||||||
{
|
{
|
||||||
result.push_back(&i->second);
|
result.push_back(&i.second);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -30,14 +30,9 @@ CZonePlacer::CZonePlacer(RmgMap & map)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CZonePlacer::~CZonePlacer()
|
int3 CZonePlacer::cords(const float3 & f) const
|
||||||
{
|
{
|
||||||
|
return int3(static_cast<si32>(std::max(0.f, (f.x * map.map().width) - 1)), static_cast<si32>(std::max(0.f, (f.y * map.map().height - 1))), f.z);
|
||||||
}
|
|
||||||
|
|
||||||
int3 CZonePlacer::cords (const float3 f) const
|
|
||||||
{
|
|
||||||
return int3((si32)std::max(0.f, (f.x * map.map().width)-1), (si32)std::max(0.f, (f.y * map.map().height-1)), f.z);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float CZonePlacer::getDistance (float distance) const
|
float CZonePlacer::getDistance (float distance) const
|
||||||
@ -94,7 +89,7 @@ void CZonePlacer::placeZones(CRandomGenerator * rand)
|
|||||||
{
|
{
|
||||||
//1. attract connected zones
|
//1. attract connected zones
|
||||||
attractConnectedZones(zones, forces, distances);
|
attractConnectedZones(zones, forces, distances);
|
||||||
for (auto zone : forces)
|
for(const auto & zone : forces)
|
||||||
{
|
{
|
||||||
zone.first->setCenter (zone.first->getCenter() + zone.second);
|
zone.first->setCenter (zone.first->getCenter() + zone.second);
|
||||||
totalForces[zone.first] = zone.second; //override
|
totalForces[zone.first] = zone.second; //override
|
||||||
@ -102,7 +97,7 @@ void CZonePlacer::placeZones(CRandomGenerator * rand)
|
|||||||
|
|
||||||
//2. separate overlapping zones
|
//2. separate overlapping zones
|
||||||
separateOverlappingZones(zones, forces, overlaps);
|
separateOverlappingZones(zones, forces, overlaps);
|
||||||
for (auto zone : forces)
|
for(const auto & zone : forces)
|
||||||
{
|
{
|
||||||
zone.first->setCenter (zone.first->getCenter() + zone.second);
|
zone.first->setCenter (zone.first->getCenter() + zone.second);
|
||||||
totalForces[zone.first] += zone.second; //accumulate
|
totalForces[zone.first] += zone.second; //accumulate
|
||||||
@ -118,7 +113,7 @@ void CZonePlacer::placeZones(CRandomGenerator * rand)
|
|||||||
|
|
||||||
float totalDistance = 0;
|
float totalDistance = 0;
|
||||||
float totalOverlap = 0;
|
float totalOverlap = 0;
|
||||||
for (auto zone : distances) //find most misplaced zone
|
for(const auto & zone : distances) //find most misplaced zone
|
||||||
{
|
{
|
||||||
totalDistance += zone.second;
|
totalDistance += zone.second;
|
||||||
float overlap = overlaps[zone.first];
|
float overlap = overlaps[zone.first];
|
||||||
@ -146,13 +141,13 @@ void CZonePlacer::placeZones(CRandomGenerator * rand)
|
|||||||
bestTotalDistance = totalDistance;
|
bestTotalDistance = totalDistance;
|
||||||
bestTotalOverlap = totalOverlap;
|
bestTotalOverlap = totalOverlap;
|
||||||
|
|
||||||
for (auto zone : zones)
|
for(const auto & zone : zones)
|
||||||
bestSolution[zone.second] = zone.second->getCenter();
|
bestSolution[zone.second] = zone.second->getCenter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logGlobal->trace("Best fitness reached: total distance %2.4f, total overlap %2.4f", bestTotalDistance, bestTotalOverlap);
|
logGlobal->trace("Best fitness reached: total distance %2.4f, total overlap %2.4f", bestTotalDistance, bestTotalOverlap);
|
||||||
for (auto zone : zones) //finalize zone positions
|
for(const auto & zone : zones) //finalize zone positions
|
||||||
{
|
{
|
||||||
zone.second->setPos (cords (bestSolution[zone.second]));
|
zone.second->setPos (cords (bestSolution[zone.second]));
|
||||||
logGlobal->trace("Placed zone %d at relative position %s and coordinates %s", zone.first, zone.second->getCenter().toString(), zone.second->getPos().toString());
|
logGlobal->trace("Placed zone %d at relative position %s and coordinates %s", zone.first, zone.second->getCenter().toString(), zone.second->getPos().toString());
|
||||||
@ -174,7 +169,7 @@ void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const
|
|||||||
std::map<TRmgTemplateZoneId, int> levels;
|
std::map<TRmgTemplateZoneId, int> levels;
|
||||||
|
|
||||||
//first pass - determine fixed surface for zones
|
//first pass - determine fixed surface for zones
|
||||||
for (auto zone : zonesVector)
|
for(const auto & zone : zonesVector)
|
||||||
{
|
{
|
||||||
if (!underground) //this step is ignored
|
if (!underground) //this step is ignored
|
||||||
zonesToPlace.push_back(zone);
|
zonesToPlace.push_back(zone);
|
||||||
@ -224,7 +219,7 @@ void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto zone : zonesToPlace)
|
for(const auto & zone : zonesToPlace)
|
||||||
{
|
{
|
||||||
if (underground) //only then consider underground zones
|
if (underground) //only then consider underground zones
|
||||||
{
|
{
|
||||||
@ -240,11 +235,11 @@ void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const
|
|||||||
else
|
else
|
||||||
levels[zone.first] = 0;
|
levels[zone.first] = 0;
|
||||||
}
|
}
|
||||||
for (auto zone : zonesVector)
|
for(const auto & zone : zonesVector)
|
||||||
{
|
{
|
||||||
int level = levels[zone.first];
|
int level = levels[zone.first];
|
||||||
totalSize[level] += (zone.second->getSize() * zone.second->getSize());
|
totalSize[level] += (zone.second->getSize() * zone.second->getSize());
|
||||||
float randomAngle = static_cast<float>(rand->nextDouble(0, pi2));
|
auto randomAngle = static_cast<float>(rand->nextDouble(0, pi2));
|
||||||
zone.second->setCenter(float3(0.5f + std::sin(randomAngle) * radius, 0.5f + std::cos(randomAngle) * radius, level)); //place zones around circle
|
zone.second->setCenter(float3(0.5f + std::sin(randomAngle) * radius, 0.5f + std::cos(randomAngle) * radius, level)); //place zones around circle
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,17 +253,17 @@ void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const
|
|||||||
|
|
||||||
std::vector<float> prescaler = { 0, 0 };
|
std::vector<float> prescaler = { 0, 0 };
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
prescaler[i] = sqrt((width * height) / (totalSize[i] * 3.14f));
|
prescaler[i] = std::sqrt((width * height) / (totalSize[i] * 3.14f));
|
||||||
mapSize = static_cast<float>(sqrt(width * height));
|
mapSize = static_cast<float>(sqrt(width * height));
|
||||||
for (auto zone : zones)
|
for(const auto & zone : zones)
|
||||||
{
|
{
|
||||||
zone.second->setSize((int)(zone.second->getSize() * prescaler[zone.second->getCenter().z]));
|
zone.second->setSize(static_cast<int>(zone.second->getSize() * prescaler[zone.second->getCenter().z]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CZonePlacer::attractConnectedZones(TZoneMap &zones, TForceVector &forces, TDistanceVector &distances)
|
void CZonePlacer::attractConnectedZones(TZoneMap & zones, TForceVector & forces, TDistanceVector & distances) const
|
||||||
{
|
{
|
||||||
for (auto zone : zones)
|
for(const auto & zone : zones)
|
||||||
{
|
{
|
||||||
float3 forceVector(0, 0, 0);
|
float3 forceVector(0, 0, 0);
|
||||||
float3 pos = zone.second->getCenter();
|
float3 pos = zone.second->getCenter();
|
||||||
@ -278,7 +273,7 @@ void CZonePlacer::attractConnectedZones(TZoneMap &zones, TForceVector &forces, T
|
|||||||
{
|
{
|
||||||
auto otherZone = zones[con];
|
auto otherZone = zones[con];
|
||||||
float3 otherZoneCenter = otherZone->getCenter();
|
float3 otherZoneCenter = otherZone->getCenter();
|
||||||
float distance = static_cast<float>(pos.dist2d(otherZoneCenter));
|
auto distance = static_cast<float>(pos.dist2d(otherZoneCenter));
|
||||||
float minDistance = 0;
|
float minDistance = 0;
|
||||||
|
|
||||||
if (pos.z != otherZoneCenter.z)
|
if (pos.z != otherZoneCenter.z)
|
||||||
@ -302,21 +297,21 @@ void CZonePlacer::attractConnectedZones(TZoneMap &zones, TForceVector &forces, T
|
|||||||
|
|
||||||
void CZonePlacer::separateOverlappingZones(TZoneMap &zones, TForceVector &forces, TDistanceVector &overlaps)
|
void CZonePlacer::separateOverlappingZones(TZoneMap &zones, TForceVector &forces, TDistanceVector &overlaps)
|
||||||
{
|
{
|
||||||
for (auto zone : zones)
|
for(const auto & zone : zones)
|
||||||
{
|
{
|
||||||
float3 forceVector(0, 0, 0);
|
float3 forceVector(0, 0, 0);
|
||||||
float3 pos = zone.second->getCenter();
|
float3 pos = zone.second->getCenter();
|
||||||
|
|
||||||
float overlap = 0;
|
float overlap = 0;
|
||||||
//separate overlapping zones
|
//separate overlapping zones
|
||||||
for (auto otherZone : zones)
|
for(const auto & otherZone : zones)
|
||||||
{
|
{
|
||||||
float3 otherZoneCenter = otherZone.second->getCenter();
|
float3 otherZoneCenter = otherZone.second->getCenter();
|
||||||
//zones on different levels don't push away
|
//zones on different levels don't push away
|
||||||
if (zone == otherZone || pos.z != otherZoneCenter.z)
|
if (zone == otherZone || pos.z != otherZoneCenter.z)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float distance = static_cast<float>(pos.dist2d(otherZoneCenter));
|
auto distance = static_cast<float>(pos.dist2d(otherZoneCenter));
|
||||||
float minDistance = (zone.second->getSize() + otherZone.second->getSize()) / mapSize;
|
float minDistance = (zone.second->getSize() + otherZone.second->getSize()) / mapSize;
|
||||||
if (distance < minDistance)
|
if (distance < minDistance)
|
||||||
{
|
{
|
||||||
@ -332,7 +327,7 @@ void CZonePlacer::separateOverlappingZones(TZoneMap &zones, TForceVector &forces
|
|||||||
auto pushAwayFromBoundary = [&forceVector, pos, size, &overlap, this](float x, float y)
|
auto pushAwayFromBoundary = [&forceVector, pos, size, &overlap, this](float x, float y)
|
||||||
{
|
{
|
||||||
float3 boundary = float3(x, y, pos.z);
|
float3 boundary = float3(x, y, pos.z);
|
||||||
float distance = static_cast<float>(pos.dist2d(boundary));
|
auto distance = static_cast<float>(pos.dist2d(boundary));
|
||||||
overlap += std::max<float>(0, distance - size); //check if we're closer to map boundary than value of zone size
|
overlap += std::max<float>(0, distance - size); //check if we're closer to map boundary than value of zone size
|
||||||
forceVector -= (boundary - pos) * (size - distance) / this->getDistance(distance) * this->stiffnessConstant; //negative value
|
forceVector -= (boundary - pos) * (size - distance) / this->getDistance(distance) * this->stiffnessConstant; //negative value
|
||||||
};
|
};
|
||||||
@ -358,7 +353,7 @@ void CZonePlacer::separateOverlappingZones(TZoneMap &zones, TForceVector &forces
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CZonePlacer::moveOneZone(TZoneMap &zones, TForceVector &totalForces, TDistanceVector &distances, TDistanceVector &overlaps)
|
void CZonePlacer::moveOneZone(TZoneMap & zones, TForceVector & totalForces, TDistanceVector & distances, TDistanceVector & overlaps) const
|
||||||
{
|
{
|
||||||
float maxRatio = 0;
|
float maxRatio = 0;
|
||||||
const int maxDistanceMovementRatio = static_cast<int>(zones.size() * zones.size()); //experimental - the more zones, the greater total distance expected
|
const int maxDistanceMovementRatio = static_cast<int>(zones.size() * zones.size()); //experimental - the more zones, the greater total distance expected
|
||||||
@ -366,12 +361,12 @@ void CZonePlacer::moveOneZone(TZoneMap &zones, TForceVector &totalForces, TDista
|
|||||||
|
|
||||||
float totalDistance = 0;
|
float totalDistance = 0;
|
||||||
float totalOverlap = 0;
|
float totalOverlap = 0;
|
||||||
for (auto zone : distances) //find most misplaced zone
|
for(const auto & zone : distances) //find most misplaced zone
|
||||||
{
|
{
|
||||||
totalDistance += zone.second;
|
totalDistance += zone.second;
|
||||||
float overlap = overlaps[zone.first];
|
float overlap = overlaps[zone.first];
|
||||||
totalOverlap += overlap;
|
totalOverlap += overlap;
|
||||||
float ratio = (zone.second + overlap) / (float)totalForces[zone.first].mag(); //if distance to actual movement is long, the zone is misplaced
|
float ratio = (zone.second + overlap) / static_cast<float>(totalForces[zone.first].mag()); //if distance to actual movement is long, the zone is misplaced
|
||||||
if (ratio > maxRatio)
|
if (ratio > maxRatio)
|
||||||
{
|
{
|
||||||
maxRatio = ratio;
|
maxRatio = ratio;
|
||||||
@ -413,14 +408,14 @@ void CZonePlacer::moveOneZone(TZoneMap &zones, TForceVector &totalForces, TDista
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
float maxOverlap = 0;
|
float maxOverlap = 0;
|
||||||
for (auto otherZone : zones)
|
for(const auto & otherZone : zones)
|
||||||
{
|
{
|
||||||
float3 otherZoneCenter = otherZone.second->getCenter();
|
float3 otherZoneCenter = otherZone.second->getCenter();
|
||||||
|
|
||||||
if (otherZone.second == misplacedZone || otherZoneCenter.z != ourCenter.z)
|
if (otherZone.second == misplacedZone || otherZoneCenter.z != ourCenter.z)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float distance = static_cast<float>(otherZoneCenter.dist2dSQ(ourCenter));
|
auto distance = static_cast<float>(otherZoneCenter.dist2dSQ(ourCenter));
|
||||||
if (distance > maxOverlap)
|
if (distance > maxOverlap)
|
||||||
{
|
{
|
||||||
maxOverlap = distance;
|
maxOverlap = distance;
|
||||||
@ -478,7 +473,7 @@ void CZonePlacer::assignZones(CRandomGenerator * rand)
|
|||||||
return pr.second->getType() == ETemplateZoneType::WATER;
|
return pr.second->getType() == ETemplateZoneType::WATER;
|
||||||
});
|
});
|
||||||
|
|
||||||
typedef std::pair<std::shared_ptr<Zone>, float> Dpair;
|
using Dpair = std::pair<std::shared_ptr<Zone>, float>;
|
||||||
std::vector <Dpair> distances;
|
std::vector <Dpair> distances;
|
||||||
distances.reserve(zones.size());
|
distances.reserve(zones.size());
|
||||||
|
|
||||||
@ -490,11 +485,11 @@ void CZonePlacer::assignZones(CRandomGenerator * rand)
|
|||||||
return lhs.second / lhs.first->getSize() < rhs.second / rhs.first->getSize();
|
return lhs.second / lhs.first->getSize() < rhs.second / rhs.first->getSize();
|
||||||
};
|
};
|
||||||
|
|
||||||
auto moveZoneToCenterOfMass = [](std::shared_ptr<Zone> zone) -> void
|
auto moveZoneToCenterOfMass = [](const std::shared_ptr<Zone> & zone) -> void
|
||||||
{
|
{
|
||||||
int3 total(0, 0, 0);
|
int3 total(0, 0, 0);
|
||||||
auto tiles = zone->area().getTiles();
|
auto tiles = zone->area().getTiles();
|
||||||
for (auto tile : tiles)
|
for(const auto & tile : tiles)
|
||||||
{
|
{
|
||||||
total += tile;
|
total += tile;
|
||||||
}
|
}
|
||||||
@ -518,19 +513,19 @@ void CZonePlacer::assignZones(CRandomGenerator * rand)
|
|||||||
for(pos.y = 0; pos.y < height; pos.y++)
|
for(pos.y = 0; pos.y < height; pos.y++)
|
||||||
{
|
{
|
||||||
distances.clear();
|
distances.clear();
|
||||||
for(auto zone : zones)
|
for(const auto & zone : zones)
|
||||||
{
|
{
|
||||||
if (zone.second->getPos().z == pos.z)
|
if (zone.second->getPos().z == pos.z)
|
||||||
distances.push_back(std::make_pair(zone.second, (float)pos.dist2dSQ(zone.second->getPos())));
|
distances.emplace_back(zone.second, static_cast<float>(pos.dist2dSQ(zone.second->getPos())));
|
||||||
else
|
else
|
||||||
distances.push_back(std::make_pair(zone.second, std::numeric_limits<float>::max()));
|
distances.emplace_back(zone.second, std::numeric_limits<float>::max());
|
||||||
}
|
}
|
||||||
boost::min_element(distances, compareByDistance)->first->area().add(pos); //closest tile belongs to zone
|
boost::min_element(distances, compareByDistance)->first->area().add(pos); //closest tile belongs to zone
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto zone : zones)
|
for(const auto & zone : zones)
|
||||||
{
|
{
|
||||||
if(zone.second->area().empty())
|
if(zone.second->area().empty())
|
||||||
throw rmgException("Empty zone is generated, probably RMG template is inappropriate for map size");
|
throw rmgException("Empty zone is generated, probably RMG template is inappropriate for map size");
|
||||||
@ -540,7 +535,7 @@ void CZonePlacer::assignZones(CRandomGenerator * rand)
|
|||||||
|
|
||||||
//assign actual tiles to each zone using nonlinear norm for fine edges
|
//assign actual tiles to each zone using nonlinear norm for fine edges
|
||||||
|
|
||||||
for (auto zone : zones)
|
for(const auto & zone : zones)
|
||||||
zone.second->clearTiles(); //now populate them again
|
zone.second->clearTiles(); //now populate them again
|
||||||
|
|
||||||
for (pos.z = 0; pos.z < levels; pos.z++)
|
for (pos.z = 0; pos.z < levels; pos.z++)
|
||||||
@ -550,12 +545,12 @@ void CZonePlacer::assignZones(CRandomGenerator * rand)
|
|||||||
for (pos.y = 0; pos.y < height; pos.y++)
|
for (pos.y = 0; pos.y < height; pos.y++)
|
||||||
{
|
{
|
||||||
distances.clear();
|
distances.clear();
|
||||||
for (auto zone : zones)
|
for(const auto & zone : zones)
|
||||||
{
|
{
|
||||||
if (zone.second->getPos().z == pos.z)
|
if (zone.second->getPos().z == pos.z)
|
||||||
distances.push_back (std::make_pair(zone.second, metric(pos, zone.second->getPos())));
|
distances.emplace_back(zone.second, metric(pos, zone.second->getPos()));
|
||||||
else
|
else
|
||||||
distances.push_back (std::make_pair(zone.second, std::numeric_limits<float>::max()));
|
distances.emplace_back(zone.second, std::numeric_limits<float>::max());
|
||||||
}
|
}
|
||||||
auto zone = boost::min_element(distances, compareByDistance)->first; //closest tile belongs to zone
|
auto zone = boost::min_element(distances, compareByDistance)->first; //closest tile belongs to zone
|
||||||
zone->area().add(pos);
|
zone->area().add(pos);
|
||||||
@ -564,7 +559,7 @@ void CZonePlacer::assignZones(CRandomGenerator * rand)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//set position (town position) to center of mass of irregular zone
|
//set position (town position) to center of mass of irregular zone
|
||||||
for (auto zone : zones)
|
for(const auto & zone : zones)
|
||||||
{
|
{
|
||||||
moveZoneToCenterOfMass(zone.second);
|
moveZoneToCenterOfMass(zone.second);
|
||||||
|
|
||||||
@ -575,7 +570,7 @@ void CZonePlacer::assignZones(CRandomGenerator * rand)
|
|||||||
if (!CREATE_FULL_UNDERGROUND)
|
if (!CREATE_FULL_UNDERGROUND)
|
||||||
{
|
{
|
||||||
auto discardTiles = collectDistantTiles(*zone.second, zone.second->getSize() + 1.f);
|
auto discardTiles = collectDistantTiles(*zone.second, zone.second->getSize() + 1.f);
|
||||||
for(auto& t : discardTiles)
|
for(const auto & t : discardTiles)
|
||||||
zone.second->area().erase(t);
|
zone.second->area().erase(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,19 +31,19 @@ class CZonePlacer
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit CZonePlacer(RmgMap & map);
|
explicit CZonePlacer(RmgMap & map);
|
||||||
int3 cords (const float3 f) const;
|
int3 cords(const float3 & f) const;
|
||||||
float metric (const int3 &a, const int3 &b) const;
|
float metric (const int3 &a, const int3 &b) const;
|
||||||
float getDistance(float distance) const; //additional scaling without 0 divison
|
float getDistance(float distance) const; //additional scaling without 0 divison
|
||||||
~CZonePlacer();
|
~CZonePlacer() = default;
|
||||||
|
|
||||||
void placeZones(CRandomGenerator * rand);
|
void placeZones(CRandomGenerator * rand);
|
||||||
void assignZones(CRandomGenerator * rand);
|
void assignZones(CRandomGenerator * rand);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const bool underground, CRandomGenerator * rand);
|
void prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const bool underground, CRandomGenerator * rand);
|
||||||
void attractConnectedZones(TZoneMap &zones, TForceVector &forces, TDistanceVector &distances);
|
void attractConnectedZones(TZoneMap & zones, TForceVector & forces, TDistanceVector & distances) const;
|
||||||
void separateOverlappingZones(TZoneMap &zones, TForceVector &forces, TDistanceVector &overlaps);
|
void separateOverlappingZones(TZoneMap &zones, TForceVector &forces, TDistanceVector &overlaps);
|
||||||
void moveOneZone(TZoneMap &zones, TForceVector &totalForces, TDistanceVector &distances, TDistanceVector &overlaps);
|
void moveOneZone(TZoneMap & zones, TForceVector & totalForces, TDistanceVector & distances, TDistanceVector & overlaps) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int width;
|
int width;
|
||||||
|
@ -133,7 +133,8 @@ void ConnectionsPlacer::selfSideDirectConnection(const rmg::ZoneConnection & con
|
|||||||
auto ourArea = zone.areaPossible() + zone.freePaths();
|
auto ourArea = zone.areaPossible() + zone.freePaths();
|
||||||
auto theirArea = otherZone->areaPossible() + otherZone->freePaths();
|
auto theirArea = otherZone->areaPossible() + otherZone->freePaths();
|
||||||
theirArea.add(guardPos);
|
theirArea.add(guardPos);
|
||||||
rmg::Path ourPath(ourArea), theirPath(theirArea);
|
rmg::Path ourPath(ourArea);
|
||||||
|
rmg::Path theirPath(theirArea);
|
||||||
ourPath.connect(zone.freePaths());
|
ourPath.connect(zone.freePaths());
|
||||||
ourPath = ourPath.search(guardPos, true, costFunction);
|
ourPath = ourPath.search(guardPos, true, costFunction);
|
||||||
theirPath.connect(otherZone->freePaths());
|
theirPath.connect(otherZone->freePaths());
|
||||||
@ -210,9 +211,10 @@ void ConnectionsPlacer::selfSideIndirectConnection(const rmg::ZoneConnection & c
|
|||||||
auto & managerOther = *otherZone->getModificator<ObjectManager>();
|
auto & managerOther = *otherZone->getModificator<ObjectManager>();
|
||||||
|
|
||||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::SUBTERRANEAN_GATE, 0);
|
auto factory = VLC->objtypeh->getHandlerFor(Obj::SUBTERRANEAN_GATE, 0);
|
||||||
auto gate1 = factory->create();
|
auto * gate1 = factory->create();
|
||||||
auto gate2 = factory->create();
|
auto * gate2 = factory->create();
|
||||||
rmg::Object rmgGate1(*gate1), rmgGate2(*gate2);
|
rmg::Object rmgGate1(*gate1);
|
||||||
|
rmg::Object rmgGate2(*gate2);
|
||||||
rmgGate1.setTemplate(zone.getTerrainType());
|
rmgGate1.setTemplate(zone.getTerrainType());
|
||||||
rmgGate2.setTemplate(otherZone->getTerrainType());
|
rmgGate2.setTemplate(otherZone->getTerrainType());
|
||||||
bool guarded1 = manager.addGuard(rmgGate1, connection.getGuardStrength(), true);
|
bool guarded1 = manager.addGuard(rmgGate1, connection.getGuardStrength(), true);
|
||||||
@ -255,9 +257,9 @@ void ConnectionsPlacer::selfSideIndirectConnection(const rmg::ZoneConnection & c
|
|||||||
if(!success)
|
if(!success)
|
||||||
{
|
{
|
||||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::MONOLITH_TWO_WAY, generator.getNextMonlithIndex());
|
auto factory = VLC->objtypeh->getHandlerFor(Obj::MONOLITH_TWO_WAY, generator.getNextMonlithIndex());
|
||||||
auto teleport1 = factory->create();
|
auto * teleport1 = factory->create();
|
||||||
auto teleport2 = factory->create();
|
auto * teleport2 = factory->create();
|
||||||
|
|
||||||
zone.getModificator<ObjectManager>()->addRequiredObject(teleport1, connection.getGuardStrength());
|
zone.getModificator<ObjectManager>()->addRequiredObject(teleport1, connection.getGuardStrength());
|
||||||
otherZone->getModificator<ObjectManager>()->addRequiredObject(teleport2, connection.getGuardStrength());
|
otherZone->getModificator<ObjectManager>()->addRequiredObject(teleport2, connection.getGuardStrength());
|
||||||
|
|
||||||
@ -274,7 +276,7 @@ void ConnectionsPlacer::selfSideIndirectConnection(const rmg::ZoneConnection & c
|
|||||||
void ConnectionsPlacer::collectNeighbourZones()
|
void ConnectionsPlacer::collectNeighbourZones()
|
||||||
{
|
{
|
||||||
auto border = zone.area().getBorderOutside();
|
auto border = zone.area().getBorderOutside();
|
||||||
for(auto & i : border)
|
for(const auto & i : border)
|
||||||
{
|
{
|
||||||
if(!map.isOnMap(i))
|
if(!map.isOnMap(i))
|
||||||
continue;
|
continue;
|
||||||
|
@ -76,8 +76,8 @@ void createBorder(RmgMap & gen, Zone & zone)
|
|||||||
auto tile = borderOutsideArea.nearest(t);
|
auto tile = borderOutsideArea.nearest(t);
|
||||||
return gen.isOnMap(tile) && gen.getZones()[gen.getZoneID(tile)]->getType() != ETemplateZoneType::WATER;
|
return gen.isOnMap(tile) && gen.getZones()[gen.getZoneID(tile)]->getType() != ETemplateZoneType::WATER;
|
||||||
});
|
});
|
||||||
|
|
||||||
for(auto & tile : blockBorder.getTilesVector())
|
for(const auto & tile : blockBorder.getTilesVector())
|
||||||
{
|
{
|
||||||
if(gen.isPossible(tile))
|
if(gen.isPossible(tile))
|
||||||
{
|
{
|
||||||
|
@ -42,7 +42,7 @@ void ObjectManager::init()
|
|||||||
void ObjectManager::createDistancesPriorityQueue()
|
void ObjectManager::createDistancesPriorityQueue()
|
||||||
{
|
{
|
||||||
tilesByDistance.clear();
|
tilesByDistance.clear();
|
||||||
for (auto & tile : zone.areaPossible().getTilesVector())
|
for(const auto & tile : zone.areaPossible().getTilesVector())
|
||||||
{
|
{
|
||||||
tilesByDistance.push(std::make_pair(tile, map.getNearestObjectDistance(tile)));
|
tilesByDistance.push(std::make_pair(tile, map.getNearestObjectDistance(tile)));
|
||||||
}
|
}
|
||||||
@ -50,17 +50,17 @@ void ObjectManager::createDistancesPriorityQueue()
|
|||||||
|
|
||||||
void ObjectManager::addRequiredObject(CGObjectInstance * obj, si32 strength)
|
void ObjectManager::addRequiredObject(CGObjectInstance * obj, si32 strength)
|
||||||
{
|
{
|
||||||
requiredObjects.push_back(std::make_pair(obj, strength));
|
requiredObjects.emplace_back(obj, strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectManager::addCloseObject(CGObjectInstance * obj, si32 strength)
|
void ObjectManager::addCloseObject(CGObjectInstance * obj, si32 strength)
|
||||||
{
|
{
|
||||||
closeObjects.push_back(std::make_pair(obj, strength));
|
closeObjects.emplace_back(obj, strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectManager::addNearbyObject(CGObjectInstance * obj, CGObjectInstance * nearbyTarget)
|
void ObjectManager::addNearbyObject(CGObjectInstance * obj, CGObjectInstance * nearbyTarget)
|
||||||
{
|
{
|
||||||
nearbyObjects.push_back(std::make_pair(obj, nearbyTarget));
|
nearbyObjects.emplace_back(obj, nearbyTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectManager::updateDistances(const rmg::Object & obj)
|
void ObjectManager::updateDistances(const rmg::Object & obj)
|
||||||
@ -69,7 +69,7 @@ void ObjectManager::updateDistances(const rmg::Object & obj)
|
|||||||
for (auto tile : zone.areaPossible().getTiles()) //don't need to mark distance for not possible tiles
|
for (auto tile : zone.areaPossible().getTiles()) //don't need to mark distance for not possible tiles
|
||||||
{
|
{
|
||||||
ui32 d = obj.getArea().distanceSqr(tile); //optimization, only relative distance is interesting
|
ui32 d = obj.getArea().distanceSqr(tile); //optimization, only relative distance is interesting
|
||||||
map.setNearestObjectDistance(tile, std::min((float)d, map.getNearestObjectDistance(tile)));
|
map.setNearestObjectDistance(tile, std::min(static_cast<float>(d), map.getNearestObjectDistance(tile)));
|
||||||
tilesByDistance.push(std::make_pair(tile, map.getNearestObjectDistance(tile)));
|
tilesByDistance.push(std::make_pair(tile, map.getNearestObjectDistance(tile)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,8 +82,8 @@ const rmg::Area & ObjectManager::getVisitableArea() const
|
|||||||
std::vector<CGObjectInstance*> ObjectManager::getMines() const
|
std::vector<CGObjectInstance*> ObjectManager::getMines() const
|
||||||
{
|
{
|
||||||
std::vector<CGObjectInstance*> mines;
|
std::vector<CGObjectInstance*> mines;
|
||||||
|
|
||||||
for (auto object : objects)
|
for(auto * object : objects)
|
||||||
{
|
{
|
||||||
if (object->ID == Obj::MINE)
|
if (object->ID == Obj::MINE)
|
||||||
{
|
{
|
||||||
@ -94,7 +94,7 @@ std::vector<CGObjectInstance*> ObjectManager::getMines() const
|
|||||||
return mines;
|
return mines;
|
||||||
}
|
}
|
||||||
|
|
||||||
int3 ObjectManager::findPlaceForObject(const rmg::Area & searchArea, rmg::Object & obj, std::function<float(const int3)> weightFunction, OptimizeType optimizer) const
|
int3 ObjectManager::findPlaceForObject(const rmg::Area & searchArea, rmg::Object & obj, const std::function<float(const int3)> & weightFunction, OptimizeType optimizer) const
|
||||||
{
|
{
|
||||||
float bestWeight = 0.f;
|
float bestWeight = 0.f;
|
||||||
int3 result(-1, -1, -1);
|
int3 result(-1, -1, -1);
|
||||||
@ -159,8 +159,8 @@ int3 ObjectManager::findPlaceForObject(const rmg::Area & searchArea, rmg::Object
|
|||||||
float dist = ti.getNearestObjectDistance();
|
float dist = ti.getNearestObjectDistance();
|
||||||
if(dist < min_dist)
|
if(dist < min_dist)
|
||||||
return -1.f;
|
return -1.f;
|
||||||
|
|
||||||
for(auto & t : obj.getArea().getTilesVector())
|
for(const auto & t : obj.getArea().getTilesVector())
|
||||||
{
|
{
|
||||||
if(map.getTile(t).getNearestObjectDistance() < min_dist)
|
if(map.getTile(t).getNearestObjectDistance() < min_dist)
|
||||||
return -1.f;
|
return -1.f;
|
||||||
@ -178,8 +178,8 @@ rmg::Path ObjectManager::placeAndConnectObject(const rmg::Area & searchArea, rmg
|
|||||||
float dist = ti.getNearestObjectDistance();
|
float dist = ti.getNearestObjectDistance();
|
||||||
if(dist < min_dist)
|
if(dist < min_dist)
|
||||||
return -1.f;
|
return -1.f;
|
||||||
|
|
||||||
for(auto & t : obj.getArea().getTilesVector())
|
for(const auto & t : obj.getArea().getTilesVector())
|
||||||
{
|
{
|
||||||
if(map.getTile(t).getNearestObjectDistance() < min_dist)
|
if(map.getTile(t).getNearestObjectDistance() < min_dist)
|
||||||
return -1.f;
|
return -1.f;
|
||||||
@ -189,7 +189,7 @@ rmg::Path ObjectManager::placeAndConnectObject(const rmg::Area & searchArea, rmg
|
|||||||
}, isGuarded, onlyStraight, optimizer);
|
}, isGuarded, onlyStraight, optimizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
rmg::Path ObjectManager::placeAndConnectObject(const rmg::Area & searchArea, rmg::Object & obj, std::function<float(const int3)> weightFunction, bool isGuarded, bool onlyStraight, OptimizeType optimizer) const
|
rmg::Path ObjectManager::placeAndConnectObject(const rmg::Area & searchArea, rmg::Object & obj, const std::function<float(const int3)> & weightFunction, bool isGuarded, bool onlyStraight, OptimizeType optimizer) const
|
||||||
{
|
{
|
||||||
int3 pos;
|
int3 pos;
|
||||||
auto possibleArea = searchArea;
|
auto possibleArea = searchArea;
|
||||||
@ -205,7 +205,7 @@ rmg::Path ObjectManager::placeAndConnectObject(const rmg::Area & searchArea, rmg
|
|||||||
//we should exclude tiles which will be covered
|
//we should exclude tiles which will be covered
|
||||||
if(isGuarded)
|
if(isGuarded)
|
||||||
{
|
{
|
||||||
auto & guardedArea = obj.instances().back()->getAccessibleArea();
|
const auto & guardedArea = obj.instances().back()->getAccessibleArea();
|
||||||
accessibleArea.intersect(guardedArea);
|
accessibleArea.intersect(guardedArea);
|
||||||
accessibleArea.add(obj.instances().back()->getPosition(true));
|
accessibleArea.add(obj.instances().back()->getPosition(true));
|
||||||
}
|
}
|
||||||
@ -214,8 +214,8 @@ rmg::Path ObjectManager::placeAndConnectObject(const rmg::Area & searchArea, rmg
|
|||||||
{
|
{
|
||||||
if(isGuarded)
|
if(isGuarded)
|
||||||
{
|
{
|
||||||
auto & guardedArea = obj.instances().back()->getAccessibleArea();
|
const auto & guardedArea = obj.instances().back()->getAccessibleArea();
|
||||||
auto & unguardedArea = obj.getAccessibleArea(isGuarded);
|
const auto & unguardedArea = obj.getAccessibleArea(isGuarded);
|
||||||
if(unguardedArea.contains(t) && !guardedArea.contains(t))
|
if(unguardedArea.contains(t) && !guardedArea.contains(t))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -353,7 +353,7 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
|
|||||||
auto areaToBlock = object.getAccessibleArea(true);
|
auto areaToBlock = object.getAccessibleArea(true);
|
||||||
areaToBlock.subtract(guardedArea);
|
areaToBlock.subtract(guardedArea);
|
||||||
zone.areaPossible().subtract(areaToBlock);
|
zone.areaPossible().subtract(areaToBlock);
|
||||||
for(auto & i : areaToBlock.getTilesVector())
|
for(const auto & i : areaToBlock.getTilesVector())
|
||||||
if(map.isOnMap(i) && map.isPossible(i))
|
if(map.isOnMap(i) && map.isPossible(i))
|
||||||
map.setOccupied(i, ETileType::BLOCKED);
|
map.setOccupied(i, ETileType::BLOCKED);
|
||||||
}
|
}
|
||||||
@ -429,12 +429,12 @@ CGCreature * ObjectManager::chooseGuard(si32 strength, bool zoneGuard)
|
|||||||
continue;
|
continue;
|
||||||
if(!vstd::contains(zone.getMonsterTypes(), cre->faction))
|
if(!vstd::contains(zone.getMonsterTypes(), cre->faction))
|
||||||
continue;
|
continue;
|
||||||
if(((si32)(cre->AIValue * (cre->ammMin + cre->ammMax) / 2) < strength) && (strength < (si32)cre->AIValue * 100)) //at least one full monster. size between average size of given stack and 100
|
if((static_cast<si32>(cre->AIValue * (cre->ammMin + cre->ammMax) / 2) < strength) && (strength < static_cast<si32>(cre->AIValue) * 100)) //at least one full monster. size between average size of given stack and 100
|
||||||
{
|
{
|
||||||
possibleCreatures.push_back(cre->idNumber);
|
possibleCreatures.push_back(cre->idNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(possibleCreatures.size())
|
if(!possibleCreatures.empty())
|
||||||
{
|
{
|
||||||
creId = *RandomGeneratorUtil::nextItem(possibleCreatures, generator.rand);
|
creId = *RandomGeneratorUtil::nextItem(possibleCreatures, generator.rand);
|
||||||
amount = strength / VLC->creh->objects[creId]->AIValue;
|
amount = strength / VLC->creh->objects[creId]->AIValue;
|
||||||
@ -448,10 +448,10 @@ CGCreature * ObjectManager::chooseGuard(si32 strength, bool zoneGuard)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto guardFactory = VLC->objtypeh->getHandlerFor(Obj::MONSTER, creId);
|
auto guardFactory = VLC->objtypeh->getHandlerFor(Obj::MONSTER, creId);
|
||||||
|
|
||||||
auto guard = (CGCreature *) guardFactory->create();
|
auto * guard = dynamic_cast<CGCreature *>(guardFactory->create());
|
||||||
guard->character = CGCreature::HOSTILE;
|
guard->character = CGCreature::HOSTILE;
|
||||||
auto hlp = new CStackInstance(creId, amount);
|
auto * hlp = new CStackInstance(creId, amount);
|
||||||
//will be set during initialization
|
//will be set during initialization
|
||||||
guard->putStack(SlotID(0), hlp);
|
guard->putStack(SlotID(0), hlp);
|
||||||
return guard;
|
return guard;
|
||||||
|
@ -53,10 +53,10 @@ public:
|
|||||||
bool createRequiredObjects();
|
bool createRequiredObjects();
|
||||||
|
|
||||||
int3 findPlaceForObject(const rmg::Area & searchArea, rmg::Object & obj, si32 min_dist, OptimizeType optimizer) const;
|
int3 findPlaceForObject(const rmg::Area & searchArea, rmg::Object & obj, si32 min_dist, OptimizeType optimizer) const;
|
||||||
int3 findPlaceForObject(const rmg::Area & searchArea, rmg::Object & obj, std::function<float(const int3)> weightFunction, OptimizeType optimizer) const;
|
int3 findPlaceForObject(const rmg::Area & searchArea, rmg::Object & obj, const std::function<float(const int3)> & weightFunction, OptimizeType optimizer) const;
|
||||||
|
|
||||||
rmg::Path placeAndConnectObject(const rmg::Area & searchArea, rmg::Object & obj, si32 min_dist, bool isGuarded, bool onlyStraight, OptimizeType optimizer) const;
|
rmg::Path placeAndConnectObject(const rmg::Area & searchArea, rmg::Object & obj, si32 min_dist, bool isGuarded, bool onlyStraight, OptimizeType optimizer) const;
|
||||||
rmg::Path placeAndConnectObject(const rmg::Area & searchArea, rmg::Object & obj, std::function<float(const int3)> weightFunction, bool isGuarded, bool onlyStraight, OptimizeType optimizer) const;
|
rmg::Path placeAndConnectObject(const rmg::Area & searchArea, rmg::Object & obj, const std::function<float(const int3)> & weightFunction, bool isGuarded, bool onlyStraight, OptimizeType optimizer) const;
|
||||||
|
|
||||||
CGCreature * chooseGuard(si32 strength, bool zoneGuard = false);
|
CGCreature * chooseGuard(si32 strength, bool zoneGuard = false);
|
||||||
bool addGuard(rmg::Object & object, si32 strength, bool zoneGuard = false);
|
bool addGuard(rmg::Object & object, si32 strength, bool zoneGuard = false);
|
||||||
|
@ -36,7 +36,7 @@ void ObstacleProxy::collectPossibleObstacles(TerrainId terrain)
|
|||||||
auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID);
|
auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID);
|
||||||
if(handler->isStaticObject())
|
if(handler->isStaticObject())
|
||||||
{
|
{
|
||||||
for(auto temp : handler->getTemplates())
|
for(const auto & temp : handler->getTemplates())
|
||||||
{
|
{
|
||||||
if(temp->canBePlacedAt(terrain) && temp->getBlockMapOffset().valid())
|
if(temp->canBePlacedAt(terrain) && temp->getBlockMapOffset().valid())
|
||||||
obstaclesBySize[temp->getBlockedOffsets().size()].push_back(temp);
|
obstaclesBySize[temp->getBlockedOffsets().size()].push_back(temp);
|
||||||
@ -44,9 +44,9 @@ void ObstacleProxy::collectPossibleObstacles(TerrainId terrain)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(auto o : obstaclesBySize)
|
for(const auto & o : obstaclesBySize)
|
||||||
{
|
{
|
||||||
possibleObstacles.push_back(o);
|
possibleObstacles.emplace_back(o);
|
||||||
}
|
}
|
||||||
boost::sort(possibleObstacles, [](const ObstaclePair &p1, const ObstaclePair &p2) -> bool
|
boost::sort(possibleObstacles, [](const ObstaclePair &p1, const ObstaclePair &p2) -> bool
|
||||||
{
|
{
|
||||||
@ -57,21 +57,21 @@ void ObstacleProxy::collectPossibleObstacles(TerrainId terrain)
|
|||||||
int ObstacleProxy::getWeightedObjects(const int3 & tile, const CMap * map, CRandomGenerator & rand, std::list<rmg::Object> & allObjects, std::vector<std::pair<rmg::Object*, int3>> & weightedObjects)
|
int ObstacleProxy::getWeightedObjects(const int3 & tile, const CMap * map, CRandomGenerator & rand, std::list<rmg::Object> & allObjects, std::vector<std::pair<rmg::Object*, int3>> & weightedObjects)
|
||||||
{
|
{
|
||||||
int maxWeight = std::numeric_limits<int>::min();
|
int maxWeight = std::numeric_limits<int>::min();
|
||||||
for(int i = 0; i < possibleObstacles.size(); ++i)
|
for(auto & possibleObstacle : possibleObstacles)
|
||||||
{
|
{
|
||||||
if(!possibleObstacles[i].first)
|
if(!possibleObstacle.first)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto shuffledObstacles = possibleObstacles[i].second;
|
auto shuffledObstacles = possibleObstacle.second;
|
||||||
RandomGeneratorUtil::randomShuffle(shuffledObstacles, rand);
|
RandomGeneratorUtil::randomShuffle(shuffledObstacles, rand);
|
||||||
|
|
||||||
for(auto temp : shuffledObstacles)
|
for(const auto & temp : shuffledObstacles)
|
||||||
{
|
{
|
||||||
auto handler = VLC->objtypeh->getHandlerFor(temp->id, temp->subid);
|
auto handler = VLC->objtypeh->getHandlerFor(temp->id, temp->subid);
|
||||||
auto obj = handler->create(temp);
|
auto * obj = handler->create(temp);
|
||||||
allObjects.emplace_back(*obj);
|
allObjects.emplace_back(*obj);
|
||||||
rmg::Object * rmgObject = &allObjects.back();
|
rmg::Object * rmgObject = &allObjects.back();
|
||||||
for(auto & offset : obj->getBlockedOffsets())
|
for(const auto & offset : obj->getBlockedOffsets())
|
||||||
{
|
{
|
||||||
rmgObject->setPosition(tile - offset);
|
rmgObject->setPosition(tile - offset);
|
||||||
if(!map->isInTheMap(rmgObject->getPosition()))
|
if(!map->isInTheMap(rmgObject->getPosition()))
|
||||||
@ -89,7 +89,7 @@ int ObstacleProxy::getWeightedObjects(const int3 & tile, const CMap * map, CRand
|
|||||||
int coverageBlocked = 0;
|
int coverageBlocked = 0;
|
||||||
int coveragePossible = 0;
|
int coveragePossible = 0;
|
||||||
//do not use area intersection in optimization purposes
|
//do not use area intersection in optimization purposes
|
||||||
for(auto & t : rmgObject->getArea().getTilesVector())
|
for(const auto & t : rmgObject->getArea().getTilesVector())
|
||||||
{
|
{
|
||||||
auto coverage = verifyCoverage(t);
|
auto coverage = verifyCoverage(t);
|
||||||
if(coverage.first)
|
if(coverage.first)
|
||||||
@ -98,8 +98,8 @@ int ObstacleProxy::getWeightedObjects(const int3 & tile, const CMap * map, CRand
|
|||||||
++coveragePossible;
|
++coveragePossible;
|
||||||
}
|
}
|
||||||
|
|
||||||
int coverageOverlap = possibleObstacles[i].first - coverageBlocked - coveragePossible;
|
int coverageOverlap = possibleObstacle.first - coverageBlocked - coveragePossible;
|
||||||
int weight = possibleObstacles[i].first + coverageBlocked - coverageOverlap * possibleObstacles[i].first;
|
int weight = possibleObstacle.first + coverageBlocked - coverageOverlap * possibleObstacle.first;
|
||||||
assert(coverageOverlap >= 0);
|
assert(coverageOverlap >= 0);
|
||||||
|
|
||||||
if(weight > maxWeight)
|
if(weight > maxWeight)
|
||||||
|
@ -71,7 +71,7 @@ const std::array<std::array<int, 25>, 4> deltaTemplates
|
|||||||
void RiverPlacer::process()
|
void RiverPlacer::process()
|
||||||
{
|
{
|
||||||
preprocess();
|
preprocess();
|
||||||
for(auto & t : riverNodes)
|
for(const auto & t : riverNodes)
|
||||||
connectRiver(t);
|
connectRiver(t);
|
||||||
|
|
||||||
if(!rivers.empty())
|
if(!rivers.empty())
|
||||||
@ -134,8 +134,8 @@ void RiverPlacer::prepareHeightmap()
|
|||||||
{
|
{
|
||||||
roads.unite(m->getRoads());
|
roads.unite(m->getRoads());
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto & t : zone.area().getTilesVector())
|
for(const auto & t : zone.area().getTilesVector())
|
||||||
{
|
{
|
||||||
heightMap[t] = generator.rand.nextInt(5);
|
heightMap[t] = generator.rand.nextInt(5);
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ void RiverPlacer::preprocess()
|
|||||||
std::map<TRmgTemplateZoneId, rmg::Area> neighbourZonesTiles;
|
std::map<TRmgTemplateZoneId, rmg::Area> neighbourZonesTiles;
|
||||||
rmg::Area borderArea(zone.getArea().getBorder());
|
rmg::Area borderArea(zone.getArea().getBorder());
|
||||||
TRmgTemplateZoneId connectedToWaterZoneId = -1;
|
TRmgTemplateZoneId connectedToWaterZoneId = -1;
|
||||||
for(auto & t : zone.getArea().getBorderOutside())
|
for(const auto & t : zone.getArea().getBorderOutside())
|
||||||
{
|
{
|
||||||
if(!map.isOnMap(t))
|
if(!map.isOnMap(t))
|
||||||
{
|
{
|
||||||
@ -200,7 +200,7 @@ void RiverPlacer::preprocess()
|
|||||||
auto river = VLC->terrainTypeHandler->getById(zone.getTerrainType())->river;
|
auto river = VLC->terrainTypeHandler->getById(zone.getTerrainType())->river;
|
||||||
auto & a = neighbourZonesTiles[connectedToWaterZoneId];
|
auto & a = neighbourZonesTiles[connectedToWaterZoneId];
|
||||||
auto availableArea = zone.areaPossible() + zone.freePaths();
|
auto availableArea = zone.areaPossible() + zone.freePaths();
|
||||||
for(auto & tileToProcess : availableArea.getTilesVector())
|
for(const auto & tileToProcess : availableArea.getTilesVector())
|
||||||
{
|
{
|
||||||
int templateId = -1;
|
int templateId = -1;
|
||||||
for(int tId = 0; tId < 4; ++tId)
|
for(int tId = 0; tId < 4; ++tId)
|
||||||
@ -390,7 +390,7 @@ void RiverPlacer::connectRiver(const int3 & tile)
|
|||||||
{
|
{
|
||||||
if(templ->animationFile == targetTemplateName)
|
if(templ->animationFile == targetTemplateName)
|
||||||
{
|
{
|
||||||
auto obj = handler->create(templ);
|
auto * obj = handler->create(templ);
|
||||||
rmg::Object deltaObj(*obj, deltaPositions[pos]);
|
rmg::Object deltaObj(*obj, deltaPositions[pos]);
|
||||||
deltaObj.finalize(map);
|
deltaObj.finalize(map);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ namespace rmg
|
|||||||
void toAbsolute(Tileset & tiles, const int3 & position)
|
void toAbsolute(Tileset & tiles, const int3 & position)
|
||||||
{
|
{
|
||||||
Tileset temp;
|
Tileset temp;
|
||||||
for(auto & tile : tiles)
|
for(const auto & tile : tiles)
|
||||||
{
|
{
|
||||||
temp.insert(tile + position);
|
temp.insert(tile + position);
|
||||||
}
|
}
|
||||||
@ -36,11 +36,10 @@ Area::Area(const Area & area): dTiles(area.dTiles), dTotalShiftCache(area.dTotal
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Area::Area(const Area && area): dTiles(std::move(area.dTiles)), dTotalShiftCache(std::move(area.dTotalShiftCache))
|
Area::Area(Area && area) noexcept: dTiles(std::move(area.dTiles)), dTotalShiftCache(area.dTotalShiftCache)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Area & Area::operator=(const Area & area)
|
Area & Area::operator=(const Area & area)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
@ -49,11 +48,11 @@ Area & Area::operator=(const Area & area)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Area::Area(const Tileset & tiles): dTiles(tiles)
|
Area::Area(Tileset tiles): dTiles(std::move(tiles))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Area::Area(const Tileset & relative, const int3 & position): dTiles(relative), dTotalShiftCache(position)
|
Area::Area(Tileset relative, const int3 & position): dTiles(std::move(relative)), dTotalShiftCache(position)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +147,7 @@ const Tileset & Area::getBorder() const
|
|||||||
return dBorderCache;
|
return dBorderCache;
|
||||||
|
|
||||||
//compute border cache
|
//compute border cache
|
||||||
for(auto & t : dTiles)
|
for(const auto & t : dTiles)
|
||||||
{
|
{
|
||||||
for(auto & i : int3::getDirs())
|
for(auto & i : int3::getDirs())
|
||||||
{
|
{
|
||||||
@ -169,7 +168,7 @@ const Tileset & Area::getBorderOutside() const
|
|||||||
return dBorderOutsideCache;
|
return dBorderOutsideCache;
|
||||||
|
|
||||||
//compute outside border cache
|
//compute outside border cache
|
||||||
for(auto & t : dTiles)
|
for(const auto & t : dTiles)
|
||||||
{
|
{
|
||||||
for(auto & i : int3::getDirs())
|
for(auto & i : int3::getDirs())
|
||||||
{
|
{
|
||||||
@ -190,7 +189,7 @@ DistanceMap Area::computeDistanceMap(std::map<int, Tileset> & reverseDistanceMap
|
|||||||
|
|
||||||
while(!area.empty())
|
while(!area.empty())
|
||||||
{
|
{
|
||||||
for(auto & tile : area.getBorder())
|
for(const auto & tile : area.getBorder())
|
||||||
result[tile] = distance;
|
result[tile] = distance;
|
||||||
reverseDistanceMap[distance++] = area.getBorder();
|
reverseDistanceMap[distance++] = area.getBorder();
|
||||||
area.subtract(area.getBorder());
|
area.subtract(area.getBorder());
|
||||||
@ -210,7 +209,7 @@ bool Area::contains(const int3 & tile) const
|
|||||||
|
|
||||||
bool Area::contains(const std::vector<int3> & tiles) const
|
bool Area::contains(const std::vector<int3> & tiles) const
|
||||||
{
|
{
|
||||||
for(auto & t : tiles)
|
for(const auto & t : tiles)
|
||||||
{
|
{
|
||||||
if(!contains(t))
|
if(!contains(t))
|
||||||
return false;
|
return false;
|
||||||
@ -225,7 +224,7 @@ bool Area::contains(const Area & area) const
|
|||||||
|
|
||||||
bool Area::overlap(const std::vector<int3> & tiles) const
|
bool Area::overlap(const std::vector<int3> & tiles) const
|
||||||
{
|
{
|
||||||
for(auto & t : tiles)
|
for(const auto & t : tiles)
|
||||||
{
|
{
|
||||||
if(contains(t))
|
if(contains(t))
|
||||||
return true;
|
return true;
|
||||||
@ -280,10 +279,10 @@ int3 Area::nearest(const Area & area) const
|
|||||||
return nearTile;
|
return nearTile;
|
||||||
}
|
}
|
||||||
|
|
||||||
Area Area::getSubarea(std::function<bool(const int3 &)> filter) const
|
Area Area::getSubarea(const std::function<bool(const int3 &)> & filter) const
|
||||||
{
|
{
|
||||||
Area subset;
|
Area subset;
|
||||||
for(auto & t : getTilesVector())
|
for(const auto & t : getTilesVector())
|
||||||
if(filter(t))
|
if(filter(t))
|
||||||
subset.add(t);
|
subset.add(t);
|
||||||
return subset;
|
return subset;
|
||||||
@ -316,7 +315,7 @@ void Area::erase(const int3 & tile)
|
|||||||
void Area::unite(const Area & area)
|
void Area::unite(const Area & area)
|
||||||
{
|
{
|
||||||
invalidate();
|
invalidate();
|
||||||
for(auto & t : area.getTilesVector())
|
for(const auto & t : area.getTilesVector())
|
||||||
{
|
{
|
||||||
dTiles.insert(t);
|
dTiles.insert(t);
|
||||||
}
|
}
|
||||||
@ -325,7 +324,7 @@ void Area::intersect(const Area & area)
|
|||||||
{
|
{
|
||||||
invalidate();
|
invalidate();
|
||||||
Tileset result;
|
Tileset result;
|
||||||
for(auto & t : area.getTilesVector())
|
for(const auto & t : area.getTilesVector())
|
||||||
{
|
{
|
||||||
if(dTiles.count(t))
|
if(dTiles.count(t))
|
||||||
result.insert(t);
|
result.insert(t);
|
||||||
@ -336,7 +335,7 @@ void Area::intersect(const Area & area)
|
|||||||
void Area::subtract(const Area & area)
|
void Area::subtract(const Area & area)
|
||||||
{
|
{
|
||||||
invalidate();
|
invalidate();
|
||||||
for(auto & t : area.getTilesVector())
|
for(const auto & t : area.getTilesVector())
|
||||||
{
|
{
|
||||||
dTiles.erase(t);
|
dTiles.erase(t);
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,9 @@ namespace rmg
|
|||||||
public:
|
public:
|
||||||
Area() = default;
|
Area() = default;
|
||||||
Area(const Area &);
|
Area(const Area &);
|
||||||
Area(const Area &&);
|
Area(Area &&) noexcept;
|
||||||
Area(const Tileset & tiles);
|
Area(Tileset tiles);
|
||||||
Area(const Tileset & relative, const int3 & position); //create from relative positions
|
Area(Tileset relative, const int3 & position); //create from relative positions
|
||||||
Area & operator= (const Area &);
|
Area & operator= (const Area &);
|
||||||
|
|
||||||
const Tileset & getTiles() const;
|
const Tileset & getTiles() const;
|
||||||
@ -41,9 +41,9 @@ namespace rmg
|
|||||||
const Tileset & getBorderOutside() const; //lazy cache invalidation
|
const Tileset & getBorderOutside() const; //lazy cache invalidation
|
||||||
|
|
||||||
DistanceMap computeDistanceMap(std::map<int, Tileset> & reverseDistanceMap) const;
|
DistanceMap computeDistanceMap(std::map<int, Tileset> & reverseDistanceMap) const;
|
||||||
|
|
||||||
Area getSubarea(std::function<bool(const int3 &)> filter) const;
|
Area getSubarea(const std::function<bool(const int3 &)> & filter) const;
|
||||||
|
|
||||||
bool connected() const; //is connected
|
bool connected() const; //is connected
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
bool contains(const int3 & tile) const;
|
bool contains(const int3 & tile) const;
|
||||||
|
@ -39,7 +39,7 @@ RmgMap::RmgMap(const CMapGenOptions& mapGenOptions) :
|
|||||||
getEditManager()->getUndoManager().setUndoRedoLimit(0);
|
getEditManager()->getUndoManager().setUndoRedoLimit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RmgMap::foreach_neighbour(const int3 &pos, std::function<void(int3& pos)> foo)
|
void RmgMap::foreach_neighbour(const int3 & pos, const std::function<void(int3 & pos)> & foo) const
|
||||||
{
|
{
|
||||||
for(const int3 &dir : int3::getDirs())
|
for(const int3 &dir : int3::getDirs())
|
||||||
{
|
{
|
||||||
@ -51,7 +51,7 @@ void RmgMap::foreach_neighbour(const int3 &pos, std::function<void(int3& pos)> f
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RmgMap::foreachDirectNeighbour(const int3& pos, std::function<void(int3& pos)> foo)
|
void RmgMap::foreachDirectNeighbour(const int3 & pos, const std::function<void(int3 & pos)> & foo) const
|
||||||
{
|
{
|
||||||
for(const int3 &dir : rmg::dirs4)
|
for(const int3 &dir : rmg::dirs4)
|
||||||
{
|
{
|
||||||
@ -61,7 +61,7 @@ void RmgMap::foreachDirectNeighbour(const int3& pos, std::function<void(int3& po
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RmgMap::foreachDiagonalNeighbour(const int3& pos, std::function<void(int3& pos)> foo)
|
void RmgMap::foreachDiagonalNeighbour(const int3 & pos, const std::function<void(int3 & pos)> & foo) const
|
||||||
{
|
{
|
||||||
for (const int3 &dir : rmg::dirsDiagonal)
|
for (const int3 &dir : rmg::dirsDiagonal)
|
||||||
{
|
{
|
||||||
@ -85,13 +85,13 @@ void RmgMap::initTiles(CMapGenerator & generator)
|
|||||||
getEditManager()->clearTerrain(&generator.rand);
|
getEditManager()->clearTerrain(&generator.rand);
|
||||||
getEditManager()->getTerrainSelection().selectRange(MapRect(int3(0, 0, 0), mapGenOptions.getWidth(), mapGenOptions.getHeight()));
|
getEditManager()->getTerrainSelection().selectRange(MapRect(int3(0, 0, 0), mapGenOptions.getWidth(), mapGenOptions.getHeight()));
|
||||||
getEditManager()->drawTerrain(ETerrainId::GRASS, &generator.rand);
|
getEditManager()->drawTerrain(ETerrainId::GRASS, &generator.rand);
|
||||||
|
|
||||||
auto tmpl = mapGenOptions.getMapTemplate();
|
const auto * tmpl = mapGenOptions.getMapTemplate();
|
||||||
zones.clear();
|
zones.clear();
|
||||||
for(const auto & option : tmpl->getZones())
|
for(const auto & option : tmpl->getZones())
|
||||||
{
|
{
|
||||||
auto zone = std::make_shared<Zone>(*this, generator);
|
auto zone = std::make_shared<Zone>(*this, generator);
|
||||||
zone->setOptions(*option.second.get());
|
zone->setOptions(*option.second);
|
||||||
zones[zone->getId()] = zone;
|
zones[zone->getId()] = zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,10 +147,6 @@ void RmgMap::addModificators()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RmgMap::~RmgMap()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CMap & RmgMap::map() const
|
CMap & RmgMap::map() const
|
||||||
{
|
{
|
||||||
return *mapInstance;
|
return *mapInstance;
|
||||||
@ -289,7 +285,7 @@ ui32 RmgMap::getTotalZoneCount() const
|
|||||||
return zonesTotal;
|
return zonesTotal;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RmgMap::isAllowedSpell(SpellID sid) const
|
bool RmgMap::isAllowedSpell(const SpellID & sid) const
|
||||||
{
|
{
|
||||||
assert(sid >= 0);
|
assert(sid >= 0);
|
||||||
if (sid < mapInstance->allowedSpell.size())
|
if (sid < mapInstance->allowedSpell.size())
|
||||||
|
@ -28,15 +28,15 @@ public:
|
|||||||
CMap & map() const;
|
CMap & map() const;
|
||||||
|
|
||||||
RmgMap(const CMapGenOptions& mapGenOptions);
|
RmgMap(const CMapGenOptions& mapGenOptions);
|
||||||
~RmgMap();
|
~RmgMap() = default;
|
||||||
|
|
||||||
CMapEditManager* getEditManager() const;
|
CMapEditManager* getEditManager() const;
|
||||||
const CMapGenOptions& getMapGenOptions() const;
|
const CMapGenOptions& getMapGenOptions() const;
|
||||||
|
|
||||||
void foreach_neighbour(const int3 &pos, std::function<void(int3& pos)> foo);
|
void foreach_neighbour(const int3 & pos, const std::function<void(int3 & pos)> & foo) const;
|
||||||
void foreachDirectNeighbour(const int3 &pos, std::function<void(int3& pos)> foo);
|
void foreachDirectNeighbour(const int3 & pos, const std::function<void(int3 & pos)> & foo) const;
|
||||||
void foreachDiagonalNeighbour(const int3& pos, std::function<void(int3& pos)> foo);
|
void foreachDiagonalNeighbour(const int3 & pos, const std::function<void(int3 & pos)> & foo) const;
|
||||||
|
|
||||||
bool isBlocked(const int3 &tile) const;
|
bool isBlocked(const int3 &tile) const;
|
||||||
bool shouldBeBlocked(const int3 &tile) const;
|
bool shouldBeBlocked(const int3 &tile) const;
|
||||||
bool isPossible(const int3 &tile) const;
|
bool isPossible(const int3 &tile) const;
|
||||||
@ -65,9 +65,9 @@ public:
|
|||||||
ui32 getTotalZoneCount() const;
|
ui32 getTotalZoneCount() const;
|
||||||
void initTiles(CMapGenerator & generator);
|
void initTiles(CMapGenerator & generator);
|
||||||
void addModificators();
|
void addModificators();
|
||||||
|
|
||||||
bool isAllowedSpell(SpellID sid) const;
|
bool isAllowedSpell(const SpellID & sid) const;
|
||||||
|
|
||||||
void dump(bool zoneId) const;
|
void dump(bool zoneId) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -64,7 +64,7 @@ const rmg::Area & Object::Instance::getAccessibleArea() const
|
|||||||
{
|
{
|
||||||
auto neighbours = rmg::Area({getVisitablePosition()}).getBorderOutside();
|
auto neighbours = rmg::Area({getVisitablePosition()}).getBorderOutside();
|
||||||
rmg::Area visitable = rmg::Area(neighbours) - getBlockedArea();
|
rmg::Area visitable = rmg::Area(neighbours) - getBlockedArea();
|
||||||
for(auto & from : visitable.getTiles())
|
for(const auto & from : visitable.getTiles())
|
||||||
{
|
{
|
||||||
if(isVisitableFrom(from))
|
if(isVisitableFrom(from))
|
||||||
dAccessibleAreaCache.add(from);
|
dAccessibleAreaCache.add(from);
|
||||||
@ -166,10 +166,9 @@ Object::Object(CGObjectInstance & object)
|
|||||||
addInstance(object);
|
addInstance(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object::Object(const Object & object)
|
Object::Object(const Object & object): dStrength(object.dStrength)
|
||||||
{
|
{
|
||||||
dStrenght = object.dStrenght;
|
for(const auto & i : object.dInstances)
|
||||||
for(auto & i : object.dInstances)
|
|
||||||
addInstance(const_cast<CGObjectInstance &>(i.object()), i.getPosition());
|
addInstance(const_cast<CGObjectInstance &>(i.object()), i.getPosition());
|
||||||
setPosition(object.getPosition());
|
setPosition(object.getPosition());
|
||||||
}
|
}
|
||||||
@ -225,7 +224,7 @@ const int3 & Object::getPosition() const
|
|||||||
int3 Object::getVisitablePosition() const
|
int3 Object::getVisitablePosition() const
|
||||||
{
|
{
|
||||||
assert(!dInstances.empty());
|
assert(!dInstances.empty());
|
||||||
for(auto & instance : dInstances)
|
for(const auto & instance : dInstances)
|
||||||
if(!getArea().contains(instance.getVisitablePosition()))
|
if(!getArea().contains(instance.getVisitablePosition()))
|
||||||
return instance.getVisitablePosition();
|
return instance.getVisitablePosition();
|
||||||
|
|
||||||
@ -293,7 +292,7 @@ void Object::Instance::finalize(RmgMap & map)
|
|||||||
//If no specific template was defined for this object, select any matching
|
//If no specific template was defined for this object, select any matching
|
||||||
if (!dObject.appearance)
|
if (!dObject.appearance)
|
||||||
{
|
{
|
||||||
auto terrainType = map.map().getTile(getPosition(true)).terType;
|
const auto * terrainType = map.map().getTile(getPosition(true)).terType;
|
||||||
auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates(terrainType->getId());
|
auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates(terrainType->getId());
|
||||||
if (templates.empty())
|
if (templates.empty())
|
||||||
{
|
{
|
||||||
@ -307,14 +306,14 @@ void Object::Instance::finalize(RmgMap & map)
|
|||||||
|
|
||||||
if (dObject.isVisitable() && !map.isOnMap(dObject.visitablePos()))
|
if (dObject.isVisitable() && !map.isOnMap(dObject.visitablePos()))
|
||||||
throw rmgException(boost::to_string(boost::format("Visitable tile %s of object %d at %s is outside the map") % dObject.visitablePos().toString() % dObject.id % dObject.pos.toString()));
|
throw rmgException(boost::to_string(boost::format("Visitable tile %s of object %d at %s is outside the map") % dObject.visitablePos().toString() % dObject.id % dObject.pos.toString()));
|
||||||
|
|
||||||
for (auto & tile : dObject.getBlockedPos())
|
for(const auto & tile : dObject.getBlockedPos())
|
||||||
{
|
{
|
||||||
if(!map.isOnMap(tile))
|
if(!map.isOnMap(tile))
|
||||||
throw rmgException(boost::to_string(boost::format("Tile %s of object %d at %s is outside the map") % tile.toString() % dObject.id % dObject.pos.toString()));
|
throw rmgException(boost::to_string(boost::format("Tile %s of object %d at %s is outside the map") % tile.toString() % dObject.id % dObject.pos.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto & tile : getBlockedArea().getTilesVector())
|
for(const auto & tile : getBlockedArea().getTilesVector())
|
||||||
{
|
{
|
||||||
map.setOccupied(tile, ETileType::ETileType::USED);
|
map.setOccupied(tile, ETileType::ETileType::USED);
|
||||||
}
|
}
|
||||||
@ -326,10 +325,10 @@ void Object::finalize(RmgMap & map)
|
|||||||
{
|
{
|
||||||
if(dInstances.empty())
|
if(dInstances.empty())
|
||||||
throw rmgException("Cannot finalize object without instances");
|
throw rmgException("Cannot finalize object without instances");
|
||||||
|
|
||||||
for(auto iter = dInstances.begin(); iter != dInstances.end(); ++iter)
|
for(auto & dInstance : dInstances)
|
||||||
{
|
{
|
||||||
iter->finalize(map);
|
dInstance.finalize(map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ private:
|
|||||||
mutable Area dFullAreaCache;
|
mutable Area dFullAreaCache;
|
||||||
mutable Area dAccessibleAreaCache, dAccessibleAreaFullCache;
|
mutable Area dAccessibleAreaCache, dAccessibleAreaFullCache;
|
||||||
int3 dPosition;
|
int3 dPosition;
|
||||||
ui32 dStrenght;
|
ui32 dStrength;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ const std::function<float(const int3 &, const int3 &)> Path::DEFAULT_MOVEMENT_FU
|
|||||||
};
|
};
|
||||||
|
|
||||||
//A* priority queue
|
//A* priority queue
|
||||||
typedef std::pair<int3, float> TDistance;
|
using TDistance = std::pair<int3, float>;
|
||||||
struct NodeComparer
|
struct NodeComparer
|
||||||
{
|
{
|
||||||
bool operator()(const TDistance & lhs, const TDistance & rhs) const
|
bool operator()(const TDistance & lhs, const TDistance & rhs) const
|
||||||
@ -45,11 +45,6 @@ Path::Path(const Area & area, const int3 & src): dArea(&area)
|
|||||||
dPath.add(src);
|
dPath.add(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
Path::Path(const Path & path): dArea(path.dArea), dPath(path.dPath)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Path & Path::operator= (const Path & path)
|
Path & Path::operator= (const Path & path)
|
||||||
{
|
{
|
||||||
//do not modify area
|
//do not modify area
|
||||||
@ -154,18 +149,18 @@ Path Path::search(const Tileset & dst, bool straight, std::function<float(const
|
|||||||
|
|
||||||
Path Path::search(const int3 & dst, bool straight, std::function<float(const int3 &, const int3 &)> moveCostFunction) const
|
Path Path::search(const int3 & dst, bool straight, std::function<float(const int3 &, const int3 &)> moveCostFunction) const
|
||||||
{
|
{
|
||||||
return search(Tileset{dst}, straight, moveCostFunction);
|
return search(Tileset{dst}, straight, std::move(moveCostFunction));
|
||||||
}
|
}
|
||||||
|
|
||||||
Path Path::search(const Area & dst, bool straight, std::function<float(const int3 &, const int3 &)> moveCostFunction) const
|
Path Path::search(const Area & dst, bool straight, std::function<float(const int3 &, const int3 &)> moveCostFunction) const
|
||||||
{
|
{
|
||||||
return search(dst.getTiles(), straight, moveCostFunction);
|
return search(dst.getTiles(), straight, std::move(moveCostFunction));
|
||||||
}
|
}
|
||||||
|
|
||||||
Path Path::search(const Path & dst, bool straight, std::function<float(const int3 &, const int3 &)> moveCostFunction) const
|
Path Path::search(const Path & dst, bool straight, std::function<float(const int3 &, const int3 &)> moveCostFunction) const
|
||||||
{
|
{
|
||||||
assert(dst.dArea == dArea);
|
assert(dst.dArea == dArea);
|
||||||
return search(dst.dPath, straight, moveCostFunction);
|
return search(dst.dPath, straight, std::move(moveCostFunction));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Path::connect(const int3 & path)
|
void Path::connect(const int3 & path)
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
|
|
||||||
Path(const Area & area);
|
Path(const Area & area);
|
||||||
Path(const Area & area, const int3 & src);
|
Path(const Area & area, const int3 & src);
|
||||||
Path(const Path & path);
|
Path(const Path & path) = default;
|
||||||
Path & operator= (const Path & path);
|
Path & operator= (const Path & path);
|
||||||
bool valid() const;
|
bool valid() const;
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ void RoadPlacer::drawRoads(bool secondary)
|
|||||||
map.getEditManager()->getTerrainSelection().setSelection(roads.getTilesVector());
|
map.getEditManager()->getTerrainSelection().setSelection(roads.getTilesVector());
|
||||||
|
|
||||||
std::string roadName = (secondary ? generator.getConfig().secondaryRoadType : generator.getConfig().defaultRoadType);
|
std::string roadName = (secondary ? generator.getConfig().secondaryRoadType : generator.getConfig().defaultRoadType);
|
||||||
RoadId roadType(*VLC->modh->identifiers.getIdentifier(VLC->modh->scopeGame(), "road", roadName));
|
RoadId roadType(*VLC->modh->identifiers.getIdentifier(CModHandler::scopeGame(), "road", roadName));
|
||||||
map.getEditManager()->drawRoad(roadType, &generator.rand);
|
map.getEditManager()->drawRoad(roadType, &generator.rand);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ void RoadPlacer::connectRoads()
|
|||||||
noRoadNodes = true;
|
noRoadNodes = true;
|
||||||
if (auto* m = zone.getModificator<ObjectManager>())
|
if (auto* m = zone.getModificator<ObjectManager>())
|
||||||
{
|
{
|
||||||
for (auto object : m->getMines())
|
for(auto * object : m->getMines())
|
||||||
{
|
{
|
||||||
addRoadNode(object->visitablePos());
|
addRoadNode(object->visitablePos());
|
||||||
}
|
}
|
||||||
@ -113,8 +113,8 @@ void RoadPlacer::connectRoads()
|
|||||||
//take any tile from road nodes as destination zone for all other road nodes
|
//take any tile from road nodes as destination zone for all other road nodes
|
||||||
if(roads.empty())
|
if(roads.empty())
|
||||||
roads.add(*roadNodes.begin());
|
roads.add(*roadNodes.begin());
|
||||||
|
|
||||||
for(auto & node : roadNodes)
|
for(const auto & node : roadNodes)
|
||||||
{
|
{
|
||||||
createRoad(node);
|
createRoad(node);
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,10 @@
|
|||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
TileInfo::TileInfo():nearestObjectDistance(float(INT_MAX)), terrain()
|
TileInfo::TileInfo()
|
||||||
|
: nearestObjectDistance(static_cast<float>(std::numeric_limits<int>::max()))
|
||||||
|
, occupied(ETileType::POSSIBLE) //all tiles are initially possible to place objects or passages
|
||||||
{
|
{
|
||||||
occupied = ETileType::POSSIBLE; //all tiles are initially possible to place objects or passages
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float TileInfo::getNearestObjectDistance() const
|
float TileInfo::getNearestObjectDistance() const
|
||||||
|
@ -70,8 +70,8 @@ void TownPlacer::placeTowns(ObjectManager & manager)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto townFactory = VLC->objtypeh->getHandlerFor(Obj::TOWN, zone.getTownType());
|
auto townFactory = VLC->objtypeh->getHandlerFor(Obj::TOWN, zone.getTownType());
|
||||||
|
|
||||||
CGTownInstance * town = (CGTownInstance *) townFactory->create();
|
CGTownInstance * town = dynamic_cast<CGTownInstance *>(townFactory->create());
|
||||||
town->tempOwner = player;
|
town->tempOwner = player;
|
||||||
town->builtBuildings.insert(BuildingID::FORT);
|
town->builtBuildings.insert(BuildingID::FORT);
|
||||||
town->builtBuildings.insert(BuildingID::DEFAULT);
|
town->builtBuildings.insert(BuildingID::DEFAULT);
|
||||||
@ -126,9 +126,9 @@ void TownPlacer::placeTowns(ObjectManager & manager)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(zone.getTownTypes().size())
|
if(!zone.getTownTypes().empty())
|
||||||
zone.setTownType(*RandomGeneratorUtil::nextItem(zone.getTownTypes(), generator.rand));
|
zone.setTownType(*RandomGeneratorUtil::nextItem(zone.getTownTypes(), generator.rand));
|
||||||
else if(zone.getMonsterTypes().size())
|
else if(!zone.getMonsterTypes().empty())
|
||||||
zone.setTownType(*RandomGeneratorUtil::nextItem(zone.getMonsterTypes(), generator.rand)); //this happens in Clash of Dragons in treasure zones, where all towns are banned
|
zone.setTownType(*RandomGeneratorUtil::nextItem(zone.getMonsterTypes(), generator.rand)); //this happens in Clash of Dragons in treasure zones, where all towns are banned
|
||||||
else //just in any case
|
else //just in any case
|
||||||
zone.setTownType(getRandomTownType());
|
zone.setTownType(getRandomTownType());
|
||||||
@ -160,12 +160,12 @@ bool TownPlacer::placeMines(ObjectManager & manager)
|
|||||||
|
|
||||||
for(const auto & mineInfo : zone.getMinesInfo())
|
for(const auto & mineInfo : zone.getMinesInfo())
|
||||||
{
|
{
|
||||||
ERes res = (ERes)mineInfo.first;
|
ERes res = static_cast<ERes>(mineInfo.first);
|
||||||
for(int i = 0; i < mineInfo.second; ++i)
|
for(int i = 0; i < mineInfo.second; ++i)
|
||||||
{
|
{
|
||||||
auto mineHandler = VLC->objtypeh->getHandlerFor(Obj::MINE, res);
|
auto mineHandler = VLC->objtypeh->getHandlerFor(Obj::MINE, res);
|
||||||
auto & rmginfo = mineHandler->getRMGInfo();
|
const auto & rmginfo = mineHandler->getRMGInfo();
|
||||||
auto mine = (CGMine*)mineHandler->create();
|
auto * mine = dynamic_cast<CGMine *>(mineHandler->create());
|
||||||
mine->producedResource = res;
|
mine->producedResource = res;
|
||||||
mine->tempOwner = PlayerColor::NEUTRAL;
|
mine->tempOwner = PlayerColor::NEUTRAL;
|
||||||
mine->producedQuantity = mine->defaultResProduction();
|
mine->producedQuantity = mine->defaultResProduction();
|
||||||
@ -186,7 +186,7 @@ bool TownPlacer::placeMines(ObjectManager & manager)
|
|||||||
{
|
{
|
||||||
for(int rc = generator.rand.nextInt(1, extraRes); rc > 0; --rc)
|
for(int rc = generator.rand.nextInt(1, extraRes); rc > 0; --rc)
|
||||||
{
|
{
|
||||||
auto resourse = (CGResource*) VLC->objtypeh->getHandlerFor(Obj::RESOURCE, mine->producedResource)->create();
|
auto * resourse = dynamic_cast<CGResource *>(VLC->objtypeh->getHandlerFor(Obj::RESOURCE, mine->producedResource)->create());
|
||||||
resourse->amount = CGResource::RANDOM_AMOUNT;
|
resourse->amount = CGResource::RANDOM_AMOUNT;
|
||||||
manager.addNearbyObject(resourse, mine);
|
manager.addNearbyObject(resourse, mine);
|
||||||
}
|
}
|
||||||
@ -198,7 +198,7 @@ bool TownPlacer::placeMines(ObjectManager & manager)
|
|||||||
|
|
||||||
void TownPlacer::cleanupBoundaries(const rmg::Object & rmgObject)
|
void TownPlacer::cleanupBoundaries(const rmg::Object & rmgObject)
|
||||||
{
|
{
|
||||||
for(auto & t : rmgObject.getArea().getBorderOutside())
|
for(const auto & t : rmgObject.getArea().getBorderOutside())
|
||||||
{
|
{
|
||||||
if(map.isOnMap(t))
|
if(map.isOnMap(t))
|
||||||
{
|
{
|
||||||
@ -209,7 +209,7 @@ void TownPlacer::cleanupBoundaries(const rmg::Object & rmgObject)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TownPlacer::addNewTowns(int count, bool hasFort, PlayerColor player, ObjectManager & manager)
|
void TownPlacer::addNewTowns(int count, bool hasFort, const PlayerColor & player, ObjectManager & manager)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < count; i++)
|
for(int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
@ -219,7 +219,7 @@ void TownPlacer::addNewTowns(int count, bool hasFort, PlayerColor player, Object
|
|||||||
{
|
{
|
||||||
if(!zone.areTownsSameType())
|
if(!zone.areTownsSameType())
|
||||||
{
|
{
|
||||||
if (zone.getTownTypes().size())
|
if(!zone.getTownTypes().empty())
|
||||||
subType = *RandomGeneratorUtil::nextItem(zone.getTownTypes(), generator.rand);
|
subType = *RandomGeneratorUtil::nextItem(zone.getTownTypes(), generator.rand);
|
||||||
else
|
else
|
||||||
subType = *RandomGeneratorUtil::nextItem(zone.getDefaultTownTypes(), generator.rand); //it is possible to have zone with no towns allowed
|
subType = *RandomGeneratorUtil::nextItem(zone.getDefaultTownTypes(), generator.rand); //it is possible to have zone with no towns allowed
|
||||||
@ -227,7 +227,7 @@ void TownPlacer::addNewTowns(int count, bool hasFort, PlayerColor player, Object
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto townFactory = VLC->objtypeh->getHandlerFor(Obj::TOWN, subType);
|
auto townFactory = VLC->objtypeh->getHandlerFor(Obj::TOWN, subType);
|
||||||
auto town = (CGTownInstance *) townFactory->create();
|
auto * town = dynamic_cast<CGTownInstance *>(townFactory->create());
|
||||||
town->ID = Obj::TOWN;
|
town->ID = Obj::TOWN;
|
||||||
|
|
||||||
town->tempOwner = player;
|
town->tempOwner = player;
|
||||||
@ -257,7 +257,7 @@ void TownPlacer::addNewTowns(int count, bool hasFort, PlayerColor player, Object
|
|||||||
|
|
||||||
si32 TownPlacer::getRandomTownType(bool matchUndergroundType)
|
si32 TownPlacer::getRandomTownType(bool matchUndergroundType)
|
||||||
{
|
{
|
||||||
auto townTypesAllowed = (zone.getTownTypes().size() ? zone.getTownTypes() : zone.getDefaultTownTypes());
|
auto townTypesAllowed = (!zone.getTownTypes().empty() ? zone.getTownTypes() : zone.getDefaultTownTypes());
|
||||||
if(matchUndergroundType)
|
if(matchUndergroundType)
|
||||||
{
|
{
|
||||||
std::set<TFaction> townTypesVerify;
|
std::set<TFaction> townTypesVerify;
|
||||||
|
@ -27,7 +27,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void cleanupBoundaries(const rmg::Object & rmgObject);
|
void cleanupBoundaries(const rmg::Object & rmgObject);
|
||||||
void addNewTowns(int count, bool hasFort, PlayerColor player, ObjectManager & manager);
|
void addNewTowns(int count, bool hasFort, const PlayerColor & player, ObjectManager & manager);
|
||||||
si32 getRandomTownType(bool matchUndergroundType = false);
|
si32 getRandomTownType(bool matchUndergroundType = false);
|
||||||
void placeTowns(ObjectManager & manager);
|
void placeTowns(ObjectManager & manager);
|
||||||
bool placeMines(ObjectManager & manager);
|
bool placeMines(ObjectManager & manager);
|
||||||
|
@ -59,7 +59,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID);
|
auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID);
|
||||||
if(!handler->isStaticObject() && handler->getRMGInfo().value)
|
if(!handler->isStaticObject() && handler->getRMGInfo().value)
|
||||||
{
|
{
|
||||||
for(auto temp : handler->getTemplates())
|
for(const auto & temp : handler->getTemplates())
|
||||||
{
|
{
|
||||||
if(temp->canBePlacedAt(zone.getTerrainType()))
|
if(temp->canBePlacedAt(zone.getTerrainType()))
|
||||||
{
|
{
|
||||||
@ -99,9 +99,8 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
|
|
||||||
auto hid = *RandomGeneratorUtil::nextItem(possibleHeroes, generator.rand);
|
auto hid = *RandomGeneratorUtil::nextItem(possibleHeroes, generator.rand);
|
||||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::PRISON, 0);
|
auto factory = VLC->objtypeh->getHandlerFor(Obj::PRISON, 0);
|
||||||
auto obj = (CGHeroInstance *) factory->create();
|
auto * obj = dynamic_cast<CGHeroInstance *>(factory->create());
|
||||||
|
|
||||||
|
|
||||||
obj->subID = hid; //will be initialized later
|
obj->subID = hid; //will be initialized later
|
||||||
obj->exp = generator.getConfig().prisonExperience[i];
|
obj->exp = generator.getConfig().prisonExperience[i];
|
||||||
obj->setOwner(PlayerColor::NEUTRAL);
|
obj->setOwner(PlayerColor::NEUTRAL);
|
||||||
@ -119,8 +118,8 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//all following objects are unlimited
|
//all following objects are unlimited
|
||||||
oi.maxPerZone = std::numeric_limits<ui32>().max();
|
oi.maxPerZone = std::numeric_limits<ui32>::max();
|
||||||
|
|
||||||
std::vector<CCreature *> creatures; //native creatures for this zone
|
std::vector<CCreature *> creatures; //native creatures for this zone
|
||||||
for(auto cre : VLC->creh->objects)
|
for(auto cre : VLC->creh->objects)
|
||||||
{
|
{
|
||||||
@ -141,35 +140,35 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
{
|
{
|
||||||
//don't spawn original "neutral" dwellings that got replaced by Conflux dwellings in AB
|
//don't spawn original "neutral" dwellings that got replaced by Conflux dwellings in AB
|
||||||
static int elementalConfluxROE[] = {7, 13, 16, 47};
|
static int elementalConfluxROE[] = {7, 13, 16, 47};
|
||||||
for(int i = 0; i < 4; i++)
|
for(int & i : elementalConfluxROE)
|
||||||
vstd::erase_if_present(subObjects, elementalConfluxROE[i]);
|
vstd::erase_if_present(subObjects, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto secondaryID : subObjects)
|
for(auto secondaryID : subObjects)
|
||||||
{
|
{
|
||||||
auto dwellingHandler = dynamic_cast<const CDwellingInstanceConstructor *>(VLC->objtypeh->getHandlerFor(dwellingType, secondaryID).get());
|
const auto * dwellingHandler = dynamic_cast<const CDwellingInstanceConstructor *>(VLC->objtypeh->getHandlerFor(dwellingType, secondaryID).get());
|
||||||
auto creatures = dwellingHandler->getProducedCreatures();
|
auto creatures = dwellingHandler->getProducedCreatures();
|
||||||
if(creatures.empty())
|
if(creatures.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto cre = creatures.front();
|
const auto * cre = creatures.front();
|
||||||
if(cre->faction == zone.getTownType())
|
if(cre->faction == zone.getTownType())
|
||||||
{
|
{
|
||||||
float nativeZonesCount = static_cast<float>(map.getZoneCount(cre->faction));
|
auto nativeZonesCount = static_cast<float>(map.getZoneCount(cre->faction));
|
||||||
oi.value = static_cast<ui32>(cre->AIValue * cre->growth * (1 + (nativeZonesCount / map.getTotalZoneCount()) + (nativeZonesCount / 2)));
|
oi.value = static_cast<ui32>(cre->AIValue * cre->growth * (1 + (nativeZonesCount / map.getTotalZoneCount()) + (nativeZonesCount / 2)));
|
||||||
oi.probability = 40;
|
oi.probability = 40;
|
||||||
|
|
||||||
for(auto tmplate : dwellingHandler->getTemplates())
|
for(const auto & tmplate : dwellingHandler->getTemplates())
|
||||||
{
|
{
|
||||||
if(tmplate->canBePlacedAt(zone.getTerrainType()))
|
if(tmplate->canBePlacedAt(zone.getTerrainType()))
|
||||||
{
|
{
|
||||||
oi.generateObject = [tmplate, secondaryID, dwellingType]() -> CGObjectInstance *
|
oi.generateObject = [tmplate, secondaryID, dwellingType]() -> CGObjectInstance *
|
||||||
{
|
{
|
||||||
auto obj = VLC->objtypeh->getHandlerFor(dwellingType, secondaryID)->create(tmplate);
|
auto * obj = VLC->objtypeh->getHandlerFor(dwellingType, secondaryID)->create(tmplate);
|
||||||
obj->tempOwner = PlayerColor::NEUTRAL;
|
obj->tempOwner = PlayerColor::NEUTRAL;
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
oi.templ = tmplate;
|
oi.templ = tmplate;
|
||||||
possibleObjects.push_back(oi);
|
possibleObjects.push_back(oi);
|
||||||
}
|
}
|
||||||
@ -183,7 +182,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
oi.generateObject = [i, this]() -> CGObjectInstance *
|
oi.generateObject = [i, this]() -> CGObjectInstance *
|
||||||
{
|
{
|
||||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::SPELL_SCROLL, 0);
|
auto factory = VLC->objtypeh->getHandlerFor(Obj::SPELL_SCROLL, 0);
|
||||||
auto obj = (CGArtifact *) factory->create();
|
auto * obj = dynamic_cast<CGArtifact *>(factory->create());
|
||||||
std::vector<SpellID> out;
|
std::vector<SpellID> out;
|
||||||
|
|
||||||
for(auto spell : VLC->spellh->objects) //spellh size appears to be greater (?)
|
for(auto spell : VLC->spellh->objects) //spellh size appears to be greater (?)
|
||||||
@ -193,7 +192,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
out.push_back(spell->id);
|
out.push_back(spell->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto a = CArtifactInstance::createScroll(*RandomGeneratorUtil::nextItem(out, generator.rand));
|
auto * a = CArtifactInstance::createScroll(*RandomGeneratorUtil::nextItem(out, generator.rand));
|
||||||
obj->storedArtifact = a;
|
obj->storedArtifact = a;
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
@ -209,7 +208,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
oi.generateObject = [i]() -> CGObjectInstance *
|
oi.generateObject = [i]() -> CGObjectInstance *
|
||||||
{
|
{
|
||||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
|
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
|
||||||
auto obj = (CGPandoraBox *) factory->create();
|
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create());
|
||||||
obj->resources[Res::GOLD] = i * 5000;
|
obj->resources[Res::GOLD] = i * 5000;
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
@ -225,7 +224,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
oi.generateObject = [i]() -> CGObjectInstance *
|
oi.generateObject = [i]() -> CGObjectInstance *
|
||||||
{
|
{
|
||||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
|
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
|
||||||
auto obj = (CGPandoraBox *) factory->create();
|
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create());
|
||||||
obj->gainedExp = i * 5000;
|
obj->gainedExp = i * 5000;
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
@ -246,7 +245,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
int actualTier = creature->level > tierValues.size() ?
|
int actualTier = creature->level > tierValues.size() ?
|
||||||
tierValues.size() - 1 :
|
tierValues.size() - 1 :
|
||||||
creature->level - 1;
|
creature->level - 1;
|
||||||
float creaturesAmount = ((float)tierValues[actualTier]) / creature->AIValue;
|
float creaturesAmount = (static_cast<float>(tierValues[actualTier])) / creature->AIValue;
|
||||||
if(creaturesAmount <= 5)
|
if(creaturesAmount <= 5)
|
||||||
{
|
{
|
||||||
creaturesAmount = boost::math::round(creaturesAmount); //allow single monsters
|
creaturesAmount = boost::math::round(creaturesAmount); //allow single monsters
|
||||||
@ -267,8 +266,8 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
}
|
}
|
||||||
return static_cast<int>(creaturesAmount);
|
return static_cast<int>(creaturesAmount);
|
||||||
};
|
};
|
||||||
|
|
||||||
for(auto creature : creatures)
|
for(auto * creature : creatures)
|
||||||
{
|
{
|
||||||
int creaturesAmount = creatureToCount(creature);
|
int creaturesAmount = creatureToCount(creature);
|
||||||
if(!creaturesAmount)
|
if(!creaturesAmount)
|
||||||
@ -277,13 +276,13 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
oi.generateObject = [creature, creaturesAmount]() -> CGObjectInstance *
|
oi.generateObject = [creature, creaturesAmount]() -> CGObjectInstance *
|
||||||
{
|
{
|
||||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
|
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
|
||||||
auto obj = (CGPandoraBox *) factory->create();
|
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create());
|
||||||
auto stack = new CStackInstance(creature, creaturesAmount);
|
auto * stack = new CStackInstance(creature, creaturesAmount);
|
||||||
obj->creatures.putStack(SlotID(0), stack);
|
obj->creatures.putStack(SlotID(0), stack);
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
oi.setTemplate(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
oi.setTemplate(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
|
||||||
oi.value = static_cast<ui32>((2 * (creature->AIValue) * creaturesAmount * (1 + (float)(map.getZoneCount(creature->faction)) / map.getTotalZoneCount())) / 3);
|
oi.value = static_cast<ui32>((2 * (creature->AIValue) * creaturesAmount * (1 + static_cast<float>(map.getZoneCount(creature->faction)) / map.getTotalZoneCount())) / 3);
|
||||||
oi.probability = 3;
|
oi.probability = 3;
|
||||||
possibleObjects.push_back(oi);
|
possibleObjects.push_back(oi);
|
||||||
}
|
}
|
||||||
@ -294,8 +293,8 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
oi.generateObject = [i, this]() -> CGObjectInstance *
|
oi.generateObject = [i, this]() -> CGObjectInstance *
|
||||||
{
|
{
|
||||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
|
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
|
||||||
auto obj = (CGPandoraBox *) factory->create();
|
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create());
|
||||||
|
|
||||||
std::vector <CSpell *> spells;
|
std::vector <CSpell *> spells;
|
||||||
for(auto spell : VLC->spellh->objects)
|
for(auto spell : VLC->spellh->objects)
|
||||||
{
|
{
|
||||||
@ -304,7 +303,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
}
|
}
|
||||||
|
|
||||||
RandomGeneratorUtil::randomShuffle(spells, generator.rand);
|
RandomGeneratorUtil::randomShuffle(spells, generator.rand);
|
||||||
for(int j = 0; j < std::min(12, (int)spells.size()); j++)
|
for(int j = 0; j < std::min(12, static_cast<int>(spells.size())); j++)
|
||||||
{
|
{
|
||||||
obj->spells.push_back(spells[j]->id);
|
obj->spells.push_back(spells[j]->id);
|
||||||
}
|
}
|
||||||
@ -323,17 +322,17 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
oi.generateObject = [i, this]() -> CGObjectInstance *
|
oi.generateObject = [i, this]() -> CGObjectInstance *
|
||||||
{
|
{
|
||||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
|
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
|
||||||
auto obj = (CGPandoraBox *) factory->create();
|
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create());
|
||||||
|
|
||||||
std::vector <CSpell *> spells;
|
std::vector <CSpell *> spells;
|
||||||
for(auto spell : VLC->spellh->objects)
|
for(auto spell : VLC->spellh->objects)
|
||||||
{
|
{
|
||||||
if(map.isAllowedSpell(spell->id) && spell->school[(ESpellSchool)i])
|
if(map.isAllowedSpell(spell->id) && spell->school[static_cast<ESpellSchool>(i)])
|
||||||
spells.push_back(spell);
|
spells.push_back(spell);
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomGeneratorUtil::randomShuffle(spells, generator.rand);
|
RandomGeneratorUtil::randomShuffle(spells, generator.rand);
|
||||||
for(int j = 0; j < std::min(15, (int)spells.size()); j++)
|
for(int j = 0; j < std::min(15, static_cast<int>(spells.size())); j++)
|
||||||
{
|
{
|
||||||
obj->spells.push_back(spells[j]->id);
|
obj->spells.push_back(spells[j]->id);
|
||||||
}
|
}
|
||||||
@ -351,8 +350,8 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
oi.generateObject = [this]() -> CGObjectInstance *
|
oi.generateObject = [this]() -> CGObjectInstance *
|
||||||
{
|
{
|
||||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
|
auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
|
||||||
auto obj = (CGPandoraBox *) factory->create();
|
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create());
|
||||||
|
|
||||||
std::vector <CSpell *> spells;
|
std::vector <CSpell *> spells;
|
||||||
for(auto spell : VLC->spellh->objects)
|
for(auto spell : VLC->spellh->objects)
|
||||||
{
|
{
|
||||||
@ -361,7 +360,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
}
|
}
|
||||||
|
|
||||||
RandomGeneratorUtil::randomShuffle(spells, generator.rand);
|
RandomGeneratorUtil::randomShuffle(spells, generator.rand);
|
||||||
for(int j = 0; j < std::min(60, (int)spells.size()); j++)
|
for(int j = 0; j < std::min(60, static_cast<int>(spells.size())); j++)
|
||||||
{
|
{
|
||||||
obj->spells.push_back(spells[j]->id);
|
obj->spells.push_back(spells[j]->id);
|
||||||
}
|
}
|
||||||
@ -382,10 +381,10 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
const int questArtsRemaining = static_cast<int>(generator.getQuestArtsRemaning().size());
|
const int questArtsRemaining = static_cast<int>(generator.getQuestArtsRemaning().size());
|
||||||
|
|
||||||
//general issue is that not many artifact types are available for quests
|
//general issue is that not many artifact types are available for quests
|
||||||
|
|
||||||
if(questArtsRemaining >= genericSeerHuts + (int)creatures.size())
|
if(questArtsRemaining >= genericSeerHuts + static_cast<int>(creatures.size()))
|
||||||
{
|
{
|
||||||
seerHutsPerType = questArtsRemaining / (genericSeerHuts + (int)creatures.size());
|
seerHutsPerType = questArtsRemaining / (genericSeerHuts + static_cast<int>(creatures.size()));
|
||||||
}
|
}
|
||||||
else if(questArtsRemaining >= genericSeerHuts)
|
else if(questArtsRemaining >= genericSeerHuts)
|
||||||
{
|
{
|
||||||
@ -394,8 +393,8 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
oi.maxPerZone = seerHutsPerType;
|
oi.maxPerZone = seerHutsPerType;
|
||||||
|
|
||||||
RandomGeneratorUtil::randomShuffle(creatures, generator.rand);
|
RandomGeneratorUtil::randomShuffle(creatures, generator.rand);
|
||||||
|
|
||||||
auto generateArtInfo = [this](ArtifactID id) -> ObjectInfo
|
auto generateArtInfo = [this](const ArtifactID & id) -> ObjectInfo
|
||||||
{
|
{
|
||||||
ObjectInfo artInfo;
|
ObjectInfo artInfo;
|
||||||
artInfo.probability = std::numeric_limits<ui16>::max(); //99,9% to spawn that art in first treasure pile
|
artInfo.probability = std::numeric_limits<ui16>::max(); //99,9% to spawn that art in first treasure pile
|
||||||
@ -409,10 +408,10 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
};
|
};
|
||||||
return artInfo;
|
return artInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
for(int i = 0; i < std::min((int)creatures.size(), questArtsRemaining - genericSeerHuts); i++)
|
for(int i = 0; i < std::min(static_cast<int>(creatures.size()), questArtsRemaining - genericSeerHuts); i++)
|
||||||
{
|
{
|
||||||
auto creature = creatures[i];
|
auto * creature = creatures[i];
|
||||||
int creaturesAmount = creatureToCount(creature);
|
int creaturesAmount = creatureToCount(creature);
|
||||||
|
|
||||||
if(!creaturesAmount)
|
if(!creaturesAmount)
|
||||||
@ -423,7 +422,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
oi.generateObject = [creature, creaturesAmount, randomAppearance, this, generateArtInfo]() -> CGObjectInstance *
|
oi.generateObject = [creature, creaturesAmount, randomAppearance, this, generateArtInfo]() -> CGObjectInstance *
|
||||||
{
|
{
|
||||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance);
|
auto factory = VLC->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance);
|
||||||
auto obj = (CGSeerHut *) factory->create();
|
auto * obj = dynamic_cast<CGSeerHut *>(factory->create());
|
||||||
obj->rewardType = CGSeerHut::CREATURE;
|
obj->rewardType = CGSeerHut::CREATURE;
|
||||||
obj->rID = creature->idNumber;
|
obj->rID = creature->idNumber;
|
||||||
obj->rVal = creaturesAmount;
|
obj->rVal = creaturesAmount;
|
||||||
@ -442,7 +441,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
oi.setTemplate(Obj::SEER_HUT, randomAppearance, zone.getTerrainType());
|
oi.setTemplate(Obj::SEER_HUT, randomAppearance, zone.getTerrainType());
|
||||||
oi.value = static_cast<ui32>(((2 * (creature->AIValue) * creaturesAmount * (1 + (float)(map.getZoneCount(creature->faction)) / map.getTotalZoneCount())) - 4000) / 3);
|
oi.value = static_cast<ui32>(((2 * (creature->AIValue) * creaturesAmount * (1 + static_cast<float>(map.getZoneCount(creature->faction)) / map.getTotalZoneCount())) - 4000) / 3);
|
||||||
oi.probability = 3;
|
oi.probability = 3;
|
||||||
possibleObjects.push_back(oi);
|
possibleObjects.push_back(oi);
|
||||||
}
|
}
|
||||||
@ -459,8 +458,8 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
oi.generateObject = [i, randomAppearance, this, generateArtInfo]() -> CGObjectInstance *
|
oi.generateObject = [i, randomAppearance, this, generateArtInfo]() -> CGObjectInstance *
|
||||||
{
|
{
|
||||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance);
|
auto factory = VLC->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance);
|
||||||
auto obj = (CGSeerHut *) factory->create();
|
auto * obj = dynamic_cast<CGSeerHut *>(factory->create());
|
||||||
|
|
||||||
obj->rewardType = CGSeerHut::EXPERIENCE;
|
obj->rewardType = CGSeerHut::EXPERIENCE;
|
||||||
obj->rID = 0; //unitialized?
|
obj->rID = 0; //unitialized?
|
||||||
obj->rVal = generator.getConfig().questRewardValues[i];
|
obj->rVal = generator.getConfig().questRewardValues[i];
|
||||||
@ -483,7 +482,7 @@ void TreasurePlacer::addAllPossibleObjects()
|
|||||||
oi.generateObject = [i, randomAppearance, this, generateArtInfo]() -> CGObjectInstance *
|
oi.generateObject = [i, randomAppearance, this, generateArtInfo]() -> CGObjectInstance *
|
||||||
{
|
{
|
||||||
auto factory = VLC->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance);
|
auto factory = VLC->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance);
|
||||||
auto obj = (CGSeerHut *) factory->create();
|
auto * obj = dynamic_cast<CGSeerHut *>(factory->create());
|
||||||
obj->rewardType = CGSeerHut::RESOURCES;
|
obj->rewardType = CGSeerHut::RESOURCES;
|
||||||
obj->rID = Res::GOLD;
|
obj->rID = Res::GOLD;
|
||||||
obj->rVal = generator.getConfig().questRewardValues[i];
|
obj->rVal = generator.getConfig().questRewardValues[i];
|
||||||
@ -521,7 +520,7 @@ std::vector<ObjectInfo*> TreasurePlacer::prepareTreasurePile(const CTreasureInfo
|
|||||||
|
|
||||||
int currentValue = 0;
|
int currentValue = 0;
|
||||||
bool hasLargeObject = false;
|
bool hasLargeObject = false;
|
||||||
while(currentValue <= (int)desiredValue - 100) //no objects with value below 100 are available
|
while(currentValue <= static_cast<int>(desiredValue) - 100) //no objects with value below 100 are available
|
||||||
{
|
{
|
||||||
auto * oi = getRandomObject(desiredValue, currentValue, maxValue, !hasLargeObject);
|
auto * oi = getRandomObject(desiredValue, currentValue, maxValue, !hasLargeObject);
|
||||||
if(!oi) //fail
|
if(!oi) //fail
|
||||||
@ -550,7 +549,7 @@ std::vector<ObjectInfo*> TreasurePlacer::prepareTreasurePile(const CTreasureInfo
|
|||||||
rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*> & treasureInfos, bool densePlacement)
|
rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*> & treasureInfos, bool densePlacement)
|
||||||
{
|
{
|
||||||
rmg::Object rmgObject;
|
rmg::Object rmgObject;
|
||||||
for(auto & oi : treasureInfos)
|
for(const auto & oi : treasureInfos)
|
||||||
{
|
{
|
||||||
auto blockedArea = rmgObject.getArea();
|
auto blockedArea = rmgObject.getArea();
|
||||||
auto accessibleArea = rmgObject.getAccessibleArea();
|
auto accessibleArea = rmgObject.getAccessibleArea();
|
||||||
@ -574,7 +573,7 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
|
|||||||
if(densePlacement)
|
if(densePlacement)
|
||||||
{
|
{
|
||||||
int bestPositionsWeight = std::numeric_limits<int>::max();
|
int bestPositionsWeight = std::numeric_limits<int>::max();
|
||||||
for(auto & t : accessibleArea.getTilesVector())
|
for(const auto & t : accessibleArea.getTilesVector())
|
||||||
{
|
{
|
||||||
instance.setPosition(t);
|
instance.setPosition(t);
|
||||||
int w = rmgObject.getAccessibleArea().getTilesVector().size();
|
int w = rmgObject.getAccessibleArea().getTilesVector().size();
|
||||||
@ -640,7 +639,7 @@ ObjectInfo * TreasurePlacer::getRandomObject(ui32 desiredValue, ui32 currentValu
|
|||||||
if(oi.value >= minValue && oi.maxPerZone > 0)
|
if(oi.value >= minValue && oi.maxPerZone > 0)
|
||||||
{
|
{
|
||||||
total += oi.probability;
|
total += oi.probability;
|
||||||
thresholds.push_back(std::make_pair(total, &oi));
|
thresholds.emplace_back(total, &oi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -651,13 +650,13 @@ ObjectInfo * TreasurePlacer::getRandomObject(ui32 desiredValue, ui32 currentValu
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
int r = generator.rand.nextInt(1, total);
|
int r = generator.rand.nextInt(1, total);
|
||||||
|
auto sorter = [](const std::pair<ui32, ObjectInfo *> & rhs, const ui32 lhs) -> bool
|
||||||
|
{
|
||||||
|
return static_cast<int>(rhs.first) < lhs;
|
||||||
|
};
|
||||||
|
|
||||||
//binary search = fastest
|
//binary search = fastest
|
||||||
auto it = std::lower_bound(thresholds.begin(), thresholds.end(), r,
|
auto it = std::lower_bound(thresholds.begin(), thresholds.end(), r, sorter);
|
||||||
[](const std::pair<ui32, ObjectInfo*> &rhs, const int lhs)->bool
|
|
||||||
{
|
|
||||||
return (int)rhs.first < lhs;
|
|
||||||
});
|
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -746,8 +745,8 @@ void TreasurePlacer::createTreasures(ObjectManager & manager)
|
|||||||
auto ti = map.getTile(tile);
|
auto ti = map.getTile(tile);
|
||||||
if(ti.getNearestObjectDistance() < minDistance)
|
if(ti.getNearestObjectDistance() < minDistance)
|
||||||
return -1.f;
|
return -1.f;
|
||||||
|
|
||||||
for(auto & t : rmgObject.getArea().getTilesVector())
|
for(const auto & t : rmgObject.getArea().getTilesVector())
|
||||||
{
|
{
|
||||||
if(map.getTile(t).getNearestObjectDistance() < minDistance)
|
if(map.getTile(t).getNearestObjectDistance() < minDistance)
|
||||||
return -1.f;
|
return -1.f;
|
||||||
@ -805,13 +804,6 @@ char TreasurePlacer::dump(const int3 & t)
|
|||||||
return Modificator::dump(t);
|
return Modificator::dump(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ObjectInfo::ObjectInfo()
|
|
||||||
: templ(), value(0), probability(0), maxPerZone(1)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ObjectInfo::setTemplate(si32 type, si32 subtype, TerrainId terrainType)
|
void ObjectInfo::setTemplate(si32 type, si32 subtype, TerrainId terrainType)
|
||||||
{
|
{
|
||||||
auto templHandler = VLC->objtypeh->getHandlerFor(type, subtype);
|
auto templHandler = VLC->objtypeh->getHandlerFor(type, subtype);
|
||||||
|
@ -24,14 +24,12 @@ struct ObjectInfo
|
|||||||
std::shared_ptr<const ObjectTemplate> templ;
|
std::shared_ptr<const ObjectTemplate> templ;
|
||||||
ui32 value = 0;
|
ui32 value = 0;
|
||||||
ui16 probability = 0;
|
ui16 probability = 0;
|
||||||
ui32 maxPerZone = -1;
|
ui32 maxPerZone = 1;
|
||||||
//ui32 maxPerMap; //unused
|
//ui32 maxPerMap; //unused
|
||||||
std::function<CGObjectInstance *()> generateObject;
|
std::function<CGObjectInstance *()> generateObject;
|
||||||
|
|
||||||
void setTemplate(si32 type, si32 subtype, TerrainId terrain);
|
void setTemplate(si32 type, si32 subtype, TerrainId terrain);
|
||||||
|
|
||||||
ObjectInfo();
|
|
||||||
|
|
||||||
bool operator==(const ObjectInfo& oi) const { return (templ == oi.templ); }
|
bool operator==(const ObjectInfo& oi) const { return (templ == oi.templ); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ void WaterAdopter::createWater(EWaterContent::EWaterContent waterContent)
|
|||||||
rmg::Area noWaterSlice;
|
rmg::Area noWaterSlice;
|
||||||
for(int i = 1; i < reverseDistanceMap.size(); ++i)
|
for(int i = 1; i < reverseDistanceMap.size(); ++i)
|
||||||
{
|
{
|
||||||
for(auto & t : reverseDistanceMap[i])
|
for(const auto & t : reverseDistanceMap[i])
|
||||||
{
|
{
|
||||||
if(noWaterArea.distanceSqr(t) < 3)
|
if(noWaterArea.distanceSqr(t) < 3)
|
||||||
noWaterSlice.add(t);
|
noWaterSlice.add(t);
|
||||||
@ -140,7 +140,7 @@ void WaterAdopter::createWater(EWaterContent::EWaterContent waterContent)
|
|||||||
rmg::Area waterAdd;
|
rmg::Area waterAdd;
|
||||||
for(int coastId = 1; coastId <= coastIdMax; ++coastId)
|
for(int coastId = 1; coastId <= coastIdMax; ++coastId)
|
||||||
{
|
{
|
||||||
for(auto& tile : reverseDistanceMap[coastId])
|
for(const auto & tile : reverseDistanceMap[coastId])
|
||||||
{
|
{
|
||||||
//collect neighbout water tiles
|
//collect neighbout water tiles
|
||||||
auto collectionLambda = [this](const int3 & t, std::set<int3> & outCollection)
|
auto collectionLambda = [this](const int3 & t, std::set<int3> & outCollection)
|
||||||
@ -151,7 +151,8 @@ void WaterAdopter::createWater(EWaterContent::EWaterContent waterContent)
|
|||||||
outCollection.insert(t);
|
outCollection.insert(t);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
std::set<int3> waterCoastDirect, waterCoastDiag;
|
std::set<int3> waterCoastDirect;
|
||||||
|
std::set<int3> waterCoastDiag;
|
||||||
map.foreachDirectNeighbour(tile, std::bind(collectionLambda, std::placeholders::_1, std::ref(waterCoastDirect)));
|
map.foreachDirectNeighbour(tile, std::bind(collectionLambda, std::placeholders::_1, std::ref(waterCoastDirect)));
|
||||||
map.foreachDiagonalNeighbour(tile, std::bind(collectionLambda, std::placeholders::_1, std::ref(waterCoastDiag)));
|
map.foreachDiagonalNeighbour(tile, std::bind(collectionLambda, std::placeholders::_1, std::ref(waterCoastDiag)));
|
||||||
int waterCoastDirectNum = waterCoastDirect.size();
|
int waterCoastDirectNum = waterCoastDirect.size();
|
||||||
@ -170,10 +171,11 @@ void WaterAdopter::createWater(EWaterContent::EWaterContent waterContent)
|
|||||||
}
|
}
|
||||||
if(waterCoastDirectNum == 2 && waterCoastDiagNum >= 2)
|
if(waterCoastDirectNum == 2 && waterCoastDiagNum >= 2)
|
||||||
{
|
{
|
||||||
int3 diagSum, dirSum;
|
int3 diagSum;
|
||||||
for(auto & i : waterCoastDiag)
|
int3 dirSum;
|
||||||
|
for(const auto & i : waterCoastDiag)
|
||||||
diagSum += i - tile;
|
diagSum += i - tile;
|
||||||
for(auto & i : waterCoastDirect)
|
for(const auto & i : waterCoastDirect)
|
||||||
dirSum += i - tile;
|
dirSum += i - tile;
|
||||||
if(diagSum == int3() || dirSum == int3())
|
if(diagSum == int3() || dirSum == int3())
|
||||||
{
|
{
|
||||||
@ -192,7 +194,7 @@ void WaterAdopter::createWater(EWaterContent::EWaterContent waterContent)
|
|||||||
waterArea.unite(waterAdd);
|
waterArea.unite(waterAdd);
|
||||||
|
|
||||||
//filtering tiny "lakes"
|
//filtering tiny "lakes"
|
||||||
for(auto& tile : reverseDistanceMap[0]) //now it's only coast-water tiles
|
for(const auto & tile : reverseDistanceMap[0]) //now it's only coast-water tiles
|
||||||
{
|
{
|
||||||
if(!waterArea.contains(tile)) //for ground tiles
|
if(!waterArea.contains(tile)) //for ground tiles
|
||||||
continue;
|
continue;
|
||||||
|
@ -32,7 +32,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
void WaterProxy::process()
|
void WaterProxy::process()
|
||||||
{
|
{
|
||||||
for(auto & t : zone.area().getTilesVector())
|
for(const auto & t : zone.area().getTilesVector())
|
||||||
{
|
{
|
||||||
map.setZoneID(t, zone.getId());
|
map.setZoneID(t, zone.getId());
|
||||||
map.setOccupied(t, ETileType::POSSIBLE);
|
map.setOccupied(t, ETileType::POSSIBLE);
|
||||||
@ -41,19 +41,19 @@ void WaterProxy::process()
|
|||||||
paintZoneTerrain(zone, generator.rand, map, zone.getTerrainType());
|
paintZoneTerrain(zone, generator.rand, map, zone.getTerrainType());
|
||||||
|
|
||||||
//check terrain type
|
//check terrain type
|
||||||
for(auto & t : zone.area().getTilesVector())
|
for(const auto & t : zone.area().getTilesVector())
|
||||||
{
|
{
|
||||||
MAYBE_UNUSED(t);
|
MAYBE_UNUSED(t);
|
||||||
assert(map.isOnMap(t));
|
assert(map.isOnMap(t));
|
||||||
assert(map.map().getTile(t).terType->getId() == zone.getTerrainType());
|
assert(map.map().getTile(t).terType->getId() == zone.getTerrainType());
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto z : map.getZones())
|
for(const auto & z : map.getZones())
|
||||||
{
|
{
|
||||||
if(z.second->getId() == zone.getId())
|
if(z.second->getId() == zone.getId())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for(auto & t : z.second->area().getTilesVector())
|
for(const auto & t : z.second->area().getTilesVector())
|
||||||
{
|
{
|
||||||
if(map.map().getTile(t).terType->getId() == zone.getTerrainType())
|
if(map.map().getTile(t).terType->getId() == zone.getTerrainType())
|
||||||
{
|
{
|
||||||
@ -97,15 +97,15 @@ const std::vector<WaterProxy::Lake> & WaterProxy::getLakes() const
|
|||||||
void WaterProxy::collectLakes()
|
void WaterProxy::collectLakes()
|
||||||
{
|
{
|
||||||
int lakeId = 0;
|
int lakeId = 0;
|
||||||
for(auto lake : connectedAreas(zone.getArea(), true))
|
for(const auto & lake : connectedAreas(zone.getArea(), true))
|
||||||
{
|
{
|
||||||
lakes.push_back(Lake{});
|
lakes.push_back(Lake{});
|
||||||
lakes.back().area = lake;
|
lakes.back().area = lake;
|
||||||
lakes.back().distanceMap = lake.computeDistanceMap(lakes.back().reverseDistanceMap);
|
lakes.back().distanceMap = lake.computeDistanceMap(lakes.back().reverseDistanceMap);
|
||||||
for(auto & t : lake.getBorderOutside())
|
for(const auto & t : lake.getBorderOutside())
|
||||||
if(map.isOnMap(t))
|
if(map.isOnMap(t))
|
||||||
lakes.back().neighbourZones[map.getZoneID(t)].add(t);
|
lakes.back().neighbourZones[map.getZoneID(t)].add(t);
|
||||||
for(auto & t : lake.getTiles())
|
for(const auto & t : lake.getTiles())
|
||||||
lakeMap[t] = lakeId;
|
lakeMap[t] = lakeId;
|
||||||
|
|
||||||
//each lake must have at least one free tile
|
//each lake must have at least one free tile
|
||||||
@ -134,7 +134,7 @@ RouteInfo WaterProxy::waterRoute(Zone & dst)
|
|||||||
{
|
{
|
||||||
if(!lake.keepConnections.count(dst.getId()))
|
if(!lake.keepConnections.count(dst.getId()))
|
||||||
{
|
{
|
||||||
for(auto & ct : lake.neighbourZones[dst.getId()].getTiles())
|
for(const auto & ct : lake.neighbourZones[dst.getId()].getTiles())
|
||||||
{
|
{
|
||||||
if(map.isPossible(ct))
|
if(map.isPossible(ct))
|
||||||
map.setOccupied(ct, ETileType::BLOCKED);
|
map.setOccupied(ct, ETileType::BLOCKED);
|
||||||
@ -204,8 +204,8 @@ bool WaterProxy::placeBoat(Zone & land, const Lake & lake, RouteInfo & info)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto subObjects = VLC->objtypeh->knownSubObjects(Obj::BOAT);
|
auto subObjects = VLC->objtypeh->knownSubObjects(Obj::BOAT);
|
||||||
auto* boat = (CGBoat*)VLC->objtypeh->getHandlerFor(Obj::BOAT, *RandomGeneratorUtil::nextItem(subObjects, generator.rand))->create();
|
auto * boat = dynamic_cast<CGBoat *>(VLC->objtypeh->getHandlerFor(Obj::BOAT, *RandomGeneratorUtil::nextItem(subObjects, generator.rand))->create());
|
||||||
|
|
||||||
rmg::Object rmgObject(*boat);
|
rmg::Object rmgObject(*boat);
|
||||||
rmgObject.setTemplate(zone.getTerrainType());
|
rmgObject.setTemplate(zone.getTerrainType());
|
||||||
|
|
||||||
@ -263,7 +263,7 @@ bool WaterProxy::placeShipyard(Zone & land, const Lake & lake, si32 guard, Route
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
int subtype = chooseRandomAppearance(generator.rand, Obj::SHIPYARD, land.getTerrainType());
|
int subtype = chooseRandomAppearance(generator.rand, Obj::SHIPYARD, land.getTerrainType());
|
||||||
auto shipyard = (CGShipyard*) VLC->objtypeh->getHandlerFor(Obj::SHIPYARD, subtype)->create();
|
auto * shipyard = dynamic_cast<CGShipyard *>(VLC->objtypeh->getHandlerFor(Obj::SHIPYARD, subtype)->create());
|
||||||
shipyard->tempOwner = PlayerColor::NEUTRAL;
|
shipyard->tempOwner = PlayerColor::NEUTRAL;
|
||||||
|
|
||||||
rmg::Object rmgObject(*shipyard);
|
rmg::Object rmgObject(*shipyard);
|
||||||
@ -337,7 +337,7 @@ bool WaterProxy::placeShipyard(Zone & land, const Lake & lake, si32 guard, Route
|
|||||||
manager->placeObject(rmgObject, guarded, true);
|
manager->placeObject(rmgObject, guarded, true);
|
||||||
|
|
||||||
zone.areaPossible().subtract(shipyardOutToBlock);
|
zone.areaPossible().subtract(shipyardOutToBlock);
|
||||||
for(auto & i : shipyardOutToBlock.getTilesVector())
|
for(const auto & i : shipyardOutToBlock.getTilesVector())
|
||||||
if(map.isOnMap(i) && map.isPossible(i))
|
if(map.isOnMap(i) && map.isPossible(i))
|
||||||
map.setOccupied(i, ETileType::BLOCKED);
|
map.setOccupied(i, ETileType::BLOCKED);
|
||||||
|
|
||||||
@ -354,7 +354,7 @@ char WaterProxy::dump(const int3 & t)
|
|||||||
return '?';
|
return '?';
|
||||||
|
|
||||||
Lake & lake = lakes[lakeMap.at(t)];
|
Lake & lake = lakes[lakeMap.at(t)];
|
||||||
for(auto i : lake.neighbourZones)
|
for(const auto & i : lake.neighbourZones)
|
||||||
{
|
{
|
||||||
if(i.second.contains(t))
|
if(i.second.contains(t))
|
||||||
return lake.keepConnections.count(i.first) ? std::to_string(i.first)[0] : '=';
|
return lake.keepConnections.count(i.first) ? std::to_string(i.first)[0] : '=';
|
||||||
|
@ -46,7 +46,7 @@ void WaterRoutes::process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//prohibit to place objects on sealed off lakes
|
//prohibit to place objects on sealed off lakes
|
||||||
for(auto & lake : wproxy->getLakes())
|
for(const auto & lake : wproxy->getLakes())
|
||||||
{
|
{
|
||||||
if((lake.area * zone.freePaths()).getTilesVector().size() == 1)
|
if((lake.area * zone.freePaths()).getTilesVector().size() == 1)
|
||||||
{
|
{
|
||||||
@ -56,7 +56,7 @@ void WaterRoutes::process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//prohibit to place objects on the borders
|
//prohibit to place objects on the borders
|
||||||
for(auto & t : zone.area().getBorder())
|
for(const auto & t : zone.area().getBorder())
|
||||||
{
|
{
|
||||||
if(zone.areaPossible().contains(t))
|
if(zone.areaPossible().contains(t))
|
||||||
{
|
{
|
||||||
|
@ -26,11 +26,10 @@ std::function<bool(const int3 &)> AREA_NO_FILTER = [](const int3 & t)
|
|||||||
};
|
};
|
||||||
|
|
||||||
Zone::Zone(RmgMap & map, CMapGenerator & generator)
|
Zone::Zone(RmgMap & map, CMapGenerator & generator)
|
||||||
: ZoneOptions(),
|
: townType(ETownType::NEUTRAL)
|
||||||
townType(ETownType::NEUTRAL),
|
, terrainType(ETerrainId::GRASS)
|
||||||
terrainType(ETerrainId::GRASS),
|
, map(map)
|
||||||
map(map),
|
, generator(generator)
|
||||||
generator(generator)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -144,7 +143,7 @@ void Zone::setTerrainType(TerrainId terrain)
|
|||||||
terrainType = terrain;
|
terrainType = terrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
rmg::Path Zone::searchPath(const rmg::Area & src, bool onlyStraight, std::function<bool(const int3 &)> areafilter) const
|
rmg::Path Zone::searchPath(const rmg::Area & src, bool onlyStraight, const std::function<bool(const int3 &)> & areafilter) const
|
||||||
///connect current tile to any other free tile within zone
|
///connect current tile to any other free tile within zone
|
||||||
{
|
{
|
||||||
auto movementCost = [this](const int3 & s, const int3 & d)
|
auto movementCost = [this](const int3 & s, const int3 & d)
|
||||||
@ -157,7 +156,8 @@ rmg::Path Zone::searchPath(const rmg::Area & src, bool onlyStraight, std::functi
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto area = (dAreaPossible + dAreaFree).getSubarea(areafilter);
|
auto area = (dAreaPossible + dAreaFree).getSubarea(areafilter);
|
||||||
rmg::Path freePath(area), resultPath(area);
|
rmg::Path freePath(area);
|
||||||
|
rmg::Path resultPath(area);
|
||||||
freePath.connect(dAreaFree);
|
freePath.connect(dAreaFree);
|
||||||
|
|
||||||
//connect to all pieces
|
//connect to all pieces
|
||||||
@ -175,7 +175,7 @@ rmg::Path Zone::searchPath(const rmg::Area & src, bool onlyStraight, std::functi
|
|||||||
return resultPath;
|
return resultPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
rmg::Path Zone::searchPath(const int3 & src, bool onlyStraight, std::function<bool(const int3 &)> areafilter) const
|
rmg::Path Zone::searchPath(const int3 & src, bool onlyStraight, const std::function<bool(const int3 &)> & areafilter) const
|
||||||
///connect current tile to any other free tile within zone
|
///connect current tile to any other free tile within zone
|
||||||
{
|
{
|
||||||
return searchPath(rmg::Area({src}), onlyStraight, areafilter);
|
return searchPath(rmg::Area({src}), onlyStraight, areafilter);
|
||||||
@ -186,7 +186,7 @@ void Zone::connectPath(const rmg::Path & path)
|
|||||||
{
|
{
|
||||||
dAreaPossible.subtract(path.getPathArea());
|
dAreaPossible.subtract(path.getPathArea());
|
||||||
dAreaFree.unite(path.getPathArea());
|
dAreaFree.unite(path.getPathArea());
|
||||||
for(auto & t : path.getPathArea().getTilesVector())
|
for(const auto & t : path.getPathArea().getTilesVector())
|
||||||
map.setOccupied(t, ETileType::FREE);
|
map.setOccupied(t, ETileType::FREE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,8 +209,8 @@ void Zone::fractalize()
|
|||||||
RandomGeneratorUtil::randomShuffle(tilesToMakePath, generator.rand);
|
RandomGeneratorUtil::randomShuffle(tilesToMakePath, generator.rand);
|
||||||
|
|
||||||
int3 nodeFound(-1, -1, -1);
|
int3 nodeFound(-1, -1, -1);
|
||||||
|
|
||||||
for(auto tileToMakePath : tilesToMakePath)
|
for(const auto & tileToMakePath : tilesToMakePath)
|
||||||
{
|
{
|
||||||
//find closest free tile
|
//find closest free tile
|
||||||
int3 closestTile = clearedTiles.nearest(tileToMakePath);
|
int3 closestTile = clearedTiles.nearest(tileToMakePath);
|
||||||
@ -247,14 +247,14 @@ void Zone::fractalize()
|
|||||||
{
|
{
|
||||||
dAreaPossible.subtract(area);
|
dAreaPossible.subtract(area);
|
||||||
dAreaFree.subtract(area);
|
dAreaFree.subtract(area);
|
||||||
for(auto & t : area.getTiles())
|
for(const auto & t : area.getTiles())
|
||||||
map.setOccupied(t, ETileType::BLOCKED);
|
map.setOccupied(t, ETileType::BLOCKED);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dAreaPossible.subtract(res.getPathArea());
|
dAreaPossible.subtract(res.getPathArea());
|
||||||
dAreaFree.unite(res.getPathArea());
|
dAreaFree.unite(res.getPathArea());
|
||||||
for(auto & t : res.getPathArea().getTiles())
|
for(const auto & t : res.getPathArea().getTiles())
|
||||||
map.setOccupied(t, ETileType::FREE);
|
map.setOccupied(t, ETileType::FREE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,12 +263,12 @@ void Zone::fractalize()
|
|||||||
float blockDistance = minDistance * 0.25f;
|
float blockDistance = minDistance * 0.25f;
|
||||||
auto areaToBlock = dArea.getSubarea([this, blockDistance](const int3 & t)
|
auto areaToBlock = dArea.getSubarea([this, blockDistance](const int3 & t)
|
||||||
{
|
{
|
||||||
float distance = static_cast<float>(dAreaFree.distanceSqr(t));
|
auto distance = static_cast<float>(dAreaFree.distanceSqr(t));
|
||||||
return distance > blockDistance;
|
return distance > blockDistance;
|
||||||
});
|
});
|
||||||
dAreaPossible.subtract(areaToBlock);
|
dAreaPossible.subtract(areaToBlock);
|
||||||
dAreaFree.subtract(areaToBlock);
|
dAreaFree.subtract(areaToBlock);
|
||||||
for(auto & t : areaToBlock.getTiles())
|
for(const auto & t : areaToBlock.getTiles())
|
||||||
map.setOccupied(t, ETileType::BLOCKED);
|
map.setOccupied(t, ETileType::BLOCKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,9 +403,4 @@ char Modificator::dump(const int3 & t)
|
|||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
Modificator::~Modificator()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
@ -48,8 +48,8 @@ public:
|
|||||||
virtual void process() = 0;
|
virtual void process() = 0;
|
||||||
virtual void init() {/*override to add dependencies*/}
|
virtual void init() {/*override to add dependencies*/}
|
||||||
virtual char dump(const int3 &);
|
virtual char dump(const int3 &);
|
||||||
virtual ~Modificator();
|
virtual ~Modificator() = default;
|
||||||
|
|
||||||
void setName(const std::string & n);
|
void setName(const std::string & n);
|
||||||
const std::string & getName() const;
|
const std::string & getName() const;
|
||||||
|
|
||||||
@ -104,9 +104,9 @@ public:
|
|||||||
void setTerrainType(TerrainId terrain);
|
void setTerrainType(TerrainId terrain);
|
||||||
|
|
||||||
void connectPath(const rmg::Path & path);
|
void connectPath(const rmg::Path & path);
|
||||||
rmg::Path searchPath(const rmg::Area & src, bool onlyStraight, std::function<bool(const int3 &)> areafilter = AREA_NO_FILTER) const;
|
rmg::Path searchPath(const rmg::Area & src, bool onlyStraight, const std::function<bool(const int3 &)> & areafilter = AREA_NO_FILTER) const;
|
||||||
rmg::Path searchPath(const int3 & src, bool onlyStraight, std::function<bool(const int3 &)> areafilter = AREA_NO_FILTER) const;
|
rmg::Path searchPath(const int3 & src, bool onlyStraight, const std::function<bool(const int3 &)> & areafilter = AREA_NO_FILTER) const;
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T* getModificator()
|
T* getModificator()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user