summaryrefslogtreecommitdiff
path: root/src/actorspritemanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/actorspritemanager.cpp')
-rw-r--r--src/actorspritemanager.cpp112
1 files changed, 104 insertions, 8 deletions
diff --git a/src/actorspritemanager.cpp b/src/actorspritemanager.cpp
index 44dc30892..bbcf29090 100644
--- a/src/actorspritemanager.cpp
+++ b/src/actorspritemanager.cpp
@@ -25,6 +25,7 @@
#include "configuration.h"
#include "localplayer.h"
#include "log.h"
+#include "main.h"
#include "playerinfo.h"
#include "playerrelations.h"
@@ -99,6 +100,7 @@ class SortBeingFunctor
return being1->getDistance() < being2->getDistance();
int d1, d2;
+#ifdef MANASERV_SUPPORT
if (Net::getNetworkType() == ServerInfo::MANASERV)
{
const Vector &pos1 = being1->getPosition();
@@ -109,6 +111,7 @@ class SortBeingFunctor
+ abs((static_cast<int>(pos2.y)) - y);
}
else
+#endif
{
d1 = abs(being1->getTileX() - x) + abs(being1->getTileY() - y);
d2 = abs(being2->getTileX() - x) + abs(being2->getTileY() - y);
@@ -116,9 +119,28 @@ class SortBeingFunctor
if (d1 != d2)
return d1 < d2;
+ if (beings)
+ {
+ int w1 = defaultIndex;
+ int w2 = defaultIndex;
+ std::map<std::string, int>::iterator it1
+ = beings->find(being1->getName());
+ std::map<std::string, int>::iterator it2
+ = beings->find(being2->getName());
+ if (it1 != beings->end())
+ w1 = (*it1).second;
+ if (it2 != beings->end())
+ w2 = (*it2).second;
+
+ if (w1 != w2)
+ return w1 < w2;
+ }
+
return (being1->getName() < being2->getName());
}
int x, y;
+ std::map<std::string, int> *beings;
+ int defaultIndex;
} beingSorter;
@@ -654,12 +676,31 @@ Being *ActorSpriteManager::findNearestLivingBeing(Being *aroundBeing,
return 0;
Being *closestBeing = 0;
+ std::set<std::string> attackMobs;
+ std::set<std::string> ignoreAttackMobs;
+ std::map<std::string, int> mobsMap;
+ int defaultIndex = 10000;
maxDist = maxDist * maxDist;
bool cycleSelect = (mCyclePlayers && type == Being::PLAYER)
|| (mCycleMonsters && type == Being::MONSTER);
+ bool filtered = config.getBoolValue("enableAttackFilter");
+ bool ignoreDefault = false;
+ if (filtered)
+ {
+ attackMobs = player_node->getAttackMobsSet();
+ ignoreAttackMobs = player_node->getIgnoreAttackMobsSet();
+ mobsMap = player_node->getAttackMobsMap();
+ beingSorter.beings = &mobsMap;
+ if (ignoreAttackMobs.find("") != ignoreAttackMobs.end())
+ ignoreDefault = true;
+ std::map<std::string, int>::iterator itr = mobsMap.find("");
+ if (itr != mobsMap.end())
+ defaultIndex = (*itr).second;
+ }
+
if (cycleSelect)
{
std::vector<Being*> sortedBeings;
@@ -676,6 +717,19 @@ Being *ActorSpriteManager::findNearestLivingBeing(Being *aroundBeing,
Being *being = static_cast<Being*>(*i);
+ if (filtered)
+ {
+ if (ignoreAttackMobs.find(being->getName())
+ != ignoreAttackMobs.end())
+ {
+ continue;
+ }
+ if (ignoreDefault && attackMobs.find(being->getName())
+ == attackMobs.end())
+ {
+ continue;
+ }
+ }
if (validateBeing(aroundBeing, being, type, 0, maxDist))
{
if (being != excluded)
@@ -689,7 +743,18 @@ Being *ActorSpriteManager::findNearestLivingBeing(Being *aroundBeing,
beingSorter.x = x;
beingSorter.y = y;
+ if (filtered)
+ {
+ beingSorter.beings = &mobsMap;
+ beingSorter.defaultIndex = defaultIndex;
+ }
+ else
+ {
+ beingSorter.beings = 0;
+ }
sort(sortedBeings.begin(), sortedBeings.end(), beingSorter);
+ if (filtered)
+ beingSorter.beings = 0;
if (player_node->getTarget() == NULL)
{
@@ -725,10 +790,26 @@ Being *ActorSpriteManager::findNearestLivingBeing(Being *aroundBeing,
}
Being *being = static_cast<Being*>(*i);
+ if (filtered)
+ {
+ if (ignoreAttackMobs.find(being->getName())
+ != ignoreAttackMobs.end())
+ {
+ continue;
+ }
+ if (ignoreDefault && attackMobs.find(being->getName())
+ == attackMobs.end())
+ {
+ continue;
+ }
+ }
+
// Being *being = (*i);
bool valid = validateBeing(aroundBeing, being, type, excluded, 50);
int d = being->getDistance();
+// logger->log("dist: %d", dist);
+// logger->log("name: %s, %d, %d", being->getName().c_str(), (int)valid, d);
if (being->getType() != Being::MONSTER
|| !mTargetOnlyReachable)
{ // if distance not calculated, use old distance
@@ -738,16 +819,31 @@ Being *ActorSpriteManager::findNearestLivingBeing(Being *aroundBeing,
// logger->log("being name:" + being->getName());
// logger->log("d:" + toString(d));
-// logger->log("valid:" + toString(valid));
+// logger->log("valid:" + toString(valid))
- if (valid && (d < dist || closestBeing == 0))
+ if (valid && (d <= dist || closestBeing == 0))
{
-// if ((being->getType() == type || type == Being::UNKNOWN)
-// && (d < dist || closestBeing == NULL) // it is closer
-// && (being->mAction != Being::DEAD // no dead beings
-// || (config.getValue("targetDeadPlayers", false) && type == Being::PLAYER))
-// && being != aroundBeing)
-// {
+ if (closestBeing && filtered && d == dist)
+ {
+ int w1 = defaultIndex;
+ int w2 = defaultIndex;
+ std::map<std::string, int>::iterator it1
+ = mobsMap.find(closestBeing->getName());
+ std::map<std::string, int>::iterator it2
+ = mobsMap.find(being->getName());
+ if (it1 != mobsMap.end())
+ w1 = (*it1).second;
+ if (it2 != mobsMap.end())
+ w2 = (*it2).second;
+
+ if (w2 < w1)
+ {
+ dist = d;
+ closestBeing = being;
+ }
+ continue;
+ }
+
dist = d;
closestBeing = being;
}