1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-15 00:05:02 +02:00

- Fixed a few bugs related to the terrain view generation - Updated CMakeLists in /test(copy resources if no source files has been changed too)

This commit is contained in:
beegee1
2013-04-25 16:09:48 +00:00
parent 8273f323b1
commit 23f7be2a54
5 changed files with 97 additions and 71 deletions

View File

@ -301,7 +301,10 @@ CTerrainViewPatternConfig::CTerrainViewPatternConfig()
// Read optional attributes
pattern.id = ptrnNode["id"].String();
assert(!pattern.id.empty());
pattern.minPoints = static_cast<int>(ptrnNode["minPoints"].Float());
pattern.maxPoints = static_cast<int>(ptrnNode["maxPoints"].Float());
if(pattern.maxPoints == 0) pattern.maxPoints = std::numeric_limits<int>::max();
pattern.flipMode = ptrnNode["flipMode"].String();
if(pattern.flipMode.empty())
{
@ -388,65 +391,59 @@ std::string CDrawTerrainOperation::getLabel() const
void CDrawTerrainOperation::updateTerrainViews(const MapRect & rect)
{
for(int i = rect.x; i < rect.x + rect.width; ++i)
for(int x = rect.x; x < rect.x + rect.width; ++x)
{
for(int j = rect.y; j < rect.y + rect.height; ++j)
for(int y = rect.y; y < rect.y + rect.height; ++y)
{
const auto & patterns =
CTerrainViewPatternConfig::get().getPatternsForGroup(getTerrainGroup(map->getTile(int3(i, j, rect.z)).terType));
CTerrainViewPatternConfig::get().getPatternsForGroup(getTerrainGroup(map->getTile(int3(x, y, rect.z)).terType));
// Detect a pattern which fits best
int bestPattern = -1, bestFlip = -1;
std::string transitionReplacement;
int bestPattern = -1;
ValidationResult valRslt(false);
for(int k = 0; k < patterns.size(); ++k)
{
const auto & pattern = patterns[k];
for(int flip = 0; flip < 4; ++flip)
valRslt = validateTerrainView(int3(x, y, rect.z), pattern);
if(valRslt.result)
{
auto valRslt = validateTerrainView(int3(i, j, rect.z), flip > 0 ? getFlippedPattern(pattern, flip) : pattern);
if(valRslt.result)
{
logGlobal->debugStream() << "Pattern detected at pos " << i << "x" << j << "x" << rect.z << ": P-Nr. " << k
<< ", Flip " << flip << ", Repl. " << valRslt.transitionReplacement;
bestPattern = k;
bestFlip = flip;
transitionReplacement = valRslt.transitionReplacement;
break;
}
logGlobal->debugStream() << "Pattern detected at pos " << x << "x" << y << "x" << rect.z << ": P-Nr. " << pattern.id
<< ", Flip " << valRslt.flip << ", Repl. " << valRslt.transitionReplacement;
bestPattern = k;
break;
}
}
//assert(bestPattern != -1);
if(bestPattern == -1)
{
// This shouldn't be the case
logGlobal->warnStream() << "No pattern detected at pos " << i << "x" << j << "x" << rect.z;
logGlobal->warnStream() << "No pattern detected at pos " << x << "x" << y << "x" << rect.z;
continue;
}
// Get mapping
const TerrainViewPattern & pattern = patterns[bestPattern];
std::pair<int, int> mapping;
if(transitionReplacement.empty())
if(valRslt.transitionReplacement.empty())
{
mapping = pattern.mapping[0];
}
else
{
mapping = transitionReplacement == TerrainViewPattern::RULE_DIRT ? pattern.mapping[0] : pattern.mapping[1];
mapping = valRslt.transitionReplacement == TerrainViewPattern::RULE_DIRT ? pattern.mapping[0] : pattern.mapping[1];
}
// Set terrain view
auto & tile = map->getTile(int3(i, j, rect.z));
auto & tile = map->getTile(int3(x, y, rect.z));
if(pattern.flipMode == TerrainViewPattern::FLIP_MODE_SAME_IMAGE)
{
tile.terView = gen->getInteger(mapping.first, mapping.second);
tile.extTileFlags = bestFlip;
tile.extTileFlags = valRslt.flip;
}
else
{
const int framesPerRot = 2;
int firstFrame = mapping.first + bestFlip * framesPerRot;
int firstFrame = mapping.first + valRslt.flip * framesPerRot;
tile.terView = gen->getInteger(firstFrame, firstFrame + framesPerRot - 1);
tile.extTileFlags = 0;
}
@ -472,6 +469,20 @@ ETerrainGroup::ETerrainGroup CDrawTerrainOperation::getTerrainGroup(ETerrainType
}
CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainView(const int3 & pos, const TerrainViewPattern & pattern, int recDepth /*= 0*/) const
{
for(int flip = 0; flip < 4; ++flip)
{
auto valRslt = validateTerrainViewInner(pos, flip > 0 ? getFlippedPattern(pattern, flip) : pattern, recDepth);
if(valRslt.result)
{
valRslt.flip = flip;
return valRslt;
}
}
return ValidationResult(false);
}
CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainViewInner(const int3 & pos, const TerrainViewPattern & pattern, int recDepth /*= 0*/) const
{
ETerrainType centerTerType = map->getTile(pos).terType;
int totalPoints = 0;
@ -488,15 +499,16 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
// Get terrain group of the current cell
int cx = pos.x + (i % 3) - 1;
int cy = pos.y + (i / 3) - 1;
int3 currentPos(cx, cy, pos.z);
bool isAlien = false;
ETerrainType terType;
if(cx < 0 || cx >= map->width || cy < 0 || cy >= map->height)
if(!map->isInTheMap(currentPos))
{
terType = centerTerType;
}
else
{
terType = map->getTile(int3(cx, cy, pos.z)).terType;
terType = map->getTile(currentPos).terType;
if(terType != centerTerType)
{
isAlien = true;
@ -512,17 +524,13 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
{
if(recDepth == 0)
{
const auto & patternForRule = CTerrainViewPatternConfig::get().getPatternById(pattern.terGroup, rule.name);
auto rslt = validateTerrainView(int3(cx, cy, pos.z), patternForRule, 1);
if(!rslt.result)
if(map->isInTheMap(currentPos) && terType == centerTerType)
{
return ValidationResult(false);
}
else
{
topPoints = std::max(topPoints, rule.points);
continue;
const auto & patternForRule = CTerrainViewPatternConfig::get().getPatternById(pattern.terGroup, rule.name);
auto rslt = validateTerrainView(currentPos, patternForRule, 1);
if(rslt.result) topPoints = std::max(topPoints, rule.points);
}
continue;
}
else
{
@ -549,14 +557,20 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
|| rule.name == TerrainViewPattern::RULE_ANY)
&& isSandType(terType);
if(transitionReplacement.empty() && (rule.name == TerrainViewPattern::RULE_TRANSITION
|| rule.name == TerrainViewPattern::RULE_ANY) && (dirtTestOk || sandTestOk))
if(transitionReplacement.empty() && rule.name == TerrainViewPattern::RULE_TRANSITION
&& (dirtTestOk || sandTestOk))
{
transitionReplacement = dirtTestOk ? TerrainViewPattern::RULE_DIRT : TerrainViewPattern::RULE_SAND;
}
applyValidationRslt((dirtTestOk && transitionReplacement != TerrainViewPattern::RULE_SAND)
|| (sandTestOk && transitionReplacement != TerrainViewPattern::RULE_DIRT)
|| nativeTestOk);
if(rule.name == TerrainViewPattern::RULE_TRANSITION)
{
applyValidationRslt((dirtTestOk && transitionReplacement != TerrainViewPattern::RULE_SAND) ||
(sandTestOk && transitionReplacement != TerrainViewPattern::RULE_DIRT));
}
else
{
applyValidationRslt(dirtTestOk || sandTestOk || nativeTestOk);
}
}
else if(pattern.terGroup == ETerrainGroup::DIRT)
{
@ -593,12 +607,14 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
}
}
if(pattern.minPoints > totalPoints)
if(totalPoints >= pattern.minPoints && totalPoints <= pattern.maxPoints)
{
return ValidationResult(true, transitionReplacement);
}
else
{
return ValidationResult(false);
}
return ValidationResult(true, transitionReplacement);
}
bool CDrawTerrainOperation::isSandType(ETerrainType terType) const