From 4f8ad20236439ac3eb15b9b91c1584750118bdc0 Mon Sep 17 00:00:00 2001 From: hunuza Date: Sat, 15 Nov 2008 00:31:51 +0100 Subject: [PATCH] Move object update from ObjectAccessor to Map update. --- src/game/Map.cpp | 57 +++++++++++++++++++++ src/game/Map.h | 4 +- src/game/MapManager.cpp | 2 + src/game/ObjectAccessor.cpp | 110 +++++++++-------------------------------- src/game/ObjectAccessor.h | 2 +- src/game/PetitionMgr.h | 118 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 204 insertions(+), 89 deletions(-) create mode 100644 src/game/PetitionMgr.h diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 7892138a6..601a69e86 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -562,6 +562,63 @@ bool Map::loaded(const GridPair &p) const void Map::Update(const uint32 &t_diff) { + resetMarkedCells(); + + //TODO: Player guard + HashMapHolder::MapType& playerMap = HashMapHolder::GetContainer(); + for(HashMapHolder::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter) + { + WorldObject* obj = iter->second; + + if(!obj->IsInWorld()) + continue; + + if(obj->GetMapId() != GetId()) + continue; + + if(obj->GetInstanceId() != GetInstanceId()) + continue; + + CellPair standing_cell(MaNGOS::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 + + 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) + markCell(x,y); + } + + MaNGOS::ObjectUpdater updater(t_diff); + // for creature + TypeContainerVisitor grid_object_update(updater); + // for pets + TypeContainerVisitor world_object_update(updater); + + for(int x = 0; x < TOTAL_NUMBER_OF_CELLS_PER_MAP; ++x) + { + for(int y = 0; y < TOTAL_NUMBER_OF_CELLS_PER_MAP; ++y) + { + if(isCellMarked(x,y)) + { + CellPair pair(x,y); + Cell cell(pair); + cell.data.Part.reserved = CENTER_DISTRICT; + cell.SetNoCreate(); + CellLock cell_lock(cell, pair); + cell_lock->Visit(cell_lock, grid_object_update, *this); + cell_lock->Visit(cell_lock, world_object_update, *this); + } + } + } + // 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 if (IsBattleGroundOrArena()) diff --git a/src/game/Map.h b/src/game/Map.h index e4f9f5839..454bc0e17 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -230,8 +230,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj void UpdateObjectsVisibilityFor(Player* player, Cell cell, CellPair cellpair); void resetMarkedCells() { marked_cells.reset(); } - bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); } - void markCell(uint32 pCellId) { marked_cells.set(pCellId); } + bool isCellMarked(uint32 x, uint32 y) { return marked_cells.test(y * TOTAL_NUMBER_OF_CELLS_PER_MAP + x); } + void markCell(uint32 x, uint32 y) { marked_cells.set(y * TOTAL_NUMBER_OF_CELLS_PER_MAP + x); } private: void LoadVMap(int pX, int pY); void LoadMap(uint32 mapid, uint32 instanceid, int x,int y); diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 691448ba1..e044b1084 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -244,6 +244,8 @@ MapManager::Update(time_t diff) if( !i_timer.Passed() ) return; + ObjectAccessor::Instance().UpdatePlayers(i_timer.GetCurrent()); + for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter) { checkAndCorrectGridStatesArray(); // debugging code, should be deleted some day diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 586f84a82..b32743b28 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -246,32 +246,6 @@ ObjectAccessor::SaveAllPlayers() } void -ObjectAccessor::_update() -{ - UpdateDataMapType update_players; - { - Guard guard(i_updateGuard); - while(!i_objects.empty()) - { - Object* obj = *i_objects.begin(); - i_objects.erase(i_objects.begin()); - if (!obj) - continue; - _buildUpdateObject(obj, update_players); - obj->ClearUpdateMask(false); - } - } - - WorldPacket packet; // here we allocate a std::vector with a size of 0x10000 - for(UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) - { - iter->second.BuildPacket(&packet); - iter->first->GetSession()->SendPacket(&packet); - packet.clear(); // clean the string - } -} - -void ObjectAccessor::UpdateObject(Object* obj, Player* exceptPlayer) { UpdateDataMapType update_players; @@ -505,72 +479,36 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid) void ObjectAccessor::Update(uint32 diff) { + UpdateDataMapType update_players; { - typedef std::multimap CreatureLocationHolderType; - CreatureLocationHolderType creature_locations; - //TODO: Player guard - HashMapHolder::MapType& playerMap = HashMapHolder::GetContainer(); - for(HashMapHolder::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter) - { - if(iter->second->IsInWorld()) - { - iter->second->Update(diff); - creature_locations.insert( CreatureLocationHolderType::value_type(iter->second->GetMapId(), iter->second) ); - } - } - - Map *map; - - MaNGOS::ObjectUpdater updater(diff); - // for creature - TypeContainerVisitor grid_object_update(updater); - // for pets - TypeContainerVisitor world_object_update(updater); - - for(CreatureLocationHolderType::iterator iter=creature_locations.begin(); iter != creature_locations.end(); ++iter) - { - MapManager::Instance().GetMap((*iter).first, (*iter).second)->resetMarkedCells(); - } - - for(CreatureLocationHolderType::iterator iter=creature_locations.begin(); iter != creature_locations.end(); ++iter) + Guard guard(i_updateGuard); + while(!i_objects.empty()) { - Player *player = (*iter).second; - map = MapManager::Instance().GetMap((*iter).first, player); - - CellPair standing_cell(MaNGOS::ComputeCellPair(player->GetPositionX(), player->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) + Object* obj = *i_objects.begin(); + i_objects.erase(i_objects.begin()); + if (!obj) 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 - - 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++) - { - uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x; - if( !map->isCellMarked(cell_id) ) - { - CellPair cell_pair(x,y); - map->markCell(cell_id); - Cell cell(cell_pair); - cell.data.Part.reserved = CENTER_DISTRICT; - cell.SetNoCreate(); - CellLock cell_lock(cell, cell_pair); - cell_lock->Visit(cell_lock, grid_object_update, *map); - cell_lock->Visit(cell_lock, world_object_update, *map); - } - } - } + _buildUpdateObject(obj, update_players); + obj->ClearUpdateMask(false); } } - _update(); + WorldPacket packet; // here we allocate a std::vector with a size of 0x10000 + for(UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) + { + iter->second.BuildPacket(&packet); + iter->first->GetSession()->SendPacket(&packet); + packet.clear(); // clean the string + } +} + +void +ObjectAccessor::UpdatePlayers(uint32 diff) +{ + HashMapHolder::MapType& playerMap = HashMapHolder::GetContainer(); + for(HashMapHolder::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter) + if(iter->second->IsInWorld()) + iter->second->Update(diff); } bool diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index ccb5b8af8..628312901 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -184,6 +184,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton i_objects; LockType i_playerGuard; LockType i_updateGuard; diff --git a/src/game/PetitionMgr.h b/src/game/PetitionMgr.h new file mode 100644 index 000000000..6a763bb1d --- /dev/null +++ b/src/game/PetitionMgr.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _PETITIONMGR_H +#define _PETITIONMGR_H + +#include "Policies/Singleton.h" +#include "Database/DatabaseEnv.h" +#include "Util.h" +#include + +class Petition +{ + public: + explicit Petition() + { + } + + GMTicket(uint32 guid, std::string text, time_t update) : m_guid(guid), m_text(text), m_lastUpdate(update) + { + + } + + const char* GetText() const + { + return m_text.c_str(); + } + + uint64 GetLastUpdate() const + { + return m_lastUpdate; + } + + void SetText(const char* text) + { + m_text = text ? text : ""; + m_lastUpdate = time(NULL); + CharacterDatabase.PExecute("UPDATE character_ticket SET ticket_text = '%s' WHERE guid = '%u'", m_text.c_str(), m_guid); + } + + void DeleteFromDB() const + { + CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u' LIMIT 1", m_guid); + } + + void SaveToDB() const + { + CharacterDatabase.BeginTransaction(); + DeleteFromDB(); + CharacterDatabase.PExecute("INSERT INTO character_ticket (guid, ticket_text) VALUES ('%u', '%s')", m_guid, GetText()); + CharacterDatabase.CommitTransaction(); + } + private: + uint32 m_guid; + std::string m_text; + time_t m_lastUpdate; +}; +typedef std::map PetitionMap; + +class PetitionMgr +{ + public: + PetitionMgr() { } + ~PetitionMgr() { } + + void LoadGMTickets(); + + GMTicket* GetGMTicket(uint32 guid) + { + GMTicketMap::iterator itr = m_GMTicketMap.find(guid); + if(itr == m_GMTicketMap.end()) + return NULL; + return &(itr->second); + } + + size_t GetTicketCount() const + { + return m_GMTicketMap.size(); + } + + void Delete(uint32 guid) + { + GMTicketMap::iterator itr = m_GMTicketMap.find(guid); + if(itr == m_GMTicketMap.end()) + return; + itr->second.DeleteFromDB(); + m_GMTicketMap.erase(itr); + } + + void DeleteAll(); + + void Create(uint32 guid, const char* text) + { + GMTicket t = GMTicket(guid, text, time(NULL)); + t.SaveToDB(); + m_GMTicketMap[guid] = t; + } + private: + PetitionMap m_PetitionMap; +}; + +#define petitionmgr MaNGOS::Singleton::Instance() +#endif \ No newline at end of file -- 2.11.4.GIT