mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-02 00:10:22 +02:00
- Implemented updating additional terrain types fully(including 2 special cases)
This commit is contained in:
parent
da659a4924
commit
298f862d86
@ -1,4 +1,4 @@
|
|||||||
// Defines terrain view patterns.
|
// Defines terrain view/types patterns.
|
||||||
|
|
||||||
// The following table shows the rules for the 3x3 pattern of all terrain types:
|
// The following table shows the rules for the 3x3 pattern of all terrain types:
|
||||||
// I) normal(e.g. grass, lava, ...):
|
// I) normal(e.g. grass, lava, ...):
|
||||||
@ -8,7 +8,7 @@
|
|||||||
// T: Sand OR dirt border(all Ts in the pattern are replaced by dirt OR sand)
|
// T: Sand OR dirt border(all Ts in the pattern are replaced by dirt OR sand)
|
||||||
// ?: D,S or N
|
// ?: D,S or N
|
||||||
// II) dirt:
|
// II) dirt:
|
||||||
// N: Native type
|
// N: Native type or normal type(grass, lava, ...)
|
||||||
// S: Sand border
|
// S: Sand border
|
||||||
// ?: Any border
|
// ?: Any border
|
||||||
// III) sand:
|
// III) sand:
|
||||||
@ -18,216 +18,271 @@
|
|||||||
// S: Sand border
|
// S: Sand border
|
||||||
// ?: Any border
|
// ?: Any border
|
||||||
|
|
||||||
|
// Additional rule for validiting terrain type:
|
||||||
|
// N!: Native type always(unlike N for dirt)
|
||||||
|
|
||||||
// The order of the patterns is important, do not change!
|
// The order of the patterns is important, do not change!
|
||||||
[
|
{
|
||||||
// Extended mixed transitions
|
"terrainView" :
|
||||||
{
|
[
|
||||||
"id" : "x1",
|
// Extended mixed transitions
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "x1",
|
||||||
"T", "N", "N",
|
"data" :
|
||||||
"N", "N", "T",
|
[
|
||||||
"N", "T", "T"
|
"T", "N", "N",
|
||||||
],
|
"N", "N", "T",
|
||||||
"mapping" : { "normal" : "73,74", "dirt" : "45" }
|
"N", "T", "T"
|
||||||
},
|
],
|
||||||
{
|
"mapping" : { "normal" : "73,74", "dirt" : "45" }
|
||||||
"id" : "x2",
|
},
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "x2",
|
||||||
"D", "D", "N",
|
"data" :
|
||||||
"D", "N", "N",
|
[
|
||||||
"N", "N", "S"
|
"D", "D", "N",
|
||||||
],
|
"D", "N", "N",
|
||||||
"mapping" : { "normal" : "75" }
|
"N", "N", "S"
|
||||||
},
|
],
|
||||||
{
|
"mapping" : { "normal" : "75" }
|
||||||
"id" : "x3",
|
},
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "x3",
|
||||||
"S", "S", "N",
|
"data" :
|
||||||
"S", "N", "N",
|
[
|
||||||
"N", "N", "D"
|
"S", "S", "N",
|
||||||
],
|
"S", "N", "N",
|
||||||
"mapping" : { "normal" : "76" }
|
"N", "N", "D"
|
||||||
},
|
],
|
||||||
{
|
"mapping" : { "normal" : "76" }
|
||||||
"id" : "x4",
|
},
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "x4",
|
||||||
"N", "N", "S",
|
"data" :
|
||||||
"N", "N", "D",
|
[
|
||||||
"S", "D", "D"
|
"N", "N", "S",
|
||||||
],
|
"N", "N", "D",
|
||||||
"mapping" : { "normal" : "77" }
|
"S", "D", "D"
|
||||||
},
|
],
|
||||||
{
|
"mapping" : { "normal" : "77" }
|
||||||
"id" : "x5",
|
},
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "x5",
|
||||||
"N", "N", "D",
|
"data" :
|
||||||
"N", "N", "D",
|
[
|
||||||
"D", "D", "S"
|
"N", "N", "D",
|
||||||
],
|
"N", "N", "D",
|
||||||
"mapping" : { "normal" : "78" }
|
"D", "D", "S"
|
||||||
},
|
],
|
||||||
// No transition
|
"mapping" : { "normal" : "78" }
|
||||||
{
|
},
|
||||||
"id" : "n1",
|
// No transition
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "n1",
|
||||||
"N", "N", "N",
|
"data" :
|
||||||
"N", "N", "N",
|
[
|
||||||
"N", "N", "N"
|
"N", "N", "N",
|
||||||
],
|
"N", "N", "N",
|
||||||
"mapping" : { "normal" : "49-72", "dirt" : "21-44", "sand" : "0-23", "water" : "20-32", "rock": "0-7" }
|
"N", "N", "N"
|
||||||
},
|
],
|
||||||
// Mixed transitions
|
"mapping" : { "normal" : "49-72", "dirt" : "21-44", "sand" : "0-23", "water" : "20-32", "rock": "0-7" }
|
||||||
{
|
},
|
||||||
"id" : "m1",
|
// Mixed transitions
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "m1",
|
||||||
"T", "N", "N",
|
"data" :
|
||||||
"N", "N", "N",
|
[
|
||||||
"N", "N", "T"
|
"T", "N", "N",
|
||||||
],
|
"N", "N", "N",
|
||||||
"mapping" : { "normal" : "40, 42", "dirt" : "20" }
|
"N", "N", "T"
|
||||||
},
|
],
|
||||||
{
|
"mapping" : { "normal" : "40, 42", "dirt" : "20" }
|
||||||
"id" : "m2",
|
},
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "m2",
|
||||||
"D", "N", "N",
|
"data" :
|
||||||
"N", "N", "N",
|
[
|
||||||
"N", "N", "S"
|
"D", "N", "N",
|
||||||
],
|
"N", "N", "N",
|
||||||
"mapping" : { "normal" : "41" }
|
"N", "N", "S"
|
||||||
},
|
],
|
||||||
{
|
"mapping" : { "normal" : "41" }
|
||||||
"id" : "m3",
|
},
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "m3",
|
||||||
"N", "N", "D,N",
|
"data" :
|
||||||
"N", "N", "D",
|
[
|
||||||
"S", "D,N", "D,N"
|
"N", "N", "D,N",
|
||||||
],
|
"N", "N", "D",
|
||||||
"mapping" : { "normal" : "43" }
|
"S", "D,N", "D,N"
|
||||||
},
|
],
|
||||||
{
|
"mapping" : { "normal" : "43" }
|
||||||
"id" : "m4",
|
},
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "m4",
|
||||||
"N", "N", "S",
|
"data" :
|
||||||
"N", "N", "D",
|
[
|
||||||
"D,N", "D", "D,N"
|
"N", "N", "S",
|
||||||
],
|
"N", "N", "D",
|
||||||
"mapping" : { "normal" : "44" }
|
"D,N", "D", "D,N"
|
||||||
},
|
],
|
||||||
{
|
"mapping" : { "normal" : "44" }
|
||||||
"id" : "m5",
|
},
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "m5",
|
||||||
"N", "N", "D",
|
"data" :
|
||||||
"N", "N", "D",
|
[
|
||||||
"N", "N", "S"
|
"N", "N", "D",
|
||||||
],
|
"N", "N", "D",
|
||||||
"mapping" : { "normal" : "45" }
|
"N", "N", "S"
|
||||||
},
|
],
|
||||||
{
|
"mapping" : { "normal" : "45" }
|
||||||
"id" : "m6",
|
},
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "m6",
|
||||||
"N", "N", "N",
|
"data" :
|
||||||
"N", "N", "N",
|
[
|
||||||
"D,N", "D", "S"
|
"N", "N", "N",
|
||||||
],
|
"N", "N", "N",
|
||||||
"mapping" : { "normal" : "46" }
|
"D,N", "D", "S"
|
||||||
},
|
],
|
||||||
{
|
"mapping" : { "normal" : "46" }
|
||||||
"id" : "m7",
|
},
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "m7",
|
||||||
"N", "N", "?",
|
"data" :
|
||||||
"N", "N", "S",
|
[
|
||||||
"D-1,N", "D-1,N", "?"
|
"N", "N", "?",
|
||||||
],
|
"N", "N", "S",
|
||||||
"minPoints" : 1,
|
"D-1,N", "D-1,N", "?"
|
||||||
"mapping" : { "normal" : "47" }
|
],
|
||||||
},
|
"minPoints" : 1,
|
||||||
{
|
"mapping" : { "normal" : "47" }
|
||||||
"id" : "m8",
|
},
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "m8",
|
||||||
"N", "N", "D-1,N",
|
"data" :
|
||||||
"N", "N", "D-1,N",
|
[
|
||||||
"?", "S", "?"
|
"N", "N", "D-1,N",
|
||||||
],
|
"N", "N", "D-1,N",
|
||||||
"minPoints" : 1,
|
"?", "S", "?"
|
||||||
"mapping" : { "normal" : "48" }
|
],
|
||||||
},
|
"minPoints" : 1,
|
||||||
// Standard transitions
|
"mapping" : { "normal" : "48" }
|
||||||
{
|
},
|
||||||
"id" : "s1",
|
// Standard transitions
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "s2",
|
||||||
"T,N-1", "T,N-2", "T,N-3",
|
"data" :
|
||||||
"T,N-2", "N", "N",
|
[
|
||||||
"T", "N", "N"
|
"?", "N", "N",
|
||||||
],
|
"T", "N", "N",
|
||||||
"maxPoints" : 3,
|
"?", "N", "N"
|
||||||
"mapping" : { "normal" : "0-3, 20-23", "dirt" : "0-3", "water" : "0-3", "rock": "4D:8-15" }
|
],
|
||||||
},
|
"mapping" : { "normal" : "4-7, 24-27", "dirt" : "4-7", "water" : "4-7", "rock": "2D:16-19" }
|
||||||
{
|
},
|
||||||
"id" : "s2",
|
{
|
||||||
"data" :
|
"id" : "s3",
|
||||||
[
|
"data" :
|
||||||
"?", "N", "N",
|
[
|
||||||
"T", "N", "N",
|
"?", "T", "?",
|
||||||
"?", "N", "N"
|
"N", "N", "N",
|
||||||
],
|
"N", "N", "N"
|
||||||
"mapping" : { "normal" : "4-7, 24-27", "dirt" : "4-7", "water" : "4-7", "rock": "2D:16-19" }
|
],
|
||||||
},
|
"mapping" : { "normal" : "8-11, 28-31", "dirt" : "8-11", "water" : "8-11", "rock": "2D:20-23" }
|
||||||
{
|
},
|
||||||
"id" : "s3",
|
{
|
||||||
"data" :
|
"id" : "s4",
|
||||||
[
|
"data" :
|
||||||
"?", "T", "?",
|
[
|
||||||
"N", "N", "N",
|
"N", "N", "N",
|
||||||
"N", "N", "N"
|
"N", "N", "s3-1,m7-1,m8-1",
|
||||||
],
|
"N", "s2-1,m7-1,m8-1", "T"
|
||||||
"mapping" : { "normal" : "8-11, 28-31", "dirt" : "8-11", "water" : "8-11", "rock": "2D:20-23" }
|
],
|
||||||
},
|
"minPoints" : 2,
|
||||||
{
|
"mapping" : { "normal" : "12-15, 32-35", "dirt" : "12-15", "water" : "12-15", "rock": "4D:24-31" }
|
||||||
"id" : "s4",
|
},
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "s5",
|
||||||
"N", "N", "N",
|
"data" :
|
||||||
"N", "N", "s3-1,m7-1,m8-1",
|
[
|
||||||
"N", "s2-1,m7-1,m8-1", "T"
|
"T", "T", "?",
|
||||||
],
|
"T", "N", "s6-1,m1-1,m2-1,N",
|
||||||
"minPoints" : 2,
|
"?,x1-1,s1-1", "s6-1,m1-1,m2-1,N", "N"
|
||||||
"mapping" : { "normal" : "12-15, 32-35", "dirt" : "12-15", "water" : "12-15", "rock": "4D:24-31" }
|
],
|
||||||
},
|
"minPoints" : 1,
|
||||||
{
|
"mapping" : { "normal" : "16-17, 36-37", "dirt" : "16-17", "water" : "16-17", "rock": "4D:32-39" }
|
||||||
"id" : "s5",
|
},
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "s6",
|
||||||
"T", "T", "?",
|
"data" :
|
||||||
"T", "N", "s6-1,m1-1,m2-1,N",
|
[
|
||||||
"?", "s6-1,m1-1,m2-1,N", "N"
|
"N", "N", "N",
|
||||||
],
|
"N", "N", "s5-1,N",
|
||||||
"minPoints" : 1,
|
"N", "s5-1,N", "T"
|
||||||
"mapping" : { "normal" : "16-17, 36-37", "dirt" : "16-17", "water" : "16-17", "rock": "4D:32-39" }
|
],
|
||||||
},
|
"minPoints" : 1,
|
||||||
{
|
"mapping" : { "normal" : "18-19, 38-39", "dirt" : "18-19", "water" : "18-19", "rock": "4D:40-47" }
|
||||||
"id" : "s6",
|
},
|
||||||
"data" :
|
{
|
||||||
[
|
"id" : "s1",
|
||||||
"N", "N", "N",
|
"data" :
|
||||||
"N", "N", "s5-1,N",
|
[
|
||||||
"N", "s5-1,N", "T"
|
"?", "?", "?",
|
||||||
],
|
"?", "N", "N",
|
||||||
"minPoints" : 1,
|
"T", "N", "N"
|
||||||
"mapping" : { "normal" : "18-19, 38-39", "dirt" : "18-19", "water" : "18-19", "rock": "4D:40-47" }
|
],
|
||||||
}
|
"mapping" : { "normal" : "0-3, 20-23", "dirt" : "0-3", "water" : "0-3", "rock": "4D:8-15" }
|
||||||
]
|
}
|
||||||
|
],
|
||||||
|
"terrainType" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id" : "n1",
|
||||||
|
"data" :
|
||||||
|
[
|
||||||
|
"N!", "N!", "?",
|
||||||
|
"N!", "N!", "?",
|
||||||
|
"?", "?", "?"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id" : "n2",
|
||||||
|
"data" :
|
||||||
|
[
|
||||||
|
"N!", "N!", "D,S",
|
||||||
|
"D,S", "N!", "N!",
|
||||||
|
"D,S", "D,S", "N!"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id" : "n3",
|
||||||
|
"data" :
|
||||||
|
[
|
||||||
|
"D,S", "D,S", "N!",
|
||||||
|
"D,S", "N!", "N!",
|
||||||
|
"N!", "N!", "D,S"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id" : "s1",
|
||||||
|
"data" :
|
||||||
|
[
|
||||||
|
"T", "N", "N",
|
||||||
|
"N", "N", "N",
|
||||||
|
"N", "T-1,N", "T-1,N"
|
||||||
|
],
|
||||||
|
"minPoints" : 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id" : "s2",
|
||||||
|
"data" :
|
||||||
|
[
|
||||||
|
"N", "N", "T",
|
||||||
|
"T-1,N", "N", "N",
|
||||||
|
"T-1,N", "N", "N"
|
||||||
|
],
|
||||||
|
"minPoints" : 1
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
@ -284,9 +284,10 @@ const std::string TerrainViewPattern::RULE_DIRT = "D";
|
|||||||
const std::string TerrainViewPattern::RULE_SAND = "S";
|
const std::string TerrainViewPattern::RULE_SAND = "S";
|
||||||
const std::string TerrainViewPattern::RULE_TRANSITION = "T";
|
const std::string TerrainViewPattern::RULE_TRANSITION = "T";
|
||||||
const std::string TerrainViewPattern::RULE_NATIVE = "N";
|
const std::string TerrainViewPattern::RULE_NATIVE = "N";
|
||||||
|
const std::string TerrainViewPattern::RULE_NATIVE_STRONG = "N!";
|
||||||
const std::string TerrainViewPattern::RULE_ANY = "?";
|
const std::string TerrainViewPattern::RULE_ANY = "?";
|
||||||
|
|
||||||
TerrainViewPattern::TerrainViewPattern() : diffImages(false), rotationTypesCount(0), minPoints(0), terGroup(ETerrainGroup::NORMAL)
|
TerrainViewPattern::TerrainViewPattern() : diffImages(false), rotationTypesCount(0), minPoints(0)
|
||||||
{
|
{
|
||||||
maxPoints = std::numeric_limits<int>::max();
|
maxPoints = std::numeric_limits<int>::max();
|
||||||
}
|
}
|
||||||
@ -300,7 +301,7 @@ bool TerrainViewPattern::WeightedRule::isStandardRule() const
|
|||||||
{
|
{
|
||||||
return TerrainViewPattern::RULE_ANY == name || TerrainViewPattern::RULE_DIRT == name
|
return TerrainViewPattern::RULE_ANY == name || TerrainViewPattern::RULE_DIRT == name
|
||||||
|| TerrainViewPattern::RULE_NATIVE == name || TerrainViewPattern::RULE_SAND == name
|
|| TerrainViewPattern::RULE_NATIVE == name || TerrainViewPattern::RULE_SAND == name
|
||||||
|| TerrainViewPattern::RULE_TRANSITION == name;
|
|| TerrainViewPattern::RULE_TRANSITION == name || TerrainViewPattern::RULE_NATIVE_STRONG == name;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::mutex CTerrainViewPatternConfig::smx;
|
boost::mutex CTerrainViewPatternConfig::smx;
|
||||||
@ -315,70 +316,82 @@ CTerrainViewPatternConfig & CTerrainViewPatternConfig::get()
|
|||||||
CTerrainViewPatternConfig::CTerrainViewPatternConfig()
|
CTerrainViewPatternConfig::CTerrainViewPatternConfig()
|
||||||
{
|
{
|
||||||
const JsonNode config(ResourceID("config/terrainViewPatterns.json"));
|
const JsonNode config(ResourceID("config/terrainViewPatterns.json"));
|
||||||
const auto & patternsVec = config.Vector();
|
static const std::string patternTypes[] = { "terrainView", "terrainType" };
|
||||||
BOOST_FOREACH(const auto & ptrnNode, patternsVec)
|
for(int i = 0; i < ARRAY_COUNT(patternTypes); ++i)
|
||||||
{
|
{
|
||||||
TerrainViewPattern pattern;
|
const auto & patternsVec = config[patternTypes[i]].Vector();
|
||||||
|
BOOST_FOREACH(const auto & ptrnNode, patternsVec)
|
||||||
// Read pattern data
|
|
||||||
const JsonVector & data = ptrnNode["data"].Vector();
|
|
||||||
assert(data.size() == 9);
|
|
||||||
for(int i = 0; i < data.size(); ++i)
|
|
||||||
{
|
{
|
||||||
std::string cell = data[i].String();
|
TerrainViewPattern pattern;
|
||||||
boost::algorithm::erase_all(cell, " ");
|
|
||||||
std::vector<std::string> rules;
|
// Read pattern data
|
||||||
boost::split(rules, cell, boost::is_any_of(","));
|
const JsonVector & data = ptrnNode["data"].Vector();
|
||||||
BOOST_FOREACH(std::string ruleStr, rules)
|
assert(data.size() == 9);
|
||||||
|
for(int i = 0; i < data.size(); ++i)
|
||||||
{
|
{
|
||||||
std::vector<std::string> ruleParts;
|
std::string cell = data[i].String();
|
||||||
boost::split(ruleParts, ruleStr, boost::is_any_of("-"));
|
boost::algorithm::erase_all(cell, " ");
|
||||||
TerrainViewPattern::WeightedRule rule;
|
std::vector<std::string> rules;
|
||||||
rule.name = ruleParts[0];
|
boost::split(rules, cell, boost::is_any_of(","));
|
||||||
assert(!rule.name.empty());
|
BOOST_FOREACH(std::string ruleStr, rules)
|
||||||
if(ruleParts.size() > 1)
|
|
||||||
{
|
{
|
||||||
rule.points = boost::lexical_cast<int>(ruleParts[1]);
|
std::vector<std::string> ruleParts;
|
||||||
|
boost::split(ruleParts, ruleStr, boost::is_any_of("-"));
|
||||||
|
TerrainViewPattern::WeightedRule rule;
|
||||||
|
rule.name = ruleParts[0];
|
||||||
|
assert(!rule.name.empty());
|
||||||
|
if(ruleParts.size() > 1)
|
||||||
|
{
|
||||||
|
rule.points = boost::lexical_cast<int>(ruleParts[1]);
|
||||||
|
}
|
||||||
|
pattern.data[i].push_back(rule);
|
||||||
}
|
}
|
||||||
pattern.data[i].push_back(rule);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Read various properties
|
// Read various properties
|
||||||
pattern.id = ptrnNode["id"].String();
|
pattern.id = ptrnNode["id"].String();
|
||||||
assert(!pattern.id.empty());
|
assert(!pattern.id.empty());
|
||||||
pattern.minPoints = static_cast<int>(ptrnNode["minPoints"].Float());
|
pattern.minPoints = static_cast<int>(ptrnNode["minPoints"].Float());
|
||||||
pattern.maxPoints = static_cast<int>(ptrnNode["maxPoints"].Float());
|
pattern.maxPoints = static_cast<int>(ptrnNode["maxPoints"].Float());
|
||||||
if(pattern.maxPoints == 0) pattern.maxPoints = std::numeric_limits<int>::max();
|
if(pattern.maxPoints == 0) pattern.maxPoints = std::numeric_limits<int>::max();
|
||||||
|
|
||||||
// Read mapping
|
// Read mapping
|
||||||
const auto & mappingStruct = ptrnNode["mapping"].Struct();
|
if(i == 0)
|
||||||
BOOST_FOREACH(const auto & mappingPair, mappingStruct)
|
|
||||||
{
|
|
||||||
TerrainViewPattern terGroupPattern = pattern;
|
|
||||||
auto mappingStr = mappingPair.second.String();
|
|
||||||
boost::algorithm::erase_all(mappingStr, " ");
|
|
||||||
auto colonIndex = mappingStr.find_first_of(":");
|
|
||||||
const auto & flipMode = mappingStr.substr(0, colonIndex);
|
|
||||||
terGroupPattern.diffImages = TerrainViewPattern::FLIP_MODE_DIFF_IMAGES == &(flipMode[flipMode.length() - 1]);
|
|
||||||
if(terGroupPattern.diffImages)
|
|
||||||
{
|
{
|
||||||
terGroupPattern.rotationTypesCount = boost::lexical_cast<int>(flipMode.substr(0, flipMode.length() - 1));
|
const auto & mappingStruct = ptrnNode["mapping"].Struct();
|
||||||
assert(terGroupPattern.rotationTypesCount == 2 || terGroupPattern.rotationTypesCount == 4);
|
BOOST_FOREACH(const auto & mappingPair, mappingStruct)
|
||||||
|
{
|
||||||
|
TerrainViewPattern terGroupPattern = pattern;
|
||||||
|
auto mappingStr = mappingPair.second.String();
|
||||||
|
boost::algorithm::erase_all(mappingStr, " ");
|
||||||
|
auto colonIndex = mappingStr.find_first_of(":");
|
||||||
|
const auto & flipMode = mappingStr.substr(0, colonIndex);
|
||||||
|
terGroupPattern.diffImages = TerrainViewPattern::FLIP_MODE_DIFF_IMAGES == &(flipMode[flipMode.length() - 1]);
|
||||||
|
if(terGroupPattern.diffImages)
|
||||||
|
{
|
||||||
|
terGroupPattern.rotationTypesCount = boost::lexical_cast<int>(flipMode.substr(0, flipMode.length() - 1));
|
||||||
|
assert(terGroupPattern.rotationTypesCount == 2 || terGroupPattern.rotationTypesCount == 4);
|
||||||
|
}
|
||||||
|
mappingStr = mappingStr.substr(colonIndex + 1);
|
||||||
|
std::vector<std::string> mappings;
|
||||||
|
boost::split(mappings, mappingStr, boost::is_any_of(","));
|
||||||
|
BOOST_FOREACH(std::string mapping, mappings)
|
||||||
|
{
|
||||||
|
std::vector<std::string> range;
|
||||||
|
boost::split(range, mapping, boost::is_any_of("-"));
|
||||||
|
terGroupPattern.mapping.push_back(std::make_pair(boost::lexical_cast<int>(range[0]),
|
||||||
|
boost::lexical_cast<int>(range.size() > 1 ? range[1] : range[0])));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add pattern to the patterns map
|
||||||
|
const auto & terGroup = getTerrainGroup(mappingPair.first);
|
||||||
|
terrainViewPatterns[terGroup].push_back(terGroupPattern);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mappingStr = mappingStr.substr(colonIndex + 1);
|
else if(i == 1)
|
||||||
std::vector<std::string> mappings;
|
|
||||||
boost::split(mappings, mappingStr, boost::is_any_of(","));
|
|
||||||
BOOST_FOREACH(std::string mapping, mappings)
|
|
||||||
{
|
{
|
||||||
std::vector<std::string> range;
|
terrainTypePatterns[pattern.id] = pattern;
|
||||||
boost::split(range, mapping, boost::is_any_of("-"));
|
|
||||||
terGroupPattern.mapping.push_back(std::make_pair(boost::lexical_cast<int>(range[0]),
|
|
||||||
boost::lexical_cast<int>(range.size() > 1 ? range[1] : range[0])));
|
|
||||||
}
|
}
|
||||||
const auto & terGroup = getTerrainGroup(mappingPair.first);
|
|
||||||
terGroupPattern.terGroup = terGroup;
|
|
||||||
patterns[terGroup].push_back(terGroupPattern);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -398,14 +411,14 @@ ETerrainGroup::ETerrainGroup CTerrainViewPatternConfig::getTerrainGroup(const st
|
|||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<TerrainViewPattern> & CTerrainViewPatternConfig::getPatternsForGroup(ETerrainGroup::ETerrainGroup terGroup) const
|
const std::vector<TerrainViewPattern> & CTerrainViewPatternConfig::getTerrainViewPatternsForGroup(ETerrainGroup::ETerrainGroup terGroup) const
|
||||||
{
|
{
|
||||||
return patterns.find(terGroup)->second;
|
return terrainViewPatterns.find(terGroup)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<const TerrainViewPattern &> CTerrainViewPatternConfig::getPatternById(ETerrainGroup::ETerrainGroup terGroup, const std::string & id) const
|
boost::optional<const TerrainViewPattern &> CTerrainViewPatternConfig::getTerrainViewPatternById(ETerrainGroup::ETerrainGroup terGroup, const std::string & id) const
|
||||||
{
|
{
|
||||||
const std::vector<TerrainViewPattern> & groupPatterns = getPatternsForGroup(terGroup);
|
const std::vector<TerrainViewPattern> & groupPatterns = getTerrainViewPatternsForGroup(terGroup);
|
||||||
BOOST_FOREACH(const TerrainViewPattern & pattern, groupPatterns)
|
BOOST_FOREACH(const TerrainViewPattern & pattern, groupPatterns)
|
||||||
{
|
{
|
||||||
if(id == pattern.id)
|
if(id == pattern.id)
|
||||||
@ -416,6 +429,13 @@ boost::optional<const TerrainViewPattern &> CTerrainViewPatternConfig::getPatter
|
|||||||
return boost::optional<const TerrainViewPattern &>();
|
return boost::optional<const TerrainViewPattern &>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TerrainViewPattern & CTerrainViewPatternConfig::getTerrainTypePatternById(const std::string & id) const
|
||||||
|
{
|
||||||
|
auto it = terrainTypePatterns.find(id);
|
||||||
|
assert(it != terrainTypePatterns.end());
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
CDrawTerrainOperation::CDrawTerrainOperation(CMap * map, const CTerrainSelection & terrainSel, ETerrainType terType, CRandomGenerator * gen)
|
CDrawTerrainOperation::CDrawTerrainOperation(CMap * map, const CTerrainSelection & terrainSel, ETerrainType terType, CRandomGenerator * gen)
|
||||||
: CMapOperation(map), terrainSel(terrainSel), terType(terType), gen(gen)
|
: CMapOperation(map), terrainSel(terrainSel), terType(terType), gen(gen)
|
||||||
{
|
{
|
||||||
@ -459,9 +479,10 @@ void CDrawTerrainOperation::updateTerrainTypes()
|
|||||||
const auto & centerPos = *(positions.begin());
|
const auto & centerPos = *(positions.begin());
|
||||||
auto centerTile = map->getTile(centerPos);
|
auto centerTile = map->getTile(centerPos);
|
||||||
auto tiles = getInvalidTiles(centerPos);
|
auto tiles = getInvalidTiles(centerPos);
|
||||||
auto updateTerrainType = [&](const int3 & pos)
|
auto updateTerrainType = [&](const int3 & pos, bool tileRequiresValidation)
|
||||||
{
|
{
|
||||||
map->getTile(pos).terType = centerTile.terType;
|
map->getTile(pos).terType = centerTile.terType;
|
||||||
|
if(tileRequiresValidation) positions.insert(pos);
|
||||||
invalidateTerrainViews(pos);
|
invalidateTerrainViews(pos);
|
||||||
logGlobal->debugStream() << boost::format("Update terrain tile at '%s' to type '%i'.") % pos % centerTile.terType;
|
logGlobal->debugStream() << boost::format("Update terrain tile at '%s' to type '%i'.") % pos % centerTile.terType;
|
||||||
};
|
};
|
||||||
@ -469,7 +490,7 @@ void CDrawTerrainOperation::updateTerrainTypes()
|
|||||||
// Fill foreign invalid tiles
|
// Fill foreign invalid tiles
|
||||||
BOOST_FOREACH(const auto & tile, tiles.foreignTiles)
|
BOOST_FOREACH(const auto & tile, tiles.foreignTiles)
|
||||||
{
|
{
|
||||||
updateTerrainType(tile);
|
updateTerrainType(tile, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tiles.nativeTiles.find(centerPos) != tiles.nativeTiles.end())
|
if(tiles.nativeTiles.find(centerPos) != tiles.nativeTiles.end())
|
||||||
@ -477,8 +498,7 @@ void CDrawTerrainOperation::updateTerrainTypes()
|
|||||||
// Blow up
|
// Blow up
|
||||||
auto rect = extendTileAroundSafely(centerPos);
|
auto rect = extendTileAroundSafely(centerPos);
|
||||||
std::set<int3> suitableTiles;
|
std::set<int3> suitableTiles;
|
||||||
int invalidForeignTilesCnt, invalidNativeTilesCnt;
|
int invalidForeignTilesCnt = std::numeric_limits<int>::max(), invalidNativeTilesCnt = 0;
|
||||||
invalidForeignTilesCnt = invalidNativeTilesCnt = std::numeric_limits<int>::max();
|
|
||||||
rect.forEach([&](const int3 & posToTest)
|
rect.forEach([&](const int3 & posToTest)
|
||||||
{
|
{
|
||||||
auto & terrainTile = map->getTile(posToTest);
|
auto & terrainTile = map->getTile(posToTest);
|
||||||
@ -490,16 +510,21 @@ void CDrawTerrainOperation::updateTerrainTypes()
|
|||||||
auto addToSuitableTiles = [&](const int3 & pos)
|
auto addToSuitableTiles = [&](const int3 & pos)
|
||||||
{
|
{
|
||||||
suitableTiles.insert(pos);
|
suitableTiles.insert(pos);
|
||||||
logGlobal->debugStream() << boost::format("Found suitable tile '%s' for main tile '%s'.") % pos % centerPos;
|
logGlobal->debugStream() << boost::format(std::string("Found suitable tile '%s' for main tile '%s': ") +
|
||||||
|
"Invalid native tiles '%i', invalid foreign tiles '%i'.") % pos % centerPos % testTile.nativeTiles.size() %
|
||||||
|
testTile.foreignTiles.size();
|
||||||
};
|
};
|
||||||
|
|
||||||
if(testTile.nativeTiles.size() < invalidNativeTilesCnt ||
|
int nativeTilesCntNorm = testTile.nativeTiles.empty() ? std::numeric_limits<int>::max() : testTile.nativeTiles.size();
|
||||||
(testTile.nativeTiles.size() == invalidNativeTilesCnt && testTile.foreignTiles.size() < invalidForeignTilesCnt))
|
if(nativeTilesCntNorm > invalidNativeTilesCnt ||
|
||||||
|
(nativeTilesCntNorm == invalidNativeTilesCnt && testTile.foreignTiles.size() < invalidForeignTilesCnt))
|
||||||
{
|
{
|
||||||
|
invalidNativeTilesCnt = nativeTilesCntNorm;
|
||||||
|
invalidForeignTilesCnt = testTile.foreignTiles.size();
|
||||||
suitableTiles.clear();
|
suitableTiles.clear();
|
||||||
addToSuitableTiles(posToTest);
|
addToSuitableTiles(posToTest);
|
||||||
}
|
}
|
||||||
else if(testTile.nativeTiles.size() == invalidNativeTilesCnt &&
|
else if(nativeTilesCntNorm == invalidNativeTilesCnt &&
|
||||||
testTile.foreignTiles.size() == invalidForeignTilesCnt)
|
testTile.foreignTiles.size() == invalidForeignTilesCnt)
|
||||||
{
|
{
|
||||||
addToSuitableTiles(posToTest);
|
addToSuitableTiles(posToTest);
|
||||||
@ -508,20 +533,21 @@ void CDrawTerrainOperation::updateTerrainTypes()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bool tileRequiresValidation = invalidForeignTilesCnt > 0;
|
||||||
if(suitableTiles.size() == 1)
|
if(suitableTiles.size() == 1)
|
||||||
{
|
{
|
||||||
updateTerrainType(*suitableTiles.begin());
|
updateTerrainType(*suitableTiles.begin(), tileRequiresValidation);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const int3 directions[] = { int3(0, -1, 0), int3(-1, 0, 0), int3(0, 1, 0), int3(1, 0, 0),
|
static const int3 directions[] = { int3(0, -1, 0), int3(-1, 0, 0), int3(0, 1, 0), int3(1, 0, 0),
|
||||||
int3(-1, -1, 0), int3(-1, 1, 0), int3(1, 1, 0), int3(1, -1, 0)};
|
int3(-1, -1, 0), int3(-1, 1, 0), int3(1, 1, 0), int3(1, -1, 0)};
|
||||||
for(int i = 0; i < ARRAY_COUNT(directions); ++i)
|
for(int i = 0; i < ARRAY_COUNT(directions); ++i)
|
||||||
{
|
{
|
||||||
auto it = suitableTiles.find(centerPos + directions[i]);
|
auto it = suitableTiles.find(centerPos + directions[i]);
|
||||||
if(it != suitableTiles.end())
|
if(it != suitableTiles.end())
|
||||||
{
|
{
|
||||||
updateTerrainType(*it);
|
updateTerrainType(*it, tileRequiresValidation);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -539,7 +565,7 @@ void CDrawTerrainOperation::updateTerrainViews()
|
|||||||
BOOST_FOREACH(const auto & pos, invalidatedTerViews)
|
BOOST_FOREACH(const auto & pos, invalidatedTerViews)
|
||||||
{
|
{
|
||||||
const auto & patterns =
|
const auto & patterns =
|
||||||
CTerrainViewPatternConfig::get().getPatternsForGroup(getTerrainGroup(map->getTile(pos).terType));
|
CTerrainViewPatternConfig::get().getTerrainViewPatternsForGroup(getTerrainGroup(map->getTile(pos).terType));
|
||||||
|
|
||||||
// Detect a pattern which fits best
|
// Detect a pattern which fits best
|
||||||
int bestPattern = -1;
|
int bestPattern = -1;
|
||||||
@ -556,7 +582,7 @@ void CDrawTerrainOperation::updateTerrainViews()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(bestPattern != -1);
|
//assert(bestPattern != -1);
|
||||||
if(bestPattern == -1)
|
if(bestPattern == -1)
|
||||||
{
|
{
|
||||||
// This shouldn't be the case
|
// This shouldn't be the case
|
||||||
@ -627,7 +653,8 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
|
|||||||
|
|
||||||
CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainViewInner(const int3 & pos, const TerrainViewPattern & pattern, int recDepth /*= 0*/) const
|
CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainViewInner(const int3 & pos, const TerrainViewPattern & pattern, int recDepth /*= 0*/) const
|
||||||
{
|
{
|
||||||
ETerrainType centerTerType = map->getTile(pos).terType;
|
auto centerTerType = map->getTile(pos).terType;
|
||||||
|
auto centerTerGroup = getTerrainGroup(centerTerType);
|
||||||
int totalPoints = 0;
|
int totalPoints = 0;
|
||||||
std::string transitionReplacement;
|
std::string transitionReplacement;
|
||||||
|
|
||||||
@ -667,11 +694,14 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
|
|||||||
{
|
{
|
||||||
if(recDepth == 0 && map->isInTheMap(currentPos))
|
if(recDepth == 0 && map->isInTheMap(currentPos))
|
||||||
{
|
{
|
||||||
const auto & patternForRule = CTerrainViewPatternConfig::get().getPatternById(getTerrainGroup(terType), rule.name);
|
if(terType == centerTerType)
|
||||||
if(patternForRule)
|
|
||||||
{
|
{
|
||||||
auto rslt = validateTerrainView(currentPos, *patternForRule, 1);
|
const auto & patternForRule = CTerrainViewPatternConfig::get().getTerrainViewPatternById(getTerrainGroup(centerTerType), rule.name);
|
||||||
if(rslt.result) topPoints = std::max(topPoints, rule.points);
|
if(patternForRule)
|
||||||
|
{
|
||||||
|
auto rslt = validateTerrainView(currentPos, *patternForRule, 1);
|
||||||
|
if(rslt.result) topPoints = std::max(topPoints, rule.points);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -690,7 +720,9 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Validate cell with the ruleset of the pattern
|
// Validate cell with the ruleset of the pattern
|
||||||
if(pattern.terGroup == ETerrainGroup::NORMAL)
|
bool nativeTestOk, nativeTestStrongOk;
|
||||||
|
nativeTestOk = nativeTestStrongOk = (rule.name == TerrainViewPattern::RULE_NATIVE_STRONG || rule.name == TerrainViewPattern::RULE_NATIVE) && !isAlien;
|
||||||
|
if(centerTerGroup == ETerrainGroup::NORMAL)
|
||||||
{
|
{
|
||||||
bool dirtTestOk = (rule.name == TerrainViewPattern::RULE_DIRT || rule.name == TerrainViewPattern::RULE_TRANSITION)
|
bool dirtTestOk = (rule.name == TerrainViewPattern::RULE_DIRT || rule.name == TerrainViewPattern::RULE_TRANSITION)
|
||||||
&& isAlien && !isSandType(terType);
|
&& isAlien && !isSandType(terType);
|
||||||
@ -709,24 +741,22 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool nativeTestOk = rule.name == TerrainViewPattern::RULE_NATIVE && !isAlien;
|
|
||||||
applyValidationRslt(rule.name == TerrainViewPattern::RULE_ANY || dirtTestOk || sandTestOk || nativeTestOk);
|
applyValidationRslt(rule.name == TerrainViewPattern::RULE_ANY || dirtTestOk || sandTestOk || nativeTestOk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(pattern.terGroup == ETerrainGroup::DIRT)
|
else if(centerTerGroup == ETerrainGroup::DIRT)
|
||||||
{
|
{
|
||||||
bool nativeTestOk = rule.name == TerrainViewPattern::RULE_NATIVE && !isSandType(terType);
|
nativeTestOk = rule.name == TerrainViewPattern::RULE_NATIVE && !isSandType(terType);
|
||||||
bool sandTestOk = (rule.name == TerrainViewPattern::RULE_SAND || rule.name == TerrainViewPattern::RULE_TRANSITION)
|
bool sandTestOk = (rule.name == TerrainViewPattern::RULE_SAND || rule.name == TerrainViewPattern::RULE_TRANSITION)
|
||||||
&& isSandType(terType);
|
&& isSandType(terType);
|
||||||
applyValidationRslt(rule.name == TerrainViewPattern::RULE_ANY || sandTestOk || nativeTestOk);
|
applyValidationRslt(rule.name == TerrainViewPattern::RULE_ANY || sandTestOk || nativeTestOk || nativeTestStrongOk);
|
||||||
}
|
}
|
||||||
else if(pattern.terGroup == ETerrainGroup::SAND)
|
else if(centerTerGroup == ETerrainGroup::SAND)
|
||||||
{
|
{
|
||||||
applyValidationRslt(true);
|
applyValidationRslt(true);
|
||||||
}
|
}
|
||||||
else if(pattern.terGroup == ETerrainGroup::WATER || pattern.terGroup == ETerrainGroup::ROCK)
|
else if(centerTerGroup == ETerrainGroup::WATER || centerTerGroup == ETerrainGroup::ROCK)
|
||||||
{
|
{
|
||||||
bool nativeTestOk = rule.name == TerrainViewPattern::RULE_NATIVE && !isAlien;
|
|
||||||
bool sandTestOk = (rule.name == TerrainViewPattern::RULE_SAND || rule.name == TerrainViewPattern::RULE_TRANSITION)
|
bool sandTestOk = (rule.name == TerrainViewPattern::RULE_SAND || rule.name == TerrainViewPattern::RULE_TRANSITION)
|
||||||
&& isAlien;
|
&& isAlien;
|
||||||
applyValidationRslt(rule.name == TerrainViewPattern::RULE_ANY || sandTestOk || nativeTestOk);
|
applyValidationRslt(rule.name == TerrainViewPattern::RULE_ANY || sandTestOk || nativeTestOk);
|
||||||
@ -811,20 +841,31 @@ CDrawTerrainOperation::InvalidTiles CDrawTerrainOperation::getInvalidTiles(const
|
|||||||
{
|
{
|
||||||
if(map->isInTheMap(pos))
|
if(map->isInTheMap(pos))
|
||||||
{
|
{
|
||||||
|
auto & ptrConfig = CTerrainViewPatternConfig::get();
|
||||||
auto terType = map->getTile(pos).terType;
|
auto terType = map->getTile(pos).terType;
|
||||||
// Pattern 2x2
|
auto valid = validateTerrainView(pos, ptrConfig.getTerrainTypePatternById("n1")).result;
|
||||||
const int3 translations[4] = { int3(-1, -1, 0), int3(0, -1, 0), int3(-1, 0, 0), int3(0, 0, 0) };
|
|
||||||
bool valid = true;
|
// Special validity check for rock & water
|
||||||
for(int i = 0; i < ARRAY_COUNT(translations); ++i)
|
if(valid && centerTerType != terType && (terType == ETerrainType::WATER || terType == ETerrainType::ROCK))
|
||||||
{
|
{
|
||||||
valid = true;
|
static const std::string patternIds[] = { "s1", "s2" };
|
||||||
MapRect square(int3(pos.x + translations[i].x, pos.y + translations[i].y, pos.z), 2, 2);
|
for(int i = 0; i < ARRAY_COUNT(patternIds); ++i)
|
||||||
square.forEach([&](const int3 & pos)
|
|
||||||
{
|
{
|
||||||
if(map->isInTheMap(pos) && map->getTile(pos).terType != terType) valid = false;
|
valid = !validateTerrainView(pos, ptrConfig.getTerrainTypePatternById(patternIds[i])).result;
|
||||||
});
|
if(!valid) break;
|
||||||
if(valid) break;
|
}
|
||||||
}
|
}
|
||||||
|
// Additional validity check for non rock OR water
|
||||||
|
else if(!valid && (terType != ETerrainType::WATER && terType != ETerrainType::ROCK))
|
||||||
|
{
|
||||||
|
static const std::string patternIds[] = { "n2", "n3" };
|
||||||
|
for(int i = 0; i < ARRAY_COUNT(patternIds); ++i)
|
||||||
|
{
|
||||||
|
valid = validateTerrainView(pos, ptrConfig.getTerrainTypePatternById(patternIds[i])).result;
|
||||||
|
if(valid) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!valid)
|
if(!valid)
|
||||||
{
|
{
|
||||||
if(terType == centerTerType) tiles.nativeTiles.insert(pos);
|
if(terType == centerTerType) tiles.nativeTiles.insert(pos);
|
||||||
|
@ -42,9 +42,9 @@ struct DLL_LINKAGE MapRect
|
|||||||
template<typename Func>
|
template<typename Func>
|
||||||
void forEach(Func f) const
|
void forEach(Func f) const
|
||||||
{
|
{
|
||||||
for(int i = x; i < right(); ++i)
|
for(int j = y; j < bottom(); ++j)
|
||||||
{
|
{
|
||||||
for(int j = y; j < bottom(); ++j)
|
for(int i = x; i < right(); ++i)
|
||||||
{
|
{
|
||||||
f(int3(i, j, z));
|
f(int3(i, j, z));
|
||||||
}
|
}
|
||||||
@ -225,6 +225,7 @@ struct DLL_LINKAGE TerrainViewPattern
|
|||||||
int points;
|
int points;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const int PATTERN_DATA_SIZE = 9;
|
||||||
/// Constant for the flip mode different images. Pattern will be flipped and different images will be used(mapping area is divided into 4 parts)
|
/// Constant for the flip mode different images. Pattern will be flipped and different images will be used(mapping area is divided into 4 parts)
|
||||||
static const std::string FLIP_MODE_DIFF_IMAGES;
|
static const std::string FLIP_MODE_DIFF_IMAGES;
|
||||||
/// Constant for the rule dirt, meaning a dirty border is required.
|
/// Constant for the rule dirt, meaning a dirty border is required.
|
||||||
@ -233,8 +234,10 @@ struct DLL_LINKAGE TerrainViewPattern
|
|||||||
static const std::string RULE_SAND;
|
static const std::string RULE_SAND;
|
||||||
/// Constant for the rule transition, meaning a dirty OR sandy border is required.
|
/// Constant for the rule transition, meaning a dirty OR sandy border is required.
|
||||||
static const std::string RULE_TRANSITION;
|
static const std::string RULE_TRANSITION;
|
||||||
/// Constant for the rule native, meaning a native type is required.
|
/// Constant for the rule native, meaning a native border is required.
|
||||||
static const std::string RULE_NATIVE;
|
static const std::string RULE_NATIVE;
|
||||||
|
/// Constant for the rule native strong, meaning a native type is required.
|
||||||
|
static const std::string RULE_NATIVE_STRONG;
|
||||||
/// Constant for the rule any, meaning a native type, dirty OR sandy border is required.
|
/// Constant for the rule any, meaning a native type, dirty OR sandy border is required.
|
||||||
static const std::string RULE_ANY;
|
static const std::string RULE_ANY;
|
||||||
|
|
||||||
@ -250,7 +253,7 @@ struct DLL_LINKAGE TerrainViewPattern
|
|||||||
/// can be used. Their meaning differs also from type to type.
|
/// can be used. Their meaning differs also from type to type.
|
||||||
///
|
///
|
||||||
/// std::vector -> several rules can be used in one cell
|
/// std::vector -> several rules can be used in one cell
|
||||||
std::array<std::vector<WeightedRule>, 9> data;
|
std::array<std::vector<WeightedRule>, PATTERN_DATA_SIZE> data;
|
||||||
|
|
||||||
/// The identifier of the pattern, if it's referenced from a another pattern.
|
/// The identifier of the pattern, if it's referenced from a another pattern.
|
||||||
std::string id;
|
std::string id;
|
||||||
@ -270,8 +273,6 @@ struct DLL_LINKAGE TerrainViewPattern
|
|||||||
|
|
||||||
/// The minimum and maximum points to reach to validate the pattern successfully.
|
/// The minimum and maximum points to reach to validate the pattern successfully.
|
||||||
int minPoints, maxPoints;
|
int minPoints, maxPoints;
|
||||||
|
|
||||||
ETerrainGroup::ETerrainGroup terGroup;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The terrain view pattern config loads pattern data from the filesystem.
|
/// The terrain view pattern config loads pattern data from the filesystem.
|
||||||
@ -280,15 +281,17 @@ class DLL_LINKAGE CTerrainViewPatternConfig : public boost::noncopyable
|
|||||||
public:
|
public:
|
||||||
static CTerrainViewPatternConfig & get();
|
static CTerrainViewPatternConfig & get();
|
||||||
|
|
||||||
const std::vector<TerrainViewPattern> & getPatternsForGroup(ETerrainGroup::ETerrainGroup terGroup) const;
|
const std::vector<TerrainViewPattern> & getTerrainViewPatternsForGroup(ETerrainGroup::ETerrainGroup terGroup) const;
|
||||||
boost::optional<const TerrainViewPattern &> getPatternById(ETerrainGroup::ETerrainGroup terGroup, const std::string & id) const;
|
boost::optional<const TerrainViewPattern &> getTerrainViewPatternById(ETerrainGroup::ETerrainGroup terGroup, const std::string & id) const;
|
||||||
|
const TerrainViewPattern & getTerrainTypePatternById(const std::string & id) const;
|
||||||
ETerrainGroup::ETerrainGroup getTerrainGroup(const std::string & terGroup) const;
|
ETerrainGroup::ETerrainGroup getTerrainGroup(const std::string & terGroup) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CTerrainViewPatternConfig();
|
CTerrainViewPatternConfig();
|
||||||
~CTerrainViewPatternConfig();
|
~CTerrainViewPatternConfig();
|
||||||
|
|
||||||
std::map<ETerrainGroup::ETerrainGroup, std::vector<TerrainViewPattern> > patterns;
|
std::map<ETerrainGroup::ETerrainGroup, std::vector<TerrainViewPattern> > terrainViewPatterns;
|
||||||
|
std::map<std::string, TerrainViewPattern> terrainTypePatterns;
|
||||||
static boost::mutex smx;
|
static boost::mutex smx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,7 +21,62 @@
|
|||||||
#include "../lib/int3.h"
|
#include "../lib/int3.h"
|
||||||
#include "../lib/CRandomGenerator.h"
|
#include "../lib/CRandomGenerator.h"
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(CMapEditManager_DrawTerrain)
|
BOOST_AUTO_TEST_CASE(CMapEditManager_DrawTerrain_Type)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto map = make_unique<CMap>();
|
||||||
|
map->width = 100;
|
||||||
|
map->height = 100;
|
||||||
|
map->initTerrain();
|
||||||
|
auto editManager = map->getEditManager();
|
||||||
|
editManager->clearTerrain();
|
||||||
|
|
||||||
|
// 1x1 Blow up
|
||||||
|
editManager->getTerrainSelection().select(int3(5, 5, 0));
|
||||||
|
editManager->drawTerrain(ETerrainType::GRASS);
|
||||||
|
static const int3 squareCheck[] = { int3(5,5,0), int3(5,4,0), int3(4,4,0), int3(4,5,0) };
|
||||||
|
for(int i = 0; i < ARRAY_COUNT(squareCheck); ++i)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(map->getTile(squareCheck[i]).terType == ETerrainType::GRASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Concat to square
|
||||||
|
editManager->getTerrainSelection().select(int3(6, 5, 0));
|
||||||
|
editManager->drawTerrain(ETerrainType::GRASS);
|
||||||
|
BOOST_CHECK(map->getTile(int3(6, 4, 0)).terType == ETerrainType::GRASS);
|
||||||
|
editManager->getTerrainSelection().select(int3(6, 5, 0));
|
||||||
|
editManager->drawTerrain(ETerrainType::LAVA);
|
||||||
|
BOOST_CHECK(map->getTile(int3(4, 4, 0)).terType == ETerrainType::GRASS);
|
||||||
|
BOOST_CHECK(map->getTile(int3(7, 4, 0)).terType == ETerrainType::LAVA);
|
||||||
|
|
||||||
|
// Special case water,rock
|
||||||
|
editManager->getTerrainSelection().selectRange(MapRect(int3(10, 10, 0), 10, 5));
|
||||||
|
editManager->drawTerrain(ETerrainType::GRASS);
|
||||||
|
editManager->getTerrainSelection().selectRange(MapRect(int3(15, 17, 0), 10, 5));
|
||||||
|
editManager->drawTerrain(ETerrainType::GRASS);
|
||||||
|
editManager->getTerrainSelection().select(int3(21, 16, 0));
|
||||||
|
editManager->drawTerrain(ETerrainType::GRASS);
|
||||||
|
BOOST_CHECK(map->getTile(int3(20, 15, 0)).terType == ETerrainType::GRASS);
|
||||||
|
|
||||||
|
// Special case non water,rock
|
||||||
|
static const int3 diagonalCheck[] = { int3(31,42,0), int3(32,42,0), int3(32,43,0), int3(33,43,0), int3(33,44,0),
|
||||||
|
int3(34,44,0), int3(34,45,0), int3(35,45,0), int3(35,46,0), int3(36,46,0),
|
||||||
|
int3(36,47,0), int3(37,47,0)};
|
||||||
|
for(int i = 0; i < ARRAY_COUNT(diagonalCheck); ++i)
|
||||||
|
{
|
||||||
|
editManager->getTerrainSelection().select(diagonalCheck[i]);
|
||||||
|
}
|
||||||
|
editManager->drawTerrain(ETerrainType::GRASS);
|
||||||
|
BOOST_CHECK(map->getTile(int3(35, 44, 0)).terType == ETerrainType::WATER);
|
||||||
|
}
|
||||||
|
catch(const std::exception & e)
|
||||||
|
{
|
||||||
|
logGlobal-> errorStream() << e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(CMapEditManager_DrawTerrain_View)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -49,7 +104,7 @@ BOOST_AUTO_TEST_CASE(CMapEditManager_DrawTerrain)
|
|||||||
auto terGroup = CTerrainViewPatternConfig::get().getTerrainGroup(groupStr);
|
auto terGroup = CTerrainViewPatternConfig::get().getTerrainGroup(groupStr);
|
||||||
|
|
||||||
// Get mapping range
|
// Get mapping range
|
||||||
const auto & pattern = CTerrainViewPatternConfig::get().getPatternById(terGroup, id);
|
const auto & pattern = CTerrainViewPatternConfig::get().getTerrainViewPatternById(terGroup, id);
|
||||||
const auto & mapping = (*pattern).mapping;
|
const auto & mapping = (*pattern).mapping;
|
||||||
|
|
||||||
const auto & positionsNode = node["pos"].Vector();
|
const auto & positionsNode = node["pos"].Vector();
|
||||||
|
Binary file not shown.
@ -18,7 +18,7 @@
|
|||||||
"pattern" : "normal.s4"
|
"pattern" : "normal.s4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pos" : [ [ 5,14,0 ], [ 31,13,0 ] ],
|
"pos" : [ [ 5,14,0 ], [ 31,13,0 ], [ 17,3,0 ], [ 13,8,0 ] ],
|
||||||
"pattern" : "normal.s5"
|
"pattern" : "normal.s5"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user