diff options
-rw-r--r-- | src/actions/actions.cpp | 3 | ||||
-rw-r--r-- | src/actormanager.cpp | 67 | ||||
-rw-r--r-- | src/actormanager.h | 6 | ||||
-rw-r--r-- | src/resources/map/map.h | 3 |
4 files changed, 73 insertions, 6 deletions
diff --git a/src/actions/actions.cpp b/src/actions/actions.cpp index feba9dcaa..d2fc1c4c8 100644 --- a/src/actions/actions.cpp +++ b/src/actions/actions.cpp @@ -868,8 +868,7 @@ impHandler0(attackHuman) if (!actorManager || !localPlayer) return false; - Being *const target = actorManager->findNearestLivingBeing( - localPlayer, 10, ActorType::Player, AllowSort_true); + Being *const target = actorManager->findNearestPvpPlayer(); if (target) { localPlayer->setTarget(target); diff --git a/src/actormanager.cpp b/src/actormanager.cpp index b83a08a0d..43330a7c5 100644 --- a/src/actormanager.cpp +++ b/src/actormanager.cpp @@ -22,6 +22,7 @@ #include "actormanager.h" +#include "game.h" #include "configuration.h" #include "settings.h" @@ -52,6 +53,8 @@ #include "resources/chatobject.h" #include "resources/iteminfo.h" +#include "resources/map/map.h" + #include "resources/db/itemdb.h" #include <algorithm> @@ -905,6 +908,62 @@ void ActorManager::clear() mActors.insert(localPlayer); } +Being *ActorManager::findNearestPvpPlayer() const +{ + if (!localPlayer) + return nullptr; + + // don't attack players + if (settings.pvpAttackType == 3) + return nullptr; + + const Game *const game = Game::instance(); + if (!game) + return nullptr; + + const Map *const map = game->getCurrentMap(); + if (!map) + return nullptr; + + const int mapPvpMode = map->getPvpMode(); + Being *target = nullptr; + int minDistSquared = 20000; + + for_actors + { + if ((*it)->getType() != ActorType::Player) + continue; + + Being *const being = static_cast<Being*>(*it); + + if (!being || !being->isAlive() || + localPlayer == being) + { + continue; + } + + const int teamId = being->getTeamId(); + // this condition is very TMW-specific + if (!(mapPvpMode || teamId)) + continue; + + if (!localPlayer->checAttackPermissions(being)) + continue; + + const int dx = being->getTileX() - localPlayer->getTileX(); + const int dy = being->getTileY() - localPlayer->getTileY(); + const int distSquared = dx * dx + dy * dy; + if (distSquared < minDistSquared) + { + minDistSquared = distSquared; + target = being; + } + } + + return target; +} + + Being *ActorManager::findNearestLivingBeing(const int x, const int y, const int maxTileDist, const ActorTypeT type, @@ -1321,10 +1380,10 @@ Being* ActorManager::findMostDamagedPlayer(const int maxTileDist) const Being *const being = static_cast<Being*>(*it); - if ((!being) || (!being->isAlive()) || // don't heal dead - (player_relations.getRelation(being->getName()) == - Relation::ENEMY2) || // don't heal enemy - (localPlayer == being)) // don't heal self + if (!being || !being->isAlive() || // don't heal dead + player_relations.getRelation(being->getName()) == + Relation::ENEMY2 || // don't heal enemy + localPlayer == being) // don't heal self { continue; } diff --git a/src/actormanager.h b/src/actormanager.h index e4689bbf2..52aa3dfc8 100644 --- a/src/actormanager.h +++ b/src/actormanager.h @@ -193,6 +193,12 @@ class ActorManager final: public ConfigListener const A_WARN_UNUSED; /** + * Finds the nearest player who has PVP on, + * or just the nearest player if map pvp is on + */ + Being *findNearestPvpPlayer() const A_WARN_UNUSED; + + /** * Heal all players in distance. * * \param maxdist maximal distance. If minimal distance is larger, diff --git a/src/resources/map/map.h b/src/resources/map/map.h index ea083bd99..33b819c04 100644 --- a/src/resources/map/map.h +++ b/src/resources/map/map.h @@ -276,6 +276,9 @@ class Map final : public Properties, public ConfigListener void setPvpMode(const int mode); + int getPvpMode() const A_WARN_UNUSED + { return mPvp; } + const ObjectsLayer* getObjectsLayer() const A_WARN_UNUSED { return mObjects; } |