diff options
| -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 | 70 | ||||
| -rwxr-xr-x | src/server/game/Maps/Map.h | 18 | 
6 files changed, 99 insertions, 53 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index d92f591803e..9996acbfe9e 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 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 &);  | 
