diff options
Diffstat (limited to 'src/game/Map.cpp')
-rw-r--r-- | src/game/Map.cpp | 171 |
1 files changed, 156 insertions, 15 deletions
diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 3804560b662..c807c6ab1a1 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -466,7 +466,8 @@ bool Map::Add(Player *player) UpdatePlayerVisibility(player,cell,p); UpdateObjectsVisibilityFor(player,cell,p); - AddNotifier(player,cell,p); + //AddNotifier(player,cell,p); + AddUnitToNotify(player); return true; } @@ -496,7 +497,9 @@ Map::Add(T *obj) UpdateObjectVisibility(obj,cell,p); - AddNotifier(obj,cell,p); + //AddNotifier(obj,cell,p); + if(obj->GetTypeId() == TYPEID_UNIT || obj->GetTypeId() == TYPEID_PLAYER) + AddUnitToNotify((Unit*)obj); } void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self, bool to_possessor) @@ -594,23 +597,100 @@ bool Map::loaded(const GridPair &p) const return ( getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord) ); } -void Map::Update(const uint32 &t_diff) +/*void Map::UpdateActiveCells(const float &x, const float &y, const uint32 &t_diff) { - resetMarkedCells(); + 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::Update(const uint32 &t_diff) +{ + for(std::vector<uint64>::iterator iter = i_unitsToNotify.begin(); iter != i_unitsToNotify.end(); ++iter) + { + Unit *unit = ObjectAccessor::GetObjectInWorld(*iter, (Unit*)NULL); + if(!unit) continue; + unit->m_Notified = true; + if(!unit->IsInWorld()) + continue; + CellPair val = Trinity::ComputeCellPair(unit->GetPositionX(), unit->GetPositionY()); + Cell cell(val); + if(unit->GetTypeId() == TYPEID_PLAYER) + PlayerRelocationNotify((Player*)unit, cell, val); + else + CreatureRelocationNotify((Creature*)unit, cell, val); + } + for(std::vector<uint64>::iterator iter = i_unitsToNotify.begin(); iter != i_unitsToNotify.end(); ++iter) + { + if(Unit *unit = ObjectAccessor::GetObjectInWorld(*iter, (Unit*)NULL)) + { + unit->m_IsInNotifyList = false; + unit->m_Notified = false; + } + } + i_unitsToNotify.clear(); + + 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()) - continue; + 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); + } - CellPair standing_cell(Trinity::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY())); + 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) + { + CellPair standing_cell(Trinity::ComputeCellPair((*iter)->GetPositionX(), (*iter)->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) @@ -642,8 +722,9 @@ void Map::Update(const uint32 &t_diff) } } } - } + // UpdateActiveCells((*iter)->GetPositionX(), (*iter)->GetPositionY(), t_diff); + } // Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load ! // This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended @@ -662,6 +743,13 @@ void Map::Update(const uint32 &t_diff) void Map::Remove(Player *player, bool remove) { + // this may be called during Map::Update + // after decrement+unlink, ++m_mapRefIter will continue correctly + // when the first element of the list is being removed + // nocheck_prev will return the padding element of the RefManager + // instead of NULL in the case of prev + if(m_mapRefIter == player->GetMapRef()) + m_mapRefIter = m_mapRefIter->nocheck_prev(); player->GetMapRef().unlink(); CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) @@ -784,7 +872,8 @@ Map::PlayerRelocation(Player *player, float x, float y, float z, float orientati if(player->isPossessedByPlayer()) UpdateObjectsVisibilityFor((Player*)player->GetCharmer(), new_cell, new_val); - PlayerRelocationNotify(player,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 ) { @@ -812,8 +901,13 @@ 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->isPossessedByPlayer()) - EnsureGridLoadedForPlayer(new_cell, (Player*)creature->GetCharmer(), false); + if(creature->isActive()) + { + if(creature->isPossessedByPlayer()) + EnsureGridLoadedForPlayer(new_cell, (Player*)creature->GetCharmer(), false); + else + EnsureGridLoadedForPlayer(new_cell, NULL, false); + } } else { @@ -822,7 +916,8 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang if(creature->isPossessedByPlayer()) UpdateObjectsVisibilityFor((Player*)creature->GetCharmer(), new_cell, new_val); - CreatureRelocationNotify(creature,new_cell,new_val); + //CreatureRelocationNotify(creature,new_cell,new_val); + AddUnitToNotify(creature); } assert(CheckGridIntegrity(creature,true)); } @@ -854,7 +949,8 @@ void Map::MoveAllCreaturesInMoveList() { // update pos c->Relocate(cm.x, cm.y, cm.z, cm.ang); - CreatureRelocationNotify(c,new_cell,new_cell.cellPair()); + //CreatureRelocationNotify(c,new_cell,new_cell.cellPair()); + AddUnitToNotify(c); } else { @@ -949,7 +1045,8 @@ 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()); + //CreatureRelocationNotify(c,resp_cell,resp_cell.cellPair()); + AddUnitToNotify(c); return true; } else @@ -1508,6 +1605,36 @@ bool Map::PlayersNearGrid(uint32 x, uint32 y) const 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) + { + Player* plr = iter->getSource(); + + CellPair p = Trinity::ComputeCellPair(plr->GetPositionX(), plr->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) + { + 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; + } + + return false; +} + template void Map::Add(Corpse *); template void Map::Add(Creature *); template void Map::Add(GameObject *); @@ -1658,6 +1785,8 @@ bool InstanceMap::Add(Player *player) } if(i_data) i_data->OnPlayerEnter(player); + // for normal instances cancel the reset schedule when the + // first player enters (no players yet) SetResetSchedule(false); player->SendInitWorldStates(); @@ -1684,11 +1813,12 @@ void InstanceMap::Update(const uint32& t_diff) void InstanceMap::Remove(Player *player, bool remove) { sLog.outDetail("MAP: Removing player '%s' from instance '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName()); - SetResetSchedule(true); //if last player set unload timer if(!m_unloadTimer && m_mapRefManager.getSize() == 1) m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); Map::Remove(player, remove); + // for normal instances schedule the reset after all players have left + SetResetSchedule(true); } Creature * Map::GetCreatureInMap(uint64 guid) @@ -1923,3 +2053,14 @@ void BattleGroundMap::UnloadAll(bool pForce) Map::UnloadAll(pForce); } + +/*--------------------------TRINITY-------------------------*/ + +void Map::AddUnitToNotify(Unit* u) +{ + if(!u->m_IsInNotifyList) + { + i_unitsToNotify.push_back(u->GetGUID()); + u->m_IsInNotifyList = true; + } +}
\ No newline at end of file |