瀏覽代碼

Try to enable air/land movement

nordsoft 2 年之前
父節點
當前提交
ddcdfb643a
共有 4 個文件被更改,包括 24 次插入11 次删除
  1. 13 5
      lib/CPathfinder.cpp
  2. 4 2
      lib/mapObjects/CGHeroInstance.cpp
  3. 2 1
      lib/mapObjects/CRewardableObject.cpp
  4. 5 3
      server/CGameHandler.cpp

+ 13 - 5
lib/CPathfinder.cpp

@@ -151,7 +151,7 @@ void NodeStorage::resetTile(const int3 & tile, const EPathfindingLayer & layer,
 
 std::vector<CGPathNode *> NodeStorage::getInitialNodes()
 {
-	auto * initialNode = getNode(out.hpos, out.hero->boat ? EPathfindingLayer::SAIL : EPathfindingLayer::LAND);
+	auto * initialNode = getNode(out.hpos, out.hero->boat ? out.hero->boat->layer : EPathfindingLayer::LAND);
 
 	initialNode->turns = 0;
 	initialNode->moveRemains = out.hero->movement;
@@ -1019,12 +1019,18 @@ bool TurnInfo::isLayerAvailable(const EPathfindingLayer & layer) const
 	switch(layer)
 	{
 	case EPathfindingLayer::AIR:
-		if(!hasBonusOfType(Bonus::FLYING_MOVEMENT))
+		if(hero && hero->boat && hero->boat->layer == EPathfindingLayer::AIR)
+			break;
+			
+		if(hasBonusOfType(Bonus::FLYING_MOVEMENT))
 			return false;
 
 		break;
 
 	case EPathfindingLayer::WATER:
+		if(hero && hero->boat && hero->boat->layer == EPathfindingLayer::WATER)
+			break;
+			
 		if(!hasBonusOfType(Bonus::WATER_WALKING))
 			return false;
 
@@ -1232,15 +1238,17 @@ int CPathfinderHelper::getMovementCost(
 
 	bool isSailLayer;
 	if(indeterminate(isDstSailLayer))
-		isSailLayer = hero->boat != nullptr && dt->terType->isWater();
+		isSailLayer = hero->boat && hero->boat->layer == EPathfindingLayer::SAIL && dt->terType->isWater();
 	else
 		isSailLayer = static_cast<bool>(isDstSailLayer);
 
 	bool isWaterLayer;
 	if(indeterminate(isDstWaterLayer))
-		isWaterLayer = dt->terType->isWater();
+		isWaterLayer = ((hero->boat && hero->boat->layer == EPathfindingLayer::WATER) || ti->hasBonusOfType(Bonus::WATER_WALKING)) && dt->terType->isWater();
 	else
 		isWaterLayer = static_cast<bool>(isDstWaterLayer);
+	
+	bool isAirLayer = (hero->boat && hero->boat->layer == EPathfindingLayer::AIR) || ti->hasBonusOfType(Bonus::FLYING_MOVEMENT);
 
 	int ret = hero->getTileCost(*dt, *ct, ti);
 	if(isSailLayer)
@@ -1248,7 +1256,7 @@ int CPathfinderHelper::getMovementCost(
 		if(ct->hasFavorableWinds())
 			ret = static_cast<int>(ret * 2.0 / 3);
 	}
-	else if(ti->hasBonusOfType(Bonus::FLYING_MOVEMENT))
+	else if(isAirLayer)
 		vstd::amin(ret, GameConstants::BASE_MOVEMENT_COST + ti->valOfBonuses(Bonus::FLYING_MOVEMENT));
 	else if(isWaterLayer && ti->hasBonusOfType(Bonus::WATER_WALKING))
 		ret = static_cast<int>(ret * (100.0 + ti->valOfBonuses(Bonus::WATER_WALKING)) / 100.0);

+ 4 - 2
lib/mapObjects/CGHeroInstance.cpp

@@ -1120,9 +1120,11 @@ int CGHeroInstance::movementPointsAfterEmbark(int MPsBefore, int basicCost, bool
 
 	if(!ti->hasBonusOfType(Bonus::FREE_SHIP_BOARDING))
 		return 0; // take all MPs by default
+	
+	auto boatLayer = boat ? boat->layer : EPathfindingLayer::SAIL;
 
-	int mp1 = ti->getMaxMovePoints(disembark ? EPathfindingLayer::LAND : EPathfindingLayer::SAIL);
-	int mp2 = ti->getMaxMovePoints(disembark ? EPathfindingLayer::SAIL : EPathfindingLayer::LAND);
+	int mp1 = ti->getMaxMovePoints(disembark ? EPathfindingLayer::LAND : boatLayer);
+	int mp2 = ti->getMaxMovePoints(disembark ? boatLayer : EPathfindingLayer::LAND);
 	int ret = static_cast<int>((MPsBefore - basicCost) * static_cast<double>(mp1) / mp2);
 	return ret;
 }

+ 2 - 1
lib/mapObjects/CRewardableObject.cpp

@@ -19,6 +19,7 @@
 #include "../CPlayerState.h"
 #include "../spells/CSpellHandler.h"
 #include "../spells/ISpellMechanics.h"
+#include "../mapObjects/MiscObjects.h"
 
 #include "CObjectClassesHandler.h"
 
@@ -316,7 +317,7 @@ void CRewardableObject::grantRewardAfterLevelup(const CRewardVisitInfo & info, c
 		smp.val = hero->movement;
 
 		if (info.reward.movePercentage >= 0) // percent from max
-			smp.val = hero->maxMovePoints(hero->boat != nullptr) * info.reward.movePercentage / 100;
+			smp.val = hero->maxMovePoints(hero->boat && hero->boat->layer == EPathfindingLayer::SAIL) * info.reward.movePercentage / 100;
 		smp.val = std::max<si32>(0, smp.val + info.reward.movePoints);
 
 		cb->setMovePoints(&smp);

+ 5 - 3
server/CGameHandler.cpp

@@ -2264,7 +2264,9 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
 	const int3 guardPos = gs->guardingCreaturePosition(hmpos);
 
 	const bool embarking = !h->boat && !t.visitableObjects.empty() && t.visitableObjects.back()->ID == Obj::TRANSPORT;
-	const bool disembarking = h->boat && t.terType->isLand() && !t.blocked;
+	const bool disembarking = h->boat
+		&& (h->boat->layer == EPathfindingLayer::SAIL && t.terType->isLand())
+		&& !t.blocked;
 
 	//result structure for start - movement failed, no move points used
 	TryMoveHero tmh;
@@ -2278,8 +2280,8 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
 	auto pathfinderHelper = std::make_unique<CPathfinderHelper>(gs, h, PathfinderOptions());
 	auto ti = pathfinderHelper->getTurnInfo();
 
-	const bool canFly = pathfinderHelper->hasBonusOfType(Bonus::FLYING_MOVEMENT);
-	const bool canWalkOnSea = pathfinderHelper->hasBonusOfType(Bonus::WATER_WALKING);
+	const bool canFly = pathfinderHelper->hasBonusOfType(Bonus::FLYING_MOVEMENT) || (h->boat && h->boat->layer == EPathfindingLayer::AIR);
+	const bool canWalkOnSea = pathfinderHelper->hasBonusOfType(Bonus::WATER_WALKING) || (h->boat && h->boat->layer == EPathfindingLayer::WATER);
 	const int cost = pathfinderHelper->getMovementCost(h->visitablePos(), hmpos, nullptr, nullptr, h->movement);
 
 	//it's a rock or blocked and not visitable tile