bool PassableToTile(const Heroes & hero, const Maps::Tiles & toTile, int direct, s32 dst) { // check end point if(toTile.GetIndex() == dst) { // fix toTilePassable with action object if(MP2::isPickupObject(toTile.GetObject())) return true; // check direct to object if(MP2::isActionObject(toTile.GetObject(false), hero.isShipMaster())) return Direction::Reflect(direct) & toTile.GetPassable(); if(MP2::OBJ_HEROES == toTile.GetObject()) return toTile.isPassable(NULL, Direction::Reflect(direct), (hero.isControlAI() ? AI::HeroesSkipFog() : false)); } // check to tile direct if(! toTile.isPassable(&hero, Direction::Reflect(direct), (hero.isControlAI() ? AI::HeroesSkipFog() : false))) return false; if(toTile.GetIndex() != dst) { if(MP2::isPickupObject(toTile.GetObject()) || MP2::isActionObject(toTile.GetObject(false), hero.isShipMaster())) return false; // check hero/monster on route switch(toTile.GetObject()) { case MP2::OBJ_HEROES: case MP2::OBJ_MONSTER: return false; default: break; } // check monster protection if(CheckMonsterProtectionAndNotDst(toTile.GetIndex(), dst)) return false; } return true; }
bool PassableFromToTile(const Heroes & hero, s32 from, const s32 & to, int direct, s32 dst) { const Maps::Tiles & fromTile = world.GetTiles(from); const Maps::Tiles & toTile = world.GetTiles(to); // check start point if(hero.GetIndex() == from) { if(MP2::isActionObject(fromTile.GetObject(false), hero.isShipMaster())) { // check direct from object if(! (direct & fromTile.GetPassable())) return false; } else { // check from tile direct if(! fromTile.isPassable(&hero, direct, (hero.isControlAI() ? AI::HeroesSkipFog() : false))) return false; } } else { if(MP2::isActionObject(fromTile.GetObject(), hero.isShipMaster())) { // check direct from object if(! (direct & fromTile.GetPassable())) return false; } else { // check from tile direct if(! fromTile.isPassable(&hero, direct, (hero.isControlAI() ? AI::HeroesSkipFog() : false))) return false; } } if(fromTile.isWater() && !toTile.isWater()) { switch(toTile.GetObject()) { case MP2::OBJ_BOAT: case MP2::OBJ_MONSTER: case MP2::OBJ_HEROES: return false; case MP2::OBJ_COAST: return toTile.GetIndex() == dst; default: break; } } else if(!fromTile.isWater() && toTile.isWater()) { switch(toTile.GetObject()) { case MP2::OBJ_BOAT: return true; case MP2::OBJ_HEROES: return toTile.GetIndex() == dst; default: break; } } // check corner water/coast if(hero.isShipMaster() && (direct & (Direction::TOP_LEFT | Direction::TOP_RIGHT | Direction::BOTTOM_RIGHT | Direction::BOTTOM_LEFT))) { switch(direct) { case Direction::TOP_LEFT: if((Maps::isValidDirection(from, Direction::TOP) && ! world.GetTiles(Maps::GetDirectionIndex(from, Direction::TOP)).isWater()) || (Maps::isValidDirection(from, Direction::LEFT) && ! world.GetTiles(Maps::GetDirectionIndex(from, Direction::LEFT)).isWater())) return false; break; case Direction::TOP_RIGHT: if((Maps::isValidDirection(from, Direction::TOP) && ! world.GetTiles(Maps::GetDirectionIndex(from, Direction::TOP)).isWater()) || (Maps::isValidDirection(from, Direction::RIGHT) && ! world.GetTiles(Maps::GetDirectionIndex(from, Direction::RIGHT)).isWater())) return false; break; case Direction::BOTTOM_RIGHT: if((Maps::isValidDirection(from, Direction::BOTTOM) && ! world.GetTiles(Maps::GetDirectionIndex(from, Direction::BOTTOM)).isWater()) || (Maps::isValidDirection(from, Direction::RIGHT) && ! world.GetTiles(Maps::GetDirectionIndex(from, Direction::RIGHT)).isWater())) return false; break; case Direction::BOTTOM_LEFT: if((Maps::isValidDirection(from, Direction::BOTTOM) && ! world.GetTiles(Maps::GetDirectionIndex(from, Direction::BOTTOM)).isWater()) || (Maps::isValidDirection(from, Direction::LEFT) && ! world.GetTiles(Maps::GetDirectionIndex(from, Direction::LEFT)).isWater())) return false; break; default: break; } } return PassableToTile(hero, toTile, direct, dst); }