diff --git a/lib/mapping/CDrawRoadsOperation.cpp b/lib/mapping/CDrawRoadsOperation.cpp index c8fc0cbe1..2bd52a563 100644 --- a/lib/mapping/CDrawRoadsOperation.cpp +++ b/lib/mapping/CDrawRoadsOperation.cpp @@ -12,7 +12,7 @@ #include "CDrawRoadsOperation.h" #include "CMap.h" -const std::vector CDrawRoadsOperation::patterns = +const std::vector CDrawRoadsOperation::patterns = { //single tile. fall-back pattern { @@ -31,7 +31,7 @@ const std::vector CDrawRoadsOperation::pattern { "?","-","+", "-","+","+", - "+","+","?" + "+","+","?" }, {2,5}, {-1,-1}, @@ -43,7 +43,7 @@ const std::vector CDrawRoadsOperation::pattern { "?","-","?", "-","+","+", - "?","+","?" + "?","+","?" }, {0,1}, {0,3}, @@ -55,7 +55,7 @@ const std::vector CDrawRoadsOperation::pattern { "?","-","?", "-","+","+", - "?","-","?" + "?","-","?" }, {15,15},{11,12}, true, @@ -66,7 +66,7 @@ const std::vector CDrawRoadsOperation::pattern { "?","-","?", "-","+","-", - "?","+","?" + "?","+","?" }, {14,14},{9,10}, false, @@ -77,7 +77,7 @@ const std::vector CDrawRoadsOperation::pattern { "?","+","?", "-","+","+", - "?","+","?" + "?","+","?" }, {6,7},{7,8}, true, @@ -88,46 +88,46 @@ const std::vector CDrawRoadsOperation::pattern { "?","-","?", "+","+","+", - "?","+","?" + "?","+","?" }, {8,9},{5,6}, false, true }, - //Straight Horizontal + //Straight Horizontal { { "?","-","?", "+","+","+", - "?","-","?" + "?","-","?" }, {12,13},{11,12}, false, false }, - //Straight Vertical + //Straight Vertical { { "?","+","?", "-","+","-", - "?","+","?" + "?","+","?" }, {10,11},{9,10}, false, false }, - //X-cross + //X-cross { { "?","+","?", "+","+","+", - "?","+","?" + "?","+","?" }, {16,16},{4,4}, false, false - } - + } + }; static bool ruleIsNone(const std::string & rule) @@ -140,45 +140,47 @@ static bool ruleIsSomething(const std::string & rule) return rule == "+"; } +#ifndef NDEBUG static bool ruleIsAny(const std::string & rule) { return rule == "?"; } +#endif ///CDrawRoadsOperation CDrawRoadsOperation::CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, ERoadType::ERoadType roadType, CRandomGenerator * gen): CMapOperation(map),terrainSel(terrainSel), roadType(roadType), gen(gen) { - + } void CDrawRoadsOperation::execute() { std::set invalidated; - + for(const auto & pos : terrainSel.getSelectedItems()) { auto & tile = map->getTile(pos); tile.roadType = roadType; - + auto rect = extendTileAroundSafely(pos); rect.forEach([&invalidated](const int3 & pos) { invalidated.insert(pos); }); } - - updateTiles(invalidated); + + updateTiles(invalidated); } void CDrawRoadsOperation::undo() { - //TODO + //TODO } void CDrawRoadsOperation::redo() { - //TODO + //TODO } std::string CDrawRoadsOperation::getLabel() const @@ -188,14 +190,14 @@ std::string CDrawRoadsOperation::getLabel() const bool CDrawRoadsOperation::canApplyPattern(const RoadPattern & pattern) const { - //TODO: this method should be virtual for river support + //TODO: this method should be virtual for river support return pattern.roadMapping.first >= 0; } void CDrawRoadsOperation::flipPattern(RoadPattern& pattern, int flip) const { //todo: use cashing here and also in terrain patterns - + if(flip == 0) { return; @@ -217,7 +219,7 @@ void CDrawRoadsOperation::flipPattern(RoadPattern& pattern, int flip) const { std::swap(pattern.data[i], pattern.data[6 + i]); } - } + } } @@ -226,98 +228,98 @@ bool CDrawRoadsOperation::needUpdateTile(const TerrainTile & tile) const return tile.roadType != ERoadType::NO_ROAD; //TODO: this method should be virtual for river support } -void CDrawRoadsOperation::updateTiles(std::set & invalidated) +void CDrawRoadsOperation::updateTiles(std::set & invalidated) { for(int3 coord : invalidated) { TerrainTile & tile = map->getTile(coord); ValidationResult result(false); - + if(!needUpdateTile(tile)) continue; - + int bestPattern = -1; - + for(int k = 0; k < patterns.size(); ++k) { result = validateTile(patterns[k], coord); - + if(result.result) { bestPattern = k; break; } } - + if(bestPattern != -1) { updateTile(tile, patterns[bestPattern], result.flip); } - + } }; bool CDrawRoadsOperation::tileHasSomething(const int3& pos) const { -//TODO: this method should be virtual for river support +//TODO: this method should be virtual for river support - return map->getTile(pos).roadType != ERoadType::NO_ROAD; + return map->getTile(pos).roadType != ERoadType::NO_ROAD; } void CDrawRoadsOperation::updateTile(TerrainTile & tile, const RoadPattern & pattern, const int flip) { - //TODO: this method should be virtual for river support - + //TODO: this method should be virtual for river support + const std::pair & mapping = pattern.roadMapping; - + tile.roadDir = gen->nextInt(mapping.first, mapping.second); - tile.extTileFlags = (tile.extTileFlags & 0xCF) | (flip << 4); + tile.extTileFlags = (tile.extTileFlags & 0xCF) | (flip << 4); } CDrawRoadsOperation::ValidationResult CDrawRoadsOperation::validateTile(const RoadPattern & pattern, const int3 & pos) { ValidationResult result(false); - + if(!canApplyPattern(pattern)) return result; - - + + for(int flip = 0; flip < 4; ++flip) { - if((flip == FLIP_PATTERN_BOTH) && !(pattern.hasHFlip && pattern.hasVFlip)) + if((flip == FLIP_PATTERN_BOTH) && !(pattern.hasHFlip && pattern.hasVFlip)) continue; - if((flip == FLIP_PATTERN_HORIZONTAL) && !pattern.hasHFlip) + if((flip == FLIP_PATTERN_HORIZONTAL) && !pattern.hasHFlip) continue; - if((flip == FLIP_PATTERN_VERTICAL) && !(pattern.hasVFlip)) + if((flip == FLIP_PATTERN_VERTICAL) && !(pattern.hasVFlip)) continue; - - RoadPattern flipped = pattern; - + + RoadPattern flipped = pattern; + flipPattern(flipped, flip); - + bool validated = true; - + for(int i = 0; i < 9; ++i) { if(4 == i) continue; int cx = pos.x + (i % 3) - 1; int cy = pos.y + (i / 3) - 1; - + int3 currentPos(cx, cy, pos.z); - + bool hasSomething; - + if(!map->isInTheMap(currentPos)) { hasSomething = true; //road/river can go out of map } else { - hasSomething = tileHasSomething(currentPos); + hasSomething = tileHasSomething(currentPos); } - + if(ruleIsSomething(flipped.data[i])) { if(!hasSomething) @@ -332,23 +334,22 @@ CDrawRoadsOperation::ValidationResult CDrawRoadsOperation::validateTile(const Ro { validated = false; break; - } + } } else { - assert(ruleIsAny(flipped.data[i])); - } - + assert(ruleIsAny(flipped.data[i])); + } + } - + if(validated) { result.result = true; result.flip = flip; - return result; - } + return result; + } } - + return result; } -