aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Maps
diff options
context:
space:
mode:
authormegamage <none@none.none>2011-10-07 17:36:23 -0400
committermegamage <none@none.none>2011-10-07 17:36:23 -0400
commiteb8cbae0d5d2e43585300271db86c4bd0bacd58a (patch)
treed63028a4cdfedcd3c7f7bc26039beb3ec2fd3192 /src/server/game/Maps
parent381cf2f9d3a8bfddea02574987ff64e26d1889d4 (diff)
Fix the relocation of creatures across cells. Try to fix #3054.
Diffstat (limited to 'src/server/game/Maps')
-rwxr-xr-xsrc/server/game/Maps/Map.cpp70
-rwxr-xr-xsrc/server/game/Maps/Map.h18
2 files changed, 60 insertions, 28 deletions
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index b283227bb58..1f26bba5f24 100755
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -206,7 +206,8 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), i_InstanceId(InstanceId),
m_unloadTimer(0), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE),
m_VisibilityNotifyPeriod(DEFAULT_VISIBILITY_NOTIFY_PERIOD),
-m_activeNonPlayersIter(m_activeNonPlayers.end()), i_gridExpiry(expiry), i_scriptLock(false)
+m_activeNonPlayersIter(m_activeNonPlayers.end()), i_gridExpiry(expiry),
+i_scriptLock(false), _creatureToMoveLock(false)
{
m_parentMap = (_parent ? _parent : this);
for (unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
@@ -436,6 +437,17 @@ bool Map::Add(Player* player)
}
template<class T>
+void Map::InitializeObject(T* obj)
+{
+}
+
+template<>
+void Map::InitializeObject(Creature* obj)
+{
+ obj->_moveState = CREATURE_CELL_MOVE_NONE;
+}
+
+template<class T>
void
Map::Add(T *obj)
{
@@ -464,6 +476,7 @@ Map::Add(T *obj)
AddToGrid(obj, grid, cell);
//obj->SetMap(this);
obj->AddToWorld();
+ InitializeObject(obj);
if (obj->isActiveObject())
AddToActive(obj);
@@ -792,6 +805,7 @@ Map::CreatureRelocation(Creature* creature, float x, float y, float z, float ang
{
creature->Relocate(x, y, z, ang);
creature->UpdateObjectVisibility(false);
+ RemoveCreatureFromMoveList(creature);
}
ASSERT(CheckGridIntegrity(creature, true));
@@ -799,26 +813,47 @@ Map::CreatureRelocation(Creature* creature, float x, float y, float z, float ang
void Map::AddCreatureToMoveList(Creature* c, float x, float y, float z, float ang)
{
- if (!c)
+ if (_creatureToMoveLock) //can this happen?
+ return;
+
+ if(c->_moveState == CREATURE_CELL_MOVE_NONE)
+ _creaturesToMove.push_back(c);
+ c->SetNewCellPosition(x, y, z, ang);
+}
+
+void Map::RemoveCreatureFromMoveList(Creature* c)
+{
+ if (_creatureToMoveLock) //can this happen?
return;
- i_creaturesToMove[c] = CreatureMover(x, y, z, ang);
+ if(c->_moveState == CREATURE_CELL_MOVE_ACTIVE)
+ c->_moveState = CREATURE_CELL_MOVE_INACTIVE;
}
void Map::MoveAllCreaturesInMoveList()
{
- while (!i_creaturesToMove.empty())
+ _creatureToMoveLock = true;
+ for(std::vector<Creature*>::iterator itr = _creaturesToMove.begin(); itr != _creaturesToMove.end(); ++itr)
{
- // get data and remove element;
- CreatureMoveList::iterator iter = i_creaturesToMove.begin();
- Creature* c = iter->first;
- const CreatureMover &cm = iter->second;
+ Creature* c = *itr;
+ if(c->FindMap() != this) //pet is teleported to another map
+ continue;
+
+ if(c->_moveState != CREATURE_CELL_MOVE_ACTIVE)
+ {
+ c->_moveState = CREATURE_CELL_MOVE_NONE;
+ continue;
+ }
+
+ c->_moveState = CREATURE_CELL_MOVE_NONE;
+ if(!c->IsInWorld())
+ continue;
// do move or do move to respawn or remove creature if previous all fail
- if (CreatureCellRelocation(c, Cell(Trinity::ComputeCellPair(cm.x, cm.y))))
+ if (CreatureCellRelocation(c, Cell(Trinity::ComputeCellPair(c->_newPosition.m_positionX, c->_newPosition.m_positionY))))
{
// update pos
- c->Relocate(cm.x, cm.y, cm.z, cm.ang);
+ c->Relocate(c->_newPosition);
//CreatureRelocationNotify(c, new_cell, new_cell.cellPair());
c->UpdateObjectVisibility(false);
}
@@ -826,7 +861,7 @@ void Map::MoveAllCreaturesInMoveList()
{
// if creature can't be move in new cell/grid (not loaded) move it to repawn cell/grid
// creature coordinates will be updated and notifiers send
- if (!CreatureRespawnRelocation(c))
+ if (!CreatureRespawnRelocation(c, false))
{
// ... or unload (if respawn grid also not loaded)
#ifdef TRINITY_DEBUG
@@ -844,9 +879,9 @@ void Map::MoveAllCreaturesInMoveList()
AddObjectToRemoveList(c);
}
}
-
- i_creaturesToMove.erase(iter);
}
+ _creaturesToMove.clear();
+ _creatureToMoveLock = false;
}
bool Map::CreatureCellRelocation(Creature* c, Cell new_cell)
@@ -910,14 +945,17 @@ bool Map::CreatureCellRelocation(Creature* c, Cell new_cell)
return false;
}
-bool Map::CreatureRespawnRelocation(Creature* c)
+bool Map::CreatureRespawnRelocation(Creature* c, bool diffGridOnly)
{
float resp_x, resp_y, resp_z, resp_o;
c->GetRespawnCoord(resp_x, resp_y, resp_z, &resp_o);
-
CellPair resp_val = Trinity::ComputeCellPair(resp_x, resp_y);
Cell resp_cell(resp_val);
+ //creature will be unloaded with grid
+ if(diffGridOnly && !c->GetCurrentCell().DiffGrid(resp_cell))
+ return true;
+
c->CombatStop();
c->GetMotionMaster()->Clear();
@@ -1021,7 +1059,7 @@ void Map::RemoveAllPlayers()
void Map::UnloadAll()
{
// clear all delayed moves, useless anyway do this moves before map unload.
- i_creaturesToMove.clear();
+ _creaturesToMove.clear();
for (GridRefManager<NGridType>::iterator i = GridRefManager<NGridType>::begin(); i != GridRefManager<NGridType>::end();)
{
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 640b70413f8..ff6bdac5156 100755
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -193,14 +193,6 @@ public:
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0);
};
-struct CreatureMover
-{
- CreatureMover() : x(0.0f), y(0.0f), z(0.0f), ang(0.0f) {}
- CreatureMover(float _x, float _y, float _z, float _ang) : x(_x), y(_y), z(_z), ang(_ang) {}
-
- float x, y, z, ang;
-};
-
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push, N), also any gcc version not support it at some platform
#if defined(__GNUC__)
#pragma pack(1)
@@ -226,8 +218,6 @@ enum LevelRequirementVsMode
#pragma pack(pop)
#endif
-typedef UNORDERED_MAP<Creature*, CreatureMover> CreatureMoveList;
-
#define MAX_HEIGHT 100000.0f // can be use for find ground height at surface
#define INVALID_HEIGHT -100000.0f // for check, must be equal to VMAP_INVALID_HEIGHT, real value for unknown height is VMAP_INVALID_HEIGHT_VALUE
#define MAX_FALL_DISTANCE 250000.0f // "unlimited fall" to find VMap ground if it is available, just larger than MAX_HEIGHT - INVALID_HEIGHT
@@ -344,7 +334,8 @@ class Map : public GridRefManager<NGridType>
void RemoveAllObjectsInRemoveList();
virtual void RemoveAllPlayers();
- bool CreatureRespawnRelocation(Creature* c); // used only in MoveAllCreaturesInMoveList and ObjectGridUnloader
+ // used only in MoveAllCreaturesInMoveList and ObjectGridUnloader
+ bool CreatureRespawnRelocation(Creature* c, bool diffGridOnly);
// assert print helper
bool CheckGridIntegrity(Creature* c, bool moved) const;
@@ -449,8 +440,11 @@ class Map : public GridRefManager<NGridType>
bool CreatureCellRelocation(Creature* creature, Cell new_cell);
+ template<class T> void InitializeObject(T* obj);
void AddCreatureToMoveList(Creature* c, float x, float y, float z, float ang);
- CreatureMoveList i_creaturesToMove;
+ void RemoveCreatureFromMoveList(Creature* c);
+ bool _creatureToMoveLock;
+ std::vector<Creature*> _creaturesToMove;
bool loaded(const GridPair &) const;
void EnsureGridCreated(const GridPair &);