|
@@ -102,7 +102,24 @@ void ZoneOptions::CTownInfo::serializeJson(JsonSerializeFormat & handler)
|
|
|
handler.serializeInt("castles", castleCount, 0);
|
|
|
handler.serializeInt("townDensity", townDensity, 0);
|
|
|
handler.serializeInt("castleDensity", castleDensity, 0);
|
|
|
- handler.serializeInt("sourceZone", sourceZone, NO_ZONE);
|
|
|
+ handler.serializeInt("townTypesLikeZone", townTypesLikeZone, NO_ZONE);
|
|
|
+ handler.serializeInt("townTypesNotLikeZone", townTypesNotLikeZone, NO_ZONE);
|
|
|
+ handler.serializeInt("townTypesRelatedToZoneTerrain", townTypesRelatedToZoneTerrain, NO_ZONE);
|
|
|
+}
|
|
|
+
|
|
|
+ZoneOptions::CTownHints::CTownHints()
|
|
|
+ : likeZone(NO_ZONE),
|
|
|
+ notLikeZone(NO_ZONE),
|
|
|
+ relatedToZoneTerrain(NO_ZONE)
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void ZoneOptions::CTownHints::serializeJson(JsonSerializeFormat & handler)
|
|
|
+{
|
|
|
+ handler.serializeInt("likeZone", likeZone, NO_ZONE);
|
|
|
+ handler.serializeInt("notLikeZone", notLikeZone, NO_ZONE);
|
|
|
+ handler.serializeInt("relatedToZoneTerrain", relatedToZoneTerrain, NO_ZONE);
|
|
|
}
|
|
|
|
|
|
ZoneOptions::ZoneOptions():
|
|
@@ -114,6 +131,7 @@ ZoneOptions::ZoneOptions():
|
|
|
matchTerrainToTown(true),
|
|
|
townsAreSameType(false),
|
|
|
monsterStrength(EMonsterStrength::ZONE_NORMAL),
|
|
|
+ townsLikeZone(NO_ZONE),
|
|
|
minesLikeZone(NO_ZONE),
|
|
|
terrainTypeLikeZone(NO_ZONE),
|
|
|
treasureLikeZone(NO_ZONE)
|
|
@@ -291,6 +309,11 @@ TRmgTemplateZoneId ZoneOptions::getCustomObjectsLikeZone() const
|
|
|
return customObjectsLikeZone;
|
|
|
}
|
|
|
|
|
|
+TRmgTemplateZoneId ZoneOptions::getTownsLikeZone() const
|
|
|
+{
|
|
|
+ return townsLikeZone;
|
|
|
+}
|
|
|
+
|
|
|
void ZoneOptions::addConnection(const ZoneConnection & connection)
|
|
|
{
|
|
|
connectedZoneIds.push_back(connection.getOtherZoneId(getId()));
|
|
@@ -317,16 +340,51 @@ bool ZoneOptions::isMatchTerrainToTown() const
|
|
|
return matchTerrainToTown;
|
|
|
}
|
|
|
|
|
|
+void ZoneOptions::setMatchTerrainToTown(bool value)
|
|
|
+{
|
|
|
+ matchTerrainToTown = value;
|
|
|
+}
|
|
|
+
|
|
|
const ZoneOptions::CTownInfo & ZoneOptions::getPlayerTowns() const
|
|
|
{
|
|
|
return playerTowns;
|
|
|
}
|
|
|
|
|
|
+void ZoneOptions::setPlayerTowns(const CTownInfo & value)
|
|
|
+{
|
|
|
+ playerTowns = value;
|
|
|
+}
|
|
|
+
|
|
|
const ZoneOptions::CTownInfo & ZoneOptions::getNeutralTowns() const
|
|
|
{
|
|
|
return neutralTowns;
|
|
|
}
|
|
|
|
|
|
+void ZoneOptions::setNeutralTowns(const CTownInfo & value)
|
|
|
+{
|
|
|
+ neutralTowns = value;
|
|
|
+}
|
|
|
+
|
|
|
+const std::vector<ZoneOptions::CTownHints> & ZoneOptions::getTownHints() const
|
|
|
+{
|
|
|
+ return townHints;
|
|
|
+}
|
|
|
+
|
|
|
+void ZoneOptions::setTownHints(const std::vector<CTownHints> & value)
|
|
|
+{
|
|
|
+ townHints = value;
|
|
|
+}
|
|
|
+
|
|
|
+std::set<FactionID> ZoneOptions::getBannedTownTypes() const
|
|
|
+{
|
|
|
+ return bannedTownTypes;
|
|
|
+}
|
|
|
+
|
|
|
+void ZoneOptions::setBannedTownTypes(const std::set<FactionID> & value)
|
|
|
+{
|
|
|
+ bannedTownTypes = value;
|
|
|
+}
|
|
|
+
|
|
|
void ZoneOptions::serializeJson(JsonSerializeFormat & handler)
|
|
|
{
|
|
|
static const std::vector<std::string> zoneTypes =
|
|
@@ -348,6 +406,7 @@ void ZoneOptions::serializeJson(JsonSerializeFormat & handler)
|
|
|
|
|
|
#define SERIALIZE_ZONE_LINK(fieldName) handler.serializeInt(#fieldName, fieldName, NO_ZONE);
|
|
|
|
|
|
+ SERIALIZE_ZONE_LINK(townsLikeZone);
|
|
|
SERIALIZE_ZONE_LINK(minesLikeZone);
|
|
|
SERIALIZE_ZONE_LINK(terrainTypeLikeZone);
|
|
|
SERIALIZE_ZONE_LINK(treasureLikeZone);
|
|
@@ -367,6 +426,8 @@ void ZoneOptions::serializeJson(JsonSerializeFormat & handler)
|
|
|
handler.serializeIdArray("allowedTowns", townTypes);
|
|
|
handler.serializeIdArray("bannedTowns", bannedTownTypes);
|
|
|
|
|
|
+ handler.enterArray("townHints").serializeStruct(townHints);
|
|
|
+
|
|
|
{
|
|
|
//TODO: add support for std::map to serializeEnum
|
|
|
static const std::vector<std::string> zoneMonsterStrengths =
|
|
@@ -829,6 +890,8 @@ void CRmgTemplate::afterLoad()
|
|
|
auto zone = idAndZone.second;
|
|
|
|
|
|
// Inherit properties recursively
|
|
|
+ inheritTownProperties(zone);
|
|
|
+
|
|
|
inheritZoneProperty(zone,
|
|
|
&rmg::ZoneOptions::getTerrainTypes,
|
|
|
&rmg::ZoneOptions::setTerrainTypes,
|
|
@@ -882,6 +945,31 @@ void CRmgTemplate::afterLoad()
|
|
|
allowedWaterContent.erase(EWaterContent::RANDOM);
|
|
|
}
|
|
|
|
|
|
+void CRmgTemplate::inheritTownProperties(std::shared_ptr<rmg::ZoneOptions> zone, uint32_t iteration)
|
|
|
+{
|
|
|
+ if (iteration >= 50)
|
|
|
+ {
|
|
|
+ logGlobal->error("Infinite recursion for town properties detected in template %s", name);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (zone->getTownsLikeZone() != rmg::ZoneOptions::NO_ZONE)
|
|
|
+ {
|
|
|
+ const auto otherZone = zones.at(zone->getTownsLikeZone());
|
|
|
+
|
|
|
+ // Recursively inherit from the source zone first
|
|
|
+ inheritTownProperties(otherZone, iteration + 1);
|
|
|
+
|
|
|
+ // Now copy all town-related properties from the source zone
|
|
|
+ zone->setPlayerTowns(otherZone->getPlayerTowns());
|
|
|
+ zone->setNeutralTowns(otherZone->getNeutralTowns());
|
|
|
+ zone->setMatchTerrainToTown(otherZone->isMatchTerrainToTown());
|
|
|
+ zone->setTownHints(otherZone->getTownHints());
|
|
|
+ zone->setTownTypes(otherZone->getTownTypes());
|
|
|
+ zone->setBannedTownTypes(otherZone->getBannedTownTypes());
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// TODO: Allow any integer size which does not match enum, as well
|
|
|
void CRmgTemplate::serializeSize(JsonSerializeFormat & handler, int3 & value, const std::string & fieldName)
|
|
|
{
|