diff options
author | megamage <none@none> | 2009-02-26 20:43:35 -0600 |
---|---|---|
committer | megamage <none@none> | 2009-02-26 20:43:35 -0600 |
commit | d3a69006675bb5317fab76584d5990b36c2fd5a5 (patch) | |
tree | 8a0f3e0033eb694d5aba06db5c1ecc02b690099e | |
parent | 39c513776c5dde8b5732df5ba2467d9e9e3e84fd (diff) | |
parent | bc54e91afff9b9a53902439441fa2e63e3da1a9a (diff) |
*Merge.
--HG--
branch : trunk
24 files changed, 413 insertions, 202 deletions
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp index ae12d1fe47f..4f96e672352 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp @@ -195,8 +195,6 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI EnrageUsed = false; InnderDemon_Count = 0; m_creature->SetSpeed( MOVE_RUN, 2.0f, true); - m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); - m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true); m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF); m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0); m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp index cb09a10cd51..ef69ab220bf 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp @@ -129,7 +129,7 @@ struct TRINITY_DLL_DECL instance_serpentshrine_cavern : public ScriptedInstance break; case 184956: StrangePool = go->GetGUID(); - if(go->isActive()) + if(go->isActiveObject()) SetData(DATA_STRANGE_POOL, DONE); } } diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_maiden_of_virtue.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_maiden_of_virtue.cpp index b58dfa4922c..a8581a351ff 100644 --- a/src/bindings/scripts/scripts/zone/karazhan/boss_maiden_of_virtue.cpp +++ b/src/bindings/scripts/scripts/zone/karazhan/boss_maiden_of_virtue.cpp @@ -58,9 +58,6 @@ struct TRINITY_DLL_DECL boss_maiden_of_virtueAI : public ScriptedAI Enrage_Timer = 600000; Enraged = false; - - m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); - m_creature->ApplySpellImmune(1, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true); } void KilledUnit(Unit* Victim) diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp index 8fadb5192f9..be733b5c819 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp @@ -386,9 +386,6 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); - m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true); - if(pInstance) pInstance->SetData(DATA_KAELTHASEVENT, NOT_STARTED); diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp index 3ea1e12ef1e..66ee717bc4f 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp @@ -52,16 +52,17 @@ struct TRINITY_DLL_DECL boss_void_reaverAI : public ScriptedAI uint32 KnockAway_Timer; uint32 Berserk_Timer; + bool Enraged; + void Reset() { - m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); - m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); - Pounding_Timer = 15000; ArcaneOrb_Timer = 3000; KnockAway_Timer = 30000; Berserk_Timer = 600000; + Enraged = false; + if (pInstance && m_creature->isAlive()) pInstance->SetData(DATA_VOIDREAVEREVENT, NOT_STARTED); } @@ -120,7 +121,7 @@ struct TRINITY_DLL_DECL boss_void_reaverAI : public ScriptedAI { target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); //18 yard radius minimum - if(target && target->GetTypeId() == TYPEID_PLAYER && target->isAlive() && target->GetDistance2d(m_creature) > 18) + if(target && target->GetTypeId() == TYPEID_PLAYER && target->isAlive() && target->GetDistance2d(m_creature) >= 18) target_list.push_back(target); target = NULL; } @@ -146,13 +147,10 @@ struct TRINITY_DLL_DECL boss_void_reaverAI : public ScriptedAI }else KnockAway_Timer -= diff; //Berserk - if(Berserk_Timer < diff) + if(Berserk_Timer < diff && !Enraged) { - if (m_creature->IsNonMeleeSpellCasted(false)) - m_creature->InterruptNonMeleeSpells(false); - DoCast(m_creature,SPELL_BERSERK); - Berserk_Timer = 600000; + Enraged = true; }else Berserk_Timer -= diff; DoMeleeAttackIfReady(); diff --git a/src/framework/GameSystem/Grid.h b/src/framework/GameSystem/Grid.h index 646345705d3..fad792ba5ec 100644 --- a/src/framework/GameSystem/Grid.h +++ b/src/framework/GameSystem/Grid.h @@ -105,7 +105,7 @@ class TRINITY_DLL_DECL Grid /** Returns the number of object within the grid. */ - unsigned int ActiveObjectsInGrid(void) const { return i_objects.template Count<ACTIVE_OBJECT>(); } + unsigned int ActiveObjectsInGrid(void) const { return /*m_activeGridObjects.size()+*/i_objects.template Count<ACTIVE_OBJECT>(); } /** Accessors: Returns a specific type of object in the GRID_OBJECT_TYPES */ @@ -114,12 +114,31 @@ class TRINITY_DLL_DECL Grid /** Inserts a container type object into the grid. */ - template<class SPECIFIC_OBJECT> bool AddGridObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) { return i_container.template insert<SPECIFIC_OBJECT>(hdl, obj); } + template<class SPECIFIC_OBJECT> bool AddGridObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) + { + //if(obj->isActiveObject()) + // m_activeGridObjects.insert(obj); + return i_container.template insert<SPECIFIC_OBJECT>(hdl, obj); + } /** Removes a containter type object from the grid */ - template<class SPECIFIC_OBJECT> bool RemoveGridObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) { return i_container.template remove<SPECIFIC_OBJECT>(obj, hdl); } + template<class SPECIFIC_OBJECT> bool RemoveGridObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) + { + //if(obj->isActiveObject()) + // m_activeGridObjects.erase(obj); + return i_container.template remove<SPECIFIC_OBJECT>(obj, hdl); + } + /*bool NoWorldObjectInGrid() const + { + return i_objects.GetElements().isEmpty(); + } + + bool NoGridObjectInGrid() const + { + return i_container.GetElements().isEmpty(); + }*/ private: typedef typename ThreadModel::Lock Guard; @@ -127,6 +146,8 @@ class TRINITY_DLL_DECL Grid TypeMapContainer<GRID_OBJECT_TYPES> i_container; TypeMapContainer<WORLD_OBJECT_TYPES> i_objects; + //typedef std::set<void*> ActiveGridObjects; + //ActiveGridObjects m_activeGridObjects; }; #endif diff --git a/src/framework/GameSystem/NGrid.h b/src/framework/GameSystem/NGrid.h index 45e05e73a1e..126703febd2 100644 --- a/src/framework/GameSystem/NGrid.h +++ b/src/framework/GameSystem/NGrid.h @@ -31,18 +31,26 @@ class GridInfo { public: - GridInfo() : i_timer(0) {} - GridInfo(time_t expiry, bool unload = true ) : i_timer(expiry), i_unloadflag(unload) {} + GridInfo() + : i_timer(0), i_unloadActiveLockCount(0), i_unloadExplicitLock(false), i_unloadReferenceLock(false) {} + GridInfo(time_t expiry, bool unload = true ) + : i_timer(expiry), i_unloadActiveLockCount(0), i_unloadExplicitLock(!unload), i_unloadReferenceLock(false) {} const TimeTracker& getTimeTracker() const { return i_timer; } - bool getUnloadFlag() const { return i_unloadflag; } - void setUnloadFlag( bool pFlag) { i_unloadflag = pFlag; } + bool getUnloadLock() const { return i_unloadActiveLockCount || i_unloadExplicitLock || i_unloadReferenceLock; } + void setUnloadExplicitLock( bool on ) { i_unloadExplicitLock = on; } + void setUnloadReferenceLock( bool on ) { i_unloadReferenceLock = on; } + void incUnloadActiveLock() { ++i_unloadActiveLockCount; } + void decUnloadActiveLock() { if(i_unloadActiveLockCount) --i_unloadActiveLockCount; } + void setTimer(const TimeTracker& pTimer) { i_timer = pTimer; } void ResetTimeTracker(time_t interval) { i_timer.Reset(interval); } void UpdateTimeTracker(time_t diff) { i_timer.Update(diff); } private: TimeTracker i_timer; - bool i_unloadflag; + uint16 i_unloadActiveLockCount : 16; // lock from active object spawn points (prevent clone loading) + bool i_unloadExplicitLock : 1; // explicit manual lock or config setting + bool i_unloadReferenceLock : 1; // lock from instance map copy }; typedef enum @@ -92,8 +100,11 @@ class TRINITY_DLL_DECL NGrid GridInfo* getGridInfoRef() { return &i_GridInfo; } const TimeTracker& getTimeTracker() const { return i_GridInfo.getTimeTracker(); } - bool getUnloadFlag() const { return i_GridInfo.getUnloadFlag(); } - void setUnloadFlag( bool pFlag) { i_GridInfo.setUnloadFlag(pFlag); } + bool getUnloadLock() const { return i_GridInfo.getUnloadLock(); } + void setUnloadExplicitLock( bool on ) { i_GridInfo.setUnloadExplicitLock(on); } + void setUnloadReferenceLock( bool on ) { i_GridInfo.setUnloadReferenceLock(on); } + void incUnloadActiveLock() { i_GridInfo.incUnloadActiveLock(); } + void decUnloadActiveLock() { i_GridInfo.decUnloadActiveLock(); } void ResetTimeTracker(time_t interval) { i_GridInfo.ResetTimeTracker(interval); } void UpdateTimeTracker(time_t diff) { i_GridInfo.UpdateTimeTracker(diff); } diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 5c6c7e0566b..bc8105abcc1 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1657,7 +1657,8 @@ void Creature::setDeathState(DeathState s) { SetUInt64Value (UNIT_FIELD_TARGET,0); // remove target selection in any cases (can be set at aura remove in Unit::setDeathState) SetUInt32Value(UNIT_NPC_FLAGS, 0); - setActive(false); + //if(!isPet()) + setActive(false); if(!isPet() && GetCreatureInfo()->SkinLootId) if ( LootTemplates_Skinning.HaveLootFor(GetCreatureInfo()->SkinLootId) ) @@ -1670,8 +1671,8 @@ void Creature::setDeathState(DeathState s) } if(s == JUST_ALIVED) { - if(isPet()) - setActive(true); + //if(isPet()) + // setActive(true); SetHealth(GetMaxHealth()); SetLootRecipient(NULL); Unit::setDeathState(ALIVE); diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp index ddc04d382de..d14b213d9fa 100644 --- a/src/game/DynamicObject.cpp +++ b/src/game/DynamicObject.cpp @@ -53,17 +53,7 @@ void DynamicObject::AddToWorld() void DynamicObject::RemoveFromWorld() { ///- Remove the dynamicObject from the accessor - if(IsInWorld()) - { - // Make sure the object is back to grid container for removal as farsight targets - // are switched to world container on creation and they are also set to active - if (isActive()) - { - GetMap()->SwitchGridContainers(this, false); - setActive(false); - } - ObjectAccessor::Instance().RemoveObject(this); - } + if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); WorldObject::RemoveFromWorld(); } diff --git a/src/game/GridStates.cpp b/src/game/GridStates.cpp index cedec1de60f..92054e5948a 100644 --- a/src/game/GridStates.cpp +++ b/src/game/GridStates.cpp @@ -60,14 +60,14 @@ IdleState::Update(Map &m, NGridType &grid, GridInfo &, const uint32 &x, const ui void RemovalState::Update(Map &m, NGridType &grid, GridInfo &info, const uint32 &x, const uint32 &y, const uint32 &t_diff) const { - if(info.getUnloadFlag()) + if(!info.getUnloadLock()) { info.UpdateTimeTracker(t_diff); if( info.getTimeTracker().Passed() ) { if( !m.UnloadGrid(x, y, false) ) { - sLog.outDebug("Grid[%u,%u] for map %u differed unloading due to players nearby", x, y, m.GetId()); + sLog.outDebug("Grid[%u,%u] for map %u differed unloading due to players or active objects nearby", x, y, m.GetId()); m.ResetGridExpiry(grid); } } diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 9cd5105a9e5..493e5b4b112 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -51,7 +51,7 @@ GridState* si_GridStates[MAX_GRID_STATE]; Map::~Map() { - UnloadAll(true); + UnloadAll(); } bool Map::ExistMap(uint32 mapid,int x,int y) @@ -140,7 +140,6 @@ void Map::LoadMap(uint32 mapid, uint32 instanceid, int x,int y) // return; ((MapInstanced*)(baseMap))->AddGridMapReference(GridPair(x,y)); - baseMap->SetUnloadFlag(GridPair(63-x,63-y), false); GridMaps[x][y] = baseMap->GridMaps[x][y]; return; } @@ -210,9 +209,10 @@ void Map::DeleteStateMachine() } Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode) - : i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), - i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0), i_gridExpiry(expiry) - , i_lock(false) + : i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), + i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0), i_gridExpiry(expiry), + m_activeNonPlayersIter(m_activeNonPlayers.end()) + , i_lock(false) { for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx) { @@ -269,6 +269,15 @@ void Map::AddToGrid(Creature* obj, NGridType *grid, Cell const& cell) obj->SetCurrentCell(cell); } +template<> +void Map::AddToGrid(DynamicObject* obj, NGridType *grid, Cell const& cell) +{ + if(obj->isActiveObject()) // only farsight + (*grid)(cell.CellX(), cell.CellY()).AddWorldObject<DynamicObject>(obj, obj->GetGUID()); + else + (*grid)(cell.CellX(), cell.CellY()).AddGridObject<DynamicObject>(obj, obj->GetGUID()); +} + template<class T> void Map::RemoveFromGrid(T* obj, NGridType *grid, Cell const& cell) { @@ -311,28 +320,37 @@ void Map::RemoveFromGrid(Creature* obj, NGridType *grid, Cell const& cell) } } +template<> +void Map::RemoveFromGrid(DynamicObject* obj, NGridType *grid, Cell const& cell) +{ + if(obj->isActiveObject()) // only farsight + (*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject<DynamicObject>(obj, obj->GetGUID()); + else + (*grid)(cell.CellX(), cell.CellY()).RemoveGridObject<DynamicObject>(obj, obj->GetGUID()); +} + template<class T> -void Map::SwitchGridContainers(T* obj, bool apply) +void Map::SwitchGridContainers(T* obj, bool on) { CellPair pair = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); Cell cell(pair); NGridType *ngrid = getNGrid(cell.GridX(), cell.GridY()); GridType &grid = (*ngrid)(cell.CellX(), cell.CellY()); - if(apply) + if(on) { - assert(!grid.GetWorldObject(obj->GetGUID(), obj)); + if(!grid.RemoveGridObject<T>(obj, obj->GetGUID()) + || !grid.AddWorldObject<T>(obj, obj->GetGUID())) { - grid.RemoveGridObject<T>(obj, obj->GetGUID()); - grid.AddWorldObject<T>(obj, obj->GetGUID()); + assert(false); } } else { - assert(!grid.GetGridObject(obj->GetGUID(), obj)); + if(!grid.RemoveWorldObject<T>(obj, obj->GetGUID()) + || !grid.AddGridObject<T>(obj, obj->GetGUID())) { - grid.RemoveWorldObject<T>(obj, obj->GetGUID()); - grid.AddGridObject<T>(obj, obj->GetGUID()); + assert(false); } } } @@ -391,22 +409,22 @@ Map::EnsureGridCreated(const GridPair &p) } void -Map::EnsureGridLoadedForPlayer(const Cell &cell, Player *player, bool add_player) +Map::EnsureGridLoaded(const Cell &cell, Player *player) { EnsureGridCreated(GridPair(cell.GridX(), cell.GridY())); NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); assert(grid != NULL); - if( !isGridObjectDataLoaded(cell.GridX(), cell.GridY()) ) + if (!isGridObjectDataLoaded(cell.GridX(), cell.GridY())) { - if( player != NULL ) + if (player) { player->SendDelayResponse(MAX_GRID_LOAD_TIME); DEBUG_LOG("Player %s enter cell[%u,%u] triggers of loading grid[%u,%u] on map %u", player->GetName(), cell.CellX(), cell.CellY(), cell.GridX(), cell.GridY(), i_id); } else { - DEBUG_LOG("Player nearby triggers of loading grid [%u,%u] on map %u", cell.GridX(), cell.GridY(), i_id); + DEBUG_LOG("Active object nearby triggers of loading grid [%u,%u] on map %u", cell.GridX(), cell.GridY(), i_id); } ObjectGridLoader loader(*grid, this, cell); @@ -418,11 +436,9 @@ Map::EnsureGridLoadedForPlayer(const Cell &cell, Player *player, bool add_player ResetGridExpiry(*getNGrid(cell.GridX(), cell.GridY()), 0.1f); grid->SetGridState(GRID_STATE_ACTIVE); - - if( add_player && player != NULL ) - (*grid)(cell.CellX(), cell.CellY()).AddWorldObject(player, player->GetGUID()); } - else if( player && add_player ) + + if(player) AddToGrid(player,grid,cell); } @@ -430,7 +446,7 @@ void Map::LoadGrid(float x, float y) { CellPair pair = Trinity::ComputeCellPair(x, y); Cell cell(pair); - EnsureGridLoadedForPlayer(cell, NULL, false); + EnsureGridLoaded(cell); } bool Map::Add(Player *player) @@ -442,7 +458,7 @@ bool Map::Add(Player *player) // update player state for other player and visa-versa CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); Cell cell(p); - EnsureGridLoadedForPlayer(cell, player, true); + EnsureGridLoaded(cell, player); player->AddToWorld(); SendInitSelf(player); @@ -468,14 +484,19 @@ Map::Add(T *obj) } Cell cell(p); - EnsureGridCreated(GridPair(cell.GridX(), cell.GridY())); + if(obj->isActiveObject()) + EnsureGridLoaded(cell); + else + EnsureGridCreated(GridPair(cell.GridX(), cell.GridY())); + NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); assert( grid != NULL ); AddToGrid(obj,grid,cell); obj->AddToWorld(); - if(obj->isActive()) - AddActiveObject(obj); + + if(obj->isActiveObject()) + AddToActive(obj); DEBUG_LOG("Object %u enters grid[%u,%u]", GUID_LOPART(obj->GetGUID()), cell.GridX(), cell.GridY()); @@ -646,29 +667,22 @@ void Map::Update(const uint32 &t_diff) { resetMarkedCells(); - //TODO: is there a better way to update activeobjects? - std::vector<WorldObject*> activeObjects; - for(MapRefManager::iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter) - { - Player* plr = iter->getSource(); - if(plr->IsInWorld()) - activeObjects.push_back(plr); - } - for(std::set<WorldObject *>::iterator iter = i_activeObjects.begin(); iter != i_activeObjects.end(); ++iter) - { - if((*iter)->IsInWorld()) - activeObjects.push_back(*iter); - } - Trinity::ObjectUpdater updater(t_diff); // for creature TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer > grid_object_update(updater); // for pets TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater); - for(std::vector<WorldObject*>::iterator iter = activeObjects.begin(); iter != activeObjects.end(); ++iter) + // the player iterator is stored in the map object + // to make sure calls to Map::Remove don't invalidate it + for(m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter) { - CellPair standing_cell(Trinity::ComputeCellPair((*iter)->GetPositionX(), (*iter)->GetPositionY())); + Player* plr = m_mapRefIter->getSource(); + + if(!plr->IsInWorld()) + continue; + + CellPair standing_cell(Trinity::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY())); // Check for correctness of standing_cell, it also avoids problems with update_cell if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) @@ -700,8 +714,56 @@ void Map::Update(const uint32 &t_diff) } } } + } + + // non-player active objects + if(!m_activeNonPlayers.empty()) + { + for(m_activeNonPlayersIter = m_activeNonPlayers.begin(); m_activeNonPlayersIter != m_activeNonPlayers.end(); ) + { + // skip not in world + WorldObject* obj = *m_activeNonPlayersIter; + + // step before processing, in this case if Map::Remove remove next object we correctly + // step to next-next, and if we step to end() then newly added objects can wait next update. + ++m_activeNonPlayersIter; + + if(!obj->IsInWorld()) + continue; + + CellPair standing_cell(Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY())); + + // Check for correctness of standing_cell, it also avoids problems with update_cell + if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) + continue; + + // the overloaded operators handle range checking + // so ther's no need for range checking inside the loop + CellPair begin_cell(standing_cell), end_cell(standing_cell); + begin_cell << 1; begin_cell -= 1; // upper left + end_cell >> 1; end_cell += 1; // lower right - // UpdateActiveCells((*iter)->GetPositionX(), (*iter)->GetPositionY(), t_diff); + for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x) + { + for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; ++y) + { + // marked cells are those that have been visited + // don't visit the same cell twice + uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x; + if(!isCellMarked(cell_id)) + { + markCell(cell_id); + CellPair pair(x,y); + Cell cell(pair); + cell.data.Part.reserved = CENTER_DISTRICT; + //cell.SetNoCreate(); + CellLock<NullGuard> cell_lock(cell, pair); + cell_lock->Visit(cell_lock, grid_object_update, *this); + cell_lock->Visit(cell_lock, world_object_update, *this); + } + } + } + } } RelocationNotify(); @@ -801,8 +863,8 @@ Map::Remove(T *obj, bool remove) assert( grid != NULL ); obj->RemoveFromWorld(); - if(obj->isActive()) - RemoveActiveObject(obj); + if(obj->isActiveObject()) + RemoveFromActive(obj); RemoveFromGrid(obj,grid,cell); UpdateObjectVisibility(obj,cell,p); @@ -844,7 +906,7 @@ Map::PlayerRelocation(Player *player, float x, float y, float z, float orientati if( !old_cell.DiffGrid(new_cell) ) AddToGrid(player, oldGrid,new_cell); else - EnsureGridLoadedForPlayer(new_cell, player, true); + EnsureGridLoaded(new_cell, player); } AddUnitToNotify(player); @@ -876,13 +938,6 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang #endif AddCreatureToMoveList(creature,x,y,z,ang); // in diffcell/diffgrid case notifiers called at finishing move creature in Map::MoveAllCreaturesInMoveList - if(creature->isActive()) - { - if(creature->isPossessedByPlayer()) - EnsureGridLoadedForPlayer(new_cell, (Player*)creature->GetCharmer(), false); - else - EnsureGridLoadedForPlayer(new_cell, NULL, false); - } } else { @@ -955,6 +1010,7 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell) RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell); AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell); + c->SetCurrentCell(new_cell); } else { @@ -963,8 +1019,27 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell) sLog.outDebug("Creature (GUID: %u Entry: %u) move in same grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY()); #endif } + + return true; } - else // in diff. grids + + // in diff. grids but active creature + if(c->isActiveObject()) + { + EnsureGridLoaded(new_cell); + + #ifdef TRINITY_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0) + sLog.outDebug("Active creature (GUID: %u Entry: %u) moved from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->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 + + RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell); + AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell); + + return true; + } + + // in diff. loaded grid normal creature if(loaded(GridPair(new_cell.GridX(), new_cell.GridY()))) { #ifdef TRINITY_DEBUG @@ -977,17 +1052,16 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell) EnsureGridCreated(GridPair(new_cell.GridX(), new_cell.GridY())); AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell); } - } - else - { - #ifdef TRINITY_DEBUG - if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0) - sLog.outDebug("Creature (GUID: %u Entry: %u) attempt move from grid[%u,%u]cell[%u,%u] to unloaded grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->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 - return false; + + return true; } - return true; + // fail to move: normal creature attempt move to unloaded grid + #ifdef TRINITY_DEBUG + if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0) + sLog.outDebug("Creature (GUID: %u Entry: %u) attempt move from grid[%u,%u]cell[%u,%u] to unloaded grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->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 + return false; } bool Map::CreatureRespawnRelocation(Creature *c) @@ -1019,30 +1093,38 @@ bool Map::CreatureRespawnRelocation(Creature *c) return false; } -bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce) +bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool unloadAll) { NGridType *grid = getNGrid(x, y); assert( grid != NULL); { - if(!pForce && PlayersNearGrid(x, y) ) - return false; + if(!unloadAll && ActiveObjectsNearGrid(x, y) ) + return false; 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 - // Must know real mob position before move - DoDelayedMovesAndRemoves(); + if(!unloadAll) + { + // Finish creature moves, remove and delete all creatures with delayed remove before moving to respawn grids + // Must know real mob position before move + DoDelayedMovesAndRemoves(); - // move creatures to respawn grids if this is diff.grid or to remove list - unloader.MoveToRespawnN(); + // 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 creature moves, remove and delete all creatures with delayed remove before unload + DoDelayedMovesAndRemoves(); + } + else + RemoveAllObjectsInRemoveList(); + //assert(grid.NoWorldObjectInGrid()); unloader.UnloadN(); - delete getNGrid(x, y); + //assert(grid.NoWorldObjectInGrid()); + //assert(grid.NoGridObjectInGrid()); + delete grid; setNGrid(NULL, x, y); } int gx=63-x; @@ -1065,7 +1147,7 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce) return true; } -void Map::UnloadAll(bool pForce) +void Map::UnloadAll() { // clear all delayed moves, useless anyway do this moves before map unload. i_creaturesToMove.clear(); @@ -1074,7 +1156,7 @@ void Map::UnloadAll(bool pForce) { NGridType &grid(*i->getSource()); ++i; - UnloadGrid(grid.getX(), grid.getY(), pForce); // deletes the grid and removes it from the GridRefManager + UnloadGrid(grid.getX(), grid.getY(), true); // deletes the grid and removes it from the GridRefManager } } @@ -1523,10 +1605,36 @@ void Map::AddObjectToRemoveList(WorldObject *obj) //sLog.outDebug("Object (GUID: %u TypeId: %u ) added to removing list.",obj->GetGUIDLow(),obj->GetTypeId()); } +void Map::AddObjectToSwitchList(WorldObject *obj, bool on) +{ + assert(obj->GetMapId()==GetId() && obj->GetInstanceId()==GetInstanceId()); + + std::map<WorldObject*, bool>::iterator itr = i_objectsToSwitch.find(obj); + if(itr == i_objectsToSwitch.end()) + i_objectsToSwitch.insert(itr, std::make_pair(obj, on)); + else if(itr->second != on) + i_objectsToSwitch.erase(itr); + else + assert(false); +} + void Map::RemoveAllObjectsInRemoveList() { - if(i_objectsToRemove.empty()) - return; + while(!i_objectsToSwitch.empty()) + { + std::map<WorldObject*, bool>::iterator itr = i_objectsToSwitch.begin(); + WorldObject *obj = itr->first; + bool on = itr->second; + i_objectsToSwitch.erase(itr); + + switch(obj->GetTypeId()) + { + case TYPEID_UNIT: + if(!((Creature*)obj)->isPet() && !((Creature*)obj)->isVehicle()) + SwitchGridContainers((Creature*)obj, on); + break; + } + } //sLog.outDebug("Object remover 1 check."); while(!i_objectsToRemove.empty()) @@ -1580,7 +1688,7 @@ void Map::SendToPlayers(WorldPacket const* data) const itr->getSource()->GetSession()->SendPacket(data); } -bool Map::PlayersNearGrid(uint32 x, uint32 y) const +bool Map::ActiveObjectsNearGrid(uint32 x, uint32 y) const { CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS); CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS); @@ -1599,37 +1707,59 @@ bool Map::PlayersNearGrid(uint32 x, uint32 y) const return true; } - return false; -} - -bool Map::ActiveObjectsNearGrid(uint32 x, uint32 y) const -{ - CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS); - CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS); - cell_min << 2; - cell_min -= 2; - cell_max >> 2; - cell_max += 2; - - for(MapRefManager::const_iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter) + for(ActiveNonPlayers::const_iterator iter = m_activeNonPlayers.begin(); iter != m_activeNonPlayers.end(); ++iter) { - Player* plr = iter->getSource(); + WorldObject* obj = *iter; - CellPair p = Trinity::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY()); + CellPair p = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) && (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) ) return true; } - for(std::set<WorldObject*>::const_iterator itr = i_activeObjects.begin(); itr != i_activeObjects.end(); ++itr) + return false; +} + +void Map::AddToActive( Creature* c ) +{ + AddToActiveHelper(c); + + // also not allow unloading spawn grid to prevent creating creature clone at load + if(c->GetDBTableGUIDLow()) { - CellPair p = Trinity::ComputeCellPair((*itr)->GetPositionX(), (*itr)->GetPositionY()); - if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) && - (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) ) - return true; + float x,y,z; + c->GetRespawnCoord(x,y,z); + GridPair p = Trinity::ComputeGridPair(x, y); + if(getNGrid(p.x_coord, p.y_coord)) + getNGrid(p.x_coord, p.y_coord)->incUnloadActiveLock(); + else + { + GridPair p2 = Trinity::ComputeGridPair(c->GetPositionX(), c->GetPositionY()); + sLog.outError("Active creature (GUID: %u Entry: %u) added to grid[%u,%u] but spawn grid[%u,%u] not loaded.", + c->GetGUIDLow(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord); + } } +} - return false; +void Map::RemoveFromActive( Creature* c ) +{ + RemoveFromActiveHelper(c); + + // also allow unloading spawn grid + if(c->GetDBTableGUIDLow()) + { + float x,y,z; + c->GetRespawnCoord(x,y,z); + GridPair p = Trinity::ComputeGridPair(x, y); + if(getNGrid(p.x_coord, p.y_coord)) + getNGrid(p.x_coord, p.y_coord)->decUnloadActiveLock(); + else + { + GridPair p2 = Trinity::ComputeGridPair(c->GetPositionX(), c->GetPositionY()); + sLog.outError("Active creature (GUID: %u Entry: %u) removed from grid[%u,%u] but spawn grid[%u,%u] not loaded.", + c->GetGUIDLow(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord); + } + } } template void Map::Add(Corpse *); @@ -1952,7 +2082,7 @@ time_t InstanceMap::GetResetTime() return save ? save->GetDifficulty() : DIFFICULTY_NORMAL; } -void InstanceMap::UnloadAll(bool pForce) +void InstanceMap::UnloadAll() { if(HavePlayers()) { @@ -1967,7 +2097,7 @@ void InstanceMap::UnloadAll(bool pForce) if(m_resetAfterUnload == true) objmgr.DeleteRespawnTimeForInstance(GetInstanceId()); - Map::UnloadAll(pForce); + Map::UnloadAll(); } void InstanceMap::SendResetWarnings(uint32 timeLeft) const @@ -2048,7 +2178,7 @@ void BattleGroundMap::SetUnload() m_unloadTimer = MIN_UNLOAD_DELAY; } -void BattleGroundMap::UnloadAll(bool pForce) +void BattleGroundMap::UnloadAll() { while(HavePlayers()) { @@ -2062,7 +2192,7 @@ void BattleGroundMap::UnloadAll(bool pForce) } } - Map::UnloadAll(pForce); + Map::UnloadAll(); } /*--------------------------TRINITY-------------------------*/ diff --git a/src/game/Map.h b/src/game/Map.h index 2b6fcfe6900..731b5a76fcc 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -166,11 +166,11 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O return( !getNGrid(p.x_coord, p.y_coord) || getNGrid(p.x_coord, p.y_coord)->GetGridState() == GRID_STATE_REMOVAL ); } - bool GetUnloadFlag(const GridPair &p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadFlag(); } - void SetUnloadFlag(const GridPair &p, bool unload) { getNGrid(p.x_coord, p.y_coord)->setUnloadFlag(unload); } + bool GetUnloadLock(const GridPair &p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadLock(); } + void SetUnloadLock(const GridPair &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadExplicitLock(on); } void LoadGrid(float x, float y); bool UnloadGrid(const uint32 &x, const uint32 &y, bool pForce); - virtual void UnloadAll(bool pForce); + virtual void UnloadAll(); void ResetGridExpiry(NGridType &grid, float factor = 1) const { @@ -245,6 +245,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O } void AddObjectToRemoveList(WorldObject *obj); + void AddObjectToSwitchList(WorldObject *obj, bool on); void DoDelayedMovesAndRemoves(); virtual bool RemoveBones(uint64 guid, float x, float y); @@ -259,11 +260,8 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O bool HavePlayers() const { return !m_mapRefManager.isEmpty(); } uint32 GetPlayersCountExceptGMs() const; - bool PlayersNearGrid(uint32 x,uint32 y) const; bool ActiveObjectsNearGrid(uint32 x, uint32 y) const; - void AddActiveObject(WorldObject* obj) { i_activeObjects.insert(obj); } - void RemoveActiveObject(WorldObject* obj) { i_activeObjects.erase(obj); } void AddUnitToNotify(Unit* unit); void RelocationNotify(); @@ -271,6 +269,19 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O typedef MapRefManager PlayerList; PlayerList const& GetPlayers() const { return m_mapRefManager; } + + // must called with AddToWorld + template<class T> + void AddToActive(T* obj) { AddToActiveHelper(obj); } + + void AddToActive(Creature* obj); + + // must called with RemoveFromWorld + template<class T> + void RemoveFromActive(T* obj) { RemoveFromActiveHelper(obj); } + + void RemoveFromActive(Creature* obj); + template<class T> void SwitchGridContainers(T* obj, bool active); template<class NOTIFIER> void VisitAll(const float &x, const float &y, float radius, NOTIFIER ¬ifier); template<class NOTIFIER> void VisitWorld(const float &x, const float &y, float radius, NOTIFIER ¬ifier); @@ -293,7 +304,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O CreatureMoveList i_creaturesToMove; bool loaded(const GridPair &) const; - void EnsureGridLoadedForPlayer(const Cell&, Player*, bool add_player); + void EnsureGridLoaded(const Cell&, Player* player = NULL); void EnsureGridCreated(const GridPair &); void buildNGridLinkage(NGridType* pNGridType) { pNGridType->link(this); } @@ -313,6 +324,8 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O void UpdateActiveCells(const float &x, const float &y, const uint32 &t_diff); protected: + void SetUnloadReferenceLock(const GridPair &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); } + typedef Trinity::ObjectLevelLockable<Map, ZThread::Mutex>::Lock Guard; MapEntry const* i_mapEntry; @@ -323,6 +336,10 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O MapRefManager m_mapRefManager; MapRefManager::iterator m_mapRefIter; + + typedef std::set<WorldObject*> ActiveNonPlayers; + ActiveNonPlayers m_activeNonPlayers; + ActiveNonPlayers::iterator m_activeNonPlayersIter; private: typedef GridReadGuard ReadGuard; typedef GridWriteGuard WriteGuard; @@ -334,9 +351,9 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O time_t i_gridExpiry; bool i_lock; - std::set<WorldObject *> i_activeObjects; std::vector<uint64> i_unitsToNotify; std::set<WorldObject *> i_objectsToRemove; + std::map<WorldObject*, bool> i_objectsToSwitch; // Type specific code for add/remove to/from grid template<class T> @@ -350,6 +367,27 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O template<class T> void DeleteFromWorld(T*); + + template<class T> + void AddToActiveHelper(T* obj) + { + m_activeNonPlayers.insert(obj); + } + + template<class T> + void RemoveFromActiveHelper(T* obj) + { + // Map::Update for active object in proccess + if(m_activeNonPlayersIter != m_activeNonPlayers.end()) + { + ActiveNonPlayers::iterator itr = m_activeNonPlayers.find(obj); + if(itr==m_activeNonPlayersIter) + ++m_activeNonPlayersIter; + m_activeNonPlayers.erase(itr); + } + else + m_activeNonPlayers.erase(obj); + } }; enum InstanceResetMethod @@ -376,7 +414,7 @@ class TRINITY_DLL_SPEC InstanceMap : public Map InstanceData* GetInstanceData() { return i_data; } void PermBindAllPlayers(Player *player); time_t GetResetTime(); - void UnloadAll(bool pForce); + void UnloadAll(); bool CanEnter(Player* player); void SendResetWarnings(uint32 timeLeft) const; void SetResetSchedule(bool on); @@ -398,7 +436,7 @@ class TRINITY_DLL_SPEC BattleGroundMap : public Map void Remove(Player *, bool); bool CanEnter(Player* player); void SetUnload(); - void UnloadAll(bool pForce); + void UnloadAll(); }; /*inline @@ -422,7 +460,7 @@ Map::Visit(const CellLock<LOCK_TYPE> &cell, TypeContainerVisitor<T, CONTAINER> & if( !cell->NoCreate() || loaded(GridPair(x,y)) ) { - EnsureGridLoadedForPlayer(cell, NULL, false); + EnsureGridLoaded(cell); //LOCK_TYPE guard(i_info[x][y]->i_lock); getNGrid(x, y)->Visit(cell_x, cell_y, visitor); } diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp index 116d26f4975..99d677afffa 100644 --- a/src/game/MapInstanced.cpp +++ b/src/game/MapInstanced.cpp @@ -89,11 +89,11 @@ bool MapInstanced::RemoveBones(uint64 guid, float x, float y) return remove_result || Map::RemoveBones(guid,x,y); } -void MapInstanced::UnloadAll(bool pForce) +void MapInstanced::UnloadAll() { // Unload instanced maps for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i) - i->second->UnloadAll(pForce); + i->second->UnloadAll(); // Delete the maps only after everything is unloaded to prevent crashes for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i) @@ -102,7 +102,7 @@ void MapInstanced::UnloadAll(bool pForce) m_InstancedMaps.clear(); // Unload own grids (just dummy(placeholder) grids, neccesary to unload GridMaps!) - Map::UnloadAll(pForce); + Map::UnloadAll(); } /* @@ -259,14 +259,14 @@ void MapInstanced::DestroyInstance(uint32 InstanceId) // increments the iterator after erase void MapInstanced::DestroyInstance(InstancedMaps::iterator &itr) { - itr->second->UnloadAll(true); + itr->second->UnloadAll(); // should only unload VMaps if this is the last instance and grid unloading is enabled if(m_InstancedMaps.size() <= 1 && sWorld.getConfig(CONFIG_GRID_UNLOAD)) { VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(itr->second->GetId()); // in that case, unload grids of the base map, too // so in the next map creation, (EnsureGridCreated actually) VMaps will be reloaded - Map::UnloadAll(true); + Map::UnloadAll(); } // erase map delete itr->second; diff --git a/src/game/MapInstanced.h b/src/game/MapInstanced.h index 11c08d4517a..391e99f9632 100644 --- a/src/game/MapInstanced.h +++ b/src/game/MapInstanced.h @@ -38,18 +38,25 @@ class TRINITY_DLL_DECL MapInstanced : public Map void MoveAllCreaturesInMoveList(); void RemoveAllObjectsInRemoveList(); bool RemoveBones(uint64 guid, float x, float y); - void UnloadAll(bool pForce); + void UnloadAll(); bool CanEnter(Player* player); Map* GetInstance(const WorldObject* obj); Map* FindMap(uint32 InstanceId) { return _FindMap(InstanceId); } void DestroyInstance(uint32 InstanceId); void DestroyInstance(InstancedMaps::iterator &itr); - void AddGridMapReference(const GridPair &p) { ++GridMapReference[p.x_coord][p.y_coord]; } + + void AddGridMapReference(const GridPair &p) + { + ++GridMapReference[p.x_coord][p.y_coord]; + SetUnloadReferenceLock(GridPair(63-p.x_coord, 63-p.y_coord), true); + } + void RemoveGridMapReference(const GridPair &p) { --GridMapReference[p.x_coord][p.y_coord]; - if (!GridMapReference[p.x_coord][p.y_coord]) { SetUnloadFlag(GridPair(63-p.x_coord,63-p.y_coord), true); } + if (!GridMapReference[p.x_coord][p.y_coord]) + SetUnloadReferenceLock(GridPair(63-p.x_coord, 63-p.y_coord), false); } InstancedMaps &GetInstancedMaps() { return m_InstancedMaps; } diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index fd1f7963593..df8521be7d0 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -301,7 +301,7 @@ bool MapManager::IsValidMAP(uint32 mapid) void MapManager::UnloadAll() { for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter) - iter->second->UnloadAll(true); + iter->second->UnloadAll(); while(!i_maps.empty()) { diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 272de775195..080a6af41de 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1103,19 +1103,42 @@ WorldObject::WorldObject() m_isActive = false; } -void WorldObject::setActive(bool isActive) +void WorldObject::SetWorldObject(bool on) { - // if already in the same activity state as we try to set, do nothing - if(isActive == m_isActive || isType(TYPEMASK_PLAYER)) + if(!IsInWorld()) + return; + + GetMap()->AddObjectToSwitchList(this, on); +} + +void WorldObject::setActive( bool on ) +{ + if(m_isActive==on) + return; + + if(GetTypeId() == TYPEID_PLAYER) return; - m_isActive = isActive; - if(IsInWorld()) + bool world = IsInWorld(); + + Map* map; + if(world) { - if(isActive) - GetMap()->AddActiveObject(this); - else - GetMap()->RemoveActiveObject(this); + map = GetMap(); + if(GetTypeId() == TYPEID_UNIT) + map->RemoveFromActive((Creature*)this); + else if(GetTypeId() == TYPEID_DYNAMICOBJECT) + map->RemoveFromActive((DynamicObject*)this); + } + + m_isActive = on; + + if(world) + { + if(GetTypeId() == TYPEID_UNIT) + map->AddToActive((Creature*)this); + else if(GetTypeId() == TYPEID_DYNAMICOBJECT) + map->AddToActive((DynamicObject*)this); } } @@ -1540,7 +1563,7 @@ Map const* WorldObject::GetBaseMap() const void WorldObject::AddObjectToRemoveList() { - Map* map = GetMap(); + Map* map = MapManager::Instance().FindMap(GetMapId(), GetInstanceId()); if(!map) { sLog.outError("Object (TypeId: %u Entry: %u GUID: %u) at attempt add to move list not have valid map (Id: %u).",GetTypeId(),GetEntry(),GetGUIDLow(),GetMapId()); diff --git a/src/game/Object.h b/src/game/Object.h index 266442775b5..bf88c4dd2dc 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -500,8 +500,9 @@ class TRINITY_DLL_SPEC WorldObject : public Object Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime); GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime); Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = NULL); - bool isActive() const { return m_isActive; } - void setActive(bool isActive); + bool isActiveObject() const { return m_isActive; } + void setActive(bool isActiveObject); + void SetWorldObject(bool apply); template<class NOTIFIER> void VisitNearbyObject(const float &radius, NOTIFIER ¬ifier) const { GetMap()->VisitAll(GetPositionX(), GetPositionY(), radius, notifier); } template<class NOTIFIER> void VisitNearbyGridObject(const float &radius, NOTIFIER ¬ifier) const { GetMap()->VisitGrid(GetPositionX(), GetPositionY(), radius, notifier); } template<class NOTIFIER> void VisitNearbyWorldObject(const float &radius, NOTIFIER ¬ifier) const { GetMap()->VisitWorld(GetPositionX(), GetPositionY(), radius, notifier); } diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp index 56334d1c53d..38083d02306 100644 --- a/src/game/ObjectGridLoader.cpp +++ b/src/game/ObjectGridLoader.cpp @@ -127,6 +127,9 @@ void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> & addUnitState(obj,cell); obj->AddToWorld(); + if(obj->isActiveObject()) + map->AddToActive(obj); + ++count; } @@ -152,6 +155,9 @@ void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType addUnitState(obj,cell); obj->AddToWorld(); + if(obj->isActiveObject()) + map->AddToActive(obj); + ++count; } } diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index ff2c8880852..b4b8bae9c67 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -58,7 +58,7 @@ m_declinedname(NULL) else if(type == GUARDIAN_PET) // always aggressive charmInfo->SetReactState(REACT_AGGRESSIVE); - m_isActive = true; + //m_isActive = true; } Pet::~Pet() diff --git a/src/game/Player.cpp b/src/game/Player.cpp index bc0c5c59bfa..fb5fcb3f089 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -18295,7 +18295,7 @@ bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool { // Units far than max visible distance for creature or not in our map are not visible too if (!target->IsWithinDistInMap(u - , u->isActive() ? (MAX_VISIBILITY_DISTANCE - (inVisibleList ? 0.0f : World::GetVisibleUnitGreyDistance())) + , u->isActiveObject() ? (MAX_VISIBILITY_DISTANCE - (inVisibleList ? 0.0f : World::GetVisibleUnitGreyDistance())) : (World::GetMaxVisibleDistanceForCreature() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)) , is3dDistance)) return false; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 9d9fdc70305..be224438257 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1106,7 +1106,10 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) // assisting case, healing and resurrection if(unit->hasUnitState(UNIT_STAT_ATTACK_PLAYER)) + { m_caster->SetContestedPvP(); + //m_caster->UpdatePvP(true); + } if( unit->isInCombat() && !(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NO_INITIAL_AGGRO) ) { m_caster->SetInCombatState(unit->GetCombatTimer() > 0); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 469f3f45357..468e79cb510 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3591,11 +3591,8 @@ void Spell::EffectAddFarsight(uint32 i) dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x80000002); m_caster->AddDynObject(dynObj); - Map* map = dynObj->GetMap(); - map->LoadGrid(dynObj->GetPositionX(), dynObj->GetPositionY()); // In case the spell is casted into a different grid by player - map->Add(dynObj); - map->SwitchGridContainers(dynObj, true); // Needed for forwarding player packets - dynObj->setActive(true); // Keep the grid updated even if there are no players in it + dynObj->setActive(true); //must before add to map to be put in world container + dynObj->GetMap()->Add(dynObj); //grid will also be loaded // Need to update visibility of object for client to accept farsight guid ((Player*)m_caster)->UpdateVisibilityOf(dynObj); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 52d858f8542..dbffb58c481 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -396,7 +396,7 @@ void Unit::SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end) data << getMSTime(); data << uint8( 0 ); - data << uint32(((GetUnitMovementFlags() & MOVEMENTFLAG_LEVITATING) || isInFlight())? MOVEFLAG_FLY : MOVEFLAG_WALK); + data << uint32(((GetUnitMovementFlags() & MOVEMENTFLAG_LEVITATING) || isInFlight())? (MOVEFLAG_FLY|MOVEFLAG_WALK) : MOVEFLAG_WALK); data << uint32( traveltime ); data << uint32( pathSize ); data.append( (char*)path.GetNodes(start), pathSize * 4 * 3 ); @@ -4922,7 +4922,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu // 41409 Dementia: Every 5 seconds either gives you -5% damage/healing. (Druid, Shaman, Priest, Warlock, Mage, Paladin) case 39446: { - if(GetTypeId() != TYPEID_PLAYER) + if(GetTypeId() != TYPEID_PLAYER || !this->isAlive()) return false; // Select class defined buff @@ -7765,25 +7765,19 @@ Unit* Unit::GetNextRandomRaidMemberOrPet(float radius) void Unit::AddPlayerToVision(Player* plr) { - if (m_sharedVision.empty() && GetTypeId() == TYPEID_UNIT - && !((Creature*)this)->isPet() && !((Creature*)this)->isVehicle()) - { - setActive(true); - GetMap()->SwitchGridContainers((Creature*)this, true); - } + setActive(true); + if(m_sharedVision.empty()) + SetWorldObject(true); m_sharedVision.push_back(plr); plr->SetFarsightTarget(this); } void Unit::RemovePlayerFromVision(Player* plr) { + setActive(false); m_sharedVision.remove(plr); - if (m_sharedVision.empty() && GetTypeId() == TYPEID_UNIT - && !((Creature*)this)->isPet() && !((Creature*)this)->isVehicle()) - { - setActive(false); - GetMap()->SwitchGridContainers((Creature*)this, false); - } + if(m_sharedVision.empty()) + SetWorldObject(false); plr->ClearFarsight(); } diff --git a/src/game/Unit.h b/src/game/Unit.h index 8cf3171ba92..7bc2f5b53b3 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1206,7 +1206,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject return false; } bool isPossessing(Unit* u) const { return u->isPossessed() && GetCharmGUID() == u->GetGUID(); } - bool isPossessingCreature() const { return isPossessing() && IS_CREATURE_GUID(GetCharmGUID()); } CharmInfo* GetCharmInfo() { return m_charmInfo; } CharmInfo* InitCharmInfo(Unit* charm); |