mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	TerrainTile now uses identifiers instead of pointers to VLC
This commit is contained in:
		| @@ -193,7 +193,7 @@ bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater) | ||||
| { | ||||
| 	// TODO: Such information should be provided by pathfinder | ||||
| 	// Tile must be free or with unoccupied boat | ||||
| 	if(!t->blocked) | ||||
| 	if(!t->blocked()) | ||||
| 	{ | ||||
| 		return true; | ||||
| 	} | ||||
|   | ||||
| @@ -130,10 +130,10 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta | ||||
| 				for(pos.y = 0; pos.y < sizes.y; ++pos.y) | ||||
| 				{ | ||||
| 					const TerrainTile & tile = gs->map->getTile(pos); | ||||
| 					if (!tile.terType->isPassable()) | ||||
| 					if (!tile.getTerrain()->isPassable()) | ||||
| 						continue; | ||||
|  | ||||
| 					if (tile.terType->isWater()) | ||||
| 					if (tile.isWater()) | ||||
| 					{ | ||||
| 						resetTile(pos, ELayer::SAIL, PathfinderUtil::evaluateAccessibility<ELayer::SAIL>(pos, tile, fow, player, gs)); | ||||
| 						if (useFlying) | ||||
|   | ||||
| @@ -186,7 +186,7 @@ bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater) | ||||
| { | ||||
| 	// TODO: Such information should be provided by pathfinder | ||||
| 	// Tile must be free or with unoccupied boat | ||||
| 	if(!t->blocked) | ||||
| 	if(!t->blocked()) | ||||
| 	{ | ||||
| 		return true; | ||||
| 	} | ||||
|   | ||||
| @@ -46,10 +46,10 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta | ||||
| 			for(pos.y=0; pos.y < sizes.y; ++pos.y) | ||||
| 			{ | ||||
| 				const TerrainTile & tile = gs->map->getTile(pos); | ||||
| 				if(!tile.terType->isPassable()) | ||||
| 				if(!tile.getTerrain()->isPassable()) | ||||
| 					continue; | ||||
| 				 | ||||
| 				if(tile.terType->isWater()) | ||||
| 				if(tile.getTerrain()->isWater()) | ||||
| 				{ | ||||
| 					resetTile(pos, ELayer::SAIL, PathfinderUtil::evaluateAccessibility<ELayer::SAIL>(pos, tile, fow, player, gs)); | ||||
| 					if(useFlying) | ||||
|   | ||||
| @@ -291,14 +291,12 @@ AudioPath HeroMovementController::getMovementSoundFor(const CGHeroInstance * her | ||||
| 	auto prevTile = LOCPLINT->cb->getTile(posPrev); | ||||
| 	auto nextTile = LOCPLINT->cb->getTile(posNext); | ||||
|  | ||||
| 	auto prevRoad = prevTile->roadType; | ||||
| 	auto nextRoad = nextTile->roadType; | ||||
| 	bool movingOnRoad = prevRoad->getId() != Road::NO_ROAD && nextRoad->getId() != Road::NO_ROAD; | ||||
| 	bool movingOnRoad = prevTile->hasRoad() && nextTile->hasRoad(); | ||||
|  | ||||
| 	if(movingOnRoad) | ||||
| 		return nextTile->terType->horseSound; | ||||
| 		return nextTile->getTerrain()->horseSound; | ||||
| 	else | ||||
| 		return nextTile->terType->horseSoundPenalty; | ||||
| 		return nextTile->getTerrain()->horseSoundPenalty; | ||||
| }; | ||||
|  | ||||
| void HeroMovementController::updateMovementSound(const CGHeroInstance * h, int3 posPrev, int3 nextCoord, EPathNodeAction moveType) | ||||
|   | ||||
| @@ -50,10 +50,10 @@ ColorRGBA CMinimapInstance::getTileColor(const int3 & pos) const | ||||
| 			return graphics->playerColors[player.getNum()]; | ||||
| 	} | ||||
|  | ||||
| 	if (tile->blocked && (!tile->visitable)) | ||||
| 		return tile->terType->minimapBlocked; | ||||
| 	if (tile->blocked() && !tile->visitable()) | ||||
| 		return tile->getTerrain()->minimapBlocked; | ||||
| 	else | ||||
| 		return tile->terType->minimapUnblocked; | ||||
| 		return tile->getTerrain()->minimapUnblocked; | ||||
| } | ||||
|  | ||||
| void CMinimapInstance::refreshTile(const int3 &tile) | ||||
|   | ||||
| @@ -182,7 +182,7 @@ void MapAudioPlayer::updateMusic() | ||||
| 		const auto * tile = LOCPLINT->cb->getTile(currentSelection->visitablePos()); | ||||
|  | ||||
| 		if (tile) | ||||
| 			CCS->musich->playMusicFromSet("terrain", tile->terType->getJsonKey(), true, false); | ||||
| 			CCS->musich->playMusicFromSet("terrain", tile->getTerrain()->getJsonKey(), true, false); | ||||
| 	} | ||||
|  | ||||
| 	if(audioPlaying && enemyMakingTurn) | ||||
|   | ||||
| @@ -143,7 +143,7 @@ void MapRendererTerrain::renderTile(IMapRendererContext & context, Canvas & targ | ||||
| { | ||||
| 	const TerrainTile & mapTile = context.getMapTile(coordinates); | ||||
|  | ||||
| 	int32_t terrainIndex = mapTile.terType->getIndex(); | ||||
| 	int32_t terrainIndex = mapTile.getTerrainID(); | ||||
| 	int32_t imageIndex = mapTile.terView; | ||||
| 	int32_t rotationIndex = mapTile.extTileFlags % 4; | ||||
|  | ||||
| @@ -152,11 +152,11 @@ void MapRendererTerrain::renderTile(IMapRendererContext & context, Canvas & targ | ||||
| 	assert(image); | ||||
| 	if (!image) | ||||
| 	{ | ||||
| 		logGlobal->error("Failed to find image %d for terrain %s on tile %s", imageIndex, mapTile.terType->getNameTranslated(), coordinates.toString()); | ||||
| 		logGlobal->error("Failed to find image %d for terrain %s on tile %s", imageIndex, mapTile.getTerrain()->getNameTranslated(), coordinates.toString()); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	for( auto const & element : mapTile.terType->paletteAnimation) | ||||
| 	for( auto const & element : mapTile.getTerrain()->paletteAnimation) | ||||
| 		image->shiftPalette(element.start, element.length, context.terrainImageIndex(element.length)); | ||||
|  | ||||
| 	target.draw(image, Point(0, 0)); | ||||
| @@ -166,7 +166,7 @@ uint8_t MapRendererTerrain::checksum(IMapRendererContext & context, const int3 & | ||||
| { | ||||
| 	const TerrainTile & mapTile = context.getMapTile(coordinates); | ||||
|  | ||||
| 	if(!mapTile.terType->paletteAnimation.empty()) | ||||
| 	if(!mapTile.getTerrain()->paletteAnimation.empty()) | ||||
| 		return context.terrainImageIndex(250); | ||||
| 	return 0xff - 1; | ||||
| } | ||||
| @@ -184,16 +184,16 @@ void MapRendererRiver::renderTile(IMapRendererContext & context, Canvas & target | ||||
| { | ||||
| 	const TerrainTile & mapTile = context.getMapTile(coordinates); | ||||
|  | ||||
| 	if(mapTile.riverType->getId() == River::NO_RIVER) | ||||
| 	if(!mapTile.hasRiver()) | ||||
| 		return; | ||||
|  | ||||
| 	int32_t terrainIndex = mapTile.riverType->getIndex(); | ||||
| 	int32_t terrainIndex = mapTile.getRiverID(); | ||||
| 	int32_t imageIndex = mapTile.riverDir; | ||||
| 	int32_t rotationIndex = (mapTile.extTileFlags >> 2) % 4; | ||||
|  | ||||
| 	const auto & image = storage.find(terrainIndex, rotationIndex, imageIndex); | ||||
|  | ||||
| 	for( auto const & element : mapTile.riverType->paletteAnimation) | ||||
| 	for( auto const & element : mapTile.getRiver()->paletteAnimation) | ||||
| 		image->shiftPalette(element.start, element.length, context.terrainImageIndex(element.length)); | ||||
|  | ||||
| 	target.draw(image, Point(0, 0)); | ||||
| @@ -203,7 +203,7 @@ uint8_t MapRendererRiver::checksum(IMapRendererContext & context, const int3 & c | ||||
| { | ||||
| 	const TerrainTile & mapTile = context.getMapTile(coordinates); | ||||
|  | ||||
| 	if(!mapTile.riverType->paletteAnimation.empty()) | ||||
| 	if(!mapTile.getRiver()->paletteAnimation.empty()) | ||||
| 		return context.terrainImageIndex(250); | ||||
| 	return 0xff-1; | ||||
| } | ||||
| @@ -224,9 +224,9 @@ void MapRendererRoad::renderTile(IMapRendererContext & context, Canvas & target, | ||||
| 	if(context.isInMap(coordinatesAbove)) | ||||
| 	{ | ||||
| 		const TerrainTile & mapTileAbove = context.getMapTile(coordinatesAbove); | ||||
| 		if(mapTileAbove.roadType->getId() != Road::NO_ROAD) | ||||
| 		if(mapTileAbove.hasRoad()) | ||||
| 		{ | ||||
| 			int32_t terrainIndex = mapTileAbove.roadType->getIndex(); | ||||
| 			int32_t terrainIndex = mapTileAbove.getRoadID(); | ||||
| 			int32_t imageIndex = mapTileAbove.roadDir; | ||||
| 			int32_t rotationIndex = (mapTileAbove.extTileFlags >> 4) % 4; | ||||
|  | ||||
| @@ -236,9 +236,9 @@ void MapRendererRoad::renderTile(IMapRendererContext & context, Canvas & target, | ||||
| 	} | ||||
|  | ||||
| 	const TerrainTile & mapTile = context.getMapTile(coordinates); | ||||
| 	if(mapTile.roadType->getId() != Road::NO_ROAD) | ||||
| 	if(mapTile.hasRoad()) | ||||
| 	{ | ||||
| 		int32_t terrainIndex = mapTile.roadType->getIndex(); | ||||
| 		int32_t terrainIndex = mapTile.getRoadID(); | ||||
| 		int32_t imageIndex = mapTile.roadDir; | ||||
| 		int32_t rotationIndex = (mapTile.extTileFlags >> 4) % 4; | ||||
|  | ||||
|   | ||||
| @@ -55,7 +55,7 @@ std::string CMapHandler::getTerrainDescr(const int3 & pos, bool rightClick) cons | ||||
| 	if(t.hasFavorableWinds()) | ||||
| 		return CGI->objtypeh->getObjectName(Obj::FAVORABLE_WINDS, 0); | ||||
|  | ||||
| 	std::string result = t.terType->getNameTranslated(); | ||||
| 	std::string result = t.getTerrain()->getNameTranslated(); | ||||
|  | ||||
| 	for(const auto & object : map->objects) | ||||
| 	{ | ||||
|   | ||||
| @@ -67,9 +67,9 @@ Canvas CMapOverviewWidget::createMinimapForLayer(std::unique_ptr<CMap> & map, in | ||||
| 		{ | ||||
| 			TerrainTile & tile = map->getTile(int3(x, y, layer)); | ||||
|  | ||||
| 			ColorRGBA color = tile.terType->minimapUnblocked; | ||||
| 			if (tile.blocked && (!tile.visitable)) | ||||
| 				color = tile.terType->minimapBlocked; | ||||
| 			ColorRGBA color = tile.getTerrain()->minimapUnblocked; | ||||
| 			if (tile.blocked() && !tile.visitable()) | ||||
| 				color = tile.getTerrain()->minimapBlocked; | ||||
|  | ||||
| 			if(drawPlayerElements) | ||||
| 				// if object at tile is owned - it will be colored as its owner | ||||
|   | ||||
| @@ -630,7 +630,7 @@ EBuildingState CGameInfoCallback::canBuildStructure( const CGTownInstance *t, Bu | ||||
| 	{ | ||||
| 		const TerrainTile *tile = getTile(t->bestLocation(), false); | ||||
|  | ||||
| 		if(!tile || !tile->terType->isWater()) | ||||
| 		if(!tile || !tile->isWater()) | ||||
| 			return EBuildingState::NO_WATER; //lack of water | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -72,7 +72,7 @@ void CPrivilegedInfoCallback::getFreeTiles(std::vector<int3> & tiles) const | ||||
| 			for (int yd = 0; yd < gs->map->height; yd++) | ||||
| 			{ | ||||
| 				tinfo = getTile(int3 (xd,yd,zd)); | ||||
| 				if (tinfo->terType->isLand() && tinfo->terType->isPassable() && !tinfo->blocked) //land and free | ||||
| 				if (tinfo->isLand() && tinfo->getTerrain()->isPassable() && !tinfo->blocked()) //land and free | ||||
| 					tiles.emplace_back(xd, yd, zd); | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
| @@ -437,10 +437,10 @@ void CGameState::initGrailPosition() | ||||
| 				for(int y = BORDER_WIDTH; y < map->height - BORDER_WIDTH; y++) | ||||
| 				{ | ||||
| 					const TerrainTile &t = map->getTile(int3(x, y, z)); | ||||
| 					if(!t.blocked | ||||
| 						&& !t.visitable | ||||
| 						&& t.terType->isLand() | ||||
| 						&& t.terType->isPassable() | ||||
| 					if(!t.blocked() | ||||
| 					   && !t.visitable() | ||||
| 						&& t.isLand() | ||||
| 						&& t.getTerrain()->isPassable() | ||||
| 						&& (int)map->grailPos.dist2dSQ(int3(x, y, z)) <= (map->grailRadius * map->grailRadius)) | ||||
| 						allowedPos.emplace_back(x, y, z); | ||||
| 				} | ||||
| @@ -608,7 +608,7 @@ void CGameState::initHeroes() | ||||
| 	{ | ||||
| 		assert(map->isInTheMap(hero->visitablePos())); | ||||
| 		const auto & tile = map->getTile(hero->visitablePos()); | ||||
| 		if (tile.terType->isWater()) | ||||
| 		if (tile.isWater()) | ||||
| 		{ | ||||
| 			auto handler = VLC->objtypeh->getHandlerFor(Obj::BOAT, hero->getBoatType().getNum()); | ||||
| 			auto boat = dynamic_cast<CGBoat*>(handler->create(callback, nullptr)); | ||||
| @@ -1074,10 +1074,10 @@ BattleField CGameState::battleGetBattlefieldType(int3 tile, vstd::RNG & rand) | ||||
| 	if(map->isCoastalTile(tile)) //coastal tile is always ground | ||||
| 		return BattleField(*VLC->identifiers()->getIdentifier("core", "battlefield.sand_shore")); | ||||
| 	 | ||||
| 	if (t.terType->battleFields.empty()) | ||||
| 		throw std::runtime_error("Failed to find battlefield for terrain " + t.terType->getJsonKey()); | ||||
| 	if (t.getTerrain()->battleFields.empty()) | ||||
| 		throw std::runtime_error("Failed to find battlefield for terrain " + t.getTerrain()->getJsonKey()); | ||||
|  | ||||
| 	return BattleField(*RandomGeneratorUtil::nextItem(t.terType->battleFields, rand)); | ||||
| 	return BattleField(*RandomGeneratorUtil::nextItem(t.getTerrain()->battleFields, rand)); | ||||
| } | ||||
|  | ||||
| void CGameState::fillUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out) const | ||||
| @@ -1171,7 +1171,7 @@ std::vector<CGObjectInstance*> CGameState::guardingCreatures (int3 pos) const | ||||
| 		return guards; | ||||
|  | ||||
| 	const TerrainTile &posTile = map->getTile(pos); | ||||
| 	if (posTile.visitable) | ||||
| 	if (posTile.visitable()) | ||||
| 	{ | ||||
| 		for (CGObjectInstance* obj : posTile.visitableObjects) | ||||
| 		{ | ||||
| @@ -1190,7 +1190,7 @@ std::vector<CGObjectInstance*> CGameState::guardingCreatures (int3 pos) const | ||||
| 			if (map->isInTheMap(pos)) | ||||
| 			{ | ||||
| 				const auto & tile = map->getTile(pos); | ||||
| 				if (tile.visitable && (tile.isWater() == posTile.isWater())) | ||||
| 				if (tile.visitable() && (tile.isWater() == posTile.isWater())) | ||||
| 				{ | ||||
| 					for (CGObjectInstance* obj : tile.visitableObjects) | ||||
| 					{ | ||||
|   | ||||
| @@ -101,7 +101,7 @@ void CTownInstanceConstructor::initializeObject(CGTownInstance * obj) const | ||||
|  | ||||
| void CTownInstanceConstructor::randomizeObject(CGTownInstance * object, vstd::RNG & rng) const | ||||
| { | ||||
| 	auto templ = getOverride(object->cb->getTile(object->pos)->terType->getId(), object); | ||||
| 	auto templ = getOverride(object->cb->getTile(object->pos)->getTerrainID(), object); | ||||
| 	if(templ) | ||||
| 		object->appearance = templ; | ||||
| } | ||||
|   | ||||
| @@ -102,16 +102,16 @@ ui32 CGHeroInstance::getTileMovementCost(const TerrainTile & dest, const Terrain | ||||
| 	int64_t ret = GameConstants::BASE_MOVEMENT_COST; | ||||
|  | ||||
| 	//if there is road both on dest and src tiles - use src road movement cost | ||||
| 	if(dest.roadType->getId() != Road::NO_ROAD && from.roadType->getId() != Road::NO_ROAD) | ||||
| 	if(dest.hasRoad() && from.hasRoad()) | ||||
| 	{ | ||||
| 		ret = from.roadType->movementCost; | ||||
| 		ret = from.getRoad()->movementCost; | ||||
| 	} | ||||
| 	else if(ti->nativeTerrain != from.terType->getId() &&//the terrain is not native | ||||
| 	else if(ti->nativeTerrain != from.getTerrainID() &&//the terrain is not native | ||||
| 			ti->nativeTerrain != ETerrainId::ANY_TERRAIN && //no special creature bonus | ||||
| 			!ti->hasBonusOfType(BonusType::NO_TERRAIN_PENALTY, BonusSubtypeID(from.terType->getId()))) //no special movement bonus | ||||
| 			!ti->hasBonusOfType(BonusType::NO_TERRAIN_PENALTY, BonusSubtypeID(from.getTerrainID()))) //no special movement bonus | ||||
| 	{ | ||||
|  | ||||
| 		ret = VLC->terrainTypeHandler->getById(from.terType->getId())->moveCost; | ||||
| 		ret = VLC->terrainTypeHandler->getById(from.getTerrainID())->moveCost; | ||||
| 		ret -= ti->valOfBonuses(BonusType::ROUGH_TERRAIN_DISCOUNT); | ||||
| 		if(ret < GameConstants::BASE_MOVEMENT_COST) | ||||
| 			ret = GameConstants::BASE_MOVEMENT_COST; | ||||
|   | ||||
| @@ -128,13 +128,13 @@ void CGObjectInstance::setType(MapObjectID newID, MapObjectSubID newSubID) | ||||
| 	cb->gameState()->map->removeBlockVisTiles(this, true); | ||||
| 	auto handler = VLC->objtypeh->getHandlerFor(newID, newSubID); | ||||
|  | ||||
| 	if(!handler->getTemplates(tile.terType->getId()).empty()) | ||||
| 	if(!handler->getTemplates(tile.getTerrainID()).empty()) | ||||
| 	{ | ||||
| 		appearance = handler->getTemplates(tile.terType->getId())[0]; | ||||
| 		appearance = handler->getTemplates(tile.getTerrainID())[0]; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		logGlobal->warn("Object %d:%d at %s has no templates suitable for terrain %s", newID, newSubID, visitablePos().toString(), tile.terType->getNameTranslated()); | ||||
| 		logGlobal->warn("Object %d:%d at %s has no templates suitable for terrain %s", newID, newSubID, visitablePos().toString(), tile.getTerrain()->getNameTranslated()); | ||||
| 		appearance = handler->getTemplates()[0]; // get at least some appearance since alternative is crash | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -692,7 +692,7 @@ ObjectInstanceID CGTownInstance::getObjInstanceID() const | ||||
|  | ||||
| void CGTownInstance::updateAppearance() | ||||
| { | ||||
| 	auto terrain = cb->gameState()->getTile(visitablePos())->terType->getId(); | ||||
| 	auto terrain = cb->gameState()->getTile(visitablePos())->getTerrainID(); | ||||
| 	//FIXME: not the best way to do this | ||||
| 	auto app = getObjectHandler()->getOverride(terrain, this); | ||||
| 	if (app) | ||||
|   | ||||
| @@ -90,10 +90,10 @@ int3 IBoatGenerator::bestLocation() const | ||||
| 		if(!tile) | ||||
| 			continue; // tile not visible / outside the map | ||||
|  | ||||
| 		if(!tile->terType->isWater()) | ||||
| 		if(!tile->isWater()) | ||||
| 			continue; | ||||
|  | ||||
| 		if (tile->blocked) | ||||
| 		if (tile->blocked()) | ||||
| 		{ | ||||
| 			bool hasBoat = false; | ||||
| 			for (auto const * object : tile->blockingObjects) | ||||
|   | ||||
| @@ -344,12 +344,12 @@ std::string CDrawRiversOperation::getLabel() const | ||||
|  | ||||
| void CDrawRoadsOperation::executeTile(TerrainTile & tile) | ||||
| { | ||||
| 	tile.roadType = const_cast<RoadType*>(VLC->roadTypeHandler->getByIndex(roadType.getNum())); | ||||
| 	tile.roadType = roadType; | ||||
| } | ||||
|  | ||||
| void CDrawRiversOperation::executeTile(TerrainTile & tile) | ||||
| { | ||||
| 	tile.riverType = const_cast<RiverType*>(VLC->riverTypeHandler->getByIndex(riverType.getNum())); | ||||
| 	tile.riverType = riverType; | ||||
| } | ||||
|  | ||||
| bool CDrawRoadsOperation::canApplyPattern(const LinePattern & pattern) const | ||||
| @@ -364,22 +364,22 @@ bool CDrawRiversOperation::canApplyPattern(const LinePattern & pattern) const | ||||
|  | ||||
| bool CDrawRoadsOperation::needUpdateTile(const TerrainTile & tile) const | ||||
| { | ||||
| 	return tile.roadType->getId() != Road::NO_ROAD; | ||||
| 	return tile.hasRoad(); | ||||
| } | ||||
|  | ||||
| bool CDrawRiversOperation::needUpdateTile(const TerrainTile & tile) const | ||||
| { | ||||
| 	return tile.riverType->getId() != River::NO_RIVER; | ||||
| 	return tile.hasRiver(); | ||||
| } | ||||
|  | ||||
| bool CDrawRoadsOperation::tileHasSomething(const int3& pos) const | ||||
| { | ||||
| 	return map->getTile(pos).roadType->getId() != Road::NO_ROAD; | ||||
| 	return map->getTile(pos).hasRoad(); | ||||
| } | ||||
|  | ||||
| bool CDrawRiversOperation::tileHasSomething(const int3& pos) const | ||||
| { | ||||
| 	return map->getTile(pos).riverType->getId() != River::NO_RIVER; | ||||
| 	return map->getTile(pos).hasRiver(); | ||||
| } | ||||
|  | ||||
| void CDrawRoadsOperation::updateTile(TerrainTile & tile, const LinePattern & pattern, const int flip) | ||||
|   | ||||
| @@ -131,32 +131,29 @@ void CCastleEvent::serializeJson(JsonSerializeFormat & handler) | ||||
| } | ||||
|  | ||||
| TerrainTile::TerrainTile(): | ||||
| 	terType(nullptr), | ||||
| 	riverType(VLC->riverTypeHandler->getById(River::NO_RIVER)), | ||||
| 	roadType(VLC->roadTypeHandler->getById(Road::NO_ROAD)), | ||||
| 	riverType(River::NO_RIVER), | ||||
| 	roadType(Road::NO_ROAD), | ||||
| 	terView(0), | ||||
| 	riverDir(0), | ||||
| 	roadDir(0), | ||||
| 	extTileFlags(0), | ||||
| 	visitable(false), | ||||
| 	blocked(false) | ||||
| 	extTileFlags(0) | ||||
| { | ||||
| } | ||||
|  | ||||
| bool TerrainTile::entrableTerrain(const TerrainTile * from) const | ||||
| { | ||||
| 	return entrableTerrain(from ? from->terType->isLand() : true, from ? from->terType->isWater() : true); | ||||
| 	return entrableTerrain(from ? from->isLand() : true, from ? from->isWater() : true); | ||||
| } | ||||
|  | ||||
| bool TerrainTile::entrableTerrain(bool allowLand, bool allowSea) const | ||||
| { | ||||
| 	return terType->isPassable() | ||||
| 			&& ((allowSea && terType->isWater())  ||  (allowLand && terType->isLand())); | ||||
| 	return getTerrain()->isPassable() | ||||
| 			&& ((allowSea && isWater())  ||  (allowLand && isLand())); | ||||
| } | ||||
|  | ||||
| bool TerrainTile::isClear(const TerrainTile * from) const | ||||
| { | ||||
| 	return entrableTerrain(from) && !blocked; | ||||
| 	return entrableTerrain(from) && !blocked(); | ||||
| } | ||||
|  | ||||
| Obj TerrainTile::topVisitableId(bool excludeTop) const | ||||
| @@ -177,7 +174,7 @@ CGObjectInstance * TerrainTile::topVisitableObj(bool excludeTop) const | ||||
|  | ||||
| EDiggingStatus TerrainTile::getDiggingStatus(const bool excludeTop) const | ||||
| { | ||||
| 	if(terType->isWater() || !terType->isPassable()) | ||||
| 	if(isWater() || !getTerrain()->isPassable()) | ||||
| 		return EDiggingStatus::WRONG_TERRAIN; | ||||
|  | ||||
| 	int allowedBlocked = excludeTop ? 1 : 0; | ||||
| @@ -194,9 +191,65 @@ bool TerrainTile::hasFavorableWinds() const | ||||
|  | ||||
| bool TerrainTile::isWater() const | ||||
| { | ||||
| 	return terType->isWater(); | ||||
| 	return getTerrain()->isWater(); | ||||
| } | ||||
|  | ||||
| bool TerrainTile::isLand() const | ||||
| { | ||||
| 	return getTerrain()->isLand(); | ||||
| } | ||||
|  | ||||
| bool TerrainTile::visitable() const | ||||
| { | ||||
| 	return !visitableObjects.empty(); | ||||
| } | ||||
|  | ||||
| bool TerrainTile::blocked() const | ||||
| { | ||||
| 	return !blockingObjects.empty(); | ||||
| } | ||||
|  | ||||
| bool TerrainTile::hasRiver() const | ||||
| { | ||||
| 	return getRiverID() != RiverId::NO_RIVER; | ||||
| } | ||||
|  | ||||
| bool TerrainTile::hasRoad() const | ||||
| { | ||||
| 	return getRoadID() != RoadId::NO_ROAD; | ||||
| } | ||||
|  | ||||
| const TerrainType * TerrainTile::getTerrain() const | ||||
| { | ||||
| 	return terrainType.toEntity(VLC); | ||||
| } | ||||
|  | ||||
| const RiverType * TerrainTile::getRiver() const | ||||
| { | ||||
| 	return riverType.toEntity(VLC); | ||||
| } | ||||
|  | ||||
| const RoadType * TerrainTile::getRoad() const | ||||
| { | ||||
| 	return roadType.toEntity(VLC); | ||||
| } | ||||
|  | ||||
| TerrainId TerrainTile::getTerrainID() const | ||||
| { | ||||
| 	return terrainType; | ||||
| } | ||||
|  | ||||
| RiverId TerrainTile::getRiverID() const | ||||
| { | ||||
| 	return riverType; | ||||
| } | ||||
|  | ||||
| RoadId TerrainTile::getRoadID() const | ||||
| { | ||||
| 	return roadType; | ||||
| } | ||||
|  | ||||
|  | ||||
| CMap::CMap(IGameCallback * cb) | ||||
| 	: GameCallbackHolder(cb) | ||||
| 	, checksum(0) | ||||
| @@ -243,15 +296,10 @@ void CMap::removeBlockVisTiles(CGObjectInstance * obj, bool total) | ||||
| 			{ | ||||
| 				TerrainTile & curt = terrain[zVal][xVal][yVal]; | ||||
| 				if(total || obj->visitableAt(int3(xVal, yVal, zVal))) | ||||
| 				{ | ||||
| 					curt.visitableObjects -= obj; | ||||
| 					curt.visitable = curt.visitableObjects.size(); | ||||
| 				} | ||||
|  | ||||
| 				if(total || obj->blockingAt(int3(xVal, yVal, zVal))) | ||||
| 				{ | ||||
| 					curt.blockingObjects -= obj; | ||||
| 					curt.blocked = curt.blockingObjects.size(); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| @@ -270,15 +318,10 @@ void CMap::addBlockVisTiles(CGObjectInstance * obj) | ||||
| 			{ | ||||
| 				TerrainTile & curt = terrain[zVal][xVal][yVal]; | ||||
| 				if(obj->visitableAt(int3(xVal, yVal, zVal))) | ||||
| 				{ | ||||
| 					curt.visitableObjects.push_back(obj); | ||||
| 					curt.visitable = true; | ||||
| 				} | ||||
|  | ||||
| 				if(obj->blockingAt(int3(xVal, yVal, zVal))) | ||||
| 				{ | ||||
| 					curt.blockingObjects.push_back(obj); | ||||
| 					curt.blocked = true; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| @@ -381,7 +424,7 @@ int3 CMap::guardingCreaturePosition (int3 pos) const | ||||
| 	if (!isInTheMap(pos)) | ||||
| 		return int3(-1, -1, -1); | ||||
| 	const TerrainTile &posTile = getTile(pos); | ||||
| 	if (posTile.visitable) | ||||
| 	if (posTile.visitable()) | ||||
| 	{ | ||||
| 		for (CGObjectInstance* obj : posTile.visitableObjects) | ||||
| 		{ | ||||
| @@ -401,7 +444,7 @@ int3 CMap::guardingCreaturePosition (int3 pos) const | ||||
| 			if (isInTheMap(pos)) | ||||
| 			{ | ||||
| 				const auto & tile = getTile(pos); | ||||
|                 if (tile.visitable && (tile.isWater() == water)) | ||||
| 				if (tile.visitable() && (tile.isWater() == water)) | ||||
| 				{ | ||||
| 					for (CGObjectInstance* obj : tile.visitableObjects) | ||||
| 					{ | ||||
|   | ||||
| @@ -104,20 +104,33 @@ struct DLL_LINKAGE TerrainTile | ||||
| 	Obj topVisitableId(bool excludeTop = false) const; | ||||
| 	CGObjectInstance * topVisitableObj(bool excludeTop = false) const; | ||||
| 	bool isWater() const; | ||||
| 	EDiggingStatus getDiggingStatus(const bool excludeTop = true) const; | ||||
| 	bool isLand() const; | ||||
| 	EDiggingStatus getDiggingStatus(bool excludeTop = true) const; | ||||
| 	bool hasFavorableWinds() const; | ||||
|  | ||||
| 	const TerrainType * terType; | ||||
| 	const RiverType * riverType; | ||||
| 	const RoadType * roadType; | ||||
| 	bool visitable() const; | ||||
| 	bool blocked() const; | ||||
|  | ||||
| 	const TerrainType * getTerrain() const; | ||||
| 	const RiverType * getRiver() const; | ||||
| 	const RoadType * getRoad() const; | ||||
|  | ||||
| 	TerrainId getTerrainID() const; | ||||
| 	RiverId getRiverID() const; | ||||
| 	RoadId getRoadID() const; | ||||
|  | ||||
| 	bool hasRiver() const; | ||||
| 	bool hasRoad() const; | ||||
|  | ||||
| 	TerrainId terrainType; | ||||
| 	RiverId riverType; | ||||
| 	RoadId roadType; | ||||
| 	ui8 terView; | ||||
| 	ui8 riverDir; | ||||
| 	ui8 roadDir; | ||||
| 	/// first two bits - how to rotate terrain graphic (next two - river graphic, next two - road); | ||||
| 	///	7th bit - whether tile is coastal (allows disembarking if land or block movement if water); 8th bit - Favorable Winds effect | ||||
| 	ui8 extTileFlags; | ||||
| 	bool visitable; | ||||
| 	bool blocked; | ||||
|  | ||||
| 	std::vector<CGObjectInstance *> visitableObjects; | ||||
| 	std::vector<CGObjectInstance *> blockingObjects; | ||||
| @@ -125,15 +138,15 @@ struct DLL_LINKAGE TerrainTile | ||||
| 	template <typename Handler> | ||||
| 	void serialize(Handler & h) | ||||
| 	{ | ||||
| 		h & terType; | ||||
| 		h & terrainType; | ||||
| 		h & terView; | ||||
| 		h & riverType; | ||||
| 		h & riverDir; | ||||
| 		h & roadType; | ||||
| 		h & roadDir; | ||||
| 		h & extTileFlags; | ||||
| 		h & visitable; | ||||
| 		h & blocked; | ||||
| 	//	h & visitable; | ||||
| 	//	h & blocked; | ||||
| 		h & visitableObjects; | ||||
| 		h & blockingObjects; | ||||
| 	} | ||||
|   | ||||
| @@ -103,7 +103,7 @@ void CDrawTerrainOperation::execute() | ||||
| 	for(const auto & pos : terrainSel.getSelectedItems()) | ||||
| 	{ | ||||
| 		auto & tile = map->getTile(pos); | ||||
| 		tile.terType = const_cast<TerrainType*>(VLC->terrainTypeHandler->getById(terType)); | ||||
| 		tile.terrainType = terType; | ||||
| 		invalidateTerrainViews(pos); | ||||
| 	} | ||||
|  | ||||
| @@ -137,7 +137,7 @@ void CDrawTerrainOperation::updateTerrainTypes() | ||||
| 		auto tiles = getInvalidTiles(centerPos); | ||||
| 		auto updateTerrainType = [&](const int3& pos) | ||||
| 		{ | ||||
| 			map->getTile(pos).terType = centerTile.terType; | ||||
| 			map->getTile(pos).terrainType = centerTile.terrainType; | ||||
| 			positions.insert(pos); | ||||
| 			invalidateTerrainViews(pos); | ||||
| 			//logGlobal->debug("Set additional terrain tile at pos '%s' to type '%s'", pos, centerTile.terType); | ||||
| @@ -161,10 +161,10 @@ void CDrawTerrainOperation::updateTerrainTypes() | ||||
| 			rect.forEach([&](const int3& posToTest) | ||||
| 				{ | ||||
| 					auto & terrainTile = map->getTile(posToTest); | ||||
| 					if(centerTile.terType->getId() != terrainTile.terType->getId()) | ||||
| 					if(centerTile.getTerrain() != terrainTile.getTerrain()) | ||||
| 					{ | ||||
| 						const auto * formerTerType = terrainTile.terType; | ||||
| 						terrainTile.terType = centerTile.terType; | ||||
| 						const auto formerTerType = terrainTile.terrainType; | ||||
| 						terrainTile.terrainType = centerTile.terrainType; | ||||
| 						auto testTile = getInvalidTiles(posToTest); | ||||
|  | ||||
| 						int nativeTilesCntNorm = testTile.nativeTiles.empty() ? std::numeric_limits<int>::max() : static_cast<int>(testTile.nativeTiles.size()); | ||||
| @@ -221,7 +221,7 @@ void CDrawTerrainOperation::updateTerrainTypes() | ||||
| 							suitableTiles.insert(posToTest); | ||||
| 						} | ||||
|  | ||||
| 						terrainTile.terType = formerTerType; | ||||
| 						terrainTile.terrainType = formerTerType; | ||||
| 					} | ||||
| 				}); | ||||
|  | ||||
| @@ -264,7 +264,7 @@ void CDrawTerrainOperation::updateTerrainViews() | ||||
| { | ||||
| 	for(const auto & pos : invalidatedTerViews) | ||||
| 	{ | ||||
| 		const auto & patterns = VLC->terviewh->getTerrainViewPatterns(map->getTile(pos).terType->getId()); | ||||
| 		const auto & patterns = VLC->terviewh->getTerrainViewPatterns(map->getTile(pos).getTerrainID()); | ||||
|  | ||||
| 		// Detect a pattern which fits best | ||||
| 		int bestPattern = -1; | ||||
| @@ -340,7 +340,7 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi | ||||
|  | ||||
| CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainViewInner(const int3& pos, const TerrainViewPattern& pattern, int recDepth) const | ||||
| { | ||||
| 	const auto * centerTerType = map->getTile(pos).terType; | ||||
| 	const auto * centerTerType = map->getTile(pos).getTerrain(); | ||||
| 	int totalPoints = 0; | ||||
| 	std::string transitionReplacement; | ||||
|  | ||||
| @@ -372,24 +372,24 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi | ||||
| 			} | ||||
| 			else if(widthTooHigh) | ||||
| 			{ | ||||
| 				terType = map->getTile(int3(currentPos.x - 1, currentPos.y, currentPos.z)).terType; | ||||
| 				terType = map->getTile(int3(currentPos.x - 1, currentPos.y, currentPos.z)).getTerrain(); | ||||
| 			} | ||||
| 			else if(heightTooHigh) | ||||
| 			{ | ||||
| 				terType = map->getTile(int3(currentPos.x, currentPos.y - 1, currentPos.z)).terType; | ||||
| 				terType = map->getTile(int3(currentPos.x, currentPos.y - 1, currentPos.z)).getTerrain(); | ||||
| 			} | ||||
| 			else if(widthTooLess) | ||||
| 			{ | ||||
| 				terType = map->getTile(int3(currentPos.x + 1, currentPos.y, currentPos.z)).terType; | ||||
| 				terType = map->getTile(int3(currentPos.x + 1, currentPos.y, currentPos.z)).getTerrain(); | ||||
| 			} | ||||
| 			else if(heightTooLess) | ||||
| 			{ | ||||
| 				terType = map->getTile(int3(currentPos.x, currentPos.y + 1, currentPos.z)).terType; | ||||
| 				terType = map->getTile(int3(currentPos.x, currentPos.y + 1, currentPos.z)).getTerrain(); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			terType = map->getTile(currentPos).terType; | ||||
| 			terType = map->getTile(currentPos).getTerrain(); | ||||
| 			if(terType != centerTerType && (terType->isPassable() || centerTerType->isPassable())) | ||||
| 			{ | ||||
| 				isAlien = true; | ||||
| @@ -509,13 +509,13 @@ CDrawTerrainOperation::InvalidTiles CDrawTerrainOperation::getInvalidTiles(const | ||||
| { | ||||
| 	//TODO: this is very expensive function for RMG, needs optimization | ||||
| 	InvalidTiles tiles; | ||||
| 	const auto * centerTerType = map->getTile(centerPos).terType; | ||||
| 	const auto * centerTerType = map->getTile(centerPos).getTerrain(); | ||||
| 	auto rect = extendTileAround(centerPos); | ||||
| 	rect.forEach([&](const int3& pos) | ||||
| 		{ | ||||
| 			if(map->isInTheMap(pos)) | ||||
| 			{ | ||||
| 				const auto * terType = map->getTile(pos).terType; | ||||
| 				const auto * terType = map->getTile(pos).getTerrain(); | ||||
| 				auto valid = validateTerrainView(pos, VLC->terviewh->getTerrainTypePatternById("n1")).result; | ||||
|  | ||||
| 				// Special validity check for rock & water | ||||
|   | ||||
| @@ -356,7 +356,7 @@ void CTerrainViewPatternUtils::printDebuggingInfoAboutTile(const CMap * map, con | ||||
| 			{ | ||||
| 				auto debugTile = map->getTile(debugPos); | ||||
|  | ||||
| 				std::string terType = debugTile.terType->shortIdentifier; | ||||
| 				std::string terType = debugTile.getTerrain()->shortIdentifier; | ||||
| 				line += terType; | ||||
| 				line.insert(line.end(), PADDED_LENGTH - terType.size(), ' '); | ||||
| 			} | ||||
|   | ||||
| @@ -988,17 +988,13 @@ void CMapLoaderH3M::readTerrain() | ||||
| 			for(pos.x = 0; pos.x < map->width; pos.x++) | ||||
| 			{ | ||||
| 				auto & tile = map->getTile(pos); | ||||
| 				tile.terType = VLC->terrainTypeHandler->getById(reader->readTerrain()); | ||||
| 				tile.terrainType = reader->readTerrain(); | ||||
| 				tile.terView = reader->readUInt8(); | ||||
| 				tile.riverType = VLC->riverTypeHandler->getById(reader->readRiver()); | ||||
| 				tile.riverType = reader->readRiver(); | ||||
| 				tile.riverDir = reader->readUInt8(); | ||||
| 				tile.roadType = VLC->roadTypeHandler->getById(reader->readRoad()); | ||||
| 				tile.roadType = reader->readRoad(); | ||||
| 				tile.roadDir = reader->readUInt8(); | ||||
| 				tile.extTileFlags = reader->readUInt8(); | ||||
| 				tile.blocked = !tile.terType->isPassable(); | ||||
| 				tile.visitable = false; | ||||
|  | ||||
| 				assert(tile.terType->getId() != ETerrainId::NONE); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -260,34 +260,34 @@ CMapFormatJson::CMapFormatJson(): | ||||
|  | ||||
| } | ||||
|  | ||||
| TerrainType * CMapFormatJson::getTerrainByCode(const std::string & code) | ||||
| TerrainId CMapFormatJson::getTerrainByCode(const std::string & code) | ||||
| { | ||||
| 	for(const auto & object : VLC->terrainTypeHandler->objects) | ||||
| 	{ | ||||
| 		if(object->shortIdentifier == code) | ||||
| 			return const_cast<TerrainType *>(object.get()); | ||||
| 			return object->getId(); | ||||
| 	} | ||||
| 	return nullptr; | ||||
| 	return TerrainId::NONE; | ||||
| } | ||||
|  | ||||
| RiverType * CMapFormatJson::getRiverByCode(const std::string & code) | ||||
| RiverId CMapFormatJson::getRiverByCode(const std::string & code) | ||||
| { | ||||
| 	for(const auto & object : VLC->riverTypeHandler->objects) | ||||
| 	{ | ||||
| 		if (object->shortIdentifier == code) | ||||
| 			return const_cast<RiverType *>(object.get()); | ||||
| 			return object->getId(); | ||||
| 	} | ||||
| 	return nullptr; | ||||
| 	return RiverId::NO_RIVER; | ||||
| } | ||||
|  | ||||
| RoadType * CMapFormatJson::getRoadByCode(const std::string & code) | ||||
| RoadId CMapFormatJson::getRoadByCode(const std::string & code) | ||||
| { | ||||
| 	for(const auto & object : VLC->roadTypeHandler->objects) | ||||
| 	{ | ||||
| 		if (object->shortIdentifier == code) | ||||
| 			return const_cast<RoadType *>(object.get()); | ||||
| 			return object->getId(); | ||||
| 	} | ||||
| 	return nullptr; | ||||
| 	return RoadId::NO_ROAD; | ||||
| } | ||||
|  | ||||
| void CMapFormatJson::serializeAllowedFactions(JsonSerializeFormat & handler, std::set<FactionID> & value) const | ||||
| @@ -890,7 +890,7 @@ void CMapLoaderJson::readTerrainTile(const std::string & src, TerrainTile & tile | ||||
| 		using namespace TerrainDetail; | ||||
| 		{//terrain type | ||||
| 			const std::string typeCode = src.substr(0, 2); | ||||
| 			tile.terType = getTerrainByCode(typeCode); | ||||
| 			tile.terrainType = getTerrainByCode(typeCode); | ||||
| 		} | ||||
| 		int startPos = 2; //0+typeCode fixed length | ||||
| 		{//terrain view | ||||
| @@ -920,7 +920,7 @@ void CMapLoaderJson::readTerrainTile(const std::string & src, TerrainTile & tile | ||||
| 			tile.roadType = getRoadByCode(typeCode); | ||||
| 			if(!tile.roadType) //it's not a road, it's a river | ||||
| 			{ | ||||
| 				tile.roadType = VLC->roadTypeHandler->getById(Road::NO_ROAD); | ||||
| 				tile.roadType = Road::NO_ROAD; | ||||
| 				tile.riverType = getRiverByCode(typeCode); | ||||
| 				hasRoad = false; | ||||
| 				if(!tile.riverType) | ||||
| @@ -1254,13 +1254,13 @@ std::string CMapSaverJson::writeTerrainTile(const TerrainTile & tile) | ||||
| 	out.setf(std::ios::dec, std::ios::basefield); | ||||
| 	out.unsetf(std::ios::showbase); | ||||
|  | ||||
| 	out << tile.terType->shortIdentifier << static_cast<int>(tile.terView) << flipCodes[tile.extTileFlags % 4]; | ||||
| 	out << tile.getTerrain()->shortIdentifier << static_cast<int>(tile.terView) << flipCodes[tile.extTileFlags % 4]; | ||||
|  | ||||
| 	if(tile.roadType->getId() != Road::NO_ROAD) | ||||
| 		out << tile.roadType->shortIdentifier << static_cast<int>(tile.roadDir) << flipCodes[(tile.extTileFlags >> 4) % 4]; | ||||
| 	if(tile.hasRoad()) | ||||
| 		out << tile.getRoad()->shortIdentifier << static_cast<int>(tile.roadDir) << flipCodes[(tile.extTileFlags >> 4) % 4]; | ||||
|  | ||||
| 	if(tile.riverType->getId() != River::NO_RIVER) | ||||
| 		out << tile.riverType->shortIdentifier << static_cast<int>(tile.riverDir) << flipCodes[(tile.extTileFlags >> 2) % 4]; | ||||
| 	if(tile.hasRiver()) | ||||
| 		out << tile.getRiver()->shortIdentifier << static_cast<int>(tile.riverDir) << flipCodes[(tile.extTileFlags >> 2) % 4]; | ||||
|  | ||||
| 	return out.str(); | ||||
| } | ||||
|   | ||||
| @@ -60,9 +60,9 @@ protected: | ||||
|  | ||||
| 	CMapFormatJson(); | ||||
|  | ||||
| 	static TerrainType * getTerrainByCode(const std::string & code); | ||||
| 	static RiverType * getRiverByCode(const std::string & code); | ||||
| 	static RoadType * getRoadByCode(const std::string & code); | ||||
| 	static TerrainId getTerrainByCode(const std::string & code); | ||||
| 	static RiverId getRiverByCode(const std::string & code); | ||||
| 	static RoadId getRoadByCode(const std::string & code); | ||||
|  | ||||
| 	void serializeAllowedFactions(JsonSerializeFormat & handler, std::set<FactionID> & value) const; | ||||
|  | ||||
|   | ||||
| @@ -596,25 +596,19 @@ void CPathfinderHelper::getNeighbours( | ||||
| 			continue; | ||||
|  | ||||
| 		const TerrainTile & destTile = map->getTile(destCoord); | ||||
| 		if(!destTile.terType->isPassable()) | ||||
| 		if(!destTile.getTerrain()->isPassable()) | ||||
| 			continue; | ||||
|  | ||||
| // 		//we cannot visit things from blocked tiles | ||||
| // 		if(srcTile.blocked && !srcTile.visitable && destTile.visitable && srcTile.blockingObjects.front()->ID != HEROI_TYPE) | ||||
| // 		{ | ||||
| // 			continue; | ||||
| // 		} | ||||
|  | ||||
| 		/// Following condition let us avoid diagonal movement over coast when sailing | ||||
| 		if(srcTile.terType->isWater() && limitCoastSailing && destTile.terType->isWater() && dir.x && dir.y) //diagonal move through water | ||||
| 		if(srcTile.isWater() && limitCoastSailing && destTile.isWater() && dir.x && dir.y) //diagonal move through water | ||||
| 		{ | ||||
| 			const int3 horizontalNeighbour = srcCoord + int3{dir.x, 0, 0}; | ||||
| 			const int3 verticalNeighbour = srcCoord + int3{0, dir.y, 0}; | ||||
| 			if(map->getTile(horizontalNeighbour).terType->isLand() || map->getTile(verticalNeighbour).terType->isLand()) | ||||
| 			if(map->getTile(horizontalNeighbour).isLand() || map->getTile(verticalNeighbour).isLand()) | ||||
| 				continue; | ||||
| 		} | ||||
|  | ||||
| 		if(indeterminate(onLand) || onLand == destTile.terType->isLand()) | ||||
| 		if(indeterminate(onLand) || onLand == destTile.isLand()) | ||||
| 		{ | ||||
| 			vec.push_back(destCoord); | ||||
| 		} | ||||
| @@ -662,13 +656,13 @@ int CPathfinderHelper::getMovementCost( | ||||
|  | ||||
| 	bool isSailLayer; | ||||
| 	if(indeterminate(isDstSailLayer)) | ||||
| 		isSailLayer = hero->boat && hero->boat->layer == EPathfindingLayer::SAIL && dt->terType->isWater(); | ||||
| 		isSailLayer = hero->boat && hero->boat->layer == EPathfindingLayer::SAIL && dt->isWater(); | ||||
| 	else | ||||
| 		isSailLayer = static_cast<bool>(isDstSailLayer); | ||||
|  | ||||
| 	bool isWaterLayer; | ||||
| 	if(indeterminate(isDstWaterLayer)) | ||||
| 		isWaterLayer = ((hero->boat && hero->boat->layer == EPathfindingLayer::WATER) || ti->hasBonusOfType(BonusType::WATER_WALKING)) && dt->terType->isWater(); | ||||
| 		isWaterLayer = ((hero->boat && hero->boat->layer == EPathfindingLayer::WATER) || ti->hasBonusOfType(BonusType::WATER_WALKING)) && dt->isWater(); | ||||
| 	else | ||||
| 		isWaterLayer = static_cast<bool>(isDstWaterLayer); | ||||
| 	 | ||||
| @@ -703,7 +697,7 @@ int CPathfinderHelper::getMovementCost( | ||||
| 	{ | ||||
| 		NeighbourTilesVector vec; | ||||
|  | ||||
| 		getNeighbours(*dt, dst, vec, ct->terType->isLand(), true); | ||||
| 		getNeighbours(*dt, dst, vec, ct->isLand(), true); | ||||
| 		for(const auto & elem : vec) | ||||
| 		{ | ||||
| 			int fcost = getMovementCost(dst, elem, nullptr, nullptr, left, false); | ||||
|   | ||||
| @@ -41,7 +41,7 @@ void NodeStorage::initialize(const PathfinderOptions & options, const CGameState | ||||
| 			for(pos.y=0; pos.y < sizes.y; ++pos.y) | ||||
| 			{ | ||||
| 				const TerrainTile & tile = gs->map->getTile(pos); | ||||
| 				if(tile.terType->isWater()) | ||||
| 				if(tile.isWater()) | ||||
| 				{ | ||||
| 					resetTile(pos, ELayer::SAIL, PathfinderUtil::evaluateAccessibility<ELayer::SAIL>(pos, tile, fow, player, gs)); | ||||
| 					if(useFlying) | ||||
| @@ -49,7 +49,7 @@ void NodeStorage::initialize(const PathfinderOptions & options, const CGameState | ||||
| 					if(useWaterWalking) | ||||
| 						resetTile(pos, ELayer::WATER, PathfinderUtil::evaluateAccessibility<ELayer::WATER>(pos, tile, fow, player, gs)); | ||||
| 				} | ||||
| 				if(tile.terType->isLand()) | ||||
| 				if(tile.isLand()) | ||||
| 				{ | ||||
| 					resetTile(pos, ELayer::LAND, PathfinderUtil::evaluateAccessibility<ELayer::LAND>(pos, tile, fow, player, gs)); | ||||
| 					if(useFlying) | ||||
|   | ||||
| @@ -32,7 +32,7 @@ namespace PathfinderUtil | ||||
| 		{ | ||||
| 		case ELayer::LAND: | ||||
| 		case ELayer::SAIL: | ||||
| 			if(tinfo.visitable) | ||||
| 			if(tinfo.visitable()) | ||||
| 			{ | ||||
| 				if(tinfo.visitableObjects.front()->ID == Obj::SANCTUARY && tinfo.visitableObjects.back()->ID == Obj::HERO && tinfo.visitableObjects.back()->tempOwner != player) //non-owned hero stands on Sanctuary | ||||
| 				{ | ||||
| @@ -51,7 +51,7 @@ namespace PathfinderUtil | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			else if(tinfo.blocked) | ||||
| 			else if(tinfo.blocked()) | ||||
| 			{ | ||||
| 				return EPathAccessibility::BLOCKED; | ||||
| 			} | ||||
| @@ -64,7 +64,7 @@ namespace PathfinderUtil | ||||
| 			break; | ||||
|  | ||||
| 		case ELayer::WATER: | ||||
| 			if(tinfo.blocked || tinfo.terType->isLand()) | ||||
| 			if(tinfo.blocked() || tinfo.isLand()) | ||||
| 				return EPathAccessibility::BLOCKED; | ||||
|  | ||||
| 			break; | ||||
|   | ||||
| @@ -380,7 +380,7 @@ void LayerTransitionRule::process( | ||||
|  | ||||
| 	case EPathfindingLayer::SAIL: | ||||
| 		// have to disembark first before visiting objects on land | ||||
| 		if (destination.tile->visitable) | ||||
| 		if (destination.tile->visitable()) | ||||
| 			destination.blocked = true; | ||||
|  | ||||
| 		//can disembark only on accessible tiles or tiles guarded by nearby monster | ||||
| @@ -397,7 +397,7 @@ void LayerTransitionRule::process( | ||||
| 				if (destination.node->accessible == EPathAccessibility::BLOCKVIS) | ||||
| 				{ | ||||
| 					// Can't visit 'blockvisit' objects on coast if hero will end up on water terrain | ||||
| 					if (source.tile->blocked || !destination.tile->entrableTerrain(source.tile)) | ||||
| 					if (source.tile->blocked() || !destination.tile->entrableTerrain(source.tile)) | ||||
| 						destination.blocked = true; | ||||
| 				} | ||||
| 			} | ||||
|   | ||||
| @@ -63,16 +63,16 @@ void Rewardable::Interface::grantRewardBeforeLevelup(const Rewardable::VisitInfo | ||||
| 		const auto functor = [&props](const TerrainTile * tile) | ||||
| 		{ | ||||
| 			int score = 0; | ||||
| 			if (tile->terType->isSurface()) | ||||
| 			if (tile->getTerrain()->isSurface()) | ||||
| 				score += props.scoreSurface; | ||||
|  | ||||
| 			if (tile->terType->isUnderground()) | ||||
| 			if (tile->getTerrain()->isUnderground()) | ||||
| 				score += props.scoreSubterra; | ||||
|  | ||||
| 			if (tile->terType->isWater()) | ||||
| 			if (tile->getTerrain()->isWater()) | ||||
| 				score += props.scoreWater; | ||||
|  | ||||
| 			if (tile->terType->isRock()) | ||||
| 			if (tile->getTerrain()->isRock()) | ||||
| 				score += props.scoreRock; | ||||
|  | ||||
| 			return score > 0; | ||||
|   | ||||
| @@ -484,7 +484,7 @@ void Object::Instance::finalize(RmgMap & map, vstd::RNG & rng) | ||||
| 	//If no specific template was defined for this object, select any matching | ||||
| 	if (!dObject.appearance) | ||||
| 	{ | ||||
| 		const auto * terrainType = map.getTile(getPosition(true)).terType; | ||||
| 		const auto * terrainType = map.getTile(getPosition(true)).getTerrain(); | ||||
| 		auto templates = dObject.getObjectHandler()->getTemplates(terrainType->getId()); | ||||
| 		if (templates.empty()) | ||||
| 		{ | ||||
|   | ||||
| @@ -149,7 +149,7 @@ void RoadPlacer::drawRoads(bool secondary) | ||||
| 	//Do not draw roads on underground rock or water | ||||
| 	roads.erase_if([this](const int3& pos) -> bool | ||||
| 	{ | ||||
| 		const auto* terrain = map.getTile(pos).terType; | ||||
| 		const auto* terrain = map.getTile(pos).getTerrain(); | ||||
| 		return !terrain->isPassable() || !terrain->isLand(); | ||||
| 	}); | ||||
|  | ||||
|   | ||||
| @@ -72,7 +72,7 @@ void RockFiller::init() | ||||
|  | ||||
| char RockFiller::dump(const int3 & t) | ||||
| { | ||||
| 	if(!map.getTile(t).terType->isPassable()) | ||||
| 	if(!map.getTile(t).getTerrain()->isPassable()) | ||||
| 	{ | ||||
| 		return zone.area()->contains(t) ? 'R' : 'E'; | ||||
| 	} | ||||
|   | ||||
| @@ -60,7 +60,7 @@ void RockPlacer::postProcess() | ||||
| 		//Finally mark rock tiles as occupied, spawn no obstacles there | ||||
| 		rockArea = zone.area()->getSubarea([this](const int3 & t) | ||||
| 		{ | ||||
| 			return !map.getTile(t).terType->isPassable(); | ||||
| 			return !map.getTile(t).getTerrain()->isPassable(); | ||||
| 		}); | ||||
|  | ||||
| 		// Do not place rock on roads | ||||
| @@ -96,7 +96,7 @@ void RockPlacer::init() | ||||
|  | ||||
| char RockPlacer::dump(const int3 & t) | ||||
| { | ||||
| 	if(!map.getTile(t).terType->isPassable()) | ||||
| 	if(!map.getTile(t).getTerrain()->isPassable()) | ||||
| 	{ | ||||
| 		return zone.area()->contains(t) ? 'R' : 'E'; | ||||
| 	} | ||||
|   | ||||
| @@ -51,7 +51,7 @@ void WaterProxy::process() | ||||
| 	for([[maybe_unused]] const auto & t : area->getTilesVector()) | ||||
| 	{ | ||||
| 		assert(map.isOnMap(t)); | ||||
| 		assert(map.getTile(t).terType->getId() == zone.getTerrainType()); | ||||
| 		assert(map.getTile(t).getTerrainID() == zone.getTerrainType()); | ||||
| 	} | ||||
|  | ||||
| 	// FIXME: Possible deadlock for 2 zones | ||||
| @@ -66,7 +66,7 @@ void WaterProxy::process() | ||||
| 		auto secondAreaPossible = z.second->areaPossible(); | ||||
| 		for(const auto & t : secondArea->getTilesVector()) | ||||
| 		{ | ||||
| 			if(map.getTile(t).terType->getId() == zone.getTerrainType()) | ||||
| 			if(map.getTile(t).getTerrainID() == zone.getTerrainType()) | ||||
| 			{ | ||||
| 				secondArea->erase(t); | ||||
| 				secondAreaPossible->erase(t); | ||||
|   | ||||
| @@ -374,7 +374,7 @@ bool DimensionDoorMechanics::canBeCastAtImpl(spells::Problem & problem, const CG | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		if (dest->blocked) | ||||
| 		if (dest->blocked()) | ||||
| 			return false; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -1123,7 +1123,7 @@ void MainWindow::on_actionUpdate_appearance_triggered() | ||||
| 			continue; | ||||
| 		} | ||||
| 		 | ||||
| 		auto * terrain = controller.map()->getTile(obj->visitablePos()).terType; | ||||
| 		auto * terrain = controller.map()->getTile(obj->visitablePos()).getTerrain(); | ||||
| 		 | ||||
| 		if(handler->isStaticObject()) | ||||
| 		{ | ||||
|   | ||||
| @@ -429,10 +429,10 @@ void MapController::commitObstacleFill(int level) | ||||
| 	for(auto & t : selection) | ||||
| 	{ | ||||
| 		auto tl = _map->getTile(t); | ||||
| 		if(tl.blocked || tl.visitable) | ||||
| 		if(tl.blocked() || tl.visitable()) | ||||
| 			continue; | ||||
| 		 | ||||
| 		auto terrain = tl.terType->getId(); | ||||
| 		auto terrain = tl.getTerrainID(); | ||||
| 		_obstaclePainters[terrain]->addBlockedTile(t); | ||||
| 	} | ||||
| 	 | ||||
|   | ||||
| @@ -93,7 +93,7 @@ void MapHandler::drawTerrainTile(QPainter & painter, int x, int y, int z) | ||||
| 	auto & tinfo = map->getTile(int3(x, y, z)); | ||||
| 	ui8 rotation = tinfo.extTileFlags % 4; | ||||
| 	 | ||||
| 	auto terrainName = tinfo.terType->getJsonKey(); | ||||
| 	auto terrainName = tinfo.getTerrain()->getJsonKey(); | ||||
| 	 | ||||
| 	if(terrainImages.at(terrainName).size() <= tinfo.terView) | ||||
| 		return; | ||||
| @@ -110,7 +110,7 @@ void MapHandler::drawRoad(QPainter & painter, int x, int y, int z) | ||||
| 	 | ||||
| 	if(tinfoUpper && tinfoUpper->roadType) | ||||
| 	{ | ||||
| 		auto roadName = tinfoUpper->roadType->getJsonKey(); | ||||
| 		auto roadName = tinfoUpper->getRoad()->getJsonKey(); | ||||
| 		QRect source(0, tileSize / 2, tileSize, tileSize / 2); | ||||
| 		ui8 rotation = (tinfoUpper->extTileFlags >> 4) % 4; | ||||
| 		bool hflip = (rotation == 1 || rotation == 3); | ||||
| @@ -123,7 +123,7 @@ void MapHandler::drawRoad(QPainter & painter, int x, int y, int z) | ||||
| 	 | ||||
| 	if(tinfo.roadType) //print road from this tile | ||||
| 	{ | ||||
| 		auto roadName = tinfo.roadType->getJsonKey(); | ||||
| 		auto roadName = tinfo.getRoad()->getJsonKey(); | ||||
| 		QRect source(0, 0, tileSize, tileSize / 2); | ||||
| 		ui8 rotation = (tinfo.extTileFlags >> 4) % 4; | ||||
| 		bool hflip = (rotation == 1 || rotation == 3); | ||||
| @@ -139,11 +139,11 @@ void MapHandler::drawRiver(QPainter & painter, int x, int y, int z) | ||||
| { | ||||
| 	auto & tinfo = map->getTile(int3(x, y, z)); | ||||
|  | ||||
| 	if(tinfo.riverType->getId() == River::NO_RIVER) | ||||
| 	if(!tinfo.hasRiver()) | ||||
| 		return; | ||||
| 	 | ||||
| 	//TODO: use ui8 instead of string key | ||||
| 	auto riverName = tinfo.riverType->getJsonKey(); | ||||
| 	auto riverName = tinfo.getRiver()->getJsonKey(); | ||||
|  | ||||
| 	if(riverImages.at(riverName).size() <= tinfo.riverDir) | ||||
| 		return; | ||||
| @@ -441,9 +441,9 @@ QRgb MapHandler::getTileColor(int x, int y, int z) | ||||
| 	 | ||||
| 	auto & tile = map->getTile(int3(x, y, z)); | ||||
| 	 | ||||
| 	auto color = tile.terType->minimapUnblocked; | ||||
| 	if (tile.blocked && (!tile.visitable)) | ||||
| 		color = tile.terType->minimapBlocked; | ||||
| 	auto color = tile.getTerrain()->minimapUnblocked; | ||||
| 	if (tile.blocked() && (!tile.visitable())) | ||||
| 		color = tile.getTerrain()->minimapBlocked; | ||||
| 	 | ||||
| 	return qRgb(color.r, color.g, color.b); | ||||
| } | ||||
|   | ||||
| @@ -364,7 +364,7 @@ void MapView::mousePressEvent(QMouseEvent *event) | ||||
| 						else if(controller->map()->getTile(tile).riverType | ||||
| 						   && controller->map()->getTile(tile).riverType != controller->map()->getTile(tilen).riverType) | ||||
| 							continue; | ||||
| 						else if(controller->map()->getTile(tile).terType != controller->map()->getTile(tilen).terType) | ||||
| 						else if(controller->map()->getTile(tile).terrainType != controller->map()->getTile(tilen).terrainType) | ||||
| 							continue; | ||||
| 					} | ||||
| 					if(event->button() == Qt::LeftButton && sc->selectionTerrainView.selection().count(tilen)) | ||||
|   | ||||
| @@ -101,9 +101,9 @@ void PassabilityLayer::update() | ||||
| 			for(int i = 0; i < map->width; ++i) | ||||
| 			{ | ||||
| 				auto tl = map->getTile(int3(i, j, scene->level)); | ||||
| 				if(tl.blocked || tl.visitable) | ||||
| 				if(tl.blocked() || tl.visitable()) | ||||
| 				{ | ||||
| 					painter.fillRect(i * 32, j * 32, 31, 31, tl.visitable ? QColor(200, 200, 0, 64) : QColor(255, 0, 0, 64)); | ||||
| 					painter.fillRect(i * 32, j * 32, 31, 31, tl.visitable() ? QColor(200, 200, 0, 64) : QColor(255, 0, 0, 64)); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
| @@ -830,9 +830,8 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme | ||||
|  | ||||
| 	const bool embarking = !h->boat && objectToVisit && objectToVisit->ID == Obj::BOAT; | ||||
| 	const bool disembarking = h->boat | ||||
| 		&& t.terType->isLand() | ||||
| 		&& (dst == h->pos | ||||
| 			|| (h->boat->layer == EPathfindingLayer::SAIL && !t.blocked)); | ||||
| 		&& t.isLand() | ||||
| 		&& (dst == h->pos || (h->boat->layer == EPathfindingLayer::SAIL && !t.blocked())); | ||||
|  | ||||
| 	//result structure for start - movement failed, no move points used | ||||
| 	TryMoveHero tmh; | ||||
| @@ -850,9 +849,9 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme | ||||
| 	const bool canWalkOnSea = pathfinderHelper->hasBonusOfType(BonusType::WATER_WALKING) || (h->boat && h->boat->layer == EPathfindingLayer::WATER); | ||||
| 	const int cost = pathfinderHelper->getMovementCost(h->visitablePos(), hmpos, nullptr, nullptr, h->movementPointsRemaining()); | ||||
|  | ||||
| 	const bool movingOntoObstacle = t.blocked && !t.visitable; | ||||
| 	const bool movingOntoObstacle = t.blocked() && !t.visitable(); | ||||
| 	const bool objectCoastVisitable = objectToVisit && objectToVisit->isCoastVisitable(); | ||||
| 	const bool movingOntoWater = !h->boat && t.terType->isWater() && !objectCoastVisitable; | ||||
| 	const bool movingOntoWater = !h->boat && t.isWater() && !objectCoastVisitable; | ||||
|  | ||||
| 	const auto complainRet = [&](const std::string & message) | ||||
| 	{ | ||||
| @@ -876,14 +875,14 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme | ||||
|  | ||||
| 	//it's a rock or blocked and not visitable tile | ||||
| 	//OR hero is on land and dest is water and (there is not present only one object - boat) | ||||
| 	if (!t.terType->isPassable() || (movingOntoObstacle && !canFly)) | ||||
| 	if (!t.getTerrain()->isPassable() || (movingOntoObstacle && !canFly)) | ||||
| 		return complainRet("Cannot move hero, destination tile is blocked!"); | ||||
|  | ||||
| 	//hero is not on boat/water walking and dst water tile doesn't contain boat/hero (objs visitable from land) -> we test back cause boat may be on top of another object (#276) | ||||
| 	if(movingOntoWater && !canFly && !canWalkOnSea) | ||||
| 		return complainRet("Cannot move hero, destination tile is on water!"); | ||||
|  | ||||
| 	if(h->boat && h->boat->layer == EPathfindingLayer::SAIL && t.terType->isLand() && t.blocked) | ||||
| 	if(h->boat && h->boat->layer == EPathfindingLayer::SAIL && t.isLand() && t.blocked()) | ||||
| 		return complainRet("Cannot disembark hero, tile is blocked!"); | ||||
|  | ||||
| 	if(distance(h->pos, dst) >= 1.5 && movementMode == EMovementMode::STANDARD) | ||||
| @@ -895,7 +894,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme | ||||
| 	if(h->movementPointsRemaining() < cost && dst != h->pos && movementMode == EMovementMode::STANDARD) | ||||
| 		return complainRet("Hero doesn't have any movement points left!"); | ||||
|  | ||||
| 	if (transit && !canFly && !(canWalkOnSea && t.terType->isWater()) && !CGTeleport::isTeleport(objectToVisit)) | ||||
| 	if (transit && !canFly && !(canWalkOnSea && t.isWater()) && !CGTeleport::isTeleport(objectToVisit)) | ||||
| 		return complainRet("Hero cannot transit over this tile!"); | ||||
|  | ||||
| 	//several generic blocks of code | ||||
| @@ -1017,7 +1016,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme | ||||
| 			if (CGTeleport::isTeleport(objectToVisit)) | ||||
| 				visitDest = DONT_VISIT_DEST; | ||||
|  | ||||
| 			if (canFly || (canWalkOnSea && t.terType->isWater())) | ||||
| 			if (canFly || (canWalkOnSea && t.isWater())) | ||||
| 			{ | ||||
| 				lookForGuards = IGNORE_GUARDS; | ||||
| 				visitDest = DONT_VISIT_DEST; | ||||
|   | ||||
| @@ -157,7 +157,7 @@ void BattleProcessor::startBattle(const CArmedInstance *army1, const CArmedInsta | ||||
| BattleID BattleProcessor::setupBattle(int3 tile, BattleSideArray<const CArmedInstance *> armies, BattleSideArray<const CGHeroInstance *> heroes, const BattleLayout & layout, const CGTownInstance *town) | ||||
| { | ||||
| 	const auto & t = *gameHandler->getTile(tile); | ||||
| 	TerrainId terrain = t.terType->getId(); | ||||
| 	TerrainId terrain = t.getTerrainID(); | ||||
| 	if (town) | ||||
| 		terrain = town->getNativeTerrain(); | ||||
| 	else if (gameHandler->gameState()->map->isCoastalTile(tile)) //coastal tile is always ground | ||||
|   | ||||
		Reference in New Issue
	
	Block a user