From 939b3c05a19d30b869351e97f274cb6da019cf4e Mon Sep 17 00:00:00 2001 From: ArseniyShestakov Date: Sat, 24 Oct 2015 15:34:27 +0300 Subject: [PATCH] CPathfinder: use struct instead of enum for options Suggested by @DjWarmonger as better alternative from performance standpoint while struct still more organized than bunch of variables. Other reason of change it's that in future we may need non-boolean options, e.g for patrol movement and some new pathfinder usages. --- lib/CGameState.cpp | 32 ++++++++++++++++++++------------ lib/CGameState.h | 20 +++++++++++--------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 1590cd984..567ae73e8 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -3410,7 +3410,7 @@ bool CPathfinder::checkDestinationTile() return true; // This one is tricky, we can ignore fact that tile is not ACCESSIBLE in case if it's our hero block it. Though this need investigation if(dp->accessible == CGPathNode::VISITABLE && CGTeleport::isTeleport(dt->topVisitableObj())) return true; // For now we'll always allow transit for teleporters - if(useEmbarkCost && vstd::contains(options, EOptions::EMBARK_AND_DISEMBARK)) + if(useEmbarkCost && options.useEmbarkAndDisembark) return true; if(isDestinationGuarded() && !isSourceGuarded()) return true; // Can step into a hostile tile once @@ -3611,6 +3611,17 @@ bool CPathfinder::isMovementPossible() return true; } +CPathfinder::PathfinderOptions::PathfinderOptions() +{ + useFlying = false; + useWaterWalking = false; + useEmbarkAndDisembark = true; + useTeleportTWoWay = true; + useTeleportOneWay = true; + useTeleportOneWayRandom = false; + useTeleportWhirlpool = false; +} + CPathfinder::CPathfinder(CPathsInfo &_out, CGameState *_gs, const CGHeroInstance *_hero) : CGameInfoCallback(_gs, boost::optional()), out(_out), hero(_hero), FoW(getPlayerTeam(hero->tempOwner)->fogOfWarMap) { assert(hero); @@ -3627,14 +3638,11 @@ CPathfinder::CPathfinder(CPathsInfo &_out, CGameState *_gs, const CGHeroInstance initializeGraph(); if(hero->canFly()) - options.insert(EOptions::FLYING); - else if(hero->canWalkOnSea()) - options.insert(EOptions::WALKING_ON_SEA); - options.insert(EOptions::EMBARK_AND_DISEMBARK); - options.insert(EOptions::TELEPORT_TWO_WAY); - options.insert(EOptions::TELEPORT_ONE_WAY); + options.useFlying = true; + if(hero->canWalkOnSea()) + options.useWaterWalking = true; if (CGWhirlpool::isProtected(hero)) - options.insert(EOptions::TELEPORT_WHIRLPOOL); + options.useTeleportWhirlpool = true; neighbours.reserve(16); } @@ -3647,12 +3655,12 @@ CRandomGenerator & CGameState::getRandomGenerator() bool CPathfinder::addTeleportTwoWay(const CGTeleport * obj) const { - return vstd::contains(options,EOptions::TELEPORT_TWO_WAY) && gs->isTeleportChannelBidirectional(obj->channel, hero->tempOwner); + return options.useTeleportTWoWay && gs->isTeleportChannelBidirectional(obj->channel, hero->tempOwner); } bool CPathfinder::addTeleportOneWay(const CGTeleport * obj) const { - if(vstd::contains(options,EOptions::TELEPORT_ONE_WAY) && isTeleportChannelUnidirectional(obj->channel, hero->tempOwner)) + if(options.useTeleportOneWay && isTeleportChannelUnidirectional(obj->channel, hero->tempOwner)) { auto passableExits = CGTeleport::getPassableExits(gs, hero, gs->getTeleportChannelExits(obj->channel, hero->tempOwner)); if(passableExits.size() == 1) @@ -3663,7 +3671,7 @@ bool CPathfinder::addTeleportOneWay(const CGTeleport * obj) const bool CPathfinder::addTeleportOneWayRandom(const CGTeleport * obj) const { - if(vstd::contains(options,EOptions::TELEPORT_ONE_WAY_RANDOM) && isTeleportChannelUnidirectional(obj->channel, hero->tempOwner)) + if(options.useTeleportOneWayRandom && isTeleportChannelUnidirectional(obj->channel, hero->tempOwner)) { auto passableExits = CGTeleport::getPassableExits(gs, hero, gs->getTeleportChannelExits(obj->channel, hero->tempOwner)); if(passableExits.size() > 1) @@ -3674,5 +3682,5 @@ bool CPathfinder::addTeleportOneWayRandom(const CGTeleport * obj) const bool CPathfinder::addTeleportWhirlpool(const CGWhirlpool * obj) const { - return vstd::contains(options,EOptions::TELEPORT_WHIRLPOOL) && obj; + return options.useTeleportWhirlpool && obj; } diff --git a/lib/CGameState.h b/lib/CGameState.h index c5c646582..7a4bae191 100644 --- a/lib/CGameState.h +++ b/lib/CGameState.h @@ -279,17 +279,19 @@ struct DLL_EXPORT DuelParameters class CPathfinder : private CGameInfoCallback { private: - enum class EOptions + struct PathfinderOptions { - FLYING, - WALKING_ON_SEA, - EMBARK_AND_DISEMBARK, - TELEPORT_TWO_WAY, // Two-way monoliths and Subterranean Gate - TELEPORT_ONE_WAY, // One-way monoliths with one known exit only - TELEPORT_ONE_WAY_RANDOM, // One-way monoliths with more than one known exit - TELEPORT_WHIRLPOOL // Force enabled if hero protected or unaffected (have one stack of one creature) + bool useFlying; + bool useWaterWalking; + bool useEmbarkAndDisembark; + bool useTeleportTWoWay; // Two-way monoliths and Subterranean Gate + bool useTeleportOneWay; // One-way monoliths with one known exit only + bool useTeleportOneWayRandom; // One-way monoliths with more than one known exit + bool useTeleportWhirlpool; // Force enabled if hero protected or unaffected (have one stack of one creature) + + PathfinderOptions(); }; - std::set options; + PathfinderOptions options; CPathsInfo &out; const CGHeroInstance *hero;