| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 | 
							- /*
 
-  * CDrawRoadsOperation.cpp, part of VCMI engine
 
-  *
 
-  * Authors: listed in file AUTHORS in main folder
 
-  *
 
-  * License: GNU General Public License v2.0 or later
 
-  * Full text of license available in license.txt file, in main folder
 
-  *
 
-  */
 
- #include "StdInc.h"
 
- #include "CDrawRoadsOperation.h"
 
- #include "CMap.h"
 
- VCMI_LIB_NAMESPACE_BEGIN
 
- const std::vector<CDrawLinesOperation::LinePattern> CDrawLinesOperation::patterns =
 
- {
 
- 	//single tile. fall-back pattern
 
- 	{
 
- 		{
 
-           "-","-","-",
 
-           "-","+","-",
 
-           "-","-","-"
 
-         },
 
-         {14,14},
 
-         {9,9},
 
-         false,
 
-         false
 
- 	},
 
- 	//Road straight with angle
 
- 	{
 
- 		{
 
-           "?","-","+",
 
-           "-","+","+",
 
-           "+","+","?"
 
-         },
 
-         {2,5},
 
-         {-1,-1},
 
-         true,
 
-         true
 
- 	},
 
- 	//Turn
 
- 	{
 
- 		{
 
-           "?","-","?",
 
-           "-","+","+",
 
-           "?","+","?"
 
-         },
 
-         {0,1},
 
-         {0,3},
 
-         true,
 
-         true
 
- 	},
 
- 	//Dead end horizontal
 
- 	{
 
- 		{
 
-           "?","-","?",
 
-           "-","+","+",
 
-           "?","-","?"
 
-         },
 
-         {15,15},{11,12},
 
-         true,
 
-         false
 
- 	},
 
- 	//Dead end vertical
 
- 	{
 
- 		{
 
-           "?","-","?",
 
-           "-","+","-",
 
-           "?","+","?"
 
-         },
 
-         {14,14},{9,10},
 
-         false,
 
-         true
 
- 	},
 
- 	//T-cross horizontal
 
- 	{
 
- 		{
 
-           "?","+","?",
 
-           "-","+","+",
 
-           "?","+","?"
 
-         },
 
-         {6,7},{7,8},
 
-         true,
 
-         false
 
- 	},
 
- 	//T-cross vertical
 
- 	{
 
- 		{
 
-           "?","-","?",
 
-           "+","+","+",
 
-           "?","+","?"
 
-         },
 
-         {8,9},{5,6},
 
-         false,
 
-         true
 
- 	},
 
- 	//Straight Horizontal
 
- 	{
 
- 		{
 
-           "?","-","?",
 
-           "+","+","+",
 
-           "?","-","?"
 
-         },
 
-         {12,13},{11,12},
 
-         false,
 
-         false
 
- 	},
 
- 	//Straight Vertical
 
- 	{
 
- 		{
 
-           "?","+","?",
 
-           "-","+","-",
 
-           "?","+","?"
 
-         },
 
-         {10,11},{9,10},
 
-         false,
 
-         false
 
- 	},
 
- 	//X-cross
 
- 	{
 
- 		{
 
-           "?","+","?",
 
-           "+","+","+",
 
-           "?","+","?"
 
-         },
 
-         {16,16},{4,4},
 
-         false,
 
-         false
 
- 	}
 
- };
 
- static bool ruleIsNone(const std::string & rule)
 
- {
 
- 	return rule == "-";
 
- }
 
- static bool ruleIsSomething(const std::string & rule)
 
- {
 
- 	return rule == "+";
 
- }
 
- #ifndef NDEBUG
 
- static bool ruleIsAny(const std::string & rule)
 
- {
 
- 	return rule == "?";
 
- }
 
- #endif
 
- ///CDrawLinesOperation
 
- CDrawLinesOperation::CDrawLinesOperation(CMap * map, const CTerrainSelection & terrainSel, CRandomGenerator * gen):
 
- 	CMapOperation(map),
 
- 	terrainSel(terrainSel),
 
- 	gen(gen)
 
- {
 
- }
 
- ///CDrawRoadsOperation
 
- CDrawRoadsOperation::CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, RoadId roadType, CRandomGenerator * gen):
 
- 	CDrawLinesOperation(map, terrainSel,gen),
 
- 	roadType(roadType)
 
- {
 
- }
 
- ///CDrawRiversOperation
 
- CDrawRiversOperation::CDrawRiversOperation(CMap * map, const CTerrainSelection & terrainSel, RiverId riverType, CRandomGenerator * gen):
 
- 	CDrawLinesOperation(map, terrainSel, gen),
 
- 	riverType(riverType)
 
- {
 
- }
 
- void CDrawLinesOperation::execute()
 
- {
 
- 	std::set<int3> invalidated;
 
- 	for(const auto & pos : terrainSel.getSelectedItems())
 
- 	{
 
- 		executeTile(map->getTile(pos));
 
- 		auto rect = extendTileAroundSafely(pos);
 
- 		rect.forEach([&invalidated](const int3 & pos)
 
- 		{
 
- 			invalidated.insert(pos);
 
- 		});
 
- 	}
 
- 	updateTiles(invalidated);
 
- }
 
- void CDrawLinesOperation::undo()
 
- {
 
-   //TODO
 
- }
 
- void CDrawLinesOperation::redo()
 
- {
 
-   //TODO
 
- }
 
- void CDrawLinesOperation::flipPattern(LinePattern& pattern, int flip) const
 
- {
 
- 	//todo: use cashing here and also in terrain patterns
 
- 	if(flip == 0)
 
- 	{
 
- 		return;
 
- 	}
 
- 	if(flip == FLIP_PATTERN_HORIZONTAL || flip == FLIP_PATTERN_BOTH)
 
- 	{
 
- 		for(int i = 0; i < 3; ++i)
 
- 		{
 
- 			int y = i * 3;
 
- 			std::swap(pattern.data[y], pattern.data[y + 2]);
 
- 		}
 
- 	}
 
- 	if(flip == FLIP_PATTERN_VERTICAL || flip == FLIP_PATTERN_BOTH)
 
- 	{
 
- 		for(int i = 0; i < 3; ++i)
 
- 		{
 
- 			std::swap(pattern.data[i], pattern.data[6 + i]);
 
- 		}
 
- 	}
 
- }
 
- void CDrawLinesOperation::updateTiles(std::set<int3> & 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);
 
- 		}
 
- 	}
 
- }
 
- CDrawLinesOperation::ValidationResult CDrawLinesOperation::validateTile(const LinePattern & 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))
 
- 			continue;
 
- 		if((flip == FLIP_PATTERN_HORIZONTAL) && !pattern.hasHFlip)
 
- 			continue;
 
- 		if((flip == FLIP_PATTERN_VERTICAL) && !(pattern.hasVFlip))
 
- 			continue;
 
- 		LinePattern 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 = !map->isInTheMap(currentPos) || tileHasSomething(currentPos);
 
- 			if(ruleIsSomething(flipped.data[i]))
 
- 			{
 
- 				if(!hasSomething)
 
- 				{
 
- 					validated = false;
 
- 					break;
 
- 				}
 
- 			}
 
- 			else if(ruleIsNone(flipped.data[i]))
 
- 			{
 
- 				if(hasSomething)
 
- 				{
 
- 					validated = false;
 
- 					break;
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				assert(ruleIsAny(flipped.data[i]));
 
- 			}
 
- 		}
 
- 		if(validated)
 
- 		{
 
- 			result.result = true;
 
- 			result.flip = flip;
 
- 			return result;
 
- 		}
 
- 	}
 
- 	return result;
 
- }
 
- std::string CDrawRoadsOperation::getLabel() const
 
- {
 
- 	return "Draw Roads";
 
- }
 
- std::string CDrawRiversOperation::getLabel() const
 
- {
 
- 	return "Draw Rivers";
 
- }
 
- void CDrawRoadsOperation::executeTile(TerrainTile & tile)
 
- {
 
- 	tile.roadType = const_cast<RoadType*>(&VLC->terrainTypeHandler->roads()[roadType]);
 
- }
 
- void CDrawRiversOperation::executeTile(TerrainTile & tile)
 
- {
 
- 	tile.riverType = const_cast<RiverType*>(&VLC->terrainTypeHandler->rivers()[riverType]);
 
- }
 
- bool CDrawRoadsOperation::canApplyPattern(const LinePattern & pattern) const
 
- {
 
- 	return pattern.roadMapping.first >= 0;
 
- }
 
- bool CDrawRiversOperation::canApplyPattern(const LinePattern & pattern) const
 
- {
 
- 	return pattern.riverMapping.first >= 0;
 
- }
 
- bool CDrawRoadsOperation::needUpdateTile(const TerrainTile & tile) const
 
- {
 
- 	return tile.roadType->id != Road::NO_ROAD;
 
- }
 
- bool CDrawRiversOperation::needUpdateTile(const TerrainTile & tile) const
 
- {
 
- 	return tile.riverType->id != River::NO_RIVER;
 
- }
 
- bool CDrawRoadsOperation::tileHasSomething(const int3& pos) const
 
- {
 
- 	return map->getTile(pos).roadType->id != Road::NO_ROAD;
 
- }
 
- bool CDrawRiversOperation::tileHasSomething(const int3& pos) const
 
- {
 
- 	return map->getTile(pos).riverType->id != River::NO_RIVER;
 
- }
 
- void CDrawRoadsOperation::updateTile(TerrainTile & tile, const LinePattern & pattern, const int flip)
 
- {
 
- 	const std::pair<int, int> & mapping  = pattern.roadMapping;
 
- 	tile.roadDir = gen->nextInt(mapping.first, mapping.second);
 
- 	tile.extTileFlags = (tile.extTileFlags & 0b11001111) | (flip << 4);
 
- }
 
- void CDrawRiversOperation::updateTile(TerrainTile & tile, const LinePattern & pattern, const int flip)
 
- {
 
- 	const std::pair<int, int> & mapping  = pattern.riverMapping;
 
- 	
 
- 	tile.riverDir = gen->nextInt(mapping.first, mapping.second);
 
- 	tile.extTileFlags = (tile.extTileFlags & 0b00111111) | (flip << 2);
 
- }
 
- VCMI_LIB_NAMESPACE_END
 
 
  |