mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Merge pull request #4038 from IvanSavenko/pathfinder_fixes
[1.5.2] Pathfinder fixes
This commit is contained in:
		| @@ -664,15 +664,15 @@ size_t MapRendererPath::selectImageArrow(bool reachableToday, const int3 & curr, | ||||
| 	// is (directionToArrowIndex[7][5]) | ||||
| 	// | ||||
| 	const static size_t directionToArrowIndex[9][9] = { | ||||
| 		{16, 17, 18, 7,  0, 19, 6,  5,  0 }, | ||||
| 		{8,  9,  18, 7,  0, 19, 6,  0,  20}, | ||||
| 		{8,  1,  10, 7,  0, 19, 0,  21, 20}, | ||||
| 		{24, 17, 18, 15, 0, 0,  6,  5,  4 }, | ||||
| 		{16, 17, 18, 7,  0, 19, 6,  5,  12}, | ||||
| 		{8,  9,  18, 7,  0, 19, 6,  13, 20}, | ||||
| 		{8,  1,  10, 7,  0, 19, 14, 21, 20}, | ||||
| 		{24, 17, 18, 15, 0, 11, 6,  5,  4 }, | ||||
| 		{0,  0,  0,  0,  0, 0,  0,  0,  0 }, | ||||
| 		{8,  1,  2,  0,  0, 11, 22, 21, 20}, | ||||
| 		{24, 17, 0,  23, 0, 3,  14, 5,  4 }, | ||||
| 		{24, 0,  2,  23, 0, 3,  22, 13, 4 }, | ||||
| 		{0,  1,  2,  23, 0, 3,  22, 21, 12} | ||||
| 		{8,  1,  2,  15, 0, 11, 22, 21, 20}, | ||||
| 		{24, 17, 10, 23, 0, 3,  14, 5,  4 }, | ||||
| 		{24, 9,  2,  23, 0, 3,  22, 13, 4 }, | ||||
| 		{16, 1,  2,  23, 0, 3,  22, 21, 12} | ||||
| 	}; | ||||
|  | ||||
| 	size_t enterDirection = (curr.x - next.x + 1) + 3 * (curr.y - next.y + 1); | ||||
|   | ||||
| @@ -37,6 +37,7 @@ enum class EPathAccessibility : ui8 | ||||
| 	NOT_SET, | ||||
| 	ACCESSIBLE, //tile can be entered and passed | ||||
| 	VISITABLE, //tile can be entered as the last tile in path | ||||
| 	GUARDED,  //tile can be entered, but is in zone of control of nearby monster (may also contain visitable object, if any) | ||||
| 	BLOCKVIS,  //visitable from neighboring tile but not passable | ||||
| 	FLYABLE, //can only be accessed in air layer | ||||
| 	BLOCKED //tile can be neither entered nor visited | ||||
|   | ||||
| @@ -58,7 +58,7 @@ namespace PathfinderUtil | ||||
| 			else if(gs->guardingCreaturePosition(pos).valid()) | ||||
| 			{ | ||||
| 				// Monster close by; blocked visit for battle | ||||
| 				return EPathAccessibility::BLOCKVIS; | ||||
| 				return EPathAccessibility::GUARDED; | ||||
| 			} | ||||
|  | ||||
| 			break; | ||||
|   | ||||
| @@ -267,7 +267,11 @@ PathfinderBlockingRule::BlockingReason MovementAfterDestinationRule::getBlocking | ||||
| 		return BlockingReason::DESTINATION_BLOCKED; | ||||
|  | ||||
| 	case EPathNodeAction::BATTLE: | ||||
| 		/// Movement after BATTLE action only possible from guarded tile to guardian tile | ||||
| 		// H3 rule: do not allow direct attack on wandering monsters if hero lands on visitable object | ||||
| 		if (config->options.originalFlyRules && destination.nodeObject && source.node->layer == EPathfindingLayer::AIR) | ||||
| 			return BlockingReason::DESTINATION_BLOCKED; | ||||
|  | ||||
| 		// Movement after BATTLE action only possible from guarded tile to guardian tile | ||||
| 		if(destination.guarded) | ||||
| 		{ | ||||
| 			if (pathfinderHelper->options.ignoreGuards) | ||||
| @@ -275,7 +279,6 @@ PathfinderBlockingRule::BlockingReason MovementAfterDestinationRule::getBlocking | ||||
| 			else | ||||
| 				return BlockingReason::DESTINATION_GUARDED; | ||||
| 		} | ||||
|  | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| @@ -301,7 +304,7 @@ PathfinderBlockingRule::BlockingReason MovementToDestinationRule::getBlockingRea | ||||
|  | ||||
| 		if(source.guarded) | ||||
| 		{ | ||||
| 			if(!(pathfinderConfig->options.originalFlyRules && source.node->layer == EPathfindingLayer::AIR) | ||||
| 			if(source.node->layer != EPathfindingLayer::AIR // zone of control is ignored when flying | ||||
| 				&& !pathfinderConfig->options.ignoreGuards | ||||
| 				&&	(!destination.isGuardianTile || pathfinderHelper->getGuardiansCount(source.coord) > 1)) // Can step into tile of guard | ||||
| 			{ | ||||
| @@ -339,11 +342,11 @@ PathfinderBlockingRule::BlockingReason MovementToDestinationRule::getBlockingRea | ||||
| 		break; | ||||
|  | ||||
| 	case EPathfindingLayer::WATER: | ||||
| 		if(!pathfinderHelper->canMoveBetween(source.coord, destination.coord) | ||||
| 			|| destination.node->accessible != EPathAccessibility::ACCESSIBLE) | ||||
| 		{ | ||||
| 		if(!pathfinderHelper->canMoveBetween(source.coord, destination.coord)) | ||||
| 			return BlockingReason::DESTINATION_BLOCKED; | ||||
|  | ||||
| 		if (destination.node->accessible != EPathAccessibility::ACCESSIBLE) | ||||
| 			return BlockingReason::DESTINATION_BLOCKED; | ||||
| 		} | ||||
|  | ||||
| 		if(destination.guarded) | ||||
| 			return BlockingReason::DESTINATION_BLOCKED; | ||||
| @@ -376,38 +379,33 @@ void LayerTransitionRule::process( | ||||
| 		break; | ||||
|  | ||||
| 	case EPathfindingLayer::SAIL: | ||||
| 		//tile must be accessible -> exception: unblocked blockvis tiles -> clear but guarded by nearby monster coast | ||||
| 		if((destination.node->accessible != EPathAccessibility::ACCESSIBLE && (destination.node->accessible != EPathAccessibility::BLOCKVIS || destination.tile->blocked)) | ||||
| 			|| destination.tile->visitable)  //TODO: passableness problem -> town says it's passable (thus accessible) but we obviously can't disembark onto town gate | ||||
| 		{ | ||||
| 		// have to disembark first before visiting objects on land | ||||
| 		if (destination.tile->visitable) | ||||
| 			destination.blocked = true; | ||||
|  | ||||
| 		//can disembark only on accessible tiles or tiles guarded by nearby monster | ||||
| 		if((destination.node->accessible != EPathAccessibility::ACCESSIBLE && destination.node->accessible != EPathAccessibility::GUARDED)) | ||||
| 			destination.blocked = true; | ||||
| 		} | ||||
|  | ||||
| 		break; | ||||
|  | ||||
| 	case EPathfindingLayer::AIR: | ||||
| 		if(pathfinderConfig->options.originalFlyRules) | ||||
| 		{ | ||||
| 			if(source.node->accessible != EPathAccessibility::ACCESSIBLE && | ||||
| 				source.node->accessible != EPathAccessibility::VISITABLE && | ||||
| 				destination.node->accessible != EPathAccessibility::VISITABLE && | ||||
| 				 destination.node->accessible != EPathAccessibility::ACCESSIBLE) | ||||
| 			if(source.node->accessible != EPathAccessibility::ACCESSIBLE && source.node->accessible != EPathAccessibility::VISITABLE) | ||||
| 			{ | ||||
| 				if(destination.node->accessible == EPathAccessibility::BLOCKVIS) | ||||
| 				if (destination.node->accessible == EPathAccessibility::BLOCKVIS) | ||||
| 				{ | ||||
| 					if(source.nodeObject || (source.tile->blocked && destination.tile->blocked)) | ||||
| 					{ | ||||
| 					// Can't visit 'blockvisit' objects on coast if hero will end up on water terrain | ||||
| 					if (source.tile->blocked || !destination.tile->entrableTerrain(source.tile)) | ||||
| 						destination.blocked = true; | ||||
| 					} | ||||
| 				} | ||||
| 				else | ||||
| 					destination.blocked = true; | ||||
| 			} | ||||
| 		} | ||||
| 		else if(destination.node->accessible != EPathAccessibility::ACCESSIBLE) | ||||
| 		else | ||||
| 		{ | ||||
| 			/// Hero that fly can only land on accessible tiles | ||||
| 			if(destination.nodeObject) | ||||
| 			// Hero that fly can only land on accessible tiles | ||||
| 			if(destination.node->accessible != EPathAccessibility::ACCESSIBLE && destination.nodeObject) | ||||
| 				destination.blocked = true; | ||||
| 		} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user