*Fix some bugs of map/grid. Hope this can fix some crashes (without introducing new crash)

--HG--
branch : trunk
This commit is contained in:
megamage
2009-02-17 21:50:18 -06:00
parent d11c80ec54
commit be53cfe104
8 changed files with 31 additions and 202 deletions
+7 -13
View File
@@ -52,6 +52,13 @@ void DynamicObject::AddToWorld()
void DynamicObject::RemoveFromWorld()
{
// 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);
}
///- Remove the dynamicObject from the accessor
if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
WorldObject::RemoveFromWorld();
@@ -129,19 +136,6 @@ void DynamicObject::Update(uint32 p_time)
void DynamicObject::Delete()
{
// 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())
{
Map* map = GetMap();
if(!map)
{
sLog.outError("DynamicObject (TypeId: %u Entry: %u GUID: %u) at attempt add to move list not have valid map (Id: %u).",GetTypeId(),GetEntry(),GetGUIDLow(),GetMapId());
return;
}
map->SwitchGridContainers(this, false);
setActive(false);
}
SendObjectDeSpawnAnim(GetGUID());
AddObjectToRemoveList();
}
+14 -165
View File
@@ -257,17 +257,16 @@ template<>
void Map::AddToGrid(Creature* obj, NGridType *grid, Cell const& cell)
{
// add to world object registry in grid
if(obj->isPet() /*&& IS_PLAYER_GUID(obj->GetOwnerGUID())*/ || obj->isPossessedByPlayer())
if(obj->isPet() || obj->HasSharedVision())
{
(*grid)(cell.CellX(), cell.CellY()).AddWorldObject<Creature>(obj, obj->GetGUID());
obj->SetCurrentCell(cell);
}
// add to grid object store
else
{
(*grid)(cell.CellX(), cell.CellY()).AddGridObject<Creature>(obj, obj->GetGUID());
obj->SetCurrentCell(cell);
}
obj->SetCurrentCell(cell);
}
template<class T>
@@ -301,7 +300,7 @@ template<>
void Map::RemoveFromGrid(Creature* obj, NGridType *grid, Cell const& cell)
{
// remove from world object registry in grid
if(obj->isPet() || obj->isPossessedByPlayer())
if(obj->isPet() || obj->HasSharedVision())
{
(*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject<Creature>(obj, obj->GetGUID());
}
@@ -327,7 +326,8 @@ void Map::SwitchGridContainers(T* obj, bool active)
grid.RemoveGridObject<T>(obj, obj->GetGUID());
grid.AddWorldObject<T>(obj, obj->GetGUID());
}
} else
}
else
{
if (!grid.GetGridObject(obj->GetGUID(), obj))
{
@@ -338,7 +338,6 @@ void Map::SwitchGridContainers(T* obj, bool active)
}
template void Map::SwitchGridContainers(Creature *, bool);
template void Map::SwitchGridContainers(Corpse *, bool);
template void Map::SwitchGridContainers(DynamicObject *, bool);
template<class T>
@@ -349,20 +348,20 @@ void Map::DeleteFromWorld(T* obj)
}
template<class T>
void Map::AddNotifier(T* , Cell const& , CellPair const& )
void Map::AddNotifier(T*)
{
}
template<>
void Map::AddNotifier(Player* obj, Cell const& cell, CellPair const& cellpair)
void Map::AddNotifier(Player* obj)
{
PlayerRelocationNotify(obj,cell,cellpair);
AddUnitToNotify(obj);
}
template<>
void Map::AddNotifier(Creature* obj, Cell const& cell, CellPair const& cellpair)
void Map::AddNotifier(Creature* obj)
{
CreatureRelocationNotify(obj,cell,cellpair);
AddUnitToNotify(obj);
}
void
@@ -427,33 +426,6 @@ Map::EnsureGridLoadedForPlayer(const Cell &cell, Player *player, bool add_player
AddToGrid(player,grid,cell);
}
void
Map::LoadGrid(const Cell& cell, bool no_unload)
{
EnsureGridCreated(GridPair(cell.GridX(), cell.GridY()));
NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
assert(grid != NULL);
if( !isGridObjectDataLoaded(cell.GridX(), cell.GridY()) )
{
ObjectGridLoader loader(*grid, this, cell);
loader.LoadN();
setGridObjectDataLoaded(true,cell.GridX(), cell.GridY());
// Add resurrectable corpses to world object list in grid
ObjectAccessor::Instance().AddCorpsesToGrid(GridPair(cell.GridX(),cell.GridY()),(*grid)(cell.CellX(), cell.CellY()), this);
// Not sure if this is the reason that far sight cause crash
// Seems crash happens when trying to delete a far sight dynobj from an unopened grid
ResetGridExpiry(*getNGrid(cell.GridX(), cell.GridY()), 1.0f);
grid->SetGridState(GRID_STATE_ACTIVE);
if(no_unload)
getNGrid(cell.GridX(), cell.GridY())->setUnloadFlag(false);
}
//LoadVMap(63-cell.GridX(),63-cell.GridY());
}
void Map::LoadGrid(float x, float y)
{
CellPair pair = Trinity::ComputeCellPair(x, y);
@@ -476,11 +448,8 @@ bool Map::Add(Player *player)
SendInitSelf(player);
SendInitTransports(player);
//UpdatePlayerVisibility(player,cell,p);
//UpdateObjectsVisibilityFor(player,cell,p);
AddNotifier(player);
//AddNotifier(player,cell,p);
AddUnitToNotify(player);
return true;
}
@@ -510,9 +479,7 @@ Map::Add(T *obj)
UpdateObjectVisibility(obj,cell,p);
//AddNotifier(obj,cell,p);
if(obj->GetTypeId() == TYPEID_UNIT || obj->GetTypeId() == TYPEID_PLAYER)
AddUnitToNotify((Unit*)obj);
AddNotifier(obj);
}
void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self, bool to_possessor)
@@ -610,49 +577,6 @@ bool Map::loaded(const GridPair &p) const
return ( getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord) );
}
/*void Map::UpdateActiveCells(const float &x, const float &y, const uint32 &t_diff)
{
CellPair standing_cell(Trinity::ComputeCellPair(x, y));
// 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)
return;
// will this reduce the speed?
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);
// 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
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);
}
}
}
}*/
void Map::RelocationNotify()
{
//creatures may be added to the list during update
@@ -838,9 +762,6 @@ void Map::Remove(Player *player, bool remove)
SendRemoveTransports(player);
//UpdateObjectsVisibilityFor(player,cell,p);
//AddUnitToNotify(player);
if( remove )
DeleteFromWorld(player);
}
@@ -918,21 +839,12 @@ Map::PlayerRelocation(Player *player, float x, float y, float z, float orientati
RemoveFromGrid(player, oldGrid,old_cell);
if( !old_cell.DiffGrid(new_cell) )
AddToGrid(player, oldGrid,new_cell);
if( old_cell.DiffGrid(new_cell) )
else
EnsureGridLoadedForPlayer(new_cell, player, true);
}
// if move then update what player see and who seen
//UpdatePlayerVisibility(player,new_cell,new_val);
//UpdateObjectsVisibilityFor(player,new_cell,new_val);
// also update what possessing player sees
//if(player->isPossessedByPlayer())
// UpdateObjectsVisibilityFor((Player*)player->GetCharmer(), new_cell, new_val);
//PlayerRelocationNotify(player,new_cell,new_val);
AddUnitToNotify(player);
NGridType* newGrid = getNGrid(new_cell.GridX(), new_cell.GridY());
if( !same_cell && newGrid->GetGridState()!= GRID_STATE_ACTIVE )
{
@@ -971,11 +883,6 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang
else
{
creature->Relocate(x, y, z, ang);
// Update visibility back to player who is controlling the creature
//if(creature->isPossessedByPlayer())
// UpdateObjectsVisibilityFor((Player*)creature->GetCharmer(), new_cell, new_val);
//CreatureRelocationNotify(creature,new_cell,new_val);
AddUnitToNotify(creature);
}
assert(CheckGridIntegrity(creature,true));
@@ -1042,12 +949,8 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell)
sLog.outDebug("Creature (GUID: %u Entry: %u) moved in grid[%u,%u] from cell[%u,%u] to cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY());
#endif
if( !old_cell.DiffGrid(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
{
@@ -1434,60 +1337,6 @@ void Map::UpdateObjectVisibility( WorldObject* obj, Cell cell, CellPair cellpair
cell_lock->Visit(cell_lock, player_notifier, *this);
}
/*void Map::UpdatePlayerVisibility( Player* player, Cell cell, CellPair cellpair )
{
cell.data.Part.reserved = ALL_DISTRICT;
Trinity::PlayerNotifier pl_notifier(*player);
TypeContainerVisitor<Trinity::PlayerNotifier, WorldTypeMapContainer > player_notifier(pl_notifier);
CellLock<ReadGuard> cell_lock(cell, cellpair);
cell_lock->Visit(cell_lock, player_notifier, *this);
}*/
void Map::UpdateObjectsVisibilityFor( Player* player, Cell cell, CellPair cellpair )
{
Trinity::VisibleNotifier notifier(*player);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
TypeContainerVisitor<Trinity::VisibleNotifier, WorldTypeMapContainer > world_notifier(notifier);
TypeContainerVisitor<Trinity::VisibleNotifier, GridTypeMapContainer > grid_notifier(notifier);
CellLock<GridReadGuard> cell_lock(cell, cellpair);
cell_lock->Visit(cell_lock, world_notifier, *this);
cell_lock->Visit(cell_lock, grid_notifier, *this);
// send data
notifier.Notify();
}
void Map::PlayerRelocationNotify( Player* player, Cell cell, CellPair cellpair )
{
CellLock<ReadGuard> cell_lock(cell, cellpair);
Trinity::PlayerRelocationNotifier relocationNotifier(*player);
cell.data.Part.reserved = ALL_DISTRICT;
TypeContainerVisitor<Trinity::PlayerRelocationNotifier, GridTypeMapContainer > p2grid_relocation(relocationNotifier);
TypeContainerVisitor<Trinity::PlayerRelocationNotifier, WorldTypeMapContainer > p2world_relocation(relocationNotifier);
cell_lock->Visit(cell_lock, p2grid_relocation, *this);
cell_lock->Visit(cell_lock, p2world_relocation, *this);
}
void Map::CreatureRelocationNotify(Creature *creature, Cell cell, CellPair cellpair)
{
CellLock<ReadGuard> cell_lock(cell, cellpair);
Trinity::CreatureRelocationNotifier relocationNotifier(*creature);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate(); // not trigger load unloaded grids at notifier call
TypeContainerVisitor<Trinity::CreatureRelocationNotifier, WorldTypeMapContainer > c2world_relocation(relocationNotifier);
TypeContainerVisitor<Trinity::CreatureRelocationNotifier, GridTypeMapContainer > c2grid_relocation(relocationNotifier);
cell_lock->Visit(cell_lock, c2world_relocation, *this);
cell_lock->Visit(cell_lock, c2grid_relocation, *this);
}
void Map::SendInitSelf( Player * player )
{
sLog.outDetail("Creating player data for himself %u", player->GetGUIDLow());
+1 -7
View File
@@ -168,7 +168,6 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
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); }
void LoadGrid(const Cell& cell, bool no_unload = false);
void LoadGrid(float x, float y);
bool UnloadGrid(const uint32 &x, const uint32 &y, bool pForce);
virtual void UnloadAll(bool pForce);
@@ -240,8 +239,6 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
virtual bool RemoveBones(uint64 guid, float x, float y);
void UpdateObjectVisibility(WorldObject* obj, Cell cell, CellPair cellpair);
//void UpdatePlayerVisibility(Player* player, Cell cell, CellPair cellpair);
void UpdateObjectsVisibilityFor(Player* player, Cell cell, CellPair cellpair);
void resetMarkedCells() { marked_cells.reset(); }
bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); }
@@ -279,9 +276,6 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
void SendInitTransports( Player * player );
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);
@@ -338,7 +332,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
void AddToGrid(T*, NGridType *, Cell const&);
template<class T>
void AddNotifier(T*, Cell const&, CellPair const&);
void AddNotifier(T*);
template<class T>
void RemoveFromGrid(T*, NGridType *, Cell const&);
+2 -2
View File
@@ -289,12 +289,12 @@ bool MapManager::IsValidMAP(uint32 mapid)
return mEntry && (!mEntry->Instanceable() || objmgr.GetInstanceTemplate(mapid));
}
void MapManager::LoadGrid(int mapid, float x, float y, const WorldObject* obj, bool no_unload)
/*void MapManager::LoadGrid(int mapid, float x, float y, const WorldObject* obj, bool no_unload)
{
CellPair p = Trinity::ComputeCellPair(x,y);
Cell cell(p);
GetMap(mapid, obj)->LoadGrid(cell,no_unload);
}
}*/
void MapManager::UnloadAll()
{
+1 -1
View File
@@ -75,7 +75,7 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit
i_timer.Reset();
}
void LoadGrid(int mapid, float x, float y, const WorldObject* obj, bool no_unload = false);
//void LoadGrid(int mapid, float x, float y, const WorldObject* obj, bool no_unload = false);
void UnloadAll();
static bool ExistMapAndVMap(uint32 mapid, float x, float y);
-2
View File
@@ -1838,8 +1838,6 @@ void Player::RemoveFromWorld()
///- Release charmed creatures, unsummon totems and remove pets/guardians
StopCastingCharm();
StopCastingBindSight();
RemoveCharmAuras();
RemoveBindSightAuras();
UnsummonAllTotems();
RemoveMiniPet();
RemoveGuardians();
+3 -10
View File
@@ -4830,7 +4830,7 @@ void Unit::RemoveDynObject(uint32 spellid)
for (DynObjectGUIDs::iterator i = m_dynObjGUIDs.begin(); i != m_dynObjGUIDs.end();)
{
DynamicObject* dynObj = ObjectAccessor::GetDynamicObject(*this, *i);
if(!dynObj)
if(!dynObj) // may happen if a dynobj is removed when grid unload
{
i = m_dynObjGUIDs.erase(i);
}
@@ -8473,20 +8473,11 @@ void Unit::RemovePlayerFromVision(Player* plr)
void Unit::RemoveBindSightAuras()
{
/*while (!m_sharedVision.empty())
{
Player* plr = *m_sharedVision.begin();
m_sharedVision.erase(m_sharedVision.begin());
plr->ClearFarsight();
}*/
RemoveSpellsCausingAura(SPELL_AURA_BIND_SIGHT);
}
void Unit::RemoveCharmAuras()
{
if (!GetCharmer())
return;
RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM);
RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS_PET);
RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS);
@@ -11132,6 +11123,8 @@ void Unit::RemoveFromWorld()
// cleanup
if(IsInWorld())
{
RemoveCharmAuras();
RemoveBindSightAuras();
RemoveNotOwnSingleTargetAuras();
}
+1
View File
@@ -1095,6 +1095,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
SharedVisionList const& GetSharedVisionList() { return m_sharedVision; }
void AddPlayerToVision(Player* plr);
void RemovePlayerFromVision(Player* plr);
bool HasSharedVision() const { return !m_sharedVision.empty(); }
void RemoveBindSightAuras();
void RemoveCharmAuras();