diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/Entities/Creature/Creature.cpp | 3 | ||||
-rwxr-xr-x | src/server/game/Entities/Creature/Creature.h | 36 | ||||
-rwxr-xr-x | src/server/game/Grids/ObjectGridLoader.cpp | 22 | ||||
-rwxr-xr-x | src/server/game/Grids/ObjectGridLoader.h | 3 | ||||
-rwxr-xr-x | src/server/game/Maps/Map.cpp | 72 | ||||
-rwxr-xr-x | src/server/game/Maps/Map.h | 18 |
6 files changed, 100 insertions, 54 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index a8e219f4f6b..5ac2fdcaca1 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -143,7 +143,8 @@ m_PlayerDamageReq(0), m_lootMoney(0), m_lootRecipient(0), m_lootRecipientGroup(0 m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), -m_creatureInfo(NULL), m_creatureData(NULL), m_formation(NULL) +m_creatureInfo(NULL), m_creatureData(NULL), m_formation(NULL), +MapCreature() { m_regenTimer = CREATURE_REGEN_INTERVAL; m_valuesCount = UNIT_END; diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 3d5b86a106a..6bca501f76b 100755 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -407,7 +407,36 @@ typedef std::map<uint32, time_t> CreatureSpellCooldowns; #define MAX_VENDOR_ITEMS 150 // Limitation in 3.x.x item count in SMSG_LIST_INVENTORY -class Creature : public Unit, public GridObject<Creature> +enum CreatureCellMoveState +{ + CREATURE_CELL_MOVE_NONE, //not in move list + CREATURE_CELL_MOVE_ACTIVE, //in move list + CREATURE_CELL_MOVE_INACTIVE, //in move list but should not move +}; + +class MapCreature +{ + friend class Map; //map for moving creatures + friend class ObjectGridLoader; //grid loader for loading creatures + +public: + MapCreature() : _moveState(CREATURE_CELL_MOVE_NONE) {} + +private: + Cell _currentCell; + Cell const& GetCurrentCell() const { return _currentCell; } + void SetCurrentCell(Cell const& cell) { _currentCell = cell; } + + CreatureCellMoveState _moveState; + Position _newPosition; + void SetNewCellPosition(float x, float y, float z, float o) + { + _moveState = CREATURE_CELL_MOVE_ACTIVE; + _newPosition.Relocate(x, y, z, o); + } +}; + +class Creature : public Unit, public GridObject<Creature>, public MapCreature { public: @@ -598,10 +627,6 @@ class Creature : public Unit, public GridObject<Creature> MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; } void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; } - // for use only in LoadHelper, Map::Add Map::CreatureCellRelocation - Cell const& GetCurrentCell() const { return m_currentCell; } - void SetCurrentCell(Cell const& cell) { m_currentCell = cell; } - void RemoveCorpse(bool setSpawnTime = true); void ForcedDespawn(uint32 timeMSToDespawn = 0); @@ -703,7 +728,6 @@ class Creature : public Unit, public GridObject<Creature> void RegenerateHealth(); void Regenerate(Powers power); MovementGeneratorType m_defaultMovementType; - Cell m_currentCell; // store current cell where creature listed uint32 m_DBTableGuid; ///< For new or temporary creatures is 0 for saved it is lowguid uint32 m_equipmentId; diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp index 58521b76bff..b0e7de88491 100755 --- a/src/server/game/Grids/ObjectGridLoader.cpp +++ b/src/server/game/Grids/ObjectGridLoader.cpp @@ -57,20 +57,8 @@ ObjectGridRespawnMover::Visit(CreatureMapType &m) Creature* c = iter->getSource(); ++iter; - ASSERT(!c->isPet() && "ObjectGridRespawnMover don't must be called for pets"); - - Cell const& cur_cell = c->GetCurrentCell(); - - float resp_x, resp_y, resp_z; - c->GetRespawnCoord(resp_x, resp_y, resp_z); - CellPair resp_val = Trinity::ComputeCellPair(resp_x, resp_y); - Cell resp_cell(resp_val); - - if (cur_cell.DiffGrid(resp_cell)) - { - c->GetMap()->CreatureRespawnRelocation(c); - // false result ignored: will be unload with other creatures at grid - } + ASSERT(!c->isPet() && "ObjectGridRespawnMover must not be called for pets"); + c->GetMap()->CreatureRespawnRelocation(c, true); } } @@ -94,11 +82,11 @@ class ObjectWorldLoader uint32 i_corpses; }; -template<class T> void AddUnitState(T* /*obj*/, CellPair const& /*cell_pair*/) +template<class T> static void ObjectGridLoader::SetObjectCell(T* /*obj*/, CellPair const& /*cell_pair*/) { } -template<> void AddUnitState(Creature* obj, CellPair const& cell_pair) +template<> static void ObjectGridLoader::SetObjectCell(Creature* obj, CellPair const& cell_pair) { Cell cell(cell_pair); @@ -109,7 +97,7 @@ template <class T> void AddObjectHelper(CellPair &cell, GridRefManager<T> &m, uint32 &count, Map* map, T *obj) { obj->GetGridRef().link(&m, obj); - AddUnitState(obj, cell); + ObjectGridLoader::SetObjectCell(obj, cell); obj->AddToWorld(); if (obj->isActiveObject()) map->AddToActive(obj); diff --git a/src/server/game/Grids/ObjectGridLoader.h b/src/server/game/Grids/ObjectGridLoader.h index 901080293a4..5fc5dc47e71 100755 --- a/src/server/game/Grids/ObjectGridLoader.h +++ b/src/server/game/Grids/ObjectGridLoader.h @@ -40,11 +40,12 @@ class ObjectGridLoader void Visit(GameObjectMapType &m); void Visit(CreatureMapType &m); void Visit(CorpseMapType &) const {} - void Visit(DynamicObjectMapType&) const {} void LoadN(void); + template<class T> static void SetObjectCell(T* obj, CellPair const& cellPair); + private: Cell i_cell; NGridType &i_grid; diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 26e058a32f3..4096154fa37 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -205,7 +205,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) @@ -435,6 +436,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) { @@ -463,6 +475,7 @@ Map::Add(T *obj) AddToGrid(obj, grid, cell); //obj->SetMap(this); obj->AddToWorld(); + InitializeObject(obj); if (obj->isActiveObject()) AddToActive(obj); @@ -791,6 +804,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)); @@ -798,26 +812,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); } @@ -825,7 +860,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 @@ -843,9 +878,9 @@ void Map::MoveAllCreaturesInMoveList() AddObjectToRemoveList(c); } } - - i_creaturesToMove.erase(iter); } + _creaturesToMove.clear(); + _creatureToMoveLock = false; } bool Map::CreatureCellRelocation(Creature* c, Cell new_cell) @@ -909,14 +944,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(); @@ -1020,7 +1058,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();) { @@ -2678,4 +2716,4 @@ void Map::UpdateIteratorBack(Player* player) { if (m_mapRefIter == player->GetMapRef()) m_mapRefIter = m_mapRefIter->nocheck_prev(); -}
\ No newline at end of file +} diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index bbd3b20ecfb..8359a49a316 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 &); |