Merge commit 'origin/master' into 330

This commit is contained in:
tomrus88 2009-10-22 18:50:58 +04:00
commit e7c56a0f45
29 changed files with 283 additions and 293 deletions

View file

@ -21,7 +21,7 @@
DROP TABLE IF EXISTS `character_db_version`; DROP TABLE IF EXISTS `character_db_version`;
CREATE TABLE `character_db_version` ( CREATE TABLE `character_db_version` (
`required_8596_01_characters_bugreport` bit(1) default NULL `required_8702_01_characters_character_reputation` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
-- --

View file

@ -345,6 +345,7 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
/*id fm familyMaskA fmMaskB icon vis cat eff aur ef name code */ /*id fm familyMaskA fmMaskB icon vis cat eff aur ef name code */
( 0, 3,0x0000000020000000,0x00000000, -1, -1, -1, 2, -1,-1,'Arcane Blast', 'Spell::EffectSchoolDMG'), ( 0, 3,0x0000000020000000,0x00000000, -1, -1, -1, 2, -1,-1,'Arcane Blast', 'Spell::EffectSchoolDMG'),
( 0, 9,0x0000000000000800,0x00000000, -1, -1, -1, 2, -1,-1,'Arcane Shot', 'Spell::EffectSchoolDMG'), ( 0, 9,0x0000000000000800,0x00000000, -1, -1, -1, 2, -1,-1,'Arcane Shot', 'Spell::EffectSchoolDMG'),
( 0, 5,0x0000000000004000,0x00000000, -1, -1, -1, -1, -1,-1,'Drain Soul', 'Aura::HandlePeriodicDamage'),
( 0,10,0x0000000000004000,0x00000000, -1, -1, -1, 2, -1,-1,'Avenger\'s Shield', 'Spell::EffectSchoolDMG'), ( 0,10,0x0000000000004000,0x00000000, -1, -1, -1, 2, -1,-1,'Avenger\'s Shield', 'Spell::EffectSchoolDMG'),
( 0, 4,0x0000040000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Bloodthirst', 'Spell::EffectSchoolDMG'), ( 0, 4,0x0000040000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Bloodthirst', 'Spell::EffectSchoolDMG'),
(0, 4,0x0000000000000001,0x00000000, -1, 867, -1, 3, -1,-1,'Charge', 'Spell::EffectDummy'), (0, 4,0x0000000000000001,0x00000000, -1, 867, -1, 3, -1,-1,'Charge', 'Spell::EffectDummy'),

View file

@ -0,0 +1,3 @@
ALTER TABLE character_db_version CHANGE COLUMN required_8596_01_characters_bugreport required_8702_01_characters_character_reputation bit;
UPDATE character_reputation SET standing = 0 WHERE faction IN (729, 730) AND standing < 0;

View file

@ -138,6 +138,7 @@ pkgdata_DATA = \
8676_01_mangos_creature_template.sql \ 8676_01_mangos_creature_template.sql \
8688_01_mangos_creature_template.sql \ 8688_01_mangos_creature_template.sql \
8693_01_mangos_spell_proc_event.sql \ 8693_01_mangos_spell_proc_event.sql \
8702_01_characters_character_reputation.sql \
README README
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'
@ -256,4 +257,5 @@ EXTRA_DIST = \
8676_01_mangos_creature_template.sql \ 8676_01_mangos_creature_template.sql \
8688_01_mangos_creature_template.sql \ 8688_01_mangos_creature_template.sql \
8693_01_mangos_spell_proc_event.sql \ 8693_01_mangos_spell_proc_event.sql \
8702_01_characters_character_reputation.sql \
README README

View file

@ -1778,7 +1778,7 @@ Creature* ChatHandler::getSelectedCreature()
if(!m_session) if(!m_session)
return NULL; return NULL;
return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection()); return m_session->GetPlayer()->GetMap()->GetCreatureOrPetOrVehicle(m_session->GetPlayer()->GetSelection());
} }
char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1) char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1)

View file

@ -369,7 +369,7 @@ void Creature::Update(uint32 diff)
uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), GetTypeId()); uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), GetTypeId());
if (poolid) if (poolid)
poolhandler.UpdatePool(poolid, GetGUIDLow(), GetTypeId()); poolhandler.UpdatePool(poolid, GetGUIDLow(), TYPEID_UNIT);
else else
GetMap()->Add(this); GetMap()->Add(this);
} }

View file

@ -580,7 +580,9 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
for (IdList::iterator itr = mGameEventPoolIds[internal_event_id].begin();itr != mGameEventPoolIds[internal_event_id].end();++itr) for (IdList::iterator itr = mGameEventPoolIds[internal_event_id].begin();itr != mGameEventPoolIds[internal_event_id].end();++itr)
{ {
poolhandler.SpawnPool(*itr); poolhandler.SpawnPool(*itr, 0, 0);
poolhandler.SpawnPool(*itr, 0, TYPEID_GAMEOBJECT);
poolhandler.SpawnPool(*itr, 0, TYPEID_UNIT);
} }
} }

View file

@ -79,7 +79,7 @@ void GameObject::RemoveFromWorld()
// Remove GO from owner // Remove GO from owner
if(uint64 owner_guid = GetOwnerGUID()) if(uint64 owner_guid = GetOwnerGUID())
{ {
if (Unit* owner = IS_PLAYER_GUID(owner_guid) ? ObjectAccessor::FindPlayer(owner_guid) : GetMap()->GetCreatureOrPet(owner_guid)) if (Unit* owner = ObjectAccessor::GetUnit(*this,owner_guid))
owner->RemoveGameObject(this,false); owner->RemoveGameObject(this,false);
else else
{ {

View file

@ -1093,6 +1093,10 @@ void LoadLootTemplates_Creature()
for(LootIdSet::const_iterator itr = ids_setUsed.begin(); itr != ids_setUsed.end(); ++itr) for(LootIdSet::const_iterator itr = ids_setUsed.begin(); itr != ids_setUsed.end(); ++itr)
ids_set.erase(*itr); ids_set.erase(*itr);
// for alterac valley we've defined Player-loot inside creature_loot_template id=0
// this hack is used, so that we won't need to create an extra table player_loot_template for just one case
ids_set.erase(0);
// output error for any still listed (not referenced from appropriate table) ids // output error for any still listed (not referenced from appropriate table) ids
LootTemplates_Creature.ReportUnusedIds(ids_set); LootTemplates_Creature.ReportUnusedIds(ids_set);
} }

View file

@ -202,7 +202,8 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0), i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0),
m_activeNonPlayersIter(m_activeNonPlayers.end()), m_activeNonPlayersIter(m_activeNonPlayers.end()),
i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this), i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this),
m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE) m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE),
m_hiDynObjectGuid(1), m_hiVehicleGuid(1)
{ {
for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx) for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
{ {
@ -775,7 +776,30 @@ bool Map::RemoveBones(uint64 guid, float x, float y)
{ {
if (IsRemovalGrid(x, y)) if (IsRemovalGrid(x, y))
{ {
Corpse * corpse = ObjectAccessor::Instance().GetObjectInWorld(GetId(), x, y, guid, (Corpse*)NULL); Corpse* corpse = ObjectAccessor::GetObjectInWorld(guid, (Corpse*)NULL);
if(!corpse || corpse->GetMapId() != GetId())
return false;
CellPair p = MaNGOS::ComputeCellPair(x,y);
if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP )
{
sLog.outError("Map::RemoveBones: invalid coordinates supplied X:%f Y:%f grid cell [%u:%u]", x, y, p.x_coord, p.y_coord);
return false;
}
CellPair q = MaNGOS::ComputeCellPair(corpse->GetPositionX(),corpse->GetPositionY());
if(q.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || q.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP )
{
sLog.outError("Map::RemoveBones: object (GUID: %u TypeId: %u) has invalid coordinates X:%f Y:%f grid cell [%u:%u]", corpse->GetGUIDLow(), corpse->GetTypeId(), corpse->GetPositionX(), corpse->GetPositionY(), q.x_coord, q.y_coord);
return false;
}
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 false;
if(corpse && corpse->GetTypeId() == TYPEID_CORPSE && corpse->GetType() == CORPSE_BONES) if(corpse && corpse->GetTypeId() == TYPEID_CORPSE && corpse->GetType() == CORPSE_BONES)
corpse->DeleteBonesFromWorld(); corpse->DeleteBonesFromWorld();
else else
@ -3401,12 +3425,18 @@ Pet* Map::GetPet(uint64 guid)
return m_objectsStore.find<Pet>(guid, (Pet*)NULL); return m_objectsStore.find<Pet>(guid, (Pet*)NULL);
} }
Unit* Map::GetCreatureOrPet(uint64 guid) Creature* Map::GetCreatureOrPetOrVehicle(uint64 guid)
{ {
if (Unit* ret = GetCreature(guid)) if (IS_PLAYER_GUID(guid))
return ret; return NULL;
if (IS_PET_GUID(guid))
return GetPet(guid); return GetPet(guid);
if (IS_VEHICLE_GUID(guid))
return GetVehicle(guid);
return GetCreature(guid);
} }
GameObject* Map::GetGameObject(uint64 guid) GameObject* Map::GetGameObject(uint64 guid)
@ -3440,3 +3470,31 @@ void Map::SendObjectUpdates()
packet.clear(); // clean the string packet.clear(); // clean the string
} }
} }
uint32 Map::GenerateLocalLowGuid(HighGuid guidhigh)
{
// TODO: for map local guid counters possible force reload map instead shutdown server at guid counter overflow
switch(guidhigh)
{
case HIGHGUID_DYNAMICOBJECT:
if (m_hiDynObjectGuid >= 0xFFFFFFFE)
{
sLog.outError("DynamicObject guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiDynObjectGuid++;
case HIGHGUID_VEHICLE:
if(m_hiVehicleGuid>=0x00FFFFFF)
{
sLog.outError("Vehicle guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiVehicleGuid++;
default:
ASSERT(0);
}
ASSERT(0);
return 0;
}

View file

@ -37,6 +37,7 @@
#include <bitset> #include <bitset>
#include <list> #include <list>
class Creature;
class Unit; class Unit;
class WorldPacket; class WorldPacket;
class InstanceData; class InstanceData;
@ -429,7 +430,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
Creature* GetCreature(uint64 guid); Creature* GetCreature(uint64 guid);
Vehicle* GetVehicle(uint64 guid); Vehicle* GetVehicle(uint64 guid);
Pet* GetPet(uint64 guid); Pet* GetPet(uint64 guid);
Unit* GetCreatureOrPet(uint64 guid); Creature* GetCreatureOrPetOrVehicle(uint64 guid);
GameObject* GetGameObject(uint64 guid); GameObject* GetGameObject(uint64 guid);
DynamicObject* GetDynamicObject(uint64 guid); DynamicObject* GetDynamicObject(uint64 guid);
@ -444,6 +445,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
{ {
i_objectsToClientUpdate.erase( obj ); i_objectsToClientUpdate.erase( obj );
} }
// DynObjects currently
uint32 GenerateLocalLowGuid(HighGuid guidhigh);
private: private:
void LoadMapAndVMap(int gx, int gy); void LoadMapAndVMap(int gx, int gy);
void LoadVMap(int gx, int gy); void LoadVMap(int gx, int gy);
@ -526,6 +530,10 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
std::set<WorldObject *> i_objectsToRemove; std::set<WorldObject *> i_objectsToRemove;
std::multimap<time_t, ScriptAction> m_scriptSchedule; std::multimap<time_t, ScriptAction> m_scriptSchedule;
// Map local low guid counters
uint32 m_hiDynObjectGuid;
uint32 m_hiVehicleGuid;
// Type specific code for add/remove to/from grid // Type specific code for add/remove to/from grid
template<class T> template<class T>
void AddToGrid(T*, NGridType *, Cell const&); void AddToGrid(T*, NGridType *, Cell const&);

View file

@ -505,7 +505,7 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
_player->m_movementInfo = mi; _player->m_movementInfo = mi;
// using charm guid, because we don't have vehicle guid... // using charm guid, because we don't have vehicle guid...
if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID)) if(Vehicle *vehicle = _player->GetMap()->GetVehicle(vehicleGUID))
{ {
// Aura::HandleAuraControlVehicle will call Player::ExitVehicle // Aura::HandleAuraControlVehicle will call Player::ExitVehicle
vehicle->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE); vehicle->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE);

View file

@ -50,21 +50,6 @@ ObjectAccessor::~ObjectAccessor()
delete itr->second; delete itr->second;
} }
Creature*
ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid)
{
if(IS_PLAYER_GUID(guid) || !u.IsInWorld())
return NULL;
if(IS_PET_GUID(guid))
return u.GetMap()->GetPet(guid);
if(IS_VEHICLE_GUID(guid))
return u.GetMap()->GetVehicle(guid);
return u.GetMap()->GetCreature(guid);
}
Unit* Unit*
ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid) ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid)
{ {
@ -74,7 +59,10 @@ ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid)
if(IS_PLAYER_GUID(guid)) if(IS_PLAYER_GUID(guid))
return FindPlayer(guid); return FindPlayer(guid);
return GetCreatureOrPetOrVehicle(u, guid); if (!u.IsInWorld())
return NULL;
return u.GetMap()->GetCreatureOrPetOrVehicle(guid);
} }
Corpse* Corpse*
@ -182,18 +170,6 @@ ObjectAccessor::SaveAllPlayers()
itr->second->SaveToDB(); itr->second->SaveToDB();
} }
Pet*
ObjectAccessor::GetPet(uint64 guid)
{
return GetObjectInWorld(guid, (Pet*)NULL);
}
Vehicle*
ObjectAccessor::GetVehicle(uint64 guid)
{
return GetObjectInWorld(guid, (Vehicle*)NULL);
}
Corpse* Corpse*
ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid) ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid)
{ {
@ -343,11 +319,3 @@ template class HashMapHolder<Corpse>;
/// Define the static member of ObjectAccessor /// Define the static member of ObjectAccessor
std::list<Map*> ObjectAccessor::i_mapList; std::list<Map*> ObjectAccessor::i_mapList;
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 Vehicle* ObjectAccessor::GetObjectInWorld<Vehicle>(uint32 mapid, float x, float y, uint64 guid, Vehicle* /*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*/);

View file

@ -30,16 +30,14 @@
#include "GridDefines.h" #include "GridDefines.h"
#include "Object.h" #include "Object.h"
#include "Player.h" #include "Player.h"
#include "Corpse.h"
#include <set> #include <set>
#include <list> #include <list>
class Creature; class Creature;
class Corpse;
class Unit; class Unit;
class GameObject; class GameObject;
class DynamicObject;
class Vehicle;
class WorldObject; class WorldObject;
class Map; class Map;
@ -90,46 +88,23 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
public: public:
typedef UNORDERED_MAP<uint64, Corpse* > Player2CorpsesMapType; typedef UNORDERED_MAP<uint64, Corpse* > Player2CorpsesMapType;
template<class T> static T* GetObjectInWorld(uint64 guid, T* /*fake*/) // global
{ static Player* GetObjectInWorld(uint64 guid, Player* /*fake*/) { return HashMapHolder<Player>::Find(guid); }
return HashMapHolder<T>::Find(guid); static Corpse* GetObjectInWorld(uint64 guid, Corpse* /*fake*/) { return HashMapHolder<Corpse>::Find(guid); }
} static Unit* GetObjectInWorld(uint64 guid, Unit* /*fake*/);
template<class T> static T* GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, T* /*fake*/) // map local object with global search
{ static Creature* GetObjectInWorld(uint64 guid, Creature* /*fake*/) { return FindHelper<Creature>(guid); }
T* obj = GetObjectInWorld(guid, (T*)NULL); static GameObject* GetObjectInWorld(uint64 guid, GameObject* /*fake*/) { return FindHelper<GameObject>(guid); }
if(!obj || obj->GetMapId() != mapid) return NULL; static Pet* GetObjectInWorld(uint64 guid, Pet* /*fake*/) { return FindHelper<Pet>(guid); }
static Vehicle* GetObjectInWorld(uint64 guid, Vehicle* /*fake*/); // no implementation, link error trap until creature move to Map
CellPair p = MaNGOS::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 = MaNGOS::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 WorldObject* GetWorldObject(WorldObject const &, uint64);
static Object* GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask); static Object* GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask);
static Creature* GetCreatureOrPetOrVehicle(WorldObject const &, uint64);
static Unit* GetUnit(WorldObject const &, uint64); static Unit* GetUnit(WorldObject const &, uint64);
static Pet* GetPet(Unit const &, uint64 guid) { return GetPet(guid); }
static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); } static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); }
static Corpse* GetCorpse(WorldObject const &u, uint64 guid); static Corpse* GetCorpse(WorldObject const &u, uint64 guid);
static Pet* GetPet(uint64 guid); static Pet* GetPet(uint64 guid) { return GetObjectInWorld(guid, (Pet*)NULL); }
static Vehicle* GetVehicle(uint64 guid);
static Player* FindPlayer(uint64); static Player* FindPlayer(uint64);
Player* FindPlayerByName(const char *name) ; Player* FindPlayerByName(const char *name) ;
@ -139,20 +114,11 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
return HashMapHolder<Player>::GetContainer(); return HashMapHolder<Player>::GetContainer();
} }
template<class T> void AddObject(T *object) // For call from Player/Corpse AddToWorld/RemoveFromWorld only
{ void AddObject(Corpse *object) { HashMapHolder<Corpse>::Insert(object); }
HashMapHolder<T>::Insert(object); void AddObject(Player *object) { HashMapHolder<Player>::Insert(object); }
} void RemoveObject(Corpse *object) { HashMapHolder<Corpse>::Remove(object); }
void RemoveObject(Player *object) { HashMapHolder<Player>::Remove(object); }
template<class T> void RemoveObject(T *object)
{
HashMapHolder<T>::Remove(object);
}
void RemoveObject(Player *pl)
{
HashMapHolder<Player>::Remove(pl);
}
void SaveAllPlayers(); void SaveAllPlayers();
@ -193,33 +159,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
LockType i_corpseGuard; LockType i_corpseGuard;
}; };
/// Out of class template specializations inline Unit* ObjectAccessor::GetObjectInWorld(uint64 guid, Unit* /*fake*/)
template <> inline Creature* ObjectAccessor::GetObjectInWorld(uint64 guid, Creature* /*fake*/)
{
return FindHelper<Creature>(guid);
}
template <> inline GameObject* ObjectAccessor::GetObjectInWorld(uint64 guid, GameObject* /*fake*/)
{
return FindHelper<GameObject>(guid);
}
template <> inline DynamicObject* ObjectAccessor::GetObjectInWorld(uint64 guid, DynamicObject* /*fake*/)
{
return FindHelper<DynamicObject>(guid);
}
template <> inline Pet* ObjectAccessor::GetObjectInWorld(uint64 guid, Pet* /*fake*/)
{
return FindHelper<Pet>(guid);
}
template <> inline Vehicle* ObjectAccessor::GetObjectInWorld(uint64 guid, Vehicle* /*fake*/)
{
return FindHelper<Vehicle>(guid);
}
template <> inline Unit* ObjectAccessor::GetObjectInWorld(uint64 guid, Unit* /*fake*/)
{ {
if(!guid) if(!guid)
return NULL; return NULL;
@ -234,9 +174,9 @@ template <> inline Unit* ObjectAccessor::GetObjectInWorld(uint64 guid, Unit* /*f
} }
if (IS_PET_GUID(guid)) if (IS_PET_GUID(guid))
return (Unit*)GetObjectInWorld<Pet>(guid, (Pet*)NULL); return GetObjectInWorld(guid, (Pet*)NULL);
return (Unit*)GetObjectInWorld<Creature>(guid, (Creature*)NULL); return GetObjectInWorld(guid, (Creature*)NULL);
} }
#endif #endif

View file

@ -104,6 +104,17 @@ template<> void addUnitState(Creature *obj, CellPair const& cell_pair)
obj->SetCurrentCell(cell); obj->SetCurrentCell(cell);
} }
template<class T> bool alreadyLoaded(Map* /*map*/, uint32 /*guid*/, T* /*fake*/)
{
// Non creature objects not walk by grids
return false;
}
template<> bool alreadyLoaded(Map* map, uint32 guid, Creature* fake)
{
return map->GetObjectsStore().find<Creature>(guid,fake);
}
template <class T> template <class T>
void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &m, uint32 &count, Map* map) void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &m, uint32 &count, Map* map)
{ {
@ -111,8 +122,16 @@ void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &
for(CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid) for(CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid)
{ {
T* obj = new T;
uint32 guid = *i_guid; uint32 guid = *i_guid;
// Note: this will fully correct work only at non-instanced maps,
// at instanced maps will use dynamic selected guid
// and then duplicate just will not detected and will be 2 creature with identical DB guid
// with some chance
if (alreadyLoaded(map,guid,(T*)NULL))
continue; // still loaded in another grid (move from respawn [this] grid early), we not need second copy
T* obj = new T;
//sLog.outString("DEBUG: LoadHelper from table: %s for (guid: %u) Loading",table,guid); //sLog.outString("DEBUG: LoadHelper from table: %s for (guid: %u) Loading",table,guid);
if(!obj->LoadFromDB(guid, map)) if(!obj->LoadFromDB(guid, map))
{ {

View file

@ -130,10 +130,8 @@ ObjectMgr::ObjectMgr()
m_hiCharGuid = 1; m_hiCharGuid = 1;
m_hiCreatureGuid = 1; m_hiCreatureGuid = 1;
m_hiPetGuid = 1; m_hiPetGuid = 1;
m_hiVehicleGuid = 1;
m_hiItemGuid = 1; m_hiItemGuid = 1;
m_hiGoGuid = 1; m_hiGoGuid = 1;
m_hiDoGuid = 1;
m_hiCorpseGuid = 1; m_hiCorpseGuid = 1;
m_hiPetNumber = 1; m_hiPetNumber = 1;
m_ItemTextId = 1; m_ItemTextId = 1;
@ -5686,13 +5684,6 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
World::StopNow(ERROR_EXIT_CODE); World::StopNow(ERROR_EXIT_CODE);
} }
return m_hiPetGuid++; return m_hiPetGuid++;
case HIGHGUID_VEHICLE:
if(m_hiVehicleGuid>=0x00FFFFFF)
{
sLog.outError("Vehicle guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiVehicleGuid++;
case HIGHGUID_PLAYER: case HIGHGUID_PLAYER:
if(m_hiCharGuid>=0xFFFFFFFE) if(m_hiCharGuid>=0xFFFFFFFE)
{ {
@ -5714,13 +5705,6 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
World::StopNow(ERROR_EXIT_CODE); World::StopNow(ERROR_EXIT_CODE);
} }
return m_hiCorpseGuid++; return m_hiCorpseGuid++;
case HIGHGUID_DYNAMICOBJECT:
if(m_hiDoGuid>=0xFFFFFFFE)
{
sLog.outError("DynamicObject guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiDoGuid++;
default: default:
ASSERT(0); ASSERT(0);
} }

View file

@ -24,7 +24,6 @@
#include "Bag.h" #include "Bag.h"
#include "Creature.h" #include "Creature.h"
#include "Player.h" #include "Player.h"
#include "DynamicObject.h"
#include "GameObject.h" #include "GameObject.h"
#include "Corpse.h" #include "Corpse.h"
#include "QuestDef.h" #include "QuestDef.h"
@ -789,10 +788,8 @@ class ObjectMgr
uint32 m_hiCharGuid; uint32 m_hiCharGuid;
uint32 m_hiCreatureGuid; uint32 m_hiCreatureGuid;
uint32 m_hiPetGuid; uint32 m_hiPetGuid;
uint32 m_hiVehicleGuid;
uint32 m_hiItemGuid; uint32 m_hiItemGuid;
uint32 m_hiGoGuid; uint32 m_hiGoGuid;
uint32 m_hiDoGuid;
uint32 m_hiCorpseGuid; uint32 m_hiCorpseGuid;
QuestMap mQuestTemplates; QuestMap mQuestTemplates;

View file

@ -276,7 +276,7 @@ void WorldSession::HandlePetNameQuery( WorldPacket & recv_data )
void WorldSession::SendPetNameQuery( uint64 petguid, uint32 petnumber) void WorldSession::SendPetNameQuery( uint64 petguid, uint32 petnumber)
{ {
Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, petguid); Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(petguid);
if(!pet || !pet->GetCharmInfo() || pet->GetCharmInfo()->GetPetNumber() != petnumber) if(!pet || !pet->GetCharmInfo() || pet->GetCharmInfo()->GetPetNumber() != petnumber)
return; return;
@ -308,12 +308,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
recv_data >> petguid; recv_data >> petguid;
// FIXME: charmed case Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(petguid);
//Pet* pet = ObjectAccessor::Instance().GetPet(petguid);
if(ObjectAccessor::FindPlayer(petguid))
return;
Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, petguid);
if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm())) if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm()))
{ {
@ -456,8 +451,7 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data )
return; return;
// pet/charmed // pet/charmed
Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); if (Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(guid))
if(pet)
{ {
if(pet->isPet()) if(pet->isPet())
{ {
@ -514,10 +508,7 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
if(!_player->GetPet() && !_player->GetCharm()) if(!_player->GetPet() && !_player->GetCharm())
return; return;
if(ObjectAccessor::FindPlayer(guid)) Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(guid);
return;
Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm())) if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm()))
{ {
@ -561,10 +552,7 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
if (!_player->GetPet() && !_player->GetCharm()) if (!_player->GetPet() && !_player->GetCharm())
return; return;
if (GUID_HIPART(guid) == HIGHGUID_PLAYER) Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(guid);
return;
Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
if (!pet || (pet != _player->GetPet() && pet!= _player->GetCharm())) if (!pet || (pet != _player->GetPet() && pet!= _player->GetCharm()))
{ {

View file

@ -2079,7 +2079,7 @@ Creature* Player::GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask)
return NULL; return NULL;
// exist (we need look pets also for some interaction (quest/etc) // exist (we need look pets also for some interaction (quest/etc)
Creature *unit = ObjectAccessor::GetCreatureOrPetOrVehicle(*this,guid); Creature *unit = GetMap()->GetCreatureOrPetOrVehicle(guid);
if (!unit) if (!unit)
return NULL; return NULL;
@ -12159,8 +12159,7 @@ void Player::PrepareQuestMenu( uint64 guid )
QuestRelations* pObjectQIR; QuestRelations* pObjectQIR;
// pets also can have quests // pets also can have quests
Creature *pCreature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, guid); if (Creature *pCreature = GetMap()->GetCreatureOrPetOrVehicle(guid))
if( pCreature )
{ {
pObject = (Object*)pCreature; pObject = (Object*)pCreature;
pObjectQR = &objmgr.mCreatureQuestRelations; pObjectQR = &objmgr.mCreatureQuestRelations;
@ -12254,8 +12253,7 @@ void Player::SendPreparedQuest(uint64 guid)
std::string title = ""; std::string title = "";
// need pet case for some quests // need pet case for some quests
Creature *pCreature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this,guid); if (Creature *pCreature = GetMap()->GetCreatureOrPetOrVehicle(guid))
if (pCreature)
{ {
uint32 textid = pCreature->GetNpcTextId(); uint32 textid = pCreature->GetNpcTextId();
GossipText const* gossiptext = objmgr.GetGossipText(textid); GossipText const* gossiptext = objmgr.GetGossipText(textid);
@ -12318,8 +12316,7 @@ Quest const * Player::GetNextQuest( uint64 guid, Quest const *pQuest )
QuestRelations* pObjectQR; QuestRelations* pObjectQR;
QuestRelations* pObjectQIR; QuestRelations* pObjectQIR;
Creature *pCreature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this,guid); if (Creature *pCreature = GetMap()->GetCreatureOrPetOrVehicle(guid))
if( pCreature )
{ {
pObject = (Object*)pCreature; pObject = (Object*)pCreature;
pObjectQR = &objmgr.mCreatureQuestRelations; pObjectQR = &objmgr.mCreatureQuestRelations;
@ -18831,7 +18828,7 @@ void Player::UpdateForQuestWorldObjects()
} }
else if(IS_CREATURE_GUID(*itr) || IS_VEHICLE_GUID(*itr)) else if(IS_CREATURE_GUID(*itr) || IS_VEHICLE_GUID(*itr))
{ {
Creature *obj = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, *itr); Creature *obj = GetMap()->GetCreatureOrPetOrVehicle(*itr);
if(!obj) if(!obj)
continue; continue;

View file

@ -28,13 +28,6 @@ INSTANTIATE_SINGLETON_1(PoolHandler);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Methods of template class PoolGroup // Methods of template class PoolGroup
template <class T>
PoolGroup<T>::PoolGroup()
{
m_SpawnedPoolAmount = 0;
m_LastDespawnedNode = 0;
}
// Method to add a gameobject/creature guid to the proper list depending on pool type and chance value // Method to add a gameobject/creature guid to the proper list depending on pool type and chance value
template <class T> template <class T>
void PoolGroup<T>::AddEntry(PoolObject& poolitem, uint32 maxentries) void PoolGroup<T>::AddEntry(PoolObject& poolitem, uint32 maxentries)
@ -73,26 +66,40 @@ bool PoolGroup<T>::IsSpawnedObject(uint32 guid)
return false; return false;
} }
// Method that return a guid of a rolled creature or gameobject
// Note: Copy from loot system because it's very similar and only few things change
template <class T> template <class T>
uint32 PoolGroup<T>::RollOne(void) void PoolGroup<T>::RollOne(int32& index, PoolObjectList** store, uint32 triggerFrom)
{ {
if (!ExplicitlyChanced.empty()) // First explicitly chanced entries are checked if (!ExplicitlyChanced.empty())
{ {
float roll = rand_chance(); float roll = (float)rand_chance();
for (uint32 i = 0; i < ExplicitlyChanced.size(); ++i) for (uint32 i = 0; i < ExplicitlyChanced.size(); ++i)
{ {
roll -= ExplicitlyChanced[i].chance; roll -= ExplicitlyChanced[i].chance;
if (roll < 0) // Triggering object is marked as spawned at this time and can be also rolled (respawn case)
return ExplicitlyChanced[i].guid; // so this need explicit check for this case
if (roll < 0 && (!ExplicitlyChanced[i].spawned || ExplicitlyChanced[i].guid == triggerFrom))
{
index = i;
*store = &ExplicitlyChanced;
return;
}
} }
} }
if (!EqualChanced.empty())
return EqualChanced[irand(0, EqualChanced.size()-1)].guid;
return 0; // None found if (!EqualChanced.empty())
{
index = irand(0, EqualChanced.size()-1);
// Triggering object is marked as spawned at this time and can be also rolled (respawn case)
// so this need explicit check for this case
if (!EqualChanced[index].spawned || EqualChanced[index].guid == triggerFrom)
{
*store = &EqualChanced;
return;
}
}
index = -1;
} }
// Main method to despawn a creature or gameobject in a pool // Main method to despawn a creature or gameobject in a pool
@ -107,11 +114,7 @@ void PoolGroup<T>::DespawnObject(uint32 guid)
{ {
if (!guid || EqualChanced[i].guid == guid) if (!guid || EqualChanced[i].guid == guid)
{ {
if (guid)
m_LastDespawnedNode = EqualChanced[i].guid;
else
Despawn1Object(EqualChanced[i].guid); Despawn1Object(EqualChanced[i].guid);
EqualChanced[i].spawned = false; EqualChanced[i].spawned = false;
if (m_SpawnedPoolAmount > 0) if (m_SpawnedPoolAmount > 0)
@ -119,6 +122,21 @@ void PoolGroup<T>::DespawnObject(uint32 guid)
} }
} }
} }
for (size_t i = 0; i < ExplicitlyChanced.size(); ++i)
{
if (ExplicitlyChanced[i].spawned)
{
if (!guid || ExplicitlyChanced[i].guid == guid)
{
Despawn1Object(ExplicitlyChanced[i].guid);
ExplicitlyChanced[i].spawned = false;
if (m_SpawnedPoolAmount > 0)
--m_SpawnedPoolAmount;
}
}
}
} }
// Method that is actualy doing the removal job on one creature // Method that is actualy doing the removal job on one creature
@ -176,58 +194,48 @@ void PoolGroup<Pool>::RemoveOneRelation(uint16 child_pool_id)
} }
} }
// Method that Spawn 1+ creatures or gameobject
// if cache is false (initialization or event start), X creatures are spawned with X <= limit (< if limit higher that the number of creatures in pool)
// if cache is true, this means only one has to be spawned (or respawned if the rolled one is same as cached one)
template <class T> template <class T>
void PoolGroup<T>::SpawnObject(uint32 limit, bool cache) void PoolGroup<T>::SpawnObject(uint32 limit, uint32 triggerFrom)
{ {
if (limit == 1) // This is the only case where explicit chance is used uint32 lastDespawned = 0;
int count = limit - m_SpawnedPoolAmount;
// If triggered from some object respawn this object is still marked as spawned
// and also counted into m_SpawnedPoolAmount so we need increase count to be
// spawned by 1
if (triggerFrom)
++count;
// This will try to spawn the rest of pool, not guaranteed
for (int i = 0; i < count; ++i)
{ {
uint32 roll = RollOne(); int index;
if (!cache || (cache && m_LastDespawnedNode != roll)) PoolObjectList* store;
RollOne(index, &store, triggerFrom);
if (index == -1)
continue;
if ((*store)[index].guid == lastDespawned)
continue;
if ((*store)[index].guid == triggerFrom)
{ {
if (cache) (*store)[index].spawned = ReSpawn1Object(triggerFrom);
Despawn1Object(m_LastDespawnedNode); triggerFrom = 0;
Spawn1Object(roll); continue;
} }
else else
ReSpawn1Object(roll); (*store)[index].spawned = Spawn1Object((*store)[index].guid);
m_LastDespawnedNode = 0;
}
else if (limit < EqualChanced.size() && m_SpawnedPoolAmount < limit)
{
std::vector<uint32> IndexList;
for (size_t i = 0; i < EqualChanced.size(); ++i)
if (!EqualChanced[i].spawned)
IndexList.push_back(i);
while (m_SpawnedPoolAmount < limit && IndexList.size() > 0) if (triggerFrom)
{ {
uint32 roll = urand(1, IndexList.size()) - 1; // One spawn one despawn no count increase
uint32 index = IndexList[roll]; DespawnObject(triggerFrom);
if (!cache || (cache && EqualChanced[index].guid != m_LastDespawnedNode)) lastDespawned = triggerFrom;
{ triggerFrom = 0;
if (cache)
Despawn1Object(m_LastDespawnedNode);
EqualChanced[index].spawned = Spawn1Object(EqualChanced[index].guid);
} }
else else
EqualChanced[index].spawned = ReSpawn1Object(EqualChanced[index].guid); ++m_SpawnedPoolAmount;
if (EqualChanced[index].spawned)
++m_SpawnedPoolAmount; // limited group use the Spawned variable to store the number of actualy spawned creatures
std::vector<uint32>::iterator itr = IndexList.begin()+roll;
IndexList.erase(itr);
}
m_LastDespawnedNode = 0;
}
else // Not enough objects in pool, so spawn all
{
for (size_t i = 0; i < EqualChanced.size(); ++i)
EqualChanced[i].spawned = Spawn1Object(EqualChanced[i].guid);
} }
} }
@ -235,8 +243,7 @@ void PoolGroup<T>::SpawnObject(uint32 limit, bool cache)
template <> template <>
bool PoolGroup<Creature>::Spawn1Object(uint32 guid) bool PoolGroup<Creature>::Spawn1Object(uint32 guid)
{ {
CreatureData const* data = objmgr.GetCreatureData(guid); if (CreatureData const* data = objmgr.GetCreatureData(guid))
if (data)
{ {
objmgr.AddCreatureToGrid(guid, data); objmgr.AddCreatureToGrid(guid, data);
@ -250,12 +257,11 @@ bool PoolGroup<Creature>::Spawn1Object(uint32 guid)
if (!pCreature->LoadFromDB(guid, map)) if (!pCreature->LoadFromDB(guid, map))
{ {
delete pCreature; delete pCreature;
return false;
} }
else else
{
map->Add(pCreature); map->Add(pCreature);
} }
}
return true; return true;
} }
return false; return false;
@ -265,8 +271,7 @@ bool PoolGroup<Creature>::Spawn1Object(uint32 guid)
template <> template <>
bool PoolGroup<GameObject>::Spawn1Object(uint32 guid) bool PoolGroup<GameObject>::Spawn1Object(uint32 guid)
{ {
GameObjectData const* data = objmgr.GetGOData(guid); if (GameObjectData const* data = objmgr.GetGOData(guid))
if (data)
{ {
objmgr.AddGameobjectToGrid(guid, data); objmgr.AddGameobjectToGrid(guid, data);
// Spawn if necessary (loaded grids only) // Spawn if necessary (loaded grids only)
@ -280,6 +285,7 @@ bool PoolGroup<GameObject>::Spawn1Object(uint32 guid)
if (!pGameobject->LoadFromDB(guid, map)) if (!pGameobject->LoadFromDB(guid, map))
{ {
delete pGameobject; delete pGameobject;
return false;
} }
else else
{ {
@ -296,7 +302,9 @@ bool PoolGroup<GameObject>::Spawn1Object(uint32 guid)
template <> template <>
bool PoolGroup<Pool>::Spawn1Object(uint32 child_pool_id) bool PoolGroup<Pool>::Spawn1Object(uint32 child_pool_id)
{ {
poolhandler.SpawnPool(child_pool_id); poolhandler.SpawnPool(child_pool_id, 0, 0);
poolhandler.SpawnPool(child_pool_id, 0, TYPEID_GAMEOBJECT);
poolhandler.SpawnPool(child_pool_id, 0, TYPEID_UNIT);
return true; return true;
} }
@ -304,8 +312,7 @@ bool PoolGroup<Pool>::Spawn1Object(uint32 child_pool_id)
template <> template <>
bool PoolGroup<Creature>::ReSpawn1Object(uint32 guid) bool PoolGroup<Creature>::ReSpawn1Object(uint32 guid)
{ {
CreatureData const* data = objmgr.GetCreatureData(guid); if (CreatureData const* data = objmgr.GetCreatureData(guid))
if (data)
{ {
if (Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_UNIT), (Creature*)NULL)) if (Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_UNIT), (Creature*)NULL))
pCreature->GetMap()->Add(pCreature); pCreature->GetMap()->Add(pCreature);
@ -318,8 +325,7 @@ bool PoolGroup<Creature>::ReSpawn1Object(uint32 guid)
template <> template <>
bool PoolGroup<GameObject>::ReSpawn1Object(uint32 guid) bool PoolGroup<GameObject>::ReSpawn1Object(uint32 guid)
{ {
GameObjectData const* data = objmgr.GetGOData(guid); if (GameObjectData const* data = objmgr.GetGOData(guid))
if (data)
{ {
if (GameObject* pGameobject = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL)) if (GameObject* pGameobject = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL))
pGameobject->GetMap()->Add(pGameobject); pGameobject->GetMap()->Add(pGameobject);
@ -628,7 +634,9 @@ void PoolHandler::Initialize()
sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", pool_entry); sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", pool_entry);
continue; continue;
} }
SpawnPool(pool_entry); SpawnPool(pool_entry, 0, 0);
SpawnPool(pool_entry, 0, TYPEID_GAMEOBJECT);
SpawnPool(pool_entry, 0, TYPEID_UNIT);
count++; count++;
} while (result->NextRow()); } while (result->NextRow());
delete result; delete result;
@ -640,25 +648,35 @@ void PoolHandler::Initialize()
// Call to spawn a pool, if cache if true the method will spawn only if cached entry is different // Call to spawn a pool, if cache if true the method will spawn only if cached entry is different
// If it's same, the gameobject/creature is respawned only (added back to map) // If it's same, the gameobject/creature is respawned only (added back to map)
void PoolHandler::SpawnPool(uint16 pool_id, bool cache) void PoolHandler::SpawnPool(uint16 pool_id, uint32 guid, uint32 type)
{ {
if (!mPoolPoolGroups[pool_id].isEmpty()) switch (type)
mPoolPoolGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, cache); {
if (!mPoolGameobjectGroups[pool_id].isEmpty()) case TYPEID_UNIT:
mPoolGameobjectGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, cache);
if (!mPoolCreatureGroups[pool_id].isEmpty()) if (!mPoolCreatureGroups[pool_id].isEmpty())
mPoolCreatureGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, cache); mPoolCreatureGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, guid);
break;
case TYPEID_GAMEOBJECT:
if (!mPoolGameobjectGroups[pool_id].isEmpty())
mPoolGameobjectGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, guid);
break;
default:
if (!mPoolPoolGroups[pool_id].isEmpty())
mPoolPoolGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, guid);
}
} }
// Call to despawn a pool, all gameobjects/creatures in this pool are removed // Call to despawn a pool, all gameobjects/creatures in this pool are removed
void PoolHandler::DespawnPool(uint16 pool_id) void PoolHandler::DespawnPool(uint16 pool_id)
{ {
if (!mPoolPoolGroups[pool_id].isEmpty())
mPoolPoolGroups[pool_id].DespawnObject();
if (!mPoolGameobjectGroups[pool_id].isEmpty())
mPoolGameobjectGroups[pool_id].DespawnObject();
if (!mPoolCreatureGroups[pool_id].isEmpty()) if (!mPoolCreatureGroups[pool_id].isEmpty())
mPoolCreatureGroups[pool_id].DespawnObject(); mPoolCreatureGroups[pool_id].DespawnObject();
if (!mPoolGameobjectGroups[pool_id].isEmpty())
mPoolGameobjectGroups[pool_id].DespawnObject();
if (!mPoolPoolGroups[pool_id].isEmpty())
mPoolPoolGroups[pool_id].DespawnObject();
} }
// Call to update the pool when a gameobject/creature part of pool [pool_id] is ready to respawn // Call to update the pool when a gameobject/creature part of pool [pool_id] is ready to respawn
@ -666,19 +684,10 @@ void PoolHandler::DespawnPool(uint16 pool_id)
// Then the spawn pool call will use this cache to decide // Then the spawn pool call will use this cache to decide
void PoolHandler::UpdatePool(uint16 pool_id, uint32 guid, uint32 type) void PoolHandler::UpdatePool(uint16 pool_id, uint32 guid, uint32 type)
{ {
uint16 motherpoolid = IsPartOfAPool(pool_id, 0); if (uint16 motherpoolid = IsPartOfAPool(pool_id, 0))
SpawnPool(motherpoolid, 0, 0);
if (motherpoolid)
mPoolPoolGroups[motherpoolid].DespawnObject(pool_id);
else if (type == TYPEID_GAMEOBJECT && !mPoolGameobjectGroups[pool_id].isEmpty())
mPoolGameobjectGroups[pool_id].DespawnObject(guid);
else if (type != TYPEID_GAMEOBJECT && !mPoolCreatureGroups[pool_id].isEmpty())
mPoolCreatureGroups[pool_id].DespawnObject(guid);
if (motherpoolid)
SpawnPool(motherpoolid, true);
else else
SpawnPool(pool_id, true); SpawnPool(pool_id, guid, type);
} }
// Method that tell if the gameobject/creature is part of a pool and return the pool id if yes // Method that tell if the gameobject/creature is part of a pool and return the pool id if yes

View file

@ -40,25 +40,24 @@ struct PoolObject
template <class T> template <class T>
class PoolGroup class PoolGroup
{ {
typedef std::vector<PoolObject> PoolObjectList;
public: public:
PoolGroup(); PoolGroup() : m_SpawnedPoolAmount(0) { }
~PoolGroup() {}; ~PoolGroup() {};
bool isEmpty() { return ExplicitlyChanced.empty() && EqualChanced.empty(); } bool isEmpty() { return ExplicitlyChanced.empty() && EqualChanced.empty(); }
void AddEntry(PoolObject& poolitem, uint32 maxentries); void AddEntry(PoolObject& poolitem, uint32 maxentries);
bool CheckPool(void); bool CheckPool(void);
uint32 RollOne(void); void RollOne(int32& index, PoolObjectList** store, uint32 triggerFrom);
bool IsSpawnedObject(uint32 guid); bool IsSpawnedObject(uint32 guid);
void DespawnObject(uint32 guid=0); void DespawnObject(uint32 guid=0);
void Despawn1Object(uint32 guid); void Despawn1Object(uint32 guid);
void SpawnObject(uint32 limit, bool cache=false); void SpawnObject(uint32 limit, uint32 triggerFrom);
bool Spawn1Object(uint32 guid); bool Spawn1Object(uint32 guid);
bool ReSpawn1Object(uint32 guid); bool ReSpawn1Object(uint32 guid);
void RemoveOneRelation(uint16 child_pool_id); void RemoveOneRelation(uint16 child_pool_id);
private: private:
typedef std::vector<PoolObject> PoolObjectList;
PoolObjectList ExplicitlyChanced; PoolObjectList ExplicitlyChanced;
PoolObjectList EqualChanced; PoolObjectList EqualChanced;
uint32 m_LastDespawnedNode; // Store the guid of the removed creature/gameobject during a pool update
uint32 m_SpawnedPoolAmount; // Used to know the number of spawned objects uint32 m_SpawnedPoolAmount; // Used to know the number of spawned objects
}; };
@ -75,7 +74,7 @@ class PoolHandler
uint16 IsPartOfAPool(uint32 guid, uint32 type); uint16 IsPartOfAPool(uint32 guid, uint32 type);
bool IsSpawnedObject(uint16 pool_id, uint32 guid, uint32 type); bool IsSpawnedObject(uint16 pool_id, uint32 guid, uint32 type);
bool CheckPool(uint16 pool_id); bool CheckPool(uint16 pool_id);
void SpawnPool(uint16 pool_id, bool cache=false); void SpawnPool(uint16 pool_id, uint32 guid, uint32 type);
void DespawnPool(uint16 pool_id); void DespawnPool(uint16 pool_id);
void UpdatePool(uint16 pool_id, uint32 guid, uint32 type); void UpdatePool(uint16 pool_id, uint32 guid, uint32 type);
void Initialize(); void Initialize();

View file

@ -645,7 +645,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
if (IS_CREATURE_OR_PET_GUID(*itr)) if (IS_CREATURE_OR_PET_GUID(*itr))
{ {
// need also pet quests case support // need also pet quests case support
Creature *questgiver = ObjectAccessor::GetCreatureOrPetOrVehicle(*GetPlayer(),*itr); Creature *questgiver = GetPlayer()->GetMap()->GetCreatureOrPetOrVehicle(*itr);
if(!questgiver || questgiver->IsHostileTo(_player)) if(!questgiver || questgiver->IsHostileTo(_player))
continue; continue;
if(!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER)) if(!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER))

View file

@ -4509,6 +4509,17 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
} }
break; break;
} }
case SPELLFAMILY_WARLOCK:
{
// Drain Soul
if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000004000))
{
if (m_target->GetHealth() * 100 / m_target->GetMaxHealth() <= 25)
m_modifier.m_amount *= 4;
return;
}
break;
}
case SPELLFAMILY_DRUID: case SPELLFAMILY_DRUID:
{ {
// Rake // Rake

View file

@ -2872,7 +2872,7 @@ void Spell::EffectPersistentAA(uint32 i)
int32 duration = GetSpellDuration(m_spellInfo); int32 duration = GetSpellDuration(m_spellInfo);
DynamicObject* dynObj = new DynamicObject; DynamicObject* dynObj = new DynamicObject;
if (!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, radius)) if (!dynObj->Create(m_caster->GetMap()->GenerateLocalLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, radius))
{ {
delete dynObj; delete dynObj;
return; return;
@ -3679,7 +3679,7 @@ void Spell::EffectAddFarsight(uint32 i)
DynamicObject* dynObj = new DynamicObject; DynamicObject* dynObj = new DynamicObject;
// set radius to 0: spell not expected to work as persistent aura // set radius to 0: spell not expected to work as persistent aura
if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, 0)) if(!dynObj->Create(m_caster->GetMap()->GenerateLocalLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, i, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, 0))
{ {
delete dynObj; delete dynObj;
return; return;

View file

@ -458,7 +458,7 @@ void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
return; return;
} }
Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid); Creature* pet = GetPlayer()->GetMap()->GetCreatureOrPetOrVehicle(guid);
if(!pet) if(!pet)
{ {
@ -550,7 +550,7 @@ void WorldSession::HandleSpellClick( WorldPacket & recv_data )
if (_player->isInCombat()) // client prevent click and set different icon at combat state if (_player->isInCombat()) // client prevent click and set different icon at combat state
return; return;
Creature *unit = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); Creature *unit = _player->GetMap()->GetCreatureOrPetOrVehicle(guid);
if (!unit || unit->isInCombat()) // client prevent click and set different icon at combat state if (!unit || unit->isInCombat()) // client prevent click and set different icon at combat state
return; return;

View file

@ -2665,7 +2665,7 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell)
uint32 rand = urand(0,10000); uint32 rand = urand(0,10000);
if (rand < tmp) if (rand < tmp)
return SPELL_MISS_RESIST; return SPELL_MISS_MISS;
// cast by caster in front of victim // cast by caster in front of victim
if (pVictim->HasInArc(M_PI,this)) if (pVictim->HasInArc(M_PI,this))

View file

@ -626,7 +626,7 @@ bool ChatHandler::HandleDebugSpawnVehicle(const char* args)
Vehicle *v = new Vehicle; Vehicle *v = new Vehicle;
Map *map = m_session->GetPlayer()->GetMap(); Map *map = m_session->GetPlayer()->GetMap();
if (!v->Create(objmgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, entry, id, m_session->GetPlayer()->GetTeam())) if (!v->Create(map->GenerateLocalLowGuid(HIGHGUID_VEHICLE), map, entry, id, m_session->GetPlayer()->GetTeam()))
{ {
delete v; delete v;
return false; return false;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "8700" #define REVISION_NR "8710"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__ #ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__ #define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_8596_01_characters_bugreport" #define REVISION_DB_CHARACTERS "required_8702_01_characters_character_reputation"
#define REVISION_DB_MANGOS "required_8693_01_mangos_spell_proc_event" #define REVISION_DB_MANGOS "required_8693_01_mangos_spell_proc_event"
#define REVISION_DB_REALMD "required_8332_01_realmd_realmcharacters" #define REVISION_DB_REALMD "required_8332_01_realmd_realmcharacters"
#endif // __REVISION_SQL_H__ #endif // __REVISION_SQL_H__