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)
|
||||
{
|
||||
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 !
|
||||
// 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())
|
||||
|
|
|
|||
|
|
@ -230,8 +230,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, 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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -245,32 +245,6 @@ ObjectAccessor::SaveAllPlayers()
|
|||
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
|
||||
ObjectAccessor::UpdateObject(Object* obj, Player* exceptPlayer)
|
||||
{
|
||||
|
|
@ -505,72 +479,36 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid)
|
|||
void
|
||||
ObjectAccessor::Update(uint32 diff)
|
||||
{
|
||||
UpdateDataMapType update_players;
|
||||
{
|
||||
typedef std::multimap<uint32, Player *> CreatureLocationHolderType;
|
||||
CreatureLocationHolderType creature_locations;
|
||||
//TODO: Player guard
|
||||
HashMapHolder<Player>::MapType& playerMap = HashMapHolder<Player>::GetContainer();
|
||||
for(HashMapHolder<Player>::MapType::iterator iter = playerMap.begin(); iter != playerMap.end(); ++iter)
|
||||
Guard guard(i_updateGuard);
|
||||
while(!i_objects.empty())
|
||||
{
|
||||
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<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)
|
||||
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<NullGuard> 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<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
|
||||
|
|
|
|||
|
|
@ -184,6 +184,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
|||
void RemoveUpdateObject(Object *obj);
|
||||
|
||||
void Update(uint32 diff);
|
||||
void UpdatePlayers(uint32 diff);
|
||||
|
||||
Corpse* GetCorpseForPlayerGUID(uint64 guid);
|
||||
void RemoveCorpse(Corpse *corpse);
|
||||
|
|
@ -216,7 +217,6 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
|||
|
||||
static void _buildChangeObjectForPlayer(WorldObject *, UpdateDataMapType &);
|
||||
static void _buildPacket(Player *, Object *, UpdateDataMapType &);
|
||||
void _update(void);
|
||||
std::set<Object *> i_objects;
|
||||
LockType i_playerGuard;
|
||||
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