ManaPlus
actormanager.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2017 The ManaPlus Developers
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include "actormanager.h"
24 
25 #include "game.h"
26 #include "configuration.h"
27 #include "settings.h"
28 
29 #include "being/localplayer.h"
30 #include "being/playerrelations.h"
31 
32 #include "gui/sdlinput.h"
33 #include "gui/viewport.h"
34 
36 
40 
41 #include "fs/files.h"
42 
43 #include "input/inputmanager.h"
44 
45 #include "utils/checkutils.h"
46 #include "utils/foreach.h"
47 #include "utils/mathutils.h"
48 #include "utils/gettext.h"
49 
50 #include "net/beinghandler.h"
51 #include "net/charserverhandler.h"
52 #include "net/packetlimiter.h"
53 #include "net/playerhandler.h"
54 #include "net/serverfeatures.h"
55 
56 #include "resources/chatobject.h"
57 #include "resources/iteminfo.h"
58 
59 #include "resources/map/map.h"
60 
61 #include "resources/db/itemdb.h"
62 
63 #ifdef TMWA_SUPPORT
64 #include "being/playerinfo.h"
65 
66 #include "gui/windows/chatwindow.h"
67 
68 #include "net/net.h"
69 #endif // TMWA_SUPPORT
70 
71 #include <algorithm>
72 
73 #include "debug.h"
74 
75 #define for_actors for (ActorSpritesConstIterator it = mActors.begin(), \
76  it_fend = mActors.end(); it != it_fend; ++it)
77 
78 #define for_actorsm for (ActorSpritesIterator it = mActors.begin(), \
79  it_fend = mActors.end(); it != it_fend; ++it)
80 
82 
84 {
85  public:
87 
88  bool operator() (const ActorSprite *const actor) const
89  {
90  if ((actor == nullptr)
91  || actor->getType() == ActorType::FloorItem
92  || actor->getType() == ActorType::Portal)
93  {
94  return false;
95  }
96  const Being *const b = static_cast<const Being *>(actor);
97 
98  const unsigned other_y = y
99  + ((b->getType() == ActorType::Npc) ? 1 : 0);
100  const Vector &pos = b->getPixelPositionF();
101  // +++ probably here need use int positions and not float?
102  // but for now correct int positions only in Being
103  return CAST_U32(pos.x) / mapTileSize == x &&
104  (CAST_U32(pos.y) / mapTileSize == y
105  || CAST_U32(pos.y) / mapTileSize == other_y) &&
106  b->isAlive() && (type == ActorType::Unknown
107  || b->getType() == type);
108  }
109 
110  uint16_t x, y;
113 
115 {
116  public:
118 
119  bool operator() (const Being *const being) const
120  {
121  if ((being == nullptr) || (findBeing == nullptr))
122  return false;
123  return being->getId() == findBeing->getId();
124  }
125 
128 
130 {
131  public:
133 
134  bool operator() (const Being *const being1,
135  const Being *const being2) const
136  {
137  if ((being1 == nullptr) || (being2 == nullptr))
138  return false;
139 
140  if (priorityBeings != nullptr)
141  {
142  int w1 = defaultPriorityIndex;
143  int w2 = defaultPriorityIndex;
144  const StringIntMapCIter it1 = priorityBeings->find(
145  being1->getName());
146  const StringIntMapCIter it2 = priorityBeings->find(
147  being2->getName());
148  if (it1 != priorityBeings->end())
149  w1 = (*it1).second;
150  if (it2 != priorityBeings->end())
151  w2 = (*it2).second;
152 
153  if (w1 != w2)
154  return w1 < w2;
155  }
156  if (being1->getDistance() != being2->getDistance())
157  {
158  if (specialDistance && being1->getDistance() <= 2
159  && being2->getDistance() <= attackRange
160  && being2->getDistance() > 2)
161  {
162  return false;
163  }
164  else if (specialDistance && being2->getDistance() <= 2
165  && being1->getDistance() <= attackRange
166  && being1->getDistance() > 2)
167  {
168  return true;
169  }
170  return being1->getDistance() < being2->getDistance();
171  }
172 
173  const int d1 = abs(being1->getTileX() - x)
174  + abs(being1->getTileY() - y);
175  const int d2 = abs(being2->getTileX() - x)
176  + abs(being2->getTileY() - y);
177 
178  if (d1 != d2)
179  return d1 < d2;
180  if (attackBeings != nullptr)
181  {
182  int w1 = defaultAttackIndex;
183  int w2 = defaultAttackIndex;
184  const StringIntMapCIter it1 = attackBeings->find(
185  being1->getName());
186  const StringIntMapCIter it2 = attackBeings->find(
187  being2->getName());
188  if (it1 != attackBeings->end())
189  w1 = (*it1).second;
190  if (it2 != attackBeings->end())
191  w2 = (*it2).second;
192 
193  if (w1 != w2)
194  return w1 < w2;
195  }
196 
197  return being1->getName() < being2->getName();
198  }
201  int x;
202  int y;
208 
210  mActors(),
211  mDeleteActors(),
212  mActorsIdMap(),
213  mIdName(),
214  mBlockedBeings(),
215  mChars(),
216  mMap(nullptr),
217 #ifdef TMWA_SUPPORT
218  mSpellHeal1(serverConfig.getValue("spellHeal1", "#lum")),
219  mSpellHeal2(serverConfig.getValue("spellHeal2", "#inma")),
220  mSpellItenplz(serverConfig.getValue("spellItenplz", "#itenplz")),
221 #endif // TMWA_SUPPORT
222  mTargetDeadPlayers(config.getBoolValue("targetDeadPlayers")),
223  mTargetOnlyReachable(config.getBoolValue("targetOnlyReachable")),
224  mCyclePlayers(config.getBoolValue("cyclePlayers")),
225  mCycleMonsters(config.getBoolValue("cycleMonsters")),
226  mCycleNPC(config.getBoolValue("cycleNPC")),
227  mExtMouseTargeting(config.getBoolValue("extMouseTargeting")),
228  mEnableIdCollecting(config.getBoolValue("enableIdCollecting")),
229  mPriorityAttackMobs(),
230  mPriorityAttackMobsSet(),
231  mPriorityAttackMobsMap(),
232  mAttackMobs(),
233  mAttackMobsSet(),
234  mAttackMobsMap(),
235  mIgnoreAttackMobs(),
236  mIgnoreAttackMobsSet(),
237  mPickupItems(),
238  mPickupItemsSet(),
239  mPickupItemsMap(),
240  mIgnorePickupItems(),
241  mIgnorePickupItemsSet()
242 {
243  config.addListener("targetDeadPlayers", this);
244  config.addListener("targetOnlyReachable", this);
245  config.addListener("cyclePlayers", this);
246  config.addListener("cycleMonsters", this);
247  config.addListener("cycleNPC", this);
248  config.addListener("extMouseTargeting", this);
249  config.addListener("showBadges", this);
250  config.addListener("enableIdCollecting", this);
251  config.addListener("visiblenamespos", this);
252 
253  loadAttackList();
254 }
255 
257 {
258  config.removeListeners(this);
260  storeAttackList();
261  clear();
262 }
263 
264 void ActorManager::setMap(Map *const map)
265 {
266  mMap = map;
267 
268  if (localPlayer != nullptr)
269  localPlayer->setMap(map);
270 }
271 
273 {
274  localPlayer = player;
275  mActors.insert(player);
276  mActorsIdMap[player->getId()] = player;
277  if (socialWindow != nullptr)
279  if (socialWindow != nullptr)
281 }
282 
284  const ActorTypeT type,
285  const BeingTypeId subtype)
286 {
287  Being *const being = Being::createBeing(id,
288  type,
289  subtype,
290  mMap);
291 
292  mActors.insert(being);
293 
294  mActorsIdMap[being->getId()] = being;
295 
296  switch (type)
297  {
298  case ActorType::Player:
300  case ActorType::Pet:
302  case ActorType::Npc:
303  being->updateFromCache();
304  if (beingHandler != nullptr)
306  if (localPlayer != nullptr)
307  localPlayer->checkNewName(being);
308  break;
309  case ActorType::Monster:
310 #ifdef TMWA_SUPPORT
312 #endif // TMWA_SUPPORT
313  {
315  }
316  break;
317  case ActorType::Portal:
318  if ((beingHandler != nullptr) &&
319  (serverFeatures != nullptr) &&
321  {
323  }
324  break;
326  if (beingHandler != nullptr)
328  break;
330  break;
331  default:
333  case ActorType::Avatar:
334  case ActorType::Unknown:
335  reportAlways("CreateBeing for unknown type %d", CAST_S32(type));
336  break;
337  }
338 
339  if (type == ActorType::Player)
340  {
341  if (socialWindow != nullptr)
343  }
344  else if (type == ActorType::Npc)
345  {
346  if (questsWindow != nullptr)
347  questsWindow->addEffect(being);
348  }
349  return being;
350 }
351 
353  const int itemId,
354  const int x, const int y,
355  const ItemTypeT itemType,
356  const int amount,
357  const int refine,
358  const ItemColor color,
359  const Identified identified,
360  const Damaged damaged,
361  const int subX, const int subY,
362  const int *const cards)
363 {
364  FloorItem *const floorItem = new FloorItem(id,
365  itemId,
366  x, y,
367  itemType,
368  amount,
369  refine,
370  color,
371  identified,
372  damaged,
373  cards);
374  floorItem->postInit(mMap, subX, subY);
375 
376  if (!checkForPickup(floorItem))
377  floorItem->disableHightlight();
378  mActors.insert(floorItem);
379  mActorsIdMap[floorItem->getId()] = floorItem;
380  return floorItem;
381 }
382 
384 {
385  returnNullptrV(actor);
386 
387  if (actor == localPlayer)
388  return;
389 
390  mDeleteActors.insert(actor);
391 }
392 
394 {
395  returnNullptrV(actor);
396 
397  if (actor == localPlayer)
398  return;
399 
400  mActors.erase(actor);
401  const ActorSpritesMapIterator it = mActorsIdMap.find(actor->getId());
402  if (it != mActorsIdMap.end() && (*it).second == actor)
403  mActorsIdMap.erase(it);
404 }
405 
406 void ActorManager::undelete(const ActorSprite *const actor)
407 {
408  returnNullptrV(actor);
409 
410  if (actor == localPlayer)
411  return;
412 
414  {
415  if (*it == actor)
416  {
417  mDeleteActors.erase(*it);
418  return;
419  }
420  }
421 }
422 
424 {
425  const ActorSpritesMapConstIterator it = mActorsIdMap.find(id);
426  if (it != mActorsIdMap.end())
427  {
428  ActorSprite *const actor = (*it).second;
429  if ((actor != nullptr) &&
430  actor->getId() == id &&
431  actor->getType() != ActorType::FloorItem)
432  {
433  return static_cast<Being*>(actor);
434  }
435  }
436  return nullptr;
437 }
438 
440 {
441  const ActorSpritesMapConstIterator it = mActorsIdMap.find(id);
442  if (it != mActorsIdMap.end())
443  {
444  ActorSprite *const actor = (*it).second;
445  if ((actor != nullptr) &&
446  actor->getId() == id)
447  {
448  return actor;
449  }
450  }
451  return nullptr;
452 }
453 
454 Being *ActorManager::findBeing(const int x, const int y,
455  const ActorTypeT type) const
456 {
459  beingActorFinder.type = type;
460 
461  const ActorSpritesConstIterator it = std::find_if(
462  mActors.begin(), mActors.end(), beingActorFinder);
463 
464  return (it == mActors.end()) ? nullptr : static_cast<Being*>(*it);
465 }
466 
467 Being *ActorManager::findBeingByPixel(const int x, const int y,
468  const AllPlayers allPlayers) const
469 {
470  if (mMap == nullptr)
471  return nullptr;
472 
473  const bool targetDead = mTargetDeadPlayers;
474  const bool modActive = inputManager.isActionActive(
476 
477  if (mExtMouseTargeting)
478  {
479  Being *tempBeing = nullptr;
480  bool noBeing(false);
481 
483  {
484 // disabled for performance
485 // if (reportTrue(*it == nullptr))
486 // continue;
487 
488  if ((*it)->getType() == ActorType::Portal)
489  continue;
490 
491  if ((*it)->getType() == ActorType::FloorItem)
492  {
493  if (!noBeing)
494  {
495  const FloorItem *const floor
496  = static_cast<const FloorItem*>(*it);
497  const int px = floor->getPixelX();
498  const int py = floor->getPixelY();
499  if ((px - mapTileSize <= x) &&
500  (px + mapTileSize > x) &&
501  (py - mapTileSize * 2 <= y) &&
502  (py + mapTileSize / 2 > y))
503  {
504  noBeing = true;
505  }
506  }
507  continue;
508  }
509 
510  Being *const being = static_cast<Being*>(*it);
511 
512  if (being->getInfo() != nullptr &&
513  !(being->getInfo()->isTargetSelection() || modActive))
514  {
515  continue;
516  }
517 
518  if ((being->mAction != BeingAction::DEAD ||
519  (targetDead && being->getType() == ActorType::Player)) &&
520  (allPlayers == AllPlayers_true || being != localPlayer))
521  {
522  const int px = being->getPixelX();
523  const int py = being->getPixelY();
524  if ((px - mapTileSize / 2 <= x) &&
525  (px + mapTileSize / 2 > x) &&
526  (py - mapTileSize <= y) &&
527  (py > y))
528  {
529  return being;
530  }
531  else if (!noBeing &&
532  (px - mapTileSize <= x) &&
533  (px + mapTileSize > x) &&
534  (py - mapTileSize * 2 <= y) &&
535  (py + mapTileSize / 2 > y))
536  {
537  if (tempBeing != nullptr)
538  noBeing = true;
539  else
540  tempBeing = being;
541  }
542  }
543  }
544 
545  if (noBeing)
546  return nullptr;
547  return tempBeing;
548  }
550  {
551 // disabled for performance
552 // if (reportTrue(*it == nullptr))
553 // continue;
554 
555  if ((*it)->getType() == ActorType::Portal ||
556  (*it)->getType() == ActorType::FloorItem)
557  {
558  continue;
559  }
560 
561  Being *const being = static_cast<Being*>(*it);
562 
563  if (being->getInfo() != nullptr &&
564  !(being->getInfo()->isTargetSelection() || modActive))
565  {
566  continue;
567  }
568 
569  const int px = being->getPixelX();
570  const int py = being->getPixelY();
571  if ((px - mapTileSize / 2 <= x) &&
572  (px + mapTileSize / 2 > x) &&
573  (py - mapTileSize <= y) &&
574  (py > y))
575  {
576  return being;
577  }
578  }
579  return nullptr;
580 }
581 
582 void ActorManager::findBeingsByPixel(STD_VECTOR<ActorSprite*> &beings,
583  const int x, const int y,
584  const AllPlayers allPlayers) const
585 {
586  if (mMap == nullptr)
587  return;
588 
589  const int xtol = mapTileSize / 2;
590  const int uptol = mapTileSize;
591  const bool modActive = inputManager.isActionActive(
593 
594  for_actors
595  {
596  ActorSprite *const actor = *it;
597 
598 // disabled for performance
599 // if (reportTrue(actor == nullptr))
600 // continue;
601 
602  const ActorTypeT actorType = actor->getType();
603  switch (actorType)
604  {
605  default:
606  case ActorType::Unknown:
607  case ActorType::Avatar:
608  case ActorType::Portal:
609  break;
611  if ((actor->getPixelX() - xtol <= x) &&
612  (actor->getPixelX() + xtol > x) &&
613  (actor->getPixelY() - uptol <= y) &&
614  (actor->getPixelY() > y))
615  {
616  beings.push_back(actor);
617  }
618  break;
619  case ActorType::Player:
620  case ActorType::Npc:
621  case ActorType::Monster:
622  case ActorType::Pet:
627  {
628  const Being *const being = static_cast<const Being*>(*it);
629  if (being == nullptr)
630  continue;
631  if ((being->getInfo() != nullptr) &&
632  !(being->getInfo()->isTargetSelection() || modActive))
633  {
634  continue;
635  }
636  if ((being->isAlive() ||
638  actorType == ActorType::Player)) &&
639  (allPlayers == AllPlayers_true ||
640  being != localPlayer))
641  {
642  if ((actor->getPixelX() - xtol <= x) &&
643  (actor->getPixelX() + xtol > x) &&
644  (actor->getPixelY() - uptol <= y) &&
645  (actor->getPixelY() > y))
646  {
647  beings.push_back(actor);
648  }
649  }
650  break;
651  }
652  }
653  }
654 }
655 
656 Being *ActorManager::findPortalByTile(const int x, const int y) const
657 {
658  if (mMap == nullptr)
659  return nullptr;
660 
662  {
663 // disabled for performance
664 // if (reportTrue(*it == nullptr))
665 // continue;
666 
667  if ((*it)->getType() != ActorType::Portal)
668  continue;
669 
670  Being *const being = static_cast<Being*>(*it);
671 
672  if (being->getTileX() == x && being->getTileY() == y)
673  return being;
674  }
675 
676  return nullptr;
677 }
678 
680 {
681  const ActorSpritesMapConstIterator it = mActorsIdMap.find(id);
682  if (it != mActorsIdMap.end())
683  {
684  ActorSprite *const actor = (*it).second;
685  returnNullptr(nullptr, actor);
686  if (actor->getId() == id &&
687  actor->getType() == ActorType::FloorItem)
688  {
689  return static_cast<FloorItem*>(actor);
690  }
691  }
692  return nullptr;
693 }
694 
695 FloorItem *ActorManager::findItem(const int x, const int y) const
696 {
698  {
699 // disabled for performance
700 // if (reportTrue(*it == nullptr))
701 // continue;
702 
703  if ((*it)->getTileX() == x && (*it)->getTileY() == y &&
704  (*it)->getType() == ActorType::FloorItem)
705  {
706  return static_cast<FloorItem*>(*it);
707  }
708  }
709 
710  return nullptr;
711 }
712 
713 bool ActorManager::pickUpAll(const int x1, const int y1,
714  const int x2, const int y2,
715  const bool serverBuggy) const
716 {
717  if (localPlayer == nullptr)
718  return false;
719 
720  bool finded(false);
721  const bool allowAll = mPickupItemsSet.find("") != mPickupItemsSet.end();
722  if (!serverBuggy)
723  {
725  {
726 // disabled for performance
727 // if (reportTrue(*it == nullptr))
728 // continue;
729 
730  if ((*it)->getType() == ActorType::FloorItem
731  && ((*it)->getTileX() >= x1 && (*it)->getTileX() <= x2)
732  && ((*it)->getTileY() >= y1 && (*it)->getTileY() <= y2))
733  {
734  FloorItem *const item = static_cast<FloorItem*>(*it);
735  if (allowAll)
736  {
737  if (mIgnorePickupItemsSet.find(item->getName())
738  == mIgnorePickupItemsSet.end())
739  {
740  if (localPlayer->pickUp(item))
741  finded = true;
742  }
743  }
744  else
745  {
746  if (mPickupItemsSet.find(item->getName())
747  != mPickupItemsSet.end())
748  {
749  if (localPlayer->pickUp(item))
750  finded = true;
751  }
752  }
753  }
754  }
755  }
757  {
758  FloorItem *item = nullptr;
759  unsigned cnt = 65535;
761  {
762 // disabled for performance
763 // if (reportTrue(*it == nullptr))
764 // continue;
765 
766  if ((*it)->getType() == ActorType::FloorItem
767  && ((*it)->getTileX() >= x1 && (*it)->getTileX() <= x2)
768  && ((*it)->getTileY() >= y1 && (*it)->getTileY() <= y2))
769  {
770  FloorItem *const tempItem = static_cast<FloorItem*>(*it);
771  if (tempItem->getPickupCount() < cnt)
772  {
773  if (allowAll)
774  {
775  if (mIgnorePickupItemsSet.find(tempItem->getName())
776  == mIgnorePickupItemsSet.end())
777  {
778  item = tempItem;
779  cnt = item->getPickupCount();
780  if (cnt == 0)
781  {
782  item->incrementPickup();
783  localPlayer->pickUp(item);
784  return true;
785  }
786  }
787  }
788  else
789  {
790  if (mPickupItemsSet.find(tempItem->getName())
791  != mPickupItemsSet.end())
792  {
793  item = tempItem;
794  cnt = item->getPickupCount();
795  if (cnt == 0)
796  {
797  item->incrementPickup();
798  localPlayer->pickUp(item);
799  return true;
800  }
801  }
802  }
803  }
804  }
805  }
806  if ((item != nullptr) && localPlayer->pickUp(item))
807  finded = true;
808  }
809  return finded;
810 }
811 
812 bool ActorManager::pickUpNearest(const int x, const int y,
813  int maxdist) const
814 {
815  if (localPlayer == nullptr)
816  return false;
817 
818  maxdist = maxdist * maxdist;
819  FloorItem *closestItem = nullptr;
820  int dist = 0;
821  const bool allowAll = mPickupItemsSet.find("") != mPickupItemsSet.end();
822 
824  {
825 // disabled for performance
826 // if (reportTrue(*it == nullptr))
827 // continue;
828 
829  if ((*it)->getType() == ActorType::FloorItem)
830  {
831  FloorItem *const item = static_cast<FloorItem*>(*it);
832 
833  const int d = (item->getTileX() - x) * (item->getTileX() - x)
834  + (item->getTileY() - y) * (item->getTileY() - y);
835 
836  if ((d < dist || closestItem == nullptr) &&
838  item->getTileX(), item->getTileY(),
839  false)))
840  {
841  if (allowAll)
842  {
843  if (mIgnorePickupItemsSet.find(item->getName())
844  == mIgnorePickupItemsSet.end())
845  {
846  dist = d;
847  closestItem = item;
848  }
849  }
850  else
851  {
852  if (mPickupItemsSet.find(item->getName())
853  != mPickupItemsSet.end())
854  {
855  dist = d;
856  closestItem = item;
857  }
858  }
859  }
860  }
861  }
862  if ((closestItem != nullptr) && dist <= maxdist)
863  return localPlayer->pickUp(closestItem);
864 
865  return false;
866 }
867 
868 Being *ActorManager::findBeingByName(const std::string &name,
869  const ActorTypeT type) const
870 {
872  {
873 // disabled for performance
874 // if (reportTrue(*it == nullptr))
875 // continue;
876 
877  if ((*it)->getType() == ActorType::FloorItem
878  || (*it)->getType() == ActorType::Portal)
879  {
880  continue;
881  }
882 
883  Being *const being = static_cast<Being*>(*it);
884  if (being->getName() == name &&
885  (type == ActorType::Unknown || type == being->getType()))
886  {
887  return being;
888  }
889  }
890  return nullptr;
891 }
892 
893 Being *ActorManager::findNearestByName(const std::string &name,
894  const ActorTypeT &type) const
895 {
896  if (localPlayer == nullptr)
897  return nullptr;
898 
899  int dist = 0;
900  Being* closestBeing = nullptr;
901  int x, y;
902 
903  x = localPlayer->getTileX();
904  y = localPlayer->getTileY();
905 
907  {
908 // disabled for performance
909 // if (reportTrue(*it == nullptr))
910 // continue;
911 
912  if ((*it)->getType() == ActorType::FloorItem
913  || (*it)->getType() == ActorType::Portal)
914  {
915  continue;
916  }
917 
918  Being *const being = static_cast<Being*>(*it);
919 
920  if ((being != nullptr) && being->getName() == name &&
921  (type == ActorType::Unknown || type == being->getType()))
922  {
923  if (being->getType() == ActorType::Player)
924  {
925  return being;
926  }
927  const int d = (being->getTileX() - x) * (being->getTileX() - x)
928  + (being->getTileY() - y) * (being->getTileY() - y);
929 
930  if (validateBeing(nullptr, being, type, nullptr, 50)
931  && (d < dist || closestBeing == nullptr))
932  {
933  dist = d;
934  closestBeing = being;
935  }
936  }
937  }
938  return closestBeing;
939 }
940 
942 {
943  return mActors;
944 }
945 
947 {
948  BLOCK_START("ActorManager::logic")
949  for_actors
950  {
951 // disabled for performance
952 // if (reportFalse(*it))
953  (*it)->logic();
954  }
955 
956  if (mDeleteActors.empty())
957  {
958  BLOCK_END("ActorManager::logic")
959  return;
960  }
961 
962  BLOCK_START("ActorManager::logic 1")
964  {
965  const ActorSprite *const actor = *it;
966  const ActorTypeT &type = actor->getType();
967  if (type == ActorType::Player)
968  {
969  const Being *const being = static_cast<const Being*>(actor);
970  being->addToCache();
971  if (beingEquipmentWindow != nullptr)
973  }
974  if (localPlayer != nullptr)
975  {
976  if (localPlayer->getTarget() == actor)
977  localPlayer->setTarget(nullptr);
978  if (localPlayer->getPickUpTarget() == actor)
980  }
981  if (viewport != nullptr)
982  viewport->clearHover(*it);
983  }
984 
986  {
987  ActorSprite *actor = *it;
988  mActors.erase(actor);
989 
990  if (actor != nullptr)
991  {
992  const ActorSpritesMapIterator itr = mActorsIdMap.find(
993  actor->getId());
994  if (itr != mActorsIdMap.end() && (*itr).second == actor)
995  mActorsIdMap.erase(itr);
996 
997  delete actor;
998  }
999  }
1000 
1001  mDeleteActors.clear();
1002  BLOCK_END("ActorManager::logic 1")
1003  BLOCK_END("ActorManager::logic")
1004 }
1005 
1007 {
1008  if (beingEquipmentWindow != nullptr)
1009  beingEquipmentWindow->setBeing(nullptr);
1010 
1011  if (localPlayer != nullptr)
1012  {
1013  localPlayer->setTarget(nullptr);
1015  mActors.erase(localPlayer);
1016  }
1017 
1018  for_actors
1019  delete *it;
1020  mActors.clear();
1021  mDeleteActors.clear();
1022  mActorsIdMap.clear();
1023 
1024  if (localPlayer != nullptr)
1025  {
1026  mActors.insert(localPlayer);
1028  }
1029 
1030  mChars.clear();
1031 }
1032 
1034 {
1035  if (localPlayer == nullptr)
1036  return nullptr;
1037 
1038  // don't attack players
1039  if (settings.pvpAttackType == 3)
1040  return nullptr;
1041 
1042  const Game *const game = Game::instance();
1043  if (game == nullptr)
1044  return nullptr;
1045 
1046  const Map *const map = game->getCurrentMap();
1047  if (map == nullptr)
1048  return nullptr;
1049 
1050  const int mapPvpMode = map->getPvpMode();
1051  Being *target = nullptr;
1052  int minDistSquared = 20000;
1053 
1054  for_actors
1055  {
1056  if ((*it)->getType() != ActorType::Player)
1057  continue;
1058 
1059  Being *const being = static_cast<Being*>(*it);
1060 
1061  if (reportTrue(being == nullptr) ||
1062  !being->isAlive() ||
1063  localPlayer == being)
1064  {
1065  continue;
1066  }
1067 
1068  const int teamId = being->getTeamId();
1069  // this condition is very TMW-specific
1070  if (!((mapPvpMode != 0) || (teamId != 0)))
1071  continue;
1072 
1074  continue;
1075 
1076  const int dx = being->getTileX() - localPlayer->getTileX();
1077  const int dy = being->getTileY() - localPlayer->getTileY();
1078  const int distSquared = dx * dx + dy * dy;
1079  if (distSquared < minDistSquared)
1080  {
1081  minDistSquared = distSquared;
1082  target = being;
1083  }
1084  }
1085 
1086  return target;
1087 }
1088 
1089 
1091  const int maxTileDist,
1092  const ActorTypeT type,
1093  const Being *const excluded) const
1094 {
1095  const int maxDist = maxTileDist * mapTileSize;
1096 
1097  return findNearestLivingBeing(nullptr, maxDist,
1098  type,
1099  x, y,
1100  excluded,
1101  AllowSort_true);
1102 }
1103 
1105  const int maxDist,
1106  const ActorTypeT type,
1107  const AllowSort allowSort) const
1108 {
1109  if (aroundBeing == nullptr)
1110  return nullptr;
1111 
1112  return findNearestLivingBeing(aroundBeing,
1113  maxDist,
1114  type,
1115  aroundBeing->getTileX(),
1116  aroundBeing->getTileY(),
1117  aroundBeing,
1118  allowSort);
1119 }
1120 
1122  int maxDist,
1123  const ActorTypeT &type,
1124  const int x, const int y,
1125  const Being *const excluded,
1126  const AllowSort allowSort) const
1127 {
1128  if ((aroundBeing == nullptr) || (localPlayer == nullptr))
1129  return nullptr;
1130 
1131  std::set<std::string> attackMobs;
1132  std::set<std::string> priorityMobs;
1133  std::set<std::string> ignoreAttackMobs;
1134  StringIntMap attackMobsMap;
1135  StringIntMap priorityMobsMap;
1136  int defaultAttackIndex = 10000;
1137  int defaultPriorityIndex = 10000;
1138  const int attackRange = localPlayer->getAttackRange();
1139 
1140  bool specialDistance = false;
1141  if (settings.moveToTargetType == 11
1142  && localPlayer->getAttackRange() > 2)
1143  {
1144  specialDistance = true;
1145  }
1146 
1147  maxDist = maxDist * maxDist;
1148 
1149  const bool cycleSelect = allowSort == AllowSort_true
1150  && ((mCyclePlayers && type == ActorType::Player)
1151  || (mCycleMonsters && type == ActorType::Monster)
1152  || (mCycleNPC && type == ActorType::Npc));
1153 
1154  const bool filtered = allowSort == AllowSort_true
1155  && config.getBoolValue("enableAttackFilter")
1156  && type == ActorType::Monster;
1157  const bool modActive = inputManager.isActionActive(
1159 
1160  bool ignoreDefault = false;
1161  if (filtered)
1162  {
1163  attackMobs = mAttackMobsSet;
1164  priorityMobs = mPriorityAttackMobsSet;
1165  ignoreAttackMobs = mIgnoreAttackMobsSet;
1166  attackMobsMap = mAttackMobsMap;
1167  priorityMobsMap = mPriorityAttackMobsMap;
1168  beingActorSorter.attackBeings = &attackMobsMap;
1169  beingActorSorter.priorityBeings = &priorityMobsMap;
1170  beingActorSorter.specialDistance = specialDistance;
1171  beingActorSorter.attackRange = attackRange;
1172  if (ignoreAttackMobs.find("") != ignoreAttackMobs.end())
1173  ignoreDefault = true;
1174  StringIntMapCIter itr = attackMobsMap.find("");
1175  if (itr != attackMobsMap.end())
1176  defaultAttackIndex = (*itr).second;
1177  itr = priorityMobsMap.find("");
1178  if (itr != priorityMobsMap.end())
1179  defaultPriorityIndex = (*itr).second;
1180  }
1181 
1182  if (cycleSelect)
1183  {
1184  STD_VECTOR<Being*> sortedBeings;
1185 
1186  FOR_EACH (ActorSprites::iterator, i, mActors)
1187  {
1188 // disabled for performance
1189 // if (reportTrue(*i == nullptr))
1190 // continue;
1191 
1192  if ((*i)->getType() == ActorType::FloorItem
1193  || (*i)->getType() == ActorType::Portal)
1194  {
1195  continue;
1196  }
1197 
1198  Being *const being = static_cast<Being*>(*i);
1199 
1200  if (filtered)
1201  {
1202  if (ignoreAttackMobs.find(being->getName())
1203  != ignoreAttackMobs.end())
1204  {
1205  continue;
1206  }
1207  if (ignoreDefault && attackMobs.find(being->getName())
1208  == attackMobs.end() && priorityMobs.find(being->getName())
1209  == priorityMobs.end())
1210  {
1211  continue;
1212  }
1213  }
1214 
1215  if ((being->getInfo() != nullptr)
1216  && !(being->getInfo()->isTargetSelection() || modActive))
1217  {
1218  continue;
1219  }
1220 
1221  if (validateBeing(aroundBeing, being, type, nullptr, maxDist))
1222  {
1223  if (being != excluded)
1224  sortedBeings.push_back(being);
1225  }
1226  }
1227 
1228  // no selectable beings
1229  if (sortedBeings.empty())
1230  return nullptr;
1231 
1232  beingActorSorter.x = x;
1233  beingActorSorter.y = y;
1234  if (filtered)
1235  {
1236  beingActorSorter.attackBeings = &attackMobsMap;
1237  beingActorSorter.defaultAttackIndex = defaultAttackIndex;
1238  beingActorSorter.priorityBeings = &priorityMobsMap;
1239  beingActorSorter.defaultPriorityIndex = defaultPriorityIndex;
1240  }
1241  else
1242  {
1243  beingActorSorter.attackBeings = nullptr;
1244  beingActorSorter.priorityBeings = nullptr;
1245  }
1246  std::sort(sortedBeings.begin(), sortedBeings.end(), beingActorSorter);
1247  if (filtered)
1248  {
1249  beingActorSorter.attackBeings = nullptr;
1250  beingActorSorter.priorityBeings = nullptr;
1251  }
1252 
1253  if (localPlayer->getTarget() == nullptr)
1254  {
1255  Being *const target = sortedBeings.at(0);
1256 
1257  if (specialDistance && target->getType() == ActorType::Monster
1258  && target->getDistance() <= 2)
1259  {
1260  return nullptr;
1261  }
1262  // if no selected being in vector, return first nearest being
1263  return target;
1264  }
1265 
1267  STD_VECTOR<Being*>::const_iterator i = std::find_if(
1268  sortedBeings.begin(), sortedBeings.end(), beingEqualActorFinder);
1269 
1270  if (i == sortedBeings.end() || ++i == sortedBeings.end())
1271  {
1272  // if no selected being in vector, return first nearest being
1273  return sortedBeings.at(0);
1274  }
1275 
1276  // we find next being after target
1277  return *i;
1278  }
1279 
1280  int dist = 0;
1281  int index = defaultPriorityIndex;
1282  Being *closestBeing = nullptr;
1283 
1284  FOR_EACH (ActorSprites::iterator, i, mActors)
1285  {
1286 // disabled for performance
1287 // if (reportTrue(*i == nullptr))
1288 // continue;
1289 
1290  if ((*i)->getType() == ActorType::FloorItem ||
1291  (*i)->getType() == ActorType::Portal)
1292  {
1293  continue;
1294  }
1295  Being *const being = static_cast<Being*>(*i);
1296 
1297  if (filtered)
1298  {
1299  if (ignoreAttackMobs.find(being->getName())
1300  != ignoreAttackMobs.end())
1301  {
1302  continue;
1303  }
1304  if (ignoreDefault && attackMobs.find(being->getName())
1305  == attackMobs.end() && priorityMobs.find(being->getName())
1306  == priorityMobs.end())
1307  {
1308  continue;
1309  }
1310  }
1311 
1312  if ((being->getInfo() != nullptr)
1313  && !(being->getInfo()->isTargetSelection() || modActive))
1314  {
1315  continue;
1316  }
1317 
1318  const bool valid = validateBeing(aroundBeing, being,
1319  type, excluded, 50);
1320  int d = being->getDistance();
1321  if (being->getType() != ActorType::Monster
1323  { // if distance not calculated, use old distance
1324  d = (being->getTileX() - x) * (being->getTileX() - x)
1325  + (being->getTileY() - y) * (being->getTileY() - y);
1326  }
1327 
1328  if (!valid)
1329  continue;
1330 
1331  if (specialDistance && being->getDistance() <= 2
1332  && being->getType() == type)
1333  {
1334  continue;
1335  }
1336 
1337 // logger->log("being name:" + being->getName());
1338 // logger->log("index:" + toString(index));
1339 // logger->log("d:" + toString(d));
1340 
1341  if (!filtered && (d <= dist || (closestBeing == nullptr)))
1342  {
1343  dist = d;
1344  closestBeing = being;
1345  }
1346  else if (filtered)
1347  {
1348  int w2 = defaultPriorityIndex;
1349  if (closestBeing != nullptr)
1350  {
1351  const StringIntMapCIter it2 = priorityMobsMap.find(
1352  being->getName());
1353  if (it2 != priorityMobsMap.end())
1354  w2 = (*it2).second;
1355 
1356  if (w2 < index)
1357  {
1358  dist = d;
1359  closestBeing = being;
1360  index = w2;
1361  continue;
1362  }
1363  if (w2 == index && d <= dist)
1364  {
1365  dist = d;
1366  closestBeing = being;
1367  index = w2;
1368  continue;
1369  }
1370  }
1371 
1372  if (closestBeing == nullptr)
1373  {
1374  dist = d;
1375  closestBeing = being;
1376  const StringIntMapCIter it1 = priorityMobsMap.find(
1377  being->getName());
1378  if (it1 != priorityMobsMap.end())
1379  index = (*it1).second;
1380  else
1381  index = defaultPriorityIndex;
1382  }
1383  }
1384  }
1385  return (maxDist >= dist) ? closestBeing : nullptr;
1386 }
1387 
1388 bool ActorManager::validateBeing(const Being *const aroundBeing,
1389  Being *const being,
1390  const ActorTypeT &type,
1391  const Being* const excluded,
1392  const int maxCost) const
1393 {
1394  if (localPlayer == nullptr)
1395  return false;
1396  return (being != nullptr) && ((being->getType() == type
1397  || type == ActorType::Unknown) && (being->isAlive()
1398  || (mTargetDeadPlayers && type == ActorType::Player))
1399  && being != aroundBeing) && being != excluded
1401  || localPlayer->isReachable(being, maxCost));
1402 }
1403 
1404 #ifdef TMWA_SUPPORT
1406 {
1407  if (localPlayer == nullptr)
1408  return;
1409 
1411 }
1412 
1413 void ActorManager::heal(const Being *const target) const
1414 {
1416  return;
1417 
1418  if (localPlayer == nullptr ||
1419  chatWindow == nullptr ||
1420  !localPlayer->isAlive() ||
1422  {
1423  return;
1424  }
1425 
1426  // self
1427  if (target != nullptr &&
1428  localPlayer->getName() == target->getName())
1429  {
1433  {
1435  return;
1437  }
1438  }
1439  // magic levels < 2
1440  else if (PlayerInfo::getSkillLevel(340) < 2 ||
1441  PlayerInfo::getSkillLevel(341) < 2)
1442  {
1444  {
1445  if (target != nullptr &&
1446  target->getType() != ActorType::Monster)
1447  {
1449  return;
1451  + target->getName());
1452  }
1455  {
1457  return;
1459  }
1460  }
1461  }
1462  // magic level >= 2 and not self
1463  else
1464  {
1465  // mp > 10 and target not monster
1467  target != nullptr &&
1468  target->getType() != ActorType::Monster)
1469  {
1470  // target not enemy
1471  if (playerRelations.getRelation(target->getName()) !=
1473  {
1475  return;
1477  + target->getName());
1478  }
1479  // target enemy
1480  else
1481  {
1483  return;
1485  }
1486  }
1487  // heal self if selected monster or selection empty
1488  else if ((target == nullptr || target->getType() == ActorType::Monster)
1492  {
1494  return;
1496  }
1497  }
1498 }
1499 #endif // TMWA_SUPPORT
1500 
1501 Being* ActorManager::findMostDamagedPlayer(const int maxTileDist) const
1502 {
1503  if (localPlayer == nullptr)
1504  return nullptr;
1505 
1506  int maxDamageTaken = 0;
1507  Being *target = nullptr;
1508 
1509  for_actors
1510  {
1511  if ((*it)->getType() != ActorType::Player)
1512  continue;
1513 
1514  Being *const being = static_cast<Being*>(*it);
1515 
1516  if ((being == nullptr) || !being->isAlive() || // don't heal dead
1517  playerRelations.getRelation(being->getName()) ==
1518  Relation::ENEMY2 || // don't heal enemy
1519  localPlayer == being) // don't heal self
1520  {
1521  continue;
1522  }
1523 
1524  const int dx = being->getTileX() - localPlayer->getTileX();
1525  const int dy = being->getTileY() - localPlayer->getTileY();
1526  const int distance = fastSqrtInt(dx * dx + dy * dy);
1527 
1528  if (distance > maxTileDist)
1529  continue;
1530 
1531  if (being->getDamageTaken() > maxDamageTaken)
1532  {
1533  maxDamageTaken = being->getDamageTaken();
1534  target = being;
1535  }
1536  }
1537 
1538  return target;
1539 }
1540 
1541 #ifdef TMWA_SUPPORT
1543 {
1545  return;
1546  if (localPlayer == nullptr ||
1547  chatWindow == nullptr ||
1548  !localPlayer->isAlive() ||
1550  {
1551  return;
1552  }
1553 
1555  return;
1556 
1558 }
1559 #endif // TMWA_SUPPORT
1560 
1561 bool ActorManager::hasActorSprite(const ActorSprite *const actor) const
1562 {
1563  for_actors
1564  {
1565  if (actor == *it)
1566  return true;
1567  }
1568 
1569  return false;
1570 }
1571 
1573 {
1574  mBlockedBeings.insert(id);
1575 }
1576 
1578 {
1579  mBlockedBeings.erase(id);
1580 }
1581 
1582 bool ActorManager::isBlocked(const BeingId id) const
1583 {
1584  return mBlockedBeings.find(id) != mBlockedBeings.end();
1585 }
1586 
1588 {
1589  // TRANSLATORS: visible beings on map
1590  printBeingsToChat(_("Visible on map"));
1591 }
1592 
1593 void ActorManager::printBeingsToChat(const std::string &header) const
1594 {
1595  if (debugChatTab == nullptr)
1596  return;
1597 
1598  debugChatTab->chatLog("---------------------------------------",
1601  for_actors
1602  {
1603 // disabled for performance
1604 // if (reportTrue(*it == nullptr))
1605 // continue;
1606 
1607  if ((*it)->getType() == ActorType::FloorItem)
1608  continue;
1609 
1610  const Being *const being = static_cast<const Being*>(*it);
1611 
1612  debugChatTab->chatLog(strprintf("%s (%d,%d) %d",
1613  being->getName().c_str(), being->getTileX(), being->getTileY(),
1614  toInt(being->getSubType(), int)), ChatMsgType::BY_SERVER);
1615  if (mActorsIdMap.find(being->getId()) == mActorsIdMap.end())
1616  {
1617  debugChatTab->chatLog("missing in id map: %s",
1618  being->getName().c_str());
1619  }
1620  }
1621  debugChatTab->chatLog("---------------------------------------",
1624  {
1625  const ActorSprite *const actor = (*itr).second;
1626  if (actor == nullptr)
1627  continue;
1628  if (actor->getId() != (*itr).first)
1629  debugChatTab->chatLog("Actor with wrong key in map", "");
1630 
1631  bool found(false);
1632 
1633  for_actors
1634  {
1635 // disabled for performance
1636 // if (!*it)
1637 // continue;
1638 
1639  if ((*it)->getId() == actor->getId())
1640  {
1641  found = true;
1642  break;
1643  }
1644  }
1645  if (!found)
1646  debugChatTab->chatLog("Actor present in map but not in set", "");
1647  }
1648 }
1649 
1650 void ActorManager::printBeingsToChat(const STD_VECTOR<Being*> &beings,
1651  const std::string &header)
1652 {
1653  if (debugChatTab == nullptr)
1654  return;
1655 
1656  debugChatTab->chatLog("---------------------------------------",
1659 
1660  FOR_EACH (STD_VECTOR<Being*>::const_iterator, i, beings)
1661  {
1662  if (*i == nullptr)
1663  continue;
1664 
1665  const Being *const being = *i;
1666 
1667  debugChatTab->chatLog(strprintf("%s (%d,%d) %d",
1668  being->getName().c_str(), being->getTileX(), being->getTileY(),
1669  toInt(being->getSubType(), int)), ChatMsgType::BY_SERVER);
1670  }
1671  debugChatTab->chatLog("---------------------------------------",
1673 }
1674 
1676  const NpcNames npcNames) const
1677 {
1678  names.clear();
1679 
1680  for_actors
1681  {
1682 // disabled for performance
1683 // if (reportTrue(*it == nullptr))
1684 // continue;
1685 
1686  if ((*it)->getType() == ActorType::FloorItem ||
1687  (*it)->getType() == ActorType::Portal)
1688  {
1689  continue;
1690  }
1691 
1692  const Being *const being = static_cast<const Being*>(*it);
1693  if ((being->getType() == ActorType::Player ||
1694  (being->getType() == ActorType::Npc &&
1695  npcNames == NpcNames_true)) &&
1696  !being->getName().empty())
1697  {
1698  names.push_back(being->getName());
1699  }
1700  }
1701 }
1702 
1704 {
1705  names.clear();
1706 
1707  for_actors
1708  {
1709 // disabled for performance
1710 // if (reportTrue(*it == nullptr))
1711 // continue;
1712 
1713  if ((*it)->getType() == ActorType::FloorItem
1714  || (*it)->getType() == ActorType::Portal)
1715  {
1716  continue;
1717  }
1718 
1719  const Being *const being = static_cast<const Being*>(*it);
1720  if (being->getType() == ActorType::Monster &&
1721  !being->getName().empty())
1722  {
1723  names.push_back(being->getName());
1724  }
1725  }
1726 }
1727 
1729 {
1730  for_actorsm
1731  {
1732 // disabled for performance
1733 // if (reportTrue(*it == nullptr))
1734 // continue;
1735 
1736  if ((*it)->getType() == ActorType::FloorItem
1737  || (*it)->getType() == ActorType::Portal)
1738  {
1739  continue;
1740  }
1741 
1742  Being *const being = static_cast<Being*>(*it);
1743  being->setGoodStatus(-1);
1744  if (being->getType() == ActorType::Player && !being->getName().empty())
1745  being->updateName();
1746  }
1747 }
1748 
1750 {
1751  for_actorsm
1752  {
1753 // disabled for performance
1754 // if (reportTrue(*it == nullptr))
1755 // continue;
1756 
1757  if ((*it)->getType() == ActorType::FloorItem
1758  || (*it)->getType() == ActorType::Portal)
1759  {
1760  continue;
1761  }
1762 
1763  Being *const being = static_cast<Being*>(*it);
1764  if (being->getType() == ActorType::Player && !being->getName().empty())
1765  being->updateColors();
1766  }
1767 }
1768 
1770 {
1771  for_actorsm
1772  {
1773 // disabled for performance
1774 // if (reportTrue(*it == nullptr))
1775 // continue;
1776 
1777  if ((*it)->getType() == ActorType::FloorItem
1778  || (*it)->getType() == ActorType::Portal)
1779  {
1780  continue;
1781  }
1782 
1783  Being *const being = static_cast<Being*>(*it);
1784  if (being->getType() == ActorType::Player && !being->getName().empty())
1785  being->updateGuild();
1786  }
1787 }
1788 
1789 #ifdef TMWA_SUPPORT
1790 void ActorManager::parseLevels(std::string levels) const
1791 {
1792  levels.append(", ");
1793  size_t f = 0;
1794  const std::string brkEnd("), ");
1795  size_t pos = levels.find(brkEnd, f);
1796 
1797  while (pos != std::string::npos)
1798  {
1799  std::string part = levels.substr(f, pos - f);
1800  if (part.empty())
1801  break;
1802  const size_t bktPos = part.rfind('(');
1803  if (bktPos != std::string::npos)
1804  {
1805  Being *const being = findBeingByName(part.substr(0, bktPos),
1807  if (being != nullptr)
1808  {
1809  being->setLevel(atoi(part.substr(bktPos + 1).c_str()));
1810  being->addToCache();
1811  }
1812  }
1813  f = CAST_SIZE(pos + brkEnd.length());
1814  pos = levels.find(brkEnd, f);
1815  }
1817 }
1818 #endif // TMWA_SUPPORT
1819 
1820 void ActorManager::optionChanged(const std::string &name)
1821 {
1822  if (name == "targetDeadPlayers")
1823  mTargetDeadPlayers = config.getBoolValue("targetDeadPlayers");
1824  else if (name == "targetOnlyReachable")
1825  mTargetOnlyReachable = config.getBoolValue("targetOnlyReachable");
1826  else if (name == "cyclePlayers")
1827  mCyclePlayers = config.getBoolValue("cyclePlayers");
1828  else if (name == "cycleMonsters")
1829  mCycleMonsters = config.getBoolValue("cycleMonsters");
1830  else if (name == "cycleNPC")
1831  mCycleNPC = config.getBoolValue("cycleNPC");
1832  else if (name == "extMouseTargeting")
1833  mExtMouseTargeting = config.getBoolValue("extMouseTargeting");
1834  else if (name == "showBadges")
1835  updateBadges();
1836  else if (name == "visiblenamespos")
1837  updateBadges();
1838  else if (name == "enableIdCollecting")
1839  mEnableIdCollecting = config.getBoolValue("enableIdCollecting");
1840 }
1841 
1842 void ActorManager::removeAttackMob(const std::string &name)
1843 {
1844  mPriorityAttackMobs.remove(name);
1845  mAttackMobs.remove(name);
1846  mIgnoreAttackMobs.remove(name);
1847  mPriorityAttackMobsSet.erase(name);
1848  mAttackMobsSet.erase(name);
1849  mIgnoreAttackMobsSet.erase(name);
1852  storeAttackList();
1853 }
1854 
1855 void ActorManager::removePickupItem(const std::string &name)
1856 {
1857  mPickupItems.remove(name);
1858  mPickupItemsSet.erase(name);
1859  mIgnorePickupItems.remove(name);
1860  mIgnorePickupItemsSet.erase(name);
1862  storeAttackList();
1863 }
1864 
1865 #define addMobToList(name, mob) \
1866 {\
1867  const int sz = get##mob##sSize();\
1868  if (sz > 0)\
1869  {\
1870  const int idx = get##mob##Index("");\
1871  if (idx + 1 == sz)\
1872  {\
1873  std::list<std::string>::iterator itr = m##mob##s.end();\
1874  -- itr;\
1875  m##mob##s.insert(itr, name);\
1876  }\
1877  else\
1878  {\
1879  m##mob##s.push_back(name);\
1880  }\
1881  }\
1882  else\
1883  {\
1884  m##mob##s.push_back(name);\
1885  }\
1886  m##mob##sSet.insert(name);\
1887  rebuild##mob##s();\
1888 }
1889 
1890 #define rebuildMobsList(mob) \
1891 {\
1892  m##mob##sMap.clear();\
1893  std::list<std::string>::const_iterator i = m##mob##s.begin();\
1894  int cnt = 0;\
1895  while (i != m##mob##s.end())\
1896  {\
1897  m##mob##sMap[*i] = cnt;\
1898  ++ i;\
1899  ++ cnt;\
1900  }\
1901 }
1902 
1903 void ActorManager::addAttackMob(const std::string &name)
1904 {
1905  addMobToList(name, AttackMob);
1907  storeAttackList();
1908 }
1909 
1910 void ActorManager::addPriorityAttackMob(const std::string &name)
1911 {
1912  addMobToList(name, PriorityAttackMob);
1913  storeAttackList();
1914 }
1915 
1916 void ActorManager::addIgnoreAttackMob(const std::string &name)
1917 {
1918  mIgnoreAttackMobs.push_back(name);
1919  mIgnoreAttackMobsSet.insert(name);
1922  storeAttackList();
1923 }
1924 
1925 void ActorManager::addPickupItem(const std::string &name)
1926 {
1927  addMobToList(name, PickupItem);
1929  storeAttackList();
1930 }
1931 
1932 void ActorManager::addIgnorePickupItem(const std::string &name)
1933 {
1934  mIgnorePickupItems.push_back(name);
1935  mIgnorePickupItemsSet.insert(name);
1937  storeAttackList();
1938 }
1939 
1941 {
1942  rebuildMobsList(PriorityAttackMob);
1943 }
1944 
1946 {
1947  rebuildMobsList(AttackMob);
1948 }
1949 
1951 {
1952  rebuildMobsList(PickupItem);
1953 }
1954 
1955 int ActorManager::getIndexByName(const std::string &name,
1956  const StringIntMap &map)
1957 {
1958  const StringIntMapCIter i = map.find(name);
1959  if (i == map.end())
1960  return -1;
1961 
1962  return (*i).second;
1963 }
1964 
1965 int ActorManager::getPriorityAttackMobIndex(const std::string &name) const
1966 {
1967  return getIndexByName(name, mPriorityAttackMobsMap);
1968 }
1969 
1970 int ActorManager::getAttackMobIndex(const std::string &name) const
1971 {
1972  return getIndexByName(name, mAttackMobsMap);
1973 }
1974 
1975 int ActorManager::getPickupItemIndex(const std::string &name) const
1976 {
1977  return getIndexByName(name, mPickupItemsMap);
1978 }
1979 
1980 #define loadList(key, mob) \
1981 {\
1982  list = unpackList(serverConfig.getValue(key, ""));\
1983  i = list.begin();\
1984  i_end = list.end();\
1985  while (i != i_end)\
1986  {\
1987  if ((*i).empty())\
1988  empty = true;\
1989  m##mob##s.push_back(*i);\
1990  m##mob##sSet.insert(*i);\
1991  ++ i;\
1992  }\
1993 }
1994 
1996 {
1997  bool empty = false;
1998  std::list<std::string> list;
1999  std::list<std::string>::const_iterator i;
2000  std::list<std::string>::const_iterator i_end;
2001 
2002  loadList("attackPriorityMobs", PriorityAttackMob);
2003  loadList("attackMobs", AttackMob);
2004  loadList("ignoreAttackMobs", IgnoreAttackMob);
2005  if (!empty)
2006  {
2007  mAttackMobs.push_back("");
2008  mAttackMobsSet.insert("");
2009  }
2010  empty = false;
2011 
2012  loadList("pickupItems", PickupItem);
2013  loadList("ignorePickupItems", IgnorePickupItem);
2014  if (!empty)
2015  {
2016  mPickupItems.push_back("");
2017  mPickupItemsSet.insert("");
2018  }
2019 
2023 }
2024 
2026 {
2027  serverConfig.setValue("attackPriorityMobs", packList(mPriorityAttackMobs));
2028  serverConfig.setValue("attackMobs", packList(mAttackMobs));
2029  serverConfig.setValue("ignoreAttackMobs", packList(mIgnoreAttackMobs));
2030 
2031  serverConfig.setValue("pickupItems", packList(mPickupItems));
2032  serverConfig.setValue("ignorePickupItems", packList(mIgnorePickupItems));
2033 }
2034 
2036 {
2037  if (mPickupItemsSet.find("") != mPickupItemsSet.end())
2038  {
2039  if (mIgnorePickupItemsSet.find(item->getName())
2040  == mIgnorePickupItemsSet.end())
2041  {
2042  return true;
2043  }
2044  }
2045  else if ((item != nullptr) && mPickupItemsSet.find(item->getName())
2046  != mPickupItemsSet.end())
2047  {
2048  return true;
2049  }
2050  return false;
2051 }
2052 
2054 {
2055  return mPickupItemsSet.find("") != mPickupItemsSet.end();
2056 }
2057 
2058 void ActorManager::updateEffects(const std::map<BeingTypeId, int> &addEffects,
2059  const std::set<BeingTypeId> &removeEffects)
2060  const
2061 {
2062  for_actorsm
2063  {
2064 // disabled for performance
2065 // if (reportTrue(*it == nullptr))
2066 // continue;
2067  if ((*it)->getType() != ActorType::Npc)
2068  continue;
2069  Being *const being = static_cast<Being*>(*it);
2070  const BeingTypeId type = being->getSubType();
2071  if (removeEffects.find(type) != removeEffects.end())
2072  being->removeSpecialEffect();
2073  const std::map<BeingTypeId, int>::const_iterator
2074  idAdd = addEffects.find(type);
2075  if (idAdd != addEffects.end())
2076  being->addSpecialEffect((*idAdd).second);
2077  }
2078 }
2079 
2080 Being *ActorManager::cloneBeing(const Being *const srcBeing,
2081  const int dx, const int dy,
2082  const int id)
2083 {
2084  returnNullptr(nullptr, srcBeing);
2085  Being *const dstBeing = actorManager->createBeing(fromInt(
2086  toInt(srcBeing->getId(), int) + id, BeingId),
2088  srcBeing->getSubType());
2089  if (dstBeing == nullptr)
2090  return nullptr;
2091  dstBeing->setGender(srcBeing->getGender());
2092  dstBeing->setAction(srcBeing->getCurrentAction(), 0);
2093  dstBeing->setTileCoords(srcBeing->getTileX() + dx,
2094  srcBeing->getTileY() + dy);
2095  dstBeing->setName(srcBeing->getName());
2096  dstBeing->setDirection(srcBeing->getDirection());
2097  const int sz = CAST_S32(srcBeing->mSprites.size());
2098  for (int slot = 0; slot < sz; slot ++)
2099  {
2100  const int spriteId = srcBeing->getSpriteID(slot);
2101  const ItemColor color = srcBeing->getSpriteColor(slot);
2102  dstBeing->setSpriteColorId(slot,
2103  spriteId,
2104  color);
2105  }
2106  const int hairSlot = charServerHandler->hairSprite();
2107  const int hairStyle = -srcBeing->getSpriteID(hairSlot);
2108  const ItemColor hairColor = srcBeing->getHairColor();
2109  if (hairStyle != 0)
2110  {
2111  dstBeing->setSpriteColor(hairSlot,
2112  hairStyle * -1,
2113  ItemDB::get(-hairStyle).getDyeColorsString(hairColor));
2114  }
2115  else
2116  {
2117  dstBeing->unSetSprite(hairSlot);
2118  }
2119  dstBeing->setHairColor(hairColor);
2120  return dstBeing;
2121 }
2122 
2124 {
2125  const BadgeDrawType::Type showBadges = static_cast<BadgeDrawType::Type>(
2126  config.getIntValue("showBadges"));
2127  Being::mShowBadges = showBadges;
2129  config.getIntValue("visiblenamespos"));
2130 
2131  for_actors
2132  {
2133  ActorSprite *const actor = *it;
2134  if (actor->getType() == ActorType::Player)
2135  {
2136  Being *const being = static_cast<Being*>(actor);
2137  being->showBadges(showBadges != BadgeDrawType::Hide);
2138  }
2139  }
2140 }
2141 
2142 void ActorManager::updateNameId(const std::string &name,
2143  const BeingId beingId)
2144 {
2145  if (!mEnableIdCollecting)
2146  return;
2147  const int id = CAST_S32(beingId);
2148  if ((id != 0) &&
2149  (id < 2000000 ||
2150  id >= 110000000))
2151  {
2152  return;
2153  }
2154 
2155  if (mIdName.find(beingId) == mIdName.end() ||
2156  mIdName[beingId].find(name) == mIdName[beingId].end())
2157  {
2158  mIdName[beingId].insert(name);
2159  const std::string idStr = toString(id);
2160  const std::string dateStr = getDateTimeString();
2161  std::string dir;
2162  if (beingId != BeingId_zero)
2163  {
2165  idStr,
2166  stringToHexPath(name));
2167  Files::saveTextFile(dir,
2168  "info.txt",
2169  (name + "\n").append(dateStr));
2170  }
2171 
2172  dir = settings.usersDir;
2173  dir.append(stringToHexPath(name));
2174  Files::saveTextFile(dir,
2175  "seen.txt",
2176  (name + "\n").append(idStr).append("\n").append(dateStr));
2177  }
2178 }
2179 
2180 void ActorManager::updateSeenPlayers(const std::set<std::string>
2181  &onlinePlayers)
2182 {
2183  if (!mEnableIdCollecting)
2184  return;
2185 
2186  FOR_EACH (std::set<std::string>::const_iterator, it, onlinePlayers)
2187  {
2188  const std::string name = *it;
2189  if (findBeingByName(name, ActorType::Player) == nullptr)
2190  updateNameId(name, BeingId_zero);
2191  }
2192 }
2193 
2194 std::string ActorManager::getSeenPlayerById(const BeingId id) const
2195 {
2196  if (!mEnableIdCollecting)
2197  return std::string();
2198 
2199  const IdNameMappingCIter it = mIdName.find(id);
2200  if (it != mIdName.end())
2201  {
2202  if (!it->second.empty())
2203  return *(it->second.begin());
2204  }
2205  return std::string();
2206 }
2207 
2208 void ActorManager::removeRoom(const int chatId)
2209 {
2210  for_actors
2211  {
2212  ActorSprite *const actor = *it;
2213  if (actor->getType() == ActorType::Npc)
2214  {
2215  Being *const being = static_cast<Being*>(actor);
2216  const ChatObject *const chat = being->getChat();
2217  if ((chat != nullptr) && chat->chatId == chatId)
2218  {
2219  being->setChat(nullptr);
2220  }
2221  }
2222  }
2223 }
2224 
2225 void ActorManager::updateRoom(const ChatObject *const newChat)
2226 {
2227  if (newChat == nullptr)
2228  return;
2229 
2230  for_actors
2231  {
2232  const ActorSprite *const actor = *it;
2233  if (actor->getType() == ActorType::Npc)
2234  {
2235  const Being *const being = static_cast<const Being*>(actor);
2236  ChatObject *const chat = being->getChat();
2237  if ((chat != nullptr) && chat->chatId == newChat->chatId)
2238  {
2239  chat->ownerId = newChat->ownerId;
2240  chat->maxUsers = newChat->maxUsers;
2241  chat->type = newChat->type;
2242  chat->title = newChat->title;
2243  }
2244  }
2245  }
2246 }
2247 
2248 std::string ActorManager::findCharById(const int32_t id)
2249 {
2250  const std::map<int32_t, std::string>::const_iterator it = mChars.find(id);
2251  if (it == mChars.end())
2252  return std::string();
2253  return (*it).second;
2254 }
2255 
2256 void ActorManager::addChar(const int32_t id,
2257  const std::string &name)
2258 {
2259  mChars[id] = name;
2260 
2261  if (guiInput == nullptr)
2262  return;
2263 
2265 }
Net::PlayerHandler * playerHandler
Definition: net.cpp:89
#define CAST_U32
Definition: cast.h:30
StringIntMap mAttackMobsMap
Definition: actormanager.h:448
int getSpriteID(const int slot) const
Definition: being.cpp:4821
StringIntMap mPriorityAttackMobsMap
Definition: actormanager.h:447
bool mEnableIdCollecting
Definition: actormanager.h:433
int getTileY() const
Definition: flooritem.h:95
ChatWindow * chatWindow
Definition: chatwindow.cpp:88
#define FOR_EACH(type, iter, array)
Definition: foreach.h:24
Being * findNearestPvpPlayer() const
class SortBeingFunctor beingActorSorter
StringIntMap * priorityBeings
void updateActiveList()
#define _(s)
Definition: gettext.h:34
const ItemInfo & get(const int id)
Definition: itemdb.cpp:814
int fastSqrtInt(const unsigned int n)
Definition: mathutils.h:244
ActorSprites::const_iterator ActorSpritesConstIterator
Definition: actormanager.h:60
void localChatInput(const std::string &msg) const
Definition: chatwindow.cpp:684
std::map< std::string, int > StringIntMap
Definition: stringmap.h:27
int getTileY() const
Definition: being.h:173
void setBeing(Being *const being)
bool checkDefaultPickup() const
std::list< std::string > mAttackMobs
Definition: actormanager.h:448
void postInit(Map *const map, int subX, int subY)
Definition: flooritem.cpp:80
static Being * cloneBeing(const Being *const srcBeing, const int dx, const int dy, const int id)
FloorItem * findItem(const BeingId id) const
Being * findBeingByName(const std::string &name, const ActorTypeT type=ActorType::Unknown) const
class FindBeingEqualFunctor beingEqualActorFinder
void showBadges(const bool show)
Definition: being.cpp:5138
void removeAttackMob(const std::string &name)
void deleteBlock(const BeingId id)
RelationT getRelation(const std::string &name) const
QuestsWindow * questsWindow
void chatLog(std::string line, ChatMsgTypeT own, const IgnoreRecord ignoreRecord=IgnoreRecord_false, const TryRemoveColors tryRemoveColors=TryRemoveColors_true)
Definition: chattab.cpp:109
ActorSpritesMap::const_iterator ActorSpritesMapConstIterator
Definition: actormanager.h:63
#define returnNullptrV(val)
Definition: checkutils.h:257
void setTileCoords(const int x, const int y)
Definition: being.cpp:4934
#define fromInt(val, name)
Definition: intdefines.h:45
void printBeingsToChat(const std::string &header) const
std::string mSpellHeal1
Definition: actormanager.h:422
void updateColors()
Definition: being.cpp:2616
std::string usersIdDir
Definition: settings.h:117
ActorSpritesMap::iterator ActorSpritesMapIterator
Definition: actormanager.h:62
GenderT getGender() const
Definition: being.h:621
void setMap(Map *const map)
bool pickUpNearest(const int x, const int y, int maxdist) const
BeingId getId() const
Definition: actorsprite.h:63
Definition: vector.h:38
int getTileX() const
Definition: flooritem.h:92
std::string stringToHexPath(const std::string &str)
std::string pathJoin(std::string str1, const std::string &str2)
int getPickupItemIndex(const std::string &name) const
virtual bool canUseMagic() const =0
void setGoodStatus(const int n)
Definition: being.h:798
void destroy(ActorSprite *const actor)
void getMobNames(StringVect &names) const
bool mCycleMonsters
Definition: actormanager.h:430
std::string usersDir
Definition: settings.h:116
bool isTargetSelection() const
Definition: beinginfo.h:182
void setPlayer(LocalPlayer *const player)
uint16_t maxUsers
Definition: chatobject.h:47
#define BLOCK_START(name)
Definition: perfomance.h:78
Being * findBeingByPixel(const int x, const int y, const AllPlayers allPlayers=AllPlayers_false) const
void rebuildPriorityAttackMobs()
Configuration config
#define final
Definition: localconsts.h:45
virtual void setGender(const GenderT gender)
Definition: being.cpp:3514
void simulateMouseMove()
Definition: sdlinput.cpp:361
int getPvpMode() const
Definition: map.h:288
int BeingId
Definition: beingid.h:29
std::list< std::string > mPriorityAttackMobs
Definition: actormanager.h:447
const Vector & getPixelPositionF() const
Definition: actor.h:75
std::list< std::string > mPickupItems
Definition: actormanager.h:449
bool limitPackets(const PacketTypeT type)
if(!vert) return
#define for_actors
void rebuildPickupItems()
void storeAttackList() const
static VisibleNamePos::Type mVisibleNamePos
Definition: being.h:1347
#define BLOCK_END(name)
Definition: perfomance.h:79
Being * findMostDamagedPlayer(const int maxTileDist) const
StringIntMap * attackBeings
int getPriorityAttackMobIndex(const std::string &name) const
ActorType ::T ActorTypeT
Definition: actortype.h:42
uint16_t ItemColor
Definition: itemcolor.h:29
uint8_t getDirection() const
Definition: being.h:489
int getIntValue(const std::string &key) const
int getDistance() const
Definition: being.h:547
StringIntMap::const_iterator StringIntMapCIter
Definition: stringmap.h:29
const bool AllowSort_true
Definition: allowsort.h:29
std::vector< std::string > StringVect
Definition: stringvector.h:28
Configuration serverConfig
void updateEffects(const std::map< BeingTypeId, int > &addEffects, const std::set< BeingTypeId > &removeEffects) const
const bool NpcNames_true
Definition: npcnames.h:29
Map * getCurrentMap() const
Definition: game.h:106
void setSpriteColor(const unsigned int slot, const int id, const std::string &color)
Definition: being.cpp:2828
void addListener(const std::string &key, ConfigListener *const listener)
static bool checAttackPermissions(const Being *const target)
void healTarget() const
std::string mSpellHeal2
Definition: actormanager.h:423
bool isActionActive(const InputActionT index) const
static Being * createBeing(const BeingId id, const ActorTypeT type, const BeingTypeId subtype, Map *const map)
Definition: being.cpp:5493
bool checkPackets(const PacketTypeT type)
unsigned int moveToTargetType
Definition: settings.h:133
#define A_DEFAULT_COPY(func)
Definition: localconsts.h:40
void addToCache() const
Definition: being.cpp:3446
virtual void setDirection(const uint8_t direction)
Definition: being.cpp:1649
std::string getName() const
Definition: flooritem.cpp:145
#define toInt(val, name)
Definition: intdefines.h:46
ActorSpritesMap mActorsIdMap
Definition: actormanager.h:416
void updatePlayerColors() const
Settings settings
Definition: settings.cpp:31
void addPriorityAttackMob(const std::string &name)
void addPickupItem(const std::string &name)
#define CAST_U16
Definition: cast.h:28
Net::ServerFeatures * serverFeatures
Definition: net.cpp:94
bool getBoolValue(const std::string &key) const
std::string mSpellItenplz
Definition: actormanager.h:424
void updateGuild()
Definition: being.cpp:1294
virtual int getPixelY() const
Definition: actor.h:92
#define CAST_S32
Definition: cast.h:29
std::string strprintf(const char *const format,...)
Definition: stringutils.cpp:99
void addIgnoreAttackMob(const std::string &name)
void addIgnorePickupItem(const std::string &name)
ActorSprites mDeleteActors
Definition: actormanager.h:415
void setSpriteColorId(const unsigned int slot, const int id, ItemColor colorId)
Definition: being.cpp:2904
Definition: game.h:62
void undelete(const ActorSprite *const actor)
LocalPlayer * localPlayer
EquipmentWindow * beingEquipmentWindow
bool mExtMouseTargeting
Definition: actormanager.h:432
ItemColor getHairColor() const
Definition: being.h:878
bool isAlive() const
Definition: being.h:483
std::set< std::string > mIgnorePickupItemsSet
Definition: actormanager.h:449
std::vector< Sprite * > mSprites
BeingActionT getCurrentAction() const
Definition: being.h:477
std::string getSeenPlayerById(const BeingId id) const
Being * findBeing(const BeingId id) const
void setMap(Map *const map)
Net::BeingHandler * beingHandler
Definition: net.cpp:92
std::list< std::string > mIgnoreAttackMobs
Definition: actormanager.h:448
unsigned int pvpAttackType
Definition: settings.h:140
static Being * findBeing(const std::string &name, const bool npc)
Definition: actions.cpp:211
#define nullptr
Definition: localconsts.h:44
#define returnNullptr(ret, val)
Definition: checkutils.h:258
void saveTextFile(const std::string &path, const std::string &name, const std::string &text)
Definition: files.cpp:248
FloorItem * createItem(const BeingId id, const int itemId, const int x, const int y, const ItemTypeT itemType, const int amount, const int refine, const ItemColor color, const Identified identified, const Damaged damaged, const int subX, const int subY, const int *const cards)
void removeSpecialEffect()
Definition: being.cpp:4866
ActorTypeT getType() const
Definition: being.h:115
bool isBlocked(const BeingId id) const
ItemColor getSpriteColor(const int slot) const
Definition: being.cpp:4837
bool checkForPickup(const FloorItem *const item) const
ActorSprite * findActor(const BeingId id) const
static int getIndexByName(const std::string &name, const StringIntMap &map)
void addAttackMob(const std::string &name)
virtual void setAction(const BeingActionT &action, const int attackId)
Definition: being.cpp:1513
bool mTargetDeadPlayers
Definition: actormanager.h:427
void addBlock(const BeingId id)
void unSetPickUpTarget()
Definition: localplayer.h:317
int getPixelX() const
Definition: actor.h:86
SocialWindow * socialWindow
const std::string & getName() const
Definition: being.h:233
void resetBeing(const Being *const being)
void updatePickupFilter()
std::string empty
Definition: podict.cpp:25
virtual unsigned int hairSprite() const =0
Definition: map.h:68
int getDamageTaken() const
Definition: being.h:588
void checkNewName(Being *const being)
float x
Definition: vector.h:208
StringIntMap mPickupItemsMap
Definition: actormanager.h:449
const bool AllPlayers_true
Definition: allplayers.h:29
std::set< std::string > mPickupItemsSet
Definition: actormanager.h:449
IdNameMapping mIdName
Definition: actormanager.h:417
void removePickupItem(const std::string &name)
ActorSprites mActors
Definition: actormanager.h:414
ItemType ::T ItemTypeT
Definition: itemtype.h:42
ServerTypeT getNetworkType()
Definition: net.cpp:178
void incrementPickup()
Definition: flooritem.h:98
void updateName()
Definition: being.cpp:3358
Being * findNearestByName(const std::string &name, const ActorTypeT &type=ActorType::Unknown) const
ChatTab * debugChatTab
Definition: chattab.cpp:62
std::string title
Definition: chatobject.h:50
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:1774
std::string packList(const std::list< std::string > &list)
void addEffect(Being *const being)
void addSpecialEffect(const int effect)
Definition: being.cpp:4855
std::string findCharById(const int32_t id)
std::set< std::string > mAttackMobsSet
Definition: actormanager.h:448
void updateRoom(const ChatObject *const newChat)
bool pickUpAll(const int x1, const int y1, const int x2, const int y2, const bool serverBuggy=false) const
bool mCyclePlayers
Definition: actormanager.h:429
const BeingInfo * getInfo() const
Definition: being.h:404
void erase(ActorSprite *const actor)
void rebuildAttackMobs()
std::set< std::string > mPriorityAttackMobsSet
Definition: actormanager.h:447
void removeListeners(ConfigListener *const listener)
std::string mMap
Definition: gamerecv.cpp:45
int getSkillLevel(const int id)
Definition: playerinfo.cpp:118
std::set< std::string > mIgnoreAttackMobsSet
Definition: actormanager.h:448
void optionChanged(const std::string &name)
static BadgeDrawType::Type mShowBadges
Definition: being.h:1345
void itenplz() const
void setName(const std::string &name)
Definition: being.cpp:1125
void findBeingsByPixel(std::vector< ActorSprite *> &beings, const int x, const int y, const AllPlayers allPlayers) const
void setTarget(Being *const target)
float y
Definition: vector.h:208
std::map< int32_t, std::string > mChars
Definition: actormanager.h:419
int getAttackMobIndex(const std::string &name) const
const ActorSprites & getAll() const A_CONST
class FindBeingFunctor beingActorFinder
std::string getDateTimeString()
void printAllToChat()
uint16_t getTeamId() const
Definition: being.h:1079
static const int mapTileSize
Definition: map.h:26
#define reportTrue(val)
Definition: checkutils.h:251
static Game * instance()
Definition: game.h:81
const FloorItem * getPickUpTarget() const
Definition: localplayer.h:314
virtual void requestNameById(const BeingId id) const =0
void parseLevels(std::string levels) const
#define for_actorsm
int getTileX() const
Definition: being.h:167
#define CAST_SIZE
Definition: cast.h:33
int chatId
Definition: chatobject.h:46
#define loadList(key, mob)
void updatePlayerNames() const
#define CHECKLISTENERS
Definition: localconsts.h:305
void updateSeenPlayers(const std::set< std::string > &onlinePlayers)
InputManager inputManager
const BeingId BeingId_zero
Definition: beingid.h:29
bool isReachable(Being *const being, const int maxCost=0)
unsigned getPickupCount() const
Definition: flooritem.h:101
void setHairColor(const unsigned int slot, const ItemColor color)
Definition: being.cpp:3322
bool validateBeing(const Being *const aroundBeing, Being *const being, const ActorTypeT &type, const Being *const excluded=0, const int maxCost=20) const
void loadAttackList()
void updateNameId(const std::string &name, const BeingId beingId)
std::list< std::string > mIgnorePickupItems
Definition: actormanager.h:449
BeingId ownerId
Definition: chatobject.h:45
void heal(const Being *const target) const
int32_t getAttribute(const AttributesT id)
Definition: playerinfo.cpp:100
Being * findNearestLivingBeing(const int x, const int y, int maxTileDist, const ActorTypeT type, const Being *const excluded) const
void setChat(ChatObject *const obj)
Definition: being.cpp:5242
int BeingTypeId
Definition: beingtypeid.h:29
Definition: being.h:93
#define addMobToList(name, mob)
Net::CharServerHandler * charServerHandler
Definition: net.cpp:79
PlayerRelationsManager playerRelations
SDLInput * guiInput
Definition: sdlinput.cpp:96
#define reportAlways(...)
Definition: checkutils.h:252
bool updateFromCache()
Definition: being.cpp:3397
IdNameMapping::const_iterator IdNameMappingCIter
Definition: actormanager.h:66
bool hasActorSprite(const ActorSprite *const actor) const
void setValue(const std::string &key, const std::string &value)
void addChar(const int32_t id, const std::string &name)
BeingTypeId getSubType() const
Definition: being.h:395
BeingActionT mAction
Definition: being.h:1226
uint8_t type
Definition: chatobject.h:49
Being * createBeing(const BeingId id, const ActorTypeT type, const BeingTypeId subtype)
void disableHightlight()
Definition: flooritem.h:113
void unSetSprite(const unsigned int slot)
Definition: being.cpp:2799
void getPlayerNames(StringVect &names, const NpcNames npcNames) const
virtual bool haveServerWarpNames() const =0
void updateAttackFilter()
Being * findPortalByTile(const int x, const int y) const
ChatObject * getChat() const
Definition: being.h:998
ActorManager * actorManager
std::set< BeingId > mBlockedBeings
Definition: actormanager.h:418
void updatePlayerGuild() const
Viewport * viewport
Definition: viewport.cpp:35
bool mTargetOnlyReachable
Definition: actormanager.h:428
int getAttackRange() const
void setLevel(const int n)
Definition: being.h:596
Being * getTarget() const
virtual ActorTypeT getType() const
Definition: actorsprite.h:72
void updateBadges() const
bool pickUp(FloorItem *const item)
void clearHover(const ActorSprite *const actor)
Clears any matching hovers.
Definition: viewport.cpp:1051
void removeRoom(const int chatId)
std::set< ActorSprite * > ActorSprites
Definition: actormanager.h:56
#define rebuildMobsList(mob)