mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	#3876 - allow to embark after battle for AI pathfinder
This commit is contained in:
		| @@ -104,7 +104,7 @@ AINodeStorage::~AINodeStorage() = default; | ||||
|  | ||||
| void AINodeStorage::initialize(const PathfinderOptions & options, const CGameState * gs) | ||||
| { | ||||
| 	if(heroChainPass) | ||||
| 	if(heroChainPass != EHeroChainPass::INITIAL) | ||||
| 		return; | ||||
|  | ||||
| 	AISharedStorage::version++; | ||||
| @@ -157,6 +157,7 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta | ||||
| void AINodeStorage::clear() | ||||
| { | ||||
| 	actors.clear(); | ||||
| 	commitedTiles.clear(); | ||||
| 	heroChainPass = EHeroChainPass::INITIAL; | ||||
| 	heroChainTurn = 0; | ||||
| 	heroChainMaxTurns = 1; | ||||
| @@ -169,7 +170,7 @@ std::optional<AIPathNode *> AINodeStorage::getOrCreateNode( | ||||
| 	const EPathfindingLayer layer,  | ||||
| 	const ChainActor * actor) | ||||
| { | ||||
| 	int bucketIndex = ((uintptr_t)actor) % AIPathfinding::BUCKET_COUNT; | ||||
| 	int bucketIndex = ((uintptr_t)actor + static_cast<uint32_t>(layer)) % AIPathfinding::BUCKET_COUNT; | ||||
| 	int bucketOffset = bucketIndex * AIPathfinding::BUCKET_SIZE; | ||||
| 	auto chains = nodes.get(pos); | ||||
|  | ||||
| @@ -330,10 +331,38 @@ void AINodeStorage::calculateNeighbours( | ||||
|  | ||||
| 	for(auto & neighbour : accessibleNeighbourTiles) | ||||
| 	{ | ||||
| 		if(getAccessibility(neighbour, layer) == EPathAccessibility::NOT_SET) | ||||
| 		{ | ||||
| #if NKAI_PATHFINDER_TRACE_LEVEL >= 2 | ||||
| 			logAi->trace( | ||||
| 				"Node %s rejected for %s, layer %d because of inaccessibility", | ||||
| 				neighbour.toString(), | ||||
| 				source.coord.toString(), | ||||
| 				static_cast<int32_t>(layer)); | ||||
| #endif | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		auto nextNode = getOrCreateNode(neighbour, layer, srcNode->actor); | ||||
|  | ||||
| 		if(!nextNode || nextNode.value()->accessible == EPathAccessibility::NOT_SET) | ||||
| 		if(!nextNode) | ||||
| 		{ | ||||
| #if NKAI_PATHFINDER_TRACE_LEVEL >= 2 | ||||
| 			logAi->trace( | ||||
| 				"Failed to allocate node at %s[%d]", | ||||
| 				neighbour.toString(), | ||||
| 				static_cast<int32_t>(layer)); | ||||
| #endif | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| #if NKAI_PATHFINDER_TRACE_LEVEL >= 2 | ||||
| 		logAi->trace( | ||||
| 			"Node %s added to neighbors of %s, layer %d", | ||||
| 			neighbour.toString(), | ||||
| 			source.coord.toString(), | ||||
| 			static_cast<int32_t>(layer)); | ||||
| #endif | ||||
|  | ||||
| 		result.push_back(nextNode.value()); | ||||
| 	} | ||||
|   | ||||
| @@ -47,6 +47,7 @@ namespace AIPathfinding | ||||
| 		:PathfinderConfig(nodeStorage, makeRuleset(cb, ai, nodeStorage, allowBypassObjects)), aiNodeStorage(nodeStorage) | ||||
| 	{ | ||||
| 		options.canUseCast = true; | ||||
| 		options.allowLayerTransitioningAfterBattle = true; | ||||
| 	} | ||||
|  | ||||
| 	AIPathfinderConfig::~AIPathfinderConfig() = default; | ||||
|   | ||||
| @@ -34,6 +34,14 @@ namespace AIPathfinding | ||||
| 	{ | ||||
| 		LayerTransitionRule::process(source, destination, pathfinderConfig, pathfinderHelper); | ||||
|  | ||||
| #if NKAI_PATHFINDER_TRACE_LEVEL >= 2 | ||||
| 		logAi->trace("Layer transitioning %s -> %s, action: %d, blocked: %s", | ||||
| 			source.coord.toString(), | ||||
| 			destination.coord.toString(), | ||||
| 			static_cast<int32_t>(destination.action), | ||||
| 			destination.blocked ? "true" : "false"); | ||||
| #endif | ||||
|  | ||||
| 		if(!destination.blocked) | ||||
| 		{ | ||||
| 			if(source.node->layer == EPathfindingLayer::LAND | ||||
|   | ||||
| @@ -84,10 +84,11 @@ namespace AIPathfinding | ||||
|  | ||||
| #if NKAI_PATHFINDER_TRACE_LEVEL >= 2 | ||||
| 		logAi->trace( | ||||
| 			"Movement from tile %s is blocked. Try to bypass. Action: %d, blocker: %d", | ||||
| 			"Movement from tile %s is blocked. Try to bypass. Action: %d, blocker: %d, source: %s", | ||||
| 			destination.coord.toString(), | ||||
| 			(int)destination.action, | ||||
| 			(int)blocker); | ||||
| 			(int)blocker, | ||||
| 			source.coord.toString()); | ||||
| #endif | ||||
|  | ||||
| 		auto destGuardians = cb->getGuardingCreatures(destination.coord); | ||||
|   | ||||
| @@ -330,7 +330,7 @@ bool CPathfinder::isLayerTransitionPossible() const | ||||
| 	ELayer destLayer = destination.node->layer; | ||||
|  | ||||
| 	/// No layer transition allowed when previous node action is BATTLE | ||||
| 	if(source.node->action == EPathNodeAction::BATTLE) | ||||
| 	if(!config->options.allowLayerTransitioningAfterBattle && source.node->action == EPathNodeAction::BATTLE) | ||||
| 		return false; | ||||
|  | ||||
| 	switch(source.node->layer.toEnum()) | ||||
|   | ||||
| @@ -33,6 +33,7 @@ PathfinderOptions::PathfinderOptions() | ||||
| 	, oneTurnSpecialLayersLimit(true) | ||||
| 	, turnLimit(std::numeric_limits<uint8_t>::max()) | ||||
| 	, canUseCast(false) | ||||
| 	, allowLayerTransitioningAfterBattle(false) | ||||
| { | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -79,6 +79,11 @@ struct DLL_LINKAGE PathfinderOptions | ||||
| 	/// </summary> | ||||
| 	bool canUseCast; | ||||
|  | ||||
| 	/// <summary> | ||||
| 	/// For AI. AI pathfinder needs to ignore this rule as it simulates battles on the way | ||||
| 	/// </summary> | ||||
| 	bool allowLayerTransitioningAfterBattle; | ||||
|  | ||||
| 	PathfinderOptions(); | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user