소스 검색

Working SoD version of fly

Dydzio 1 년 전
부모
커밋
fd9810adf4

+ 3 - 1
config/gameConfig.json

@@ -384,7 +384,9 @@
 			// if enabled, pathfinder will take use of one-way monoliths with multiple exits.
 			"useMonolithOneWayRandom" : false,
 			// if enabled and hero has whirlpool protection effect, pathfinder will take use of whirpools
-			"useWhirlpool" : true
+			"useWhirlpool" : true,
+			// if enabled flying will work like in original game, otherwise nerf similar to HotA flying is applied
+			"originalFlyRules" : false
 		},
 		
 		"bonuses" : 

+ 1 - 0
lib/GameSettings.cpp

@@ -102,6 +102,7 @@ void GameSettings::load(const JsonNode & input)
 		{EGameSettings::PATHFINDER_USE_MONOLITH_ONE_WAY_UNIQUE, "pathfinder", "useMonolithOneWayUnique"   },
 		{EGameSettings::PATHFINDER_USE_MONOLITH_ONE_WAY_RANDOM, "pathfinder", "useMonolithOneWayRandom"   },
 		{EGameSettings::PATHFINDER_USE_WHIRLPOOL,               "pathfinder", "useWhirlpool"              },
+		{EGameSettings::PATHFINDER_ORIGINAL_FLY_RULES,          "pathfinder", "originalFlyRules"          },
 		{EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP,           "towns",     "buildingsPerTurnCap"        },
 		{EGameSettings::TOWNS_STARTING_DWELLING_CHANCES,        "towns",     "startingDwellingChances"    },
 	};

+ 1 - 0
lib/GameSettings.h

@@ -66,6 +66,7 @@ enum class EGameSettings
 	PATHFINDER_USE_MONOLITH_ONE_WAY_UNIQUE,
 	PATHFINDER_USE_MONOLITH_ONE_WAY_RANDOM,
 	PATHFINDER_USE_WHIRLPOOL,
+	PATHFINDER_ORIGINAL_FLY_RULES,
 	TOWNS_BUILDINGS_PER_TURN_CAP,
 	TOWNS_STARTING_DWELLING_CHANCES,
 	COMBAT_ONE_HEX_TRIGGERS_OBSTACLES,

+ 1 - 1
lib/pathfinder/CPathfinder.cpp

@@ -483,7 +483,7 @@ bool CPathfinderHelper::passOneTurnLimitCheck(const PathNodeInfo & source) const
 		return false;
 	if(source.node->layer == EPathfindingLayer::AIR)
 	{
-		return options.originalMovementRules && source.node->accessible == EPathAccessibility::ACCESSIBLE;
+		return options.originalFlyRules && source.node->accessible == EPathAccessibility::ACCESSIBLE;
 	}
 
 	return true;

+ 1 - 1
lib/pathfinder/PathfinderOptions.cpp

@@ -27,10 +27,10 @@ PathfinderOptions::PathfinderOptions()
 	, useTeleportOneWay(VLC->settings()->getBoolean(EGameSettings::PATHFINDER_USE_MONOLITH_ONE_WAY_UNIQUE))
 	, useTeleportOneWayRandom(VLC->settings()->getBoolean(EGameSettings::PATHFINDER_USE_MONOLITH_ONE_WAY_RANDOM))
 	, useTeleportWhirlpool(VLC->settings()->getBoolean(EGameSettings::PATHFINDER_USE_WHIRLPOOL))
+	, originalFlyRules(VLC->settings()->getBoolean(EGameSettings::PATHFINDER_ORIGINAL_FLY_RULES))
 	, useCastleGate(false)
 	, lightweightFlyingMode(false)
 	, oneTurnSpecialLayersLimit(true)
-	, originalMovementRules(true)
 	, turnLimit(std::numeric_limits<uint8_t>::max())
 	, canUseCast(false)
 {

+ 3 - 1
lib/pathfinder/PathfinderOptions.h

@@ -67,7 +67,9 @@ struct DLL_LINKAGE PathfinderOptions
 	/// - Option should also allow same tile land <-> air layer transitions.
 	///   Current implementation only allow go into (from) air layer only to neighbour tiles.
 	///   I find it's reasonable limitation, but it's will make some movements more expensive than in H3.
-	bool originalMovementRules;
+	///   Further work can also be done to mimic SoD quirks if needed
+	///   (such as picking unoptimal paths on purpose when targeting guards or being interrupted on guarded resource tile when picking it during diagonal u-turn)
+	bool originalFlyRules;
 
 	/// Max number of turns to compute. Default = infinite
 	uint8_t turnLimit;

+ 3 - 6
lib/pathfinder/PathfindingRules.cpp

@@ -301,7 +301,7 @@ PathfinderBlockingRule::BlockingReason MovementToDestinationRule::getBlockingRea
 
 		if(source.guarded)
 		{
-			if(!(pathfinderConfig->options.originalMovementRules && source.node->layer == EPathfindingLayer::AIR) 
+			if(!(pathfinderConfig->options.originalFlyRules && source.node->layer == EPathfindingLayer::AIR)
 				&& !pathfinderConfig->options.ignoreGuards
 				&&	(!destination.isGuardianTile || pathfinderHelper->getGuardiansCount(source.coord) > 1)) // Can step into tile of guard
 			{
@@ -386,11 +386,8 @@ void LayerTransitionRule::process(
 		break;
 
 	case EPathfindingLayer::AIR:
-		if(pathfinderConfig->options.originalMovementRules)
+		if(pathfinderConfig->options.originalFlyRules)
 		{
-			if(destination.coord.x == 2 && destination.coord.y == 35)
-				logGlobal->error(source.node->coord.toString() + std::string(" Layer: ") + std::to_string(destination.node->layer) + std::string(" Accessibility: ") + std::to_string((int)source.node->accessible));
-
 			if(source.node->accessible != EPathAccessibility::ACCESSIBLE &&
 				source.node->accessible != EPathAccessibility::VISITABLE &&
 				destination.node->accessible != EPathAccessibility::VISITABLE &&
@@ -398,7 +395,7 @@ void LayerTransitionRule::process(
 			{
 				if(destination.node->accessible == EPathAccessibility::BLOCKVIS)
 				{
-					if(source.nodeObject || source.tile->blocked)
+					if(source.nodeObject || (source.tile->blocked && destination.tile->blocked))
 					{
 						destination.blocked = true;
 					}

+ 1 - 1
server/CGameHandler.cpp

@@ -1195,7 +1195,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
 		if (leavingTile == LEAVING_TILE)
 			leaveTile();
 
-		if (isInTheMap(guardPos))
+		if (lookForGuards == CHECK_FOR_GUARDS && isInTheMap(guardPos))
 			tmh.attackedFrom = std::make_optional(guardPos);
 
 		tmh.result = result;