* Even more restructuring of the game library.
--HG-- branch : trunk
This commit is contained in:
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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 TRINITY_FORMULAS_H
|
||||
#define TRINITY_FORMULAS_H
|
||||
|
||||
#include "World.h"
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
namespace Honor
|
||||
{
|
||||
inline uint32 hk_honor_at_level(uint8 level, uint32 count = 1)
|
||||
{
|
||||
return uint32(ceil(count * (33.333f * ((float)level) / 21.50537f)));
|
||||
}
|
||||
}
|
||||
namespace XP
|
||||
{
|
||||
enum XPColorChar { RED, ORANGE, YELLOW, GREEN, GRAY };
|
||||
|
||||
inline uint8 GetGrayLevel(uint8 pl_level)
|
||||
{
|
||||
if (pl_level <= 5)
|
||||
return 0;
|
||||
else if (pl_level <= 39)
|
||||
return pl_level - 5 - pl_level/10;
|
||||
else if (pl_level <= 59)
|
||||
return pl_level - 1 - pl_level/5;
|
||||
else
|
||||
return pl_level - 9;
|
||||
}
|
||||
|
||||
inline XPColorChar GetColorCode(uint8 pl_level, uint8 mob_level)
|
||||
{
|
||||
if (mob_level >= pl_level + 5)
|
||||
return RED;
|
||||
else if (mob_level >= pl_level + 3)
|
||||
return ORANGE;
|
||||
else if (mob_level >= pl_level - 2)
|
||||
return YELLOW;
|
||||
else if (mob_level > GetGrayLevel(pl_level))
|
||||
return GREEN;
|
||||
else
|
||||
return GRAY;
|
||||
}
|
||||
|
||||
inline uint8 GetZeroDifference(uint8 pl_level)
|
||||
{
|
||||
if (pl_level < 8) return 5;
|
||||
if (pl_level < 10) return 6;
|
||||
if (pl_level < 12) return 7;
|
||||
if (pl_level < 16) return 8;
|
||||
if (pl_level < 20) return 9;
|
||||
if (pl_level < 30) return 11;
|
||||
if (pl_level < 40) return 12;
|
||||
if (pl_level < 45) return 13;
|
||||
if (pl_level < 50) return 14;
|
||||
if (pl_level < 55) return 15;
|
||||
if (pl_level < 60) return 16;
|
||||
return 17;
|
||||
}
|
||||
|
||||
inline uint32 BaseGain(uint8 pl_level, uint8 mob_level, ContentLevels content)
|
||||
{
|
||||
uint32 nBaseExp;
|
||||
switch (content)
|
||||
{
|
||||
case CONTENT_1_60: nBaseExp = 45; break;
|
||||
case CONTENT_61_70: nBaseExp = 235; break;
|
||||
case CONTENT_71_80: nBaseExp = 580; break;
|
||||
default:
|
||||
sLog.outError("BaseGain: Unsupported content level %u",content);
|
||||
nBaseExp = 45; break;
|
||||
}
|
||||
|
||||
if (mob_level >= pl_level)
|
||||
{
|
||||
uint8 nLevelDiff = mob_level - pl_level;
|
||||
if (nLevelDiff > 4)
|
||||
nLevelDiff = 4;
|
||||
return ((pl_level*5 + nBaseExp) * (20 + nLevelDiff)/10 + 1)/2;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8 gray_level = GetGrayLevel(pl_level);
|
||||
if (mob_level > gray_level)
|
||||
{
|
||||
uint8 ZD = GetZeroDifference(pl_level);
|
||||
return (pl_level*5 + nBaseExp) * (ZD + mob_level - pl_level)/ZD;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32 Gain(Player *pl, Unit *u)
|
||||
{
|
||||
if (u->GetTypeId() == TYPEID_UNIT && (
|
||||
((Creature*)u)->isTotem() || ((Creature*)u)->isPet() ||
|
||||
(((Creature*)u)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL)))
|
||||
return 0;
|
||||
|
||||
uint32 xp_gain = BaseGain(pl->getLevel(), u->getLevel(), GetContentLevelsForMapAndZone(u->GetMapId(),u->GetZoneId()));
|
||||
if (xp_gain == 0)
|
||||
return 0;
|
||||
|
||||
//elites in instances have a 2.75x xp bonus instead of the regular 2x world bonus
|
||||
if (u->GetTypeId() == TYPEID_UNIT && ((Creature*)u)->isElite())
|
||||
{
|
||||
if(u->GetMap() && u->GetMap()->IsDungeon())
|
||||
xp_gain *= 2.75;
|
||||
else
|
||||
xp_gain *= 2;
|
||||
}
|
||||
|
||||
return uint32(xp_gain*sWorld.getRate(RATE_XP_KILL));
|
||||
}
|
||||
|
||||
inline float xp_in_group_rate(uint32 count, bool isRaid)
|
||||
{
|
||||
if (isRaid)
|
||||
{
|
||||
// FIX ME: must apply decrease modifiers dependent from raid size
|
||||
return 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (count)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
return 1.0f;
|
||||
case 3:
|
||||
return 1.166f;
|
||||
case 4:
|
||||
return 1.3f;
|
||||
case 5:
|
||||
default:
|
||||
return 1.4f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/** \file
|
||||
\ingroup world
|
||||
*/
|
||||
|
||||
#include "Log.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Database/DatabaseImpl.h"
|
||||
#include "Platform/Define.h"
|
||||
#include "MapManager.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "GlobalEvents.h"
|
||||
#include "ObjectDefines.h"
|
||||
#include "Corpse.h"
|
||||
|
||||
static void CorpsesEraseCallBack(QueryResult_AutoPtr result, bool bones)
|
||||
{
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
uint32 guidlow = fields[0].GetUInt32();
|
||||
float positionX = fields[1].GetFloat();
|
||||
float positionY = fields[2].GetFloat();
|
||||
uint32 mapid = fields[3].GetUInt32();
|
||||
uint64 player_guid = MAKE_NEW_GUID(fields[4].GetUInt32(), 0, HIGHGUID_PLAYER);
|
||||
|
||||
uint64 guid = MAKE_NEW_GUID(guidlow, 0, HIGHGUID_CORPSE);
|
||||
|
||||
sLog.outDebug("[Global event] Removing %s %u (X:%f Y:%f Map:%u).",(bones?"bones":"corpse"),guidlow,positionX,positionY,mapid);
|
||||
|
||||
/// Resurrectable - convert corpses to bones
|
||||
if (!bones)
|
||||
{
|
||||
if (!ObjectAccessor::Instance().ConvertCorpseForPlayer(player_guid))
|
||||
{
|
||||
sLog.outDebug("Corpse %u not found in world or bones creating forbidden. Delete from DB.",guidlow);
|
||||
CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%u'",guidlow);
|
||||
}
|
||||
}
|
||||
else
|
||||
///- or delete bones
|
||||
{
|
||||
MapManager::Instance().RemoveBonesFromMap(mapid, guid, positionX, positionY);
|
||||
|
||||
///- remove bones from the database
|
||||
CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%u'",guidlow);
|
||||
}
|
||||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
/// Handle periodic erase of corpses and bones
|
||||
static void CorpsesErase(bool bones,uint32 delay)
|
||||
{
|
||||
///- Get the list of eligible corpses/bones to be removed
|
||||
//No SQL injection (uint32 and enum)
|
||||
CharacterDatabase.AsyncPQuery(&CorpsesEraseCallBack, bones, "SELECT guid,position_x,position_y,map,player FROM corpse WHERE time < (UNIX_TIMESTAMP()+'%u') AND corpse_type %s '0'", delay, (bones ? "=" : "<>"));
|
||||
}
|
||||
|
||||
/// not thread guarded variant for call from other thread
|
||||
void CorpsesErase()
|
||||
{
|
||||
CorpsesErase(true, 20*MINUTE);
|
||||
CorpsesErase(false,3*DAY);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/// \addtogroup world
|
||||
/// @{
|
||||
/// \file
|
||||
|
||||
#ifndef __GLOBALEVENTS_H
|
||||
#define __GLOBALEVENTS_H
|
||||
|
||||
void CorpsesErase();
|
||||
void HandleCorpsesErase(void*);
|
||||
#endif
|
||||
/// @}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "Player.h"
|
||||
#include "Creature.h"
|
||||
#include "GameObject.h"
|
||||
#include "DynamicObject.h"
|
||||
#include "Vehicle.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Item.h"
|
||||
#include "Corpse.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "MapManager.h"
|
||||
#include "Map.h"
|
||||
#include "CellImpl.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "Opcodes.h"
|
||||
#include "ObjectDefines.h"
|
||||
#include "MapInstanced.h"
|
||||
#include "World.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#define CLASS_LOCK Trinity::ClassLevelLockable<ObjectAccessor, ACE_Thread_Mutex>
|
||||
INSTANTIATE_SINGLETON_2(ObjectAccessor, CLASS_LOCK);
|
||||
INSTANTIATE_CLASS_MUTEX(ObjectAccessor, ACE_Thread_Mutex);
|
||||
|
||||
ObjectAccessor::ObjectAccessor()
|
||||
{
|
||||
}
|
||||
|
||||
ObjectAccessor::~ObjectAccessor()
|
||||
{
|
||||
for (Player2CorpsesMapType::const_iterator itr = i_player2corpse.begin(); itr != i_player2corpse.end(); ++itr)
|
||||
{
|
||||
itr->second->RemoveFromWorld();
|
||||
delete itr->second;
|
||||
}
|
||||
}
|
||||
|
||||
Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const& u, uint64 guid)
|
||||
{
|
||||
if (IS_PLAYER_GUID(guid))
|
||||
return NULL;
|
||||
|
||||
if (IS_PET_GUID(guid))
|
||||
return GetPet(guid);
|
||||
|
||||
return u.IsInWorld() ? u.GetMap()->GetCreature(guid) : NULL;
|
||||
}
|
||||
|
||||
Corpse* ObjectAccessor::GetCorpse(WorldObject const& u, uint64 guid)
|
||||
{
|
||||
Corpse* ret = GetObjectInWorld(guid, (Corpse*)NULL);
|
||||
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
if (ret->GetMapId() != u.GetMapId())
|
||||
return NULL;
|
||||
|
||||
if (ret->GetInstanceId() != u.GetInstanceId())
|
||||
return NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, uint64 guid)
|
||||
{
|
||||
switch (GUID_HIPART(guid))
|
||||
{
|
||||
case HIGHGUID_PLAYER: return FindPlayer(guid);
|
||||
case HIGHGUID_GAMEOBJECT: return p.GetMap()->GetGameObject(guid);
|
||||
case HIGHGUID_VEHICLE:
|
||||
case HIGHGUID_UNIT: return p.GetMap()->GetCreature(guid);
|
||||
case HIGHGUID_PET: return GetPet(guid);
|
||||
case HIGHGUID_DYNAMICOBJECT: return p.GetMap()->GetDynamicObject(guid);
|
||||
case HIGHGUID_TRANSPORT: return NULL;
|
||||
case HIGHGUID_CORPSE: return GetCorpse(p,guid);
|
||||
case HIGHGUID_MO_TRANSPORT: return NULL;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, uint64 guid, uint32 typemask)
|
||||
{
|
||||
switch (GUID_HIPART(guid))
|
||||
{
|
||||
case HIGHGUID_ITEM:
|
||||
if (typemask & TYPEMASK_ITEM && p.GetTypeId() == TYPEID_PLAYER)
|
||||
return ((Player const&)p).GetItemByGuid(guid);
|
||||
break;
|
||||
case HIGHGUID_PLAYER:
|
||||
if (typemask & TYPEMASK_PLAYER)
|
||||
return FindPlayer(guid);
|
||||
break;
|
||||
case HIGHGUID_GAMEOBJECT:
|
||||
if (typemask & TYPEMASK_GAMEOBJECT)
|
||||
return p.GetMap()->GetGameObject(guid);
|
||||
break;
|
||||
case HIGHGUID_UNIT:
|
||||
case HIGHGUID_VEHICLE:
|
||||
if (typemask & TYPEMASK_UNIT)
|
||||
return p.GetMap()->GetCreature(guid);
|
||||
break;
|
||||
case HIGHGUID_PET:
|
||||
if (typemask & TYPEMASK_UNIT)
|
||||
return GetPet(guid);
|
||||
break;
|
||||
case HIGHGUID_DYNAMICOBJECT:
|
||||
if (typemask & TYPEMASK_DYNAMICOBJECT)
|
||||
return p.GetMap()->GetDynamicObject(guid);
|
||||
break;
|
||||
case HIGHGUID_TRANSPORT:
|
||||
case HIGHGUID_CORPSE:
|
||||
case HIGHGUID_MO_TRANSPORT:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Player* ObjectAccessor::FindPlayer(uint64 guid)
|
||||
{
|
||||
Player* plr = GetObjectInWorld(guid, (Player*)NULL);
|
||||
if (!plr || !plr->IsInWorld())
|
||||
return NULL;
|
||||
|
||||
return plr;
|
||||
}
|
||||
|
||||
Player* ObjectAccessor::FindPlayerByName(const char* name)
|
||||
{
|
||||
Guard guard(*HashMapHolder<Player>::GetLock());
|
||||
HashMapHolder<Player>::MapType& m = HashMapHolder<Player>::GetContainer();
|
||||
for (HashMapHolder<Player>::MapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
if (iter->second->IsInWorld() && strcmp(name, iter->second->GetName()) == 0)
|
||||
return iter->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ObjectAccessor::SaveAllPlayers()
|
||||
{
|
||||
Guard guard(*HashMapHolder<Player>::GetLock());
|
||||
HashMapHolder<Player>::MapType& m = HashMapHolder<Player>::GetContainer();
|
||||
for (HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||
itr->second->SaveToDB();
|
||||
}
|
||||
|
||||
Pet* ObjectAccessor::GetPet(uint64 guid)
|
||||
{
|
||||
return GetObjectInWorld(guid, (Pet*)NULL);
|
||||
}
|
||||
|
||||
Corpse* ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid)
|
||||
{
|
||||
Guard guard(i_corpseGuard);
|
||||
|
||||
Player2CorpsesMapType::iterator iter = i_player2corpse.find(guid);
|
||||
if (iter == i_player2corpse.end())
|
||||
return NULL;
|
||||
|
||||
assert(iter->second->GetType() != CORPSE_BONES);
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
void ObjectAccessor::RemoveCorpse(Corpse* corpse)
|
||||
{
|
||||
assert(corpse && corpse->GetType() != CORPSE_BONES);
|
||||
|
||||
if (corpse->FindMap())
|
||||
corpse->FindMap()->Remove(corpse, false);
|
||||
else
|
||||
corpse->RemoveFromWorld();
|
||||
|
||||
// Critical section
|
||||
{
|
||||
Guard guard(i_corpseGuard);
|
||||
|
||||
Player2CorpsesMapType::iterator iter = i_player2corpse.find(corpse->GetOwnerGUID());
|
||||
if (iter == i_player2corpse.end()) // TODO: Fix this
|
||||
return;
|
||||
|
||||
// build mapid*cellid -> guid_set map
|
||||
CellPair cell_pair = Trinity::ComputeCellPair(corpse->GetPositionX(), corpse->GetPositionY());
|
||||
uint32 cell_id = (cell_pair.y_coord * TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
|
||||
|
||||
objmgr.DeleteCorpseCellData(corpse->GetMapId(), cell_id, corpse->GetOwnerGUID());
|
||||
|
||||
i_player2corpse.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectAccessor::AddCorpse(Corpse* corpse)
|
||||
{
|
||||
assert(corpse && corpse->GetType() != CORPSE_BONES);
|
||||
|
||||
// Critical section
|
||||
{
|
||||
Guard guard(i_corpseGuard);
|
||||
|
||||
assert(i_player2corpse.find(corpse->GetOwnerGUID()) == i_player2corpse.end());
|
||||
i_player2corpse[corpse->GetOwnerGUID()] = corpse;
|
||||
|
||||
// build mapid*cellid -> guid_set map
|
||||
CellPair cell_pair = Trinity::ComputeCellPair(corpse->GetPositionX(), corpse->GetPositionY());
|
||||
uint32 cell_id = (cell_pair.y_coord * TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
|
||||
|
||||
objmgr.AddCorpseCellData(corpse->GetMapId(), cell_id, corpse->GetOwnerGUID(), corpse->GetInstanceId());
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectAccessor::AddCorpsesToGrid(GridPair const& gridpair, GridType& grid, Map* map)
|
||||
{
|
||||
Guard guard(i_corpseGuard);
|
||||
|
||||
for (Player2CorpsesMapType::iterator iter = i_player2corpse.begin(); iter != i_player2corpse.end(); ++iter)
|
||||
{
|
||||
if (iter->second->GetGrid() == gridpair)
|
||||
{
|
||||
// verify, if the corpse in our instance (add only corpses which are)
|
||||
if (map->Instanceable())
|
||||
{
|
||||
if (iter->second->GetInstanceId() == map->GetInstanceId())
|
||||
grid.AddWorldObject(iter->second);
|
||||
}
|
||||
else
|
||||
grid.AddWorldObject(iter->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Corpse* ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool /*insignia*/)
|
||||
{
|
||||
Corpse* corpse = GetCorpseForPlayerGUID(player_guid);
|
||||
if (!corpse)
|
||||
{
|
||||
//in fact this function is called from several places
|
||||
//even when player doesn't have a corpse, not an error
|
||||
// TODO: really, now...
|
||||
//sLog.outError("Try remove corpse that not in map for GUID %ul", player_guid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEBUG_LOG("Deleting Corpse and spawned bones.");
|
||||
|
||||
//Map* map = corpse->FindMap();
|
||||
|
||||
// remove corpse from player_guid -> corpse map
|
||||
RemoveCorpse(corpse);
|
||||
|
||||
// done in removecorpse
|
||||
// remove resurrectable corpse from grid object registry (loaded state checked into call)
|
||||
// do not load the map if it's not loaded
|
||||
//Map *map = MapManager::Instance().FindMap(corpse->GetMapId(), corpse->GetInstanceId());
|
||||
//if (map)
|
||||
// map->Remove(corpse, false);
|
||||
|
||||
// remove corpse from DB
|
||||
corpse->DeleteFromDB();
|
||||
|
||||
// we don't want bones to save some cpu.. :)
|
||||
delete corpse;
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
Corpse* bones = NULL;
|
||||
// create the bones only if the map and the grid is loaded at the corpse's location
|
||||
// ignore bones creating option in case insignia
|
||||
if (map && (insignia ||
|
||||
(map->IsBattleGroundOrArena() ? sWorld.getConfig(CONFIG_DEATH_BONES_BG_OR_ARENA) : sWorld.getConfig(CONFIG_DEATH_BONES_WORLD))) &&
|
||||
!map->IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY()))
|
||||
{
|
||||
// Create bones, don't change Corpse
|
||||
bones = new Corpse;
|
||||
bones->Create(corpse->GetGUIDLow(), map);
|
||||
|
||||
for (int i = 3; i < CORPSE_END; ++i) // don't overwrite guid and object type
|
||||
bones->SetUInt32Value(i, corpse->GetUInt32Value(i));
|
||||
|
||||
bones->SetGrid(corpse->GetGrid());
|
||||
// bones->m_time = m_time; // don't overwrite time
|
||||
// bones->m_inWorld = m_inWorld; // don't overwrite in-world state
|
||||
// bones->m_type = m_type; // don't overwrite type
|
||||
bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
|
||||
bones->SetPhaseMask(corpse->GetPhaseMask(), false);
|
||||
|
||||
bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);
|
||||
bones->SetUInt64Value(CORPSE_FIELD_OWNER, 0);
|
||||
|
||||
for (int i = 0; i < EQUIPMENT_SLOT_END; ++i)
|
||||
{
|
||||
if (corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i))
|
||||
bones->SetUInt32Value(CORPSE_FIELD_ITEM + i, 0);
|
||||
}
|
||||
|
||||
// add bones in grid store if grid loaded where corpse placed
|
||||
map->Add(bones);
|
||||
}
|
||||
|
||||
// all references to the corpse should be removed at this point
|
||||
delete corpse;
|
||||
|
||||
return bones;
|
||||
*/
|
||||
}
|
||||
|
||||
void ObjectAccessor::Update(uint32 /*diff*/)
|
||||
{
|
||||
UpdateDataMapType update_players;
|
||||
|
||||
// Critical section
|
||||
{
|
||||
Guard guard(i_updateGuard);
|
||||
|
||||
while (!i_objects.empty())
|
||||
{
|
||||
Object* obj = *i_objects.begin();
|
||||
assert(obj && obj->IsInWorld());
|
||||
i_objects.erase(i_objects.begin());
|
||||
obj->BuildUpdate(update_players);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/// Define the static members of HashMapHolder
|
||||
|
||||
template <class T> UNORDERED_MAP< uint64, T* > HashMapHolder<T>::m_objectMap;
|
||||
template <class T> ACE_Thread_Mutex HashMapHolder<T>::i_lock;
|
||||
|
||||
/// Global definitions for the hashmap storage
|
||||
|
||||
template class HashMapHolder<Player>;
|
||||
template class HashMapHolder<Pet>;
|
||||
template class HashMapHolder<GameObject>;
|
||||
template class HashMapHolder<DynamicObject>;
|
||||
template class HashMapHolder<Creature>;
|
||||
template class HashMapHolder<Corpse>;
|
||||
|
||||
template Player* ObjectAccessor::GetObjectInWorld<Player>(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/);
|
||||
template Pet* ObjectAccessor::GetObjectInWorld<Pet>(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/);
|
||||
template Creature* ObjectAccessor::GetObjectInWorld<Creature>(uint32 mapid, float x, float y, uint64 guid, Creature* /*fake*/);
|
||||
template Corpse* ObjectAccessor::GetObjectInWorld<Corpse>(uint32 mapid, float x, float y, uint64 guid, Corpse* /*fake*/);
|
||||
template GameObject* ObjectAccessor::GetObjectInWorld<GameObject>(uint32 mapid, float x, float y, uint64 guid, GameObject* /*fake*/);
|
||||
template DynamicObject* ObjectAccessor::GetObjectInWorld<DynamicObject>(uint32 mapid, float x, float y, uint64 guid, DynamicObject* /*fake*/);
|
||||
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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 TRINITY_OBJECTACCESSOR_H
|
||||
#define TRINITY_OBJECTACCESSOR_H
|
||||
|
||||
#include "Platform/Define.h"
|
||||
#include "Policies/Singleton.h"
|
||||
#include <ace/Thread_Mutex.h>
|
||||
#include "Utilities/UnorderedMap.h"
|
||||
#include "Policies/ThreadingModel.h"
|
||||
|
||||
#include "UpdateData.h"
|
||||
|
||||
#include "GridDefines.h"
|
||||
#include "Object.h"
|
||||
#include "Player.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
class Creature;
|
||||
class Corpse;
|
||||
class Unit;
|
||||
class GameObject;
|
||||
class DynamicObject;
|
||||
class WorldObject;
|
||||
class Map;
|
||||
|
||||
template <class T>
|
||||
class HashMapHolder
|
||||
{
|
||||
public:
|
||||
|
||||
typedef UNORDERED_MAP<uint64, T*> MapType;
|
||||
typedef ACE_Thread_Mutex LockType;
|
||||
typedef Trinity::GeneralLock<LockType> Guard;
|
||||
|
||||
static void Insert(T* o)
|
||||
{
|
||||
Guard guard(i_lock);
|
||||
m_objectMap[o->GetGUID()] = o;
|
||||
}
|
||||
|
||||
static void Remove(T* o)
|
||||
{
|
||||
Guard guard(i_lock);
|
||||
m_objectMap.erase(o->GetGUID());
|
||||
}
|
||||
|
||||
static T* Find(uint64 guid)
|
||||
{
|
||||
Guard guard(i_lock);
|
||||
typename MapType::iterator itr = m_objectMap.find(guid);
|
||||
return (itr != m_objectMap.end()) ? itr->second : NULL;
|
||||
}
|
||||
|
||||
static MapType& GetContainer() { return m_objectMap; }
|
||||
|
||||
static LockType* GetLock() { return &i_lock; }
|
||||
|
||||
private:
|
||||
|
||||
//Non instanceable only static
|
||||
HashMapHolder() {}
|
||||
|
||||
static LockType i_lock;
|
||||
static MapType m_objectMap;
|
||||
};
|
||||
|
||||
class ObjectAccessor : public Trinity::Singleton<ObjectAccessor, Trinity::ClassLevelLockable<ObjectAccessor, ACE_Thread_Mutex> >
|
||||
{
|
||||
friend class Trinity::OperatorNew<ObjectAccessor>;
|
||||
ObjectAccessor();
|
||||
~ObjectAccessor();
|
||||
ObjectAccessor(const ObjectAccessor&);
|
||||
ObjectAccessor& operator=(const ObjectAccessor&);
|
||||
|
||||
public:
|
||||
|
||||
typedef UNORDERED_MAP<uint64, Corpse*> Player2CorpsesMapType;
|
||||
typedef UNORDERED_MAP<Player*, UpdateData>::value_type UpdateDataValueType;
|
||||
|
||||
template<class T> static T* GetObjectInWorld(uint64 guid, T* /*fake*/)
|
||||
{
|
||||
return HashMapHolder<T>::Find(guid);
|
||||
}
|
||||
|
||||
static Unit* GetObjectInWorld(uint64 guid, Unit* /*fake*/)
|
||||
{
|
||||
if (!guid)
|
||||
return NULL;
|
||||
|
||||
if (IS_PLAYER_GUID(guid))
|
||||
{
|
||||
Unit* u = (Unit*)HashMapHolder<Player>::Find(guid);
|
||||
if (!u || !u->IsInWorld())
|
||||
return NULL;
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
if (IS_PET_GUID(guid))
|
||||
return (Unit*)HashMapHolder<Pet>::Find(guid);
|
||||
|
||||
return (Unit*)HashMapHolder<Creature>::Find(guid);
|
||||
}
|
||||
|
||||
static Unit* GetUnitInOrOutOfWorld(uint64 guid, Unit* /*fake*/)
|
||||
{
|
||||
if (!guid)
|
||||
return NULL;
|
||||
|
||||
if (IS_PLAYER_GUID(guid))
|
||||
{
|
||||
Unit* u = (Unit*)HashMapHolder<Player>::Find(guid);
|
||||
if (!u)
|
||||
return NULL;
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
// Other object types than player are unloaded while out of world
|
||||
return GetObjectInWorld(guid, (Unit*)NULL);
|
||||
}
|
||||
|
||||
template<class T> static T* GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, T* /*fake*/)
|
||||
{
|
||||
T* obj = HashMapHolder<T>::Find(guid);
|
||||
if (!obj || obj->GetMapId() != mapid)
|
||||
return NULL;
|
||||
|
||||
CellPair p = Trinity::ComputeCellPair(x, y);
|
||||
if (p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
||||
{
|
||||
sLog.outError("ObjectAccessor::GetObjectInWorld: invalid coordinates supplied X:%f Y:%f grid cell [%u:%u]", x, y, p.x_coord, p.y_coord);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CellPair q = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
|
||||
if (q.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || q.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
||||
{
|
||||
sLog.outError("ObjectAccessor::GetObjecInWorld: object (GUID: %u TypeId: %u) has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUIDLow(), obj->GetTypeId(), obj->GetPositionX(), obj->GetPositionY(), q.x_coord, q.y_coord);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32 dx = int32(p.x_coord) - int32(q.x_coord);
|
||||
int32 dy = int32(p.y_coord) - int32(q.y_coord);
|
||||
|
||||
if (dx > -2 && dx < 2 && dy > -2 && dy < 2)
|
||||
return obj;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static WorldObject* GetWorldObject(WorldObject const&, uint64);
|
||||
static Object* GetObjectByTypeMask(WorldObject const&, uint64, uint32 typemask);
|
||||
static Creature* GetCreatureOrPetOrVehicle(WorldObject const&, uint64);
|
||||
static Unit* GetUnit(WorldObject const&, uint64 guid) { return GetObjectInWorld(guid, (Unit*)NULL); }
|
||||
static Unit* GetUnitInOrOutOfWorld(WorldObject const&, uint64 guid) { return GetUnitInOrOutOfWorld(guid, (Unit*)NULL); }
|
||||
static Pet* GetPet(Unit const&, uint64 guid) { return GetPet(guid); }
|
||||
static Player* GetPlayer(Unit const&, uint64 guid) { return FindPlayer(guid); }
|
||||
static Corpse* GetCorpse(WorldObject const& u, uint64 guid);
|
||||
static Pet* GetPet(uint64 guid);
|
||||
static Player* FindPlayer(uint64);
|
||||
|
||||
Player* FindPlayerByName(const char* name) ;
|
||||
|
||||
// when using this, you must use the hashmapholder's lock
|
||||
HashMapHolder<Player>::MapType& GetPlayers()
|
||||
{
|
||||
return HashMapHolder<Player>::GetContainer();
|
||||
}
|
||||
|
||||
// when using this, you must use the hashmapholder's lock
|
||||
HashMapHolder<Creature>::MapType& GetCreatures()
|
||||
{
|
||||
return HashMapHolder<Creature>::GetContainer();
|
||||
}
|
||||
|
||||
// when using this, you must use the hashmapholder's lock
|
||||
HashMapHolder<GameObject>::MapType& GetGameObjects()
|
||||
{
|
||||
return HashMapHolder<GameObject>::GetContainer();
|
||||
}
|
||||
|
||||
template<class T> void AddObject(T* object)
|
||||
{
|
||||
HashMapHolder<T>::Insert(object);
|
||||
}
|
||||
|
||||
template<class T> void RemoveObject(T* object)
|
||||
{
|
||||
HashMapHolder<T>::Remove(object);
|
||||
}
|
||||
|
||||
void RemoveObject(Player* pl)
|
||||
{
|
||||
HashMapHolder<Player>::Remove(pl);
|
||||
RemoveUpdateObject((Object*)pl);
|
||||
}
|
||||
|
||||
void SaveAllPlayers();
|
||||
|
||||
void AddUpdateObject(Object* obj)
|
||||
{
|
||||
Guard guard(i_updateGuard);
|
||||
i_objects.insert(obj);
|
||||
}
|
||||
|
||||
void RemoveUpdateObject(Object* obj)
|
||||
{
|
||||
Guard guard(i_updateGuard);
|
||||
i_objects.erase(obj);
|
||||
}
|
||||
|
||||
void Update(uint32 diff);
|
||||
|
||||
Corpse* GetCorpseForPlayerGUID(uint64 guid);
|
||||
void RemoveCorpse(Corpse* corpse);
|
||||
void AddCorpse(Corpse* corpse);
|
||||
void AddCorpsesToGrid(GridPair const& gridpair, GridType& grid, Map* map);
|
||||
Corpse* ConvertCorpseForPlayer(uint64 player_guid, bool insignia = false);
|
||||
|
||||
typedef ACE_Thread_Mutex LockType;
|
||||
typedef Trinity::GeneralLock<LockType> Guard;
|
||||
|
||||
private:
|
||||
|
||||
Player2CorpsesMapType i_player2corpse;
|
||||
|
||||
static void _buildChangeObjectForPlayer(WorldObject*, UpdateDataMapType&);
|
||||
static void _buildPacket(Player*, Object*, UpdateDataMapType&);
|
||||
void _update();
|
||||
|
||||
std::set<Object*> i_objects;
|
||||
|
||||
LockType i_updateGuard;
|
||||
LockType i_corpseGuard;
|
||||
};
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user