00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "beingmanager.h"
00023
00024 #include "localplayer.h"
00025 #include "monster.h"
00026 #include "npc.h"
00027 #include "player.h"
00028
00029 #ifdef TMWSERV_SUPPORT
00030 #include "net/tmwserv/protocol.h"
00031 #endif
00032
00033 #include "utils/dtor.h"
00034
00035 #include <cassert>
00036
00037 class FindBeingFunctor
00038 {
00039 public:
00040 bool operator() (Being *being)
00041 {
00042 Uint16 other_y = y + ((being->getType() == Being::NPC) ? 1 : 0);
00043 #ifdef TMWSERV_SUPPORT
00044 const Vector &pos = being->getPosition();
00045 return ((int) pos.x / 32 == x &&
00046 ((int) pos.y / 32 == y || (int) pos.y / 32 == other_y) &&
00047 #else
00048 return (being->mX == x &&
00049 (being->mY == y || being->mY == other_y) &&
00050 #endif
00051 being->mAction != Being::DEAD &&
00052 (type == Being::UNKNOWN || being->getType() == type));
00053 }
00054
00055 Uint16 x, y;
00056 Being::Type type;
00057 } beingFinder;
00058
00059 BeingManager::BeingManager()
00060 {
00061 }
00062
00063 BeingManager::~BeingManager()
00064 {
00065 clear();
00066 }
00067
00068 void BeingManager::setMap(Map *map)
00069 {
00070 mMap = map;
00071 if (player_node)
00072 player_node->setMap(map);
00073 }
00074
00075 void BeingManager::setPlayer(LocalPlayer *player)
00076 {
00077 player_node = player;
00078 mBeings.push_back(player);
00079 }
00080
00081 Being *BeingManager::createBeing(int id, Being::Type type, int subtype)
00082 {
00083 Being *being;
00084
00085 switch (type)
00086 {
00087 case Being::PLAYER:
00088 being = new Player(id, subtype, mMap);
00089 break;
00090 case Being::NPC:
00091 being = new NPC(id, subtype, mMap);
00092 break;
00093 case Being::MONSTER:
00094 being = new Monster(id, subtype, mMap);
00095 break;
00096 case Being::UNKNOWN:
00097 being = new Being(id, subtype, mMap);
00098 break;
00099 default:
00100 assert(false);
00101 }
00102
00103 mBeings.push_back(being);
00104 return being;
00105 }
00106
00107 void BeingManager::destroyBeing(Being *being)
00108 {
00109 mBeings.remove(being);
00110 #ifdef TMWSERV_SUPPORT
00111 if(being == player_node->getTarget())
00112 player_node->setTarget(NULL);
00113 #endif
00114 delete being;
00115 }
00116
00117 Being *BeingManager::findBeing(int id) const
00118 {
00119 for (Beings::const_iterator i = mBeings.begin(), i_end = mBeings.end();
00120 i != i_end; ++i)
00121 {
00122 Being *being = (*i);
00123 if (being->getId() == id)
00124 return being;
00125 }
00126 return NULL;
00127 }
00128
00129 Being *BeingManager::findBeing(int x, int y, Being::Type type) const
00130 {
00131 beingFinder.x = x;
00132 beingFinder.y = y;
00133 beingFinder.type = type;
00134
00135 Beings::const_iterator i = find_if(mBeings.begin(), mBeings.end(),
00136 beingFinder);
00137
00138 return (i == mBeings.end()) ? NULL : *i;
00139 }
00140
00141 Being *BeingManager::findBeingByPixel(int x, int y) const
00142 {
00143 Beings::const_iterator itr = mBeings.begin();
00144 Beings::const_iterator itr_end = mBeings.end();
00145
00146 for (; itr != itr_end; ++itr)
00147 {
00148 Being *being = (*itr);
00149
00150 int xtol = being->getWidth() / 2;
00151 int uptol = being->getHeight();
00152
00153 if ((being->mAction != Being::DEAD) &&
00154 (being != player_node) &&
00155 (being->getPixelX() - xtol <= x) &&
00156 (being->getPixelX() + xtol >= x) &&
00157 (being->getPixelY() - uptol <= y) &&
00158 (being->getPixelY() >= y))
00159 {
00160 return being;
00161 }
00162 }
00163
00164 return NULL;
00165 }
00166
00167 Being *BeingManager::findBeingByName(const std::string &name,
00168 Being::Type type) const
00169 {
00170 for (Beings::const_iterator i = mBeings.begin(), i_end = mBeings.end();
00171 i != i_end; ++i)
00172 {
00173 Being *being = (*i);
00174 if (being->getName() == name &&
00175 (type == Being::UNKNOWN || type == being->getType()))
00176 return being;
00177 }
00178 return NULL;
00179 }
00180
00181 const Beings &BeingManager::getAll() const
00182 {
00183 return mBeings;
00184 }
00185
00186 void BeingManager::logic()
00187 {
00188 Beings::iterator i = mBeings.begin();
00189 while (i != mBeings.end())
00190 {
00191 Being *being = (*i);
00192
00193 being->logic();
00194
00195 #ifdef EATHENA_SUPPORT
00196 if (being->mAction == Being::DEAD && being->mFrame >= 20)
00197 {
00198 delete being;
00199 i = mBeings.erase(i);
00200 }
00201 else
00202 #endif
00203 {
00204 ++i;
00205 }
00206 }
00207 }
00208
00209 void BeingManager::clear()
00210 {
00211 if (player_node)
00212 mBeings.remove(player_node);
00213
00214 delete_all(mBeings);
00215 mBeings.clear();
00216
00217 if (player_node)
00218 mBeings.push_back(player_node);
00219 }
00220
00221 Being *BeingManager::findNearestLivingBeing(int x, int y, int maxdist,
00222 Being::Type type) const
00223 {
00224 Being *closestBeing = NULL;
00225 int dist = 0;
00226
00227 #ifdef TMWSERV_SUPPORT
00228
00229
00230
00231
00232
00233
00234 x = x * 32;
00235 y = y * 32;
00236 maxdist = maxdist * 32;
00237 #endif
00238
00239 Beings::const_iterator itr = mBeings.begin();
00240 Beings::const_iterator itr_end = mBeings.end();
00241
00242 for (; itr != itr_end; ++itr)
00243 {
00244 Being *being = (*itr);
00245 #ifdef TMWSERV_SUPPORT
00246 const Vector &pos = being->getPosition();
00247 int d = abs(((int) pos.x) - x) + abs(((int) pos.y) - y);
00248 #else
00249 int d = abs(being->mX - x) + abs(being->mY - y);
00250 #endif
00251
00252 if ((being->getType() == type || type == Being::UNKNOWN)
00253 && (d < dist || closestBeing == NULL)
00254 && being->mAction != Being::DEAD)
00255 {
00256 dist = d;
00257 closestBeing = being;
00258 }
00259 }
00260
00261 return (maxdist >= dist) ? closestBeing : NULL;
00262 }
00263
00264 Being *BeingManager::findNearestLivingBeing(Being *aroundBeing, int maxdist,
00265 Being::Type type) const
00266 {
00267 Being *closestBeing = NULL;
00268 int dist = 0;
00269 #ifdef TMWSERV_SUPPORT
00270 const Vector &apos = aroundBeing->getPosition();
00271 int x = apos.x;
00272 int y = apos.y;
00273 maxdist = maxdist * 32;
00274 #else
00275 int x = aroundBeing->mX;
00276 int y = aroundBeing->mY;
00277 #endif
00278
00279 for (Beings::const_iterator i = mBeings.begin(), i_end = mBeings.end();
00280 i != i_end; ++i)
00281 {
00282 Being *being = (*i);
00283 #ifdef TMWSERV_SUPPORT
00284 const Vector &pos = being->getPosition();
00285 int d = abs(((int) pos.x) - x) + abs(((int) pos.y) - y);
00286 #else
00287 int d = abs(being->mX - x) + abs(being->mY - y);
00288 #endif
00289
00290 if ((being->getType() == type || type == Being::UNKNOWN)
00291 && (d < dist || closestBeing == NULL)
00292 && being->mAction != Being::DEAD
00293 && being != aroundBeing)
00294 {
00295 dist = d;
00296 closestBeing = being;
00297 }
00298 }
00299
00300 return (maxdist >= dist) ? closestBeing : NULL;
00301 }
00302
00303 bool BeingManager::hasBeing(Being *being) const
00304 {
00305 for (Beings::const_iterator i = mBeings.begin(), i_end = mBeings.end();
00306 i != i_end; ++i)
00307 {
00308 if (being == *i)
00309 return true;
00310 }
00311
00312 return false;
00313 }