1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-22 22:13:35 +02:00

vcmi: modernize lib/rmg

This commit is contained in:
Konstantin 2023-02-11 19:05:02 +03:00
parent c5dd8b17d7
commit 7bfb37df4d
34 changed files with 322 additions and 386 deletions

View File

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

View File

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

View File

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

View File

@ -65,7 +65,7 @@ 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();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,8 +257,8 @@ 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;

View File

@ -77,7 +77,7 @@ void createBorder(RmgMap & gen, Zone & zone)
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))
{ {

View File

@ -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)));
} }
} }
@ -83,7 +83,7 @@ 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);
@ -160,7 +160,7 @@ int3 ObjectManager::findPlaceForObject(const rmg::Area & searchArea, rmg::Object
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;
@ -179,7 +179,7 @@ rmg::Path ObjectManager::placeAndConnectObject(const rmg::Area & searchArea, rmg
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;
@ -449,9 +449,9 @@ 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;

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
@ -42,7 +42,7 @@ namespace rmg
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;

View File

@ -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)
{ {
@ -86,12 +86,12 @@ void RmgMap::initTiles(CMapGenerator & generator)
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())

View File

@ -28,14 +28,14 @@ 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;
@ -66,7 +66,7 @@ public:
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;

View File

@ -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())
{ {
@ -308,13 +307,13 @@ 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);
} }
@ -327,9 +326,9 @@ 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);
} }
} }

View File

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

View File

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

View File

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

View File

@ -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());
} }
@ -114,7 +114,7 @@ void RoadPlacer::connectRoads()
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);
} }

View File

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

View File

@ -71,7 +71,7 @@ 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;

View File

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

View File

@ -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,8 +99,7 @@ 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];
@ -119,7 +118,7 @@ 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,31 +140,31 @@ 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;
}; };
@ -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
@ -268,7 +267,7 @@ 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,7 +293,7 @@ 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,7 +350,7 @@ 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);
} }
@ -383,9 +382,9 @@ void TreasurePlacer::addAllPossibleObjects()
//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)
{ {
@ -395,7 +394,7 @@ void TreasurePlacer::addAllPossibleObjects()
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
@ -410,9 +409,9 @@ 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,7 +458,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::EXPERIENCE; obj->rewardType = CGSeerHut::EXPERIENCE;
obj->rID = 0; //unitialized? obj->rID = 0; //unitialized?
@ -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;
} }
} }
@ -747,7 +746,7 @@ void TreasurePlacer::createTreasures(ObjectManager & manager)
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);

View File

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

View File

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

View File

@ -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,7 +204,7 @@ 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] : '=';

View File

@ -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))
{ {

View File

@ -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);
} }
@ -210,7 +210,7 @@ void Zone::fractalize()
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

View File

@ -48,7 +48,7 @@ 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,8 +104,8 @@ 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()