1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Try to enable air/land movement

This commit is contained in:
nordsoft 2023-04-18 17:36:42 +04:00
parent d83566bc74
commit ddcdfb643a
4 changed files with 24 additions and 11 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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