diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index c989812a2c6..fc05c3eeee9 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -118,7 +118,8 @@ m_lootMoney(0), m_lootRecipient(0), m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f), m_subtype(subtype), 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_isDeadByDefault(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), +m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_needNotify(false), +m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_creatureInfo(NULL), m_isActiveObject(false), m_splineFlags(SPLINEFLAG_WALKMODE) { m_regenTimer = 200; @@ -334,6 +335,15 @@ void Creature::Update(uint32 diff) else m_GlobalCooldown -= diff; + if (m_needNotify) + { + m_needNotify = false; + RelocationNotify(); + + if (!IsInWorld()) + return; + } + switch( m_deathState ) { case JUST_ALIVED: @@ -2066,3 +2076,22 @@ void Creature::SendAreaSpiritHealerQueryOpcode(Player *pl) data << GetGUID() << next_resurrect; pl->SendDirectMessage(&data); } + +void Creature::RelocationNotify() +{ + CellPair new_val = MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY()); + Cell cell(new_val); + CellPair cellpair = cell.cellPair(); + + MaNGOS::CreatureRelocationNotifier relocationNotifier(*this); + cell.data.Part.reserved = ALL_DISTRICT; + cell.SetNoCreate(); // not trigger load unloaded grids at notifier call + + TypeContainerVisitor c2world_relocation(relocationNotifier); + TypeContainerVisitor c2grid_relocation(relocationNotifier); + + float radius = MAX_CREATURE_ATTACK_RADIUS * sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_AGGRO); + + cell.Visit(cellpair, c2world_relocation, *GetMap(), *this, radius); + cell.Visit(cellpair, c2grid_relocation, *GetMap(), *this, radius); +} diff --git a/src/game/Creature.h b/src/game/Creature.h index 788082cd351..1e7f2cbe96b 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -615,11 +615,14 @@ class MANGOS_DLL_SPEC Creature : public Unit bool isActiveObject() const { return m_isActiveObject || HasAuraType(SPELL_AURA_BIND_SIGHT) || HasAuraType(SPELL_AURA_FAR_SIGHT); } void SetActiveObjectState(bool on); + void SetNeedNotify() { m_needNotify = true; } + void SendAreaSpiritHealerQueryOpcode(Player *pl); protected: bool CreateFromProto(uint32 guidlow,uint32 Entry,uint32 team, const CreatureData *data = NULL); bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL); + void RelocationNotify(); // vendor items VendorItemCounts m_vendorItemCounts; @@ -652,6 +655,7 @@ class MANGOS_DLL_SPEC Creature : public Unit bool m_regenHealth; bool m_AI_locked; bool m_isDeadByDefault; + bool m_needNotify; SpellSchoolMask m_meleeDamageSchoolMask; uint32 m_originalEntry; diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 71afd30746c..3e077c75c4f 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -40,8 +40,6 @@ #include "InstanceSaveMgr.h" #include "VMapFactory.h" -#define MAX_CREATURE_ATTACK_RADIUS (45.0f * sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_AGGRO)) - GridState* si_GridStates[MAX_GRID_STATE]; static char const* MAP_MAGIC = "MAPS"; @@ -344,9 +342,9 @@ void Map::AddNotifier(Player* obj, Cell const& cell, CellPair const& cellpair) } template<> -void Map::AddNotifier(Creature* obj, Cell const& cell, CellPair const& cellpair) +void Map::AddNotifier(Creature* obj, Cell const&, CellPair const&) { - CreatureRelocationNotify(obj,cell,cellpair); + obj->SetNeedNotify(); } void @@ -904,62 +902,38 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang if ((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES) == 0) sLog.outDebug("Creature (GUID: %u Entry: %u) added to moving list from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", creature->GetGUIDLow(), creature->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); #endif - AddCreatureToMoveList(creature, x, y, z, ang); - // in diffcell/diffgrid case notifiers called at finishing move creature in Map::MoveAllCreaturesInMoveList - } - else - { - creature->Relocate(x, y, z, ang); - CreatureRelocationNotify(creature, new_cell, new_val); - } - - assert(CheckGridIntegrity(creature,true)); -} - -void Map::AddCreatureToMoveList(Creature *c, float x, float y, float z, float ang) -{ - if(!c) - return; - - i_creaturesToMove[c] = CreatureMover(x, y, z, ang); -} - -void Map::MoveAllCreaturesInMoveList() -{ - while(!i_creaturesToMove.empty()) - { - // get data and remove element; - CreatureMoveList::iterator iter = i_creaturesToMove.begin(); - Creature* c = iter->first; - CreatureMover cm = iter->second; - i_creaturesToMove.erase(iter); - - // calculate cells - CellPair new_val = MaNGOS::ComputeCellPair(cm.x, cm.y); - Cell new_cell(new_val); // do move or do move to respawn or remove creature if previous all fail - if(CreatureCellRelocation(c,new_cell)) + if(CreatureCellRelocation(creature,new_cell)) { // update pos - c->Relocate(cm.x, cm.y, cm.z, cm.ang); - CreatureRelocationNotify(c, new_cell, new_cell.cellPair()); + creature->Relocate(x, y, z, ang); + + // in diffcell/diffgrid case notifiers called in Creature::Update + creature->SetNeedNotify(); } else { // 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(creature)) { // ... or unload (if respawn grid also not loaded) #ifdef MANGOS_DEBUG if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0) - sLog.outDebug("Creature (GUID: %u Entry: %u ) can't be move to unloaded respawn grid.",c->GetGUIDLow(),c->GetEntry()); + sLog.outDebug("Creature (GUID: %u Entry: %u ) can't be move to unloaded respawn grid.",creature->GetGUIDLow(),creature->GetEntry()); #endif - AddObjectToRemoveList(c); + creature->SetNeedNotify(); } } } + else + { + creature->Relocate(x, y, z, ang); + creature->SetNeedNotify(); + } + + assert(CheckGridIntegrity(creature,true)); } bool Map::CreatureCellRelocation(Creature *c, Cell new_cell) @@ -1055,7 +1029,7 @@ bool Map::CreatureRespawnRelocation(Creature *c) { c->Relocate(resp_x, resp_y, resp_z, resp_o); c->GetMotionMaster()->Initialize(); // prevent possible problems with default move generators - CreatureRelocationNotify(c,resp_cell,resp_cell.cellPair()); + c->SetNeedNotify(); return true; } else @@ -1074,15 +1048,15 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce) DEBUG_LOG("Unloading grid[%u,%u] for map %u", x,y, i_id); ObjectGridUnloader unloader(*grid); - // Finish creature moves, remove and delete all creatures with delayed remove before moving to respawn grids + // Finish remove and delete all creatures with delayed remove before moving to respawn grids // Must know real mob position before move - DoDelayedMovesAndRemoves(); + RemoveAllObjectsInRemoveList(); // move creatures to respawn grids if this is diff.grid or to remove list unloader.MoveToRespawnN(); - // Finish creature moves, remove and delete all creatures with delayed remove before unload - DoDelayedMovesAndRemoves(); + // Finish remove and delete all creatures with delayed remove before unload + RemoveAllObjectsInRemoveList(); unloader.UnloadN(); delete getNGrid(x, y); @@ -1115,9 +1089,6 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce) void Map::UnloadAll(bool pForce) { - // clear all delayed moves, useless anyway do this moves before map unload. - i_creaturesToMove.clear(); - for (GridRefManager::iterator i = GridRefManager::begin(); i != GridRefManager::end(); ) { NGridType &grid(*i->getSource()); @@ -2066,21 +2037,10 @@ void Map::PlayerRelocationNotify( Player* player, Cell cell, CellPair cellpair ) TypeContainerVisitor p2grid_relocation(relocationNotifier); TypeContainerVisitor p2world_relocation(relocationNotifier); - cell.Visit(cellpair, p2grid_relocation, *this, *player, MAX_CREATURE_ATTACK_RADIUS); - cell.Visit(cellpair, p2world_relocation, *this, *player, MAX_CREATURE_ATTACK_RADIUS); -} - -void Map::CreatureRelocationNotify(Creature *creature, Cell cell, CellPair cellpair) -{ - MaNGOS::CreatureRelocationNotifier relocationNotifier(*creature); - cell.data.Part.reserved = ALL_DISTRICT; - cell.SetNoCreate(); // not trigger load unloaded grids at notifier call + float radius = MAX_CREATURE_ATTACK_RADIUS * sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_AGGRO); - TypeContainerVisitor c2world_relocation(relocationNotifier); - TypeContainerVisitor c2grid_relocation(relocationNotifier); - - cell.Visit(cellpair, c2world_relocation, *this, *creature, MAX_CREATURE_ATTACK_RADIUS); - cell.Visit(cellpair, c2grid_relocation, *this, *creature, MAX_CREATURE_ATTACK_RADIUS); + cell.Visit(cellpair, p2grid_relocation, *this, *player, radius); + cell.Visit(cellpair, p2world_relocation, *this, *player, radius); } void Map::SendInitSelf( Player * player ) @@ -2175,12 +2135,6 @@ inline void Map::setNGrid(NGridType *grid, uint32 x, uint32 y) i_grids[x][y] = grid; } -void Map::DoDelayedMovesAndRemoves() -{ - MoveAllCreaturesInMoveList(); - RemoveAllObjectsInRemoveList(); -} - void Map::AddObjectToRemoveList(WorldObject *obj) { assert(obj->GetMapId()==GetId() && obj->GetInstanceId()==GetInstanceId()); diff --git a/src/game/Map.h b/src/game/Map.h index d29e3a11ec4..af153a23201 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -180,14 +180,6 @@ class GridMap ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data = 0); }; -struct CreatureMover -{ - CreatureMover() : x(0), y(0), z(0), ang(0) {} - 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) @@ -219,8 +211,6 @@ enum LevelRequirementVsMode #pragma pack(pop) #endif -typedef UNORDERED_MAP 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 MIN_UNLOAD_DELAY 1 // immediate unload @@ -327,10 +317,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(x,y,z),i_id); } - virtual void MoveAllCreaturesInMoveList(); virtual void RemoveAllObjectsInRemoveList(); - bool CreatureRespawnRelocation(Creature *c); // used only in MoveAllCreaturesInMoveList and ObjectGridUnloader + bool CreatureRespawnRelocation(Creature *c); // used only in CreatureRelocation and ObjectGridUnloader // assert print helper bool CheckGridIntegrity(Creature* c, bool moved) const; @@ -371,7 +360,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj } void AddObjectToRemoveList(WorldObject *obj); - void DoDelayedMovesAndRemoves(); virtual bool RemoveBones(uint64 guid, float x, float y); @@ -445,13 +433,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj void SendRemoveTransports( Player * player ); void PlayerRelocationNotify(Player* player, Cell cell, CellPair cellpair); - void CreatureRelocationNotify(Creature *creature, Cell newcell, CellPair newval); bool CreatureCellRelocation(Creature *creature, Cell new_cell); - void AddCreatureToMoveList(Creature *c, float x, float y, float z, float ang); - CreatureMoveList i_creaturesToMove; - bool loaded(const GridPair &) const; void EnsureGridCreated(const GridPair &); bool EnsureGridLoaded(Cell const&); diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp index 76a508d9861..46263e2bee6 100644 --- a/src/game/MapInstanced.cpp +++ b/src/game/MapInstanced.cpp @@ -66,16 +66,6 @@ void MapInstanced::Update(const uint32& t) } } -void MapInstanced::MoveAllCreaturesInMoveList() -{ - for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i) - { - i->second->MoveAllCreaturesInMoveList(); - } - - Map::MoveAllCreaturesInMoveList(); -} - void MapInstanced::RemoveAllObjectsInRemoveList() { for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i) diff --git a/src/game/MapInstanced.h b/src/game/MapInstanced.h index ddd240e3e90..d9a8c66b745 100644 --- a/src/game/MapInstanced.h +++ b/src/game/MapInstanced.h @@ -34,7 +34,6 @@ class MANGOS_DLL_DECL MapInstanced : public Map // functions overwrite Map versions void Update(const uint32&); - void MoveAllCreaturesInMoveList(); void RemoveAllObjectsInRemoveList(); bool RemoveBones(uint64 guid, float x, float y); void UnloadAll(bool pForce); diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 7b0fca258af..e3b37cdda26 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -271,10 +271,10 @@ MapManager::Update(uint32 diff) i_timer.SetCurrent(0); } -void MapManager::DoDelayedMovesAndRemoves() +void MapManager::RemoveAllObjectsInRemoveList() { for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter) - iter->second->DoDelayedMovesAndRemoves(); + iter->second->RemoveAllObjectsInRemoveList(); } bool MapManager::ExistMapAndVMap(uint32 mapid, float x,float y) diff --git a/src/game/MapManager.h b/src/game/MapManager.h index 2f18730728b..e9046d2b5dd 100644 --- a/src/game/MapManager.h +++ b/src/game/MapManager.h @@ -108,7 +108,7 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton GuardianPetList; // delay time next attack to prevent client attack animation problems #define ATTACK_DISPLAY_DELAY 200 #define MAX_PLAYER_STEALTH_DETECT_RANGE 45.0f // max distance for detection targets by player +#define MAX_CREATURE_ATTACK_RADIUS 45.0f // max distance for creature aggro (use with CONFIG_FLOAT_RATE_CREATURE_AGGRO) // Regeneration defines #define REGEN_TIME_FULL 2000 // For this time difference is computed regen value diff --git a/src/game/World.cpp b/src/game/World.cpp index f9c9b659af1..751689968c0 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1429,7 +1429,7 @@ void World::Update(uint32 diff) /// ///- Move all creatures with "delayed move" and remove and delete all objects with "delayed remove" - sMapMgr.DoDelayedMovesAndRemoves(); + sMapMgr.RemoveAllObjectsInRemoveList(); // update the instance reset times sInstanceSaveMgr.Update(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d0717631ff0..a2dba2bf191 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9404" + #define REVISION_NR "9405" #endif // __REVISION_NR_H__