summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actions/actions.cpp3
-rw-r--r--src/actormanager.cpp67
-rw-r--r--src/actormanager.h6
-rw-r--r--src/resources/map/map.h3
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; }