mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
Move object update from ObjectAccessor to Map update.
This commit is contained in:
parent
d287a17597
commit
0d1b8038f5
6 changed files with 204 additions and 89 deletions
|
|
@ -562,6 +562,63 @@ bool Map::loaded(const GridPair &p) const
|
||||||
|
|
||||||
void Map::Update(const uint32 &t_diff)
|
void Map::Update(const uint32 &t_diff)
|
||||||
{
|
{
|
||||||
|
resetMarkedCells();
|
||||||
|
|
||||||
|
//TODO: Player guard
|
||||||
|
HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
|
||||||
|
for(HashMapHolder<Player>::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<MaNGOS::ObjectUpdater, GridTypeMapContainer > grid_object_update(updater);
|
||||||
|
// for pets
|
||||||
|
TypeContainerVisitor<MaNGOS::ObjectUpdater, WorldTypeMapContainer > 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<NullGuard> 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 !
|
// 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
|
// 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())
|
if (IsBattleGroundOrArena())
|
||||||
|
|
|
||||||
|
|
@ -230,8 +230,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||||
void UpdateObjectsVisibilityFor(Player* player, Cell cell, CellPair cellpair);
|
void UpdateObjectsVisibilityFor(Player* player, Cell cell, CellPair cellpair);
|
||||||
|
|
||||||
void resetMarkedCells() { marked_cells.reset(); }
|
void resetMarkedCells() { marked_cells.reset(); }
|
||||||
bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); }
|
bool isCellMarked(uint32 x, uint32 y) { return marked_cells.test(y * TOTAL_NUMBER_OF_CELLS_PER_MAP + x); }
|
||||||
void markCell(uint32 pCellId) { marked_cells.set(pCellId); }
|
void markCell(uint32 x, uint32 y) { marked_cells.set(y * TOTAL_NUMBER_OF_CELLS_PER_MAP + x); }
|
||||||
private:
|
private:
|
||||||
void LoadVMap(int pX, int pY);
|
void LoadVMap(int pX, int pY);
|
||||||
void LoadMap(uint32 mapid, uint32 instanceid, int x,int y);
|
void LoadMap(uint32 mapid, uint32 instanceid, int x,int y);
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,8 @@ MapManager::Update(time_t diff)
|
||||||
if( !i_timer.Passed() )
|
if( !i_timer.Passed() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ObjectAccessor::Instance().UpdatePlayers(i_timer.GetCurrent());
|
||||||
|
|
||||||
for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter)
|
for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter)
|
||||||
{
|
{
|
||||||
checkAndCorrectGridStatesArray(); // debugging code, should be deleted some day
|
checkAndCorrectGridStatesArray(); // debugging code, should be deleted some day
|
||||||
|
|
|
||||||
|
|
@ -245,32 +245,6 @@ ObjectAccessor::SaveAllPlayers()
|
||||||
itr->second->SaveToDB();
|
itr->second->SaveToDB();
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
void
|
||||||
ObjectAccessor::UpdateObject(Object* obj, Player* exceptPlayer)
|
ObjectAccessor::UpdateObject(Object* obj, Player* exceptPlayer)
|
||||||
{
|
{
|
||||||
|
|
@ -505,72 +479,36 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid)
|
||||||
void
|
void
|
||||||
ObjectAccessor::Update(uint32 diff)
|
ObjectAccessor::Update(uint32 diff)
|
||||||
{
|
{
|
||||||
|
UpdateDataMapType update_players;
|
||||||
{
|
{
|
||||||
typedef std::multimap<uint32, Player *> CreatureLocationHolderType;
|
Guard guard(i_updateGuard);
|
||||||
CreatureLocationHolderType creature_locations;
|
while(!i_objects.empty())
|
||||||
//TODO: Player guard
|
|
||||||
HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
|
|
||||||
for(HashMapHolder<Player>::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter)
|
|
||||||
{
|
{
|
||||||
if(iter->second->IsInWorld())
|
Object* obj = *i_objects.begin();
|
||||||
{
|
i_objects.erase(i_objects.begin());
|
||||||
iter->second->Update(diff);
|
if (!obj)
|
||||||
creature_locations.insert( CreatureLocationHolderType::value_type(iter->second->GetMapId(), iter->second) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Map *map;
|
|
||||||
|
|
||||||
MaNGOS::ObjectUpdater updater(diff);
|
|
||||||
// for creature
|
|
||||||
TypeContainerVisitor<MaNGOS::ObjectUpdater, GridTypeMapContainer > grid_object_update(updater);
|
|
||||||
// for pets
|
|
||||||
TypeContainerVisitor<MaNGOS::ObjectUpdater, WorldTypeMapContainer > 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)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
continue;
|
continue;
|
||||||
|
_buildUpdateObject(obj, update_players);
|
||||||
// the overloaded operators handle range checking
|
obj->ClearUpdateMask(false);
|
||||||
// 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<NullGuard> cell_lock(cell, cell_pair);
|
|
||||||
cell_lock->Visit(cell_lock, grid_object_update, *map);
|
|
||||||
cell_lock->Visit(cell_lock, world_object_update, *map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_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<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
|
||||||
|
for(HashMapHolder<Player>::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter)
|
||||||
|
if(iter->second->IsInWorld())
|
||||||
|
iter->second->Update(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
void RemoveUpdateObject(Object *obj);
|
void RemoveUpdateObject(Object *obj);
|
||||||
|
|
||||||
void Update(uint32 diff);
|
void Update(uint32 diff);
|
||||||
|
void UpdatePlayers(uint32 diff);
|
||||||
|
|
||||||
Corpse* GetCorpseForPlayerGUID(uint64 guid);
|
Corpse* GetCorpseForPlayerGUID(uint64 guid);
|
||||||
void RemoveCorpse(Corpse *corpse);
|
void RemoveCorpse(Corpse *corpse);
|
||||||
|
|
@ -216,7 +217,6 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||||
|
|
||||||
static void _buildChangeObjectForPlayer(WorldObject *, UpdateDataMapType &);
|
static void _buildChangeObjectForPlayer(WorldObject *, UpdateDataMapType &);
|
||||||
static void _buildPacket(Player *, Object *, UpdateDataMapType &);
|
static void _buildPacket(Player *, Object *, UpdateDataMapType &);
|
||||||
void _update(void);
|
|
||||||
std::set<Object *> i_objects;
|
std::set<Object *> i_objects;
|
||||||
LockType i_playerGuard;
|
LockType i_playerGuard;
|
||||||
LockType i_updateGuard;
|
LockType i_updateGuard;
|
||||||
|
|
|
||||||
118
src/game/PetitionMgr.h
Normal file
118
src/game/PetitionMgr.h
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
|
*
|
||||||
|
* 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 <map>
|
||||||
|
|
||||||
|
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<uint32, Petition> 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<PetitionMgr>::Instance()
|
||||||
|
#endif
|
||||||
Loading…
Add table
Add a link
Reference in a new issue