Kaynağa Gözat

Merge pull request #123 from ArseniyShestakov/mantis-1230

Okay, now we shouldn't get broken savegames. Merging.
DjWarmonger 10 yıl önce
ebeveyn
işleme
8c9f8f22d9

+ 5 - 0
config/bonuses.json

@@ -368,6 +368,11 @@
 			"icon":  "zvs/Lib1.res/E_OBST"
 		}
 	},
+	
+	"NO_TERRAIN_PENALTY":
+	{
+		"hidden": true
+	},
 
 	"NON_LIVING":
 	{

+ 9 - 0
config/creatures/neutral.json

@@ -475,6 +475,15 @@
 		"index": 142,
 		"level": 3,
 		"faction": "neutral",
+		"abilities":
+		{
+			"sandWalker" :
+			{
+				"type" : "NO_TERRAIN_PENALTY",
+				"subtype" : 1,
+				"propagator" : "HERO"
+			}
+		},
 		"doubleWide" : true,
 		"graphics" :
 		{

+ 1 - 0
lib/GameConstants.h

@@ -51,6 +51,7 @@ namespace GameConstants
 	const int SPELLS_QUANTITY=70;
 	const int CREATURES_COUNT = 197;
 
+	const ui32 BASE_MOVEMENT_COST = 100; //default cost for non-diagonal movement
 }
 
 class CArtifact;

+ 3 - 1
lib/HeroBonus.h

@@ -216,7 +216,9 @@ public:
 	BONUS_NAME(SPOILS_OF_WAR) /*val * 10^-6 * gained exp resources of subtype will be given to hero after battle*/\
 	BONUS_NAME(BLOCK)\
 	BONUS_NAME(DISGUISED) /* subtype - spell level */\
-	BONUS_NAME(VISIONS) /* subtype - spell level */
+	BONUS_NAME(VISIONS) /* subtype - spell level */\
+	BONUS_NAME(NO_TERRAIN_PENALTY) /* subtype - terrain type */\
+	/* end of list */
 	
 
 #define BONUS_SOURCE_LIST \

+ 15 - 22
lib/mapObjects/CGHeroInstance.cpp

@@ -58,56 +58,49 @@ static int lowestSpeed(const CGHeroInstance * chi)
 
 ui32 CGHeroInstance::getTileCost(const TerrainTile &dest, const TerrainTile &from) const
 {
-	//base move cost
-	unsigned ret = 100;
+	unsigned ret = GameConstants::BASE_MOVEMENT_COST;
 
 	//if there is road both on dest and src tiles - use road movement cost
-    if(dest.roadType != ERoadType::NO_ROAD && from.roadType != ERoadType::NO_ROAD)
+	if(dest.roadType != ERoadType::NO_ROAD && from.roadType != ERoadType::NO_ROAD)
 	{
-        int road = std::min(dest.roadType,from.roadType); //used road ID
+		int road = std::min(dest.roadType,from.roadType); //used road ID
 		switch(road)
 		{
-        case ERoadType::DIRT_ROAD:
+		case ERoadType::DIRT_ROAD:
 			ret = 75;
 			break;
-        case ERoadType::GRAVEL_ROAD:
+		case ERoadType::GRAVEL_ROAD:
 			ret = 65;
 			break;
-        case ERoadType::COBBLESTONE_ROAD:
+		case ERoadType::COBBLESTONE_ROAD:
 			ret = 50;
 			break;
 		default:
-            logGlobal->errorStream() << "Unknown road type: " << road << "... Something wrong!";
+			logGlobal->errorStream() << "Unknown road type: " << road << "... Something wrong!";
 			break;
 		}
 	}
-	else
+	else if(!hasBonusOfType(Bonus::NO_TERRAIN_PENALTY, from.terType))
 	{
-		//FIXME: in H3 presence of Nomad in army will remove terrain penalty for sand. Bonus not implemented in VCMI
-
 		// NOTE: in H3 neutral stacks will ignore terrain penalty only if placed as topmost stack(s) in hero army.
 		// This is clearly bug in H3 however intended behaviour is not clear.
 		// Current VCMI behaviour will ignore neutrals in calculations so army in VCMI
 		// will always have best penalty without any influence from player-defined stacks order
 
-		bool nativeArmy = true;
 		for(auto stack : stacks)
 		{
 			int nativeTerrain = VLC->townh->factions[stack.second->type->faction]->nativeTerrain;
-
-            if (nativeTerrain != -1 && nativeTerrain != from.terType)
+			if(nativeTerrain != -1 && nativeTerrain != from.terType)
 			{
-				nativeArmy = false;
+				ret = VLC->heroh->terrCosts[from.terType];
+				ret -= getSecSkillLevel(SecondarySkill::PATHFINDING) * 25;
+				if(ret < GameConstants::BASE_MOVEMENT_COST)
+					ret = GameConstants::BASE_MOVEMENT_COST;
+
 				break;
 			}
 		}
-		if (!nativeArmy)
-        {
-            ret = VLC->heroh->terrCosts[from.terType];
-            ret-=getSecSkillLevel(SecondarySkill::PATHFINDING)*25;
-            ret = ret < 100 ? 100 : ret;
-        }
- 	}
+	}
 	return ret;
 }