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`;
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';
--

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 */
( 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, 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, 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'),

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 \
8688_01_mangos_creature_template.sql \
8693_01_mangos_spell_proc_event.sql \
8702_01_characters_character_reputation.sql \
README
## Additional files to include when running 'make dist'
@ -256,4 +257,5 @@ EXTRA_DIST = \
8676_01_mangos_creature_template.sql \
8688_01_mangos_creature_template.sql \
8693_01_mangos_spell_proc_event.sql \
8702_01_characters_character_reputation.sql \
README

View file

@ -1778,7 +1778,7 @@ Creature* ChatHandler::getSelectedCreature()
if(!m_session)
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)

View file

@ -369,7 +369,7 @@ void Creature::Update(uint32 diff)
uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), GetTypeId());
if (poolid)
poolhandler.UpdatePool(poolid, GetGUIDLow(), GetTypeId());
poolhandler.UpdatePool(poolid, GetGUIDLow(), TYPEID_UNIT);
else
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)
{
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
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);
else
{

View file

@ -1093,6 +1093,10 @@ void LoadLootTemplates_Creature()
for(LootIdSet::const_iterator itr = ids_setUsed.begin(); itr != ids_setUsed.end(); ++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
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),
m_activeNonPlayersIter(m_activeNonPlayers.end()),
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)
{
@ -775,7 +776,30 @@ bool Map::RemoveBones(uint64 guid, float x, float 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)
corpse->DeleteBonesFromWorld();
else
@ -3401,12 +3425,18 @@ Pet* Map::GetPet(uint64 guid)
return m_objectsStore.find<Pet>(guid, (Pet*)NULL);
}
Unit* Map::GetCreatureOrPet(uint64 guid)
Creature* Map::GetCreatureOrPetOrVehicle(uint64 guid)
{
if (Unit* ret = GetCreature(guid))
return ret;
if (IS_PLAYER_GUID(guid))
return NULL;
return GetPet(guid);
if (IS_PET_GUID(guid))
return GetPet(guid);
if (IS_VEHICLE_GUID(guid))
return GetVehicle(guid);
return GetCreature(guid);
}
GameObject* Map::GetGameObject(uint64 guid)
@ -3439,4 +3469,32 @@ void Map::SendObjectUpdates()
iter->first->GetSession()->SendPacket(&packet);
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 <list>
class Creature;
class Unit;
class WorldPacket;
class InstanceData;
@ -429,7 +430,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
Creature* GetCreature(uint64 guid);
Vehicle* GetVehicle(uint64 guid);
Pet* GetPet(uint64 guid);
Unit* GetCreatureOrPet(uint64 guid);
Creature* GetCreatureOrPetOrVehicle(uint64 guid);
GameObject* GetGameObject(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 );
}
// DynObjects currently
uint32 GenerateLocalLowGuid(HighGuid guidhigh);
private:
void LoadMapAndVMap(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::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
template<class T>
void AddToGrid(T*, NGridType *, Cell const&);

View file

@ -505,7 +505,7 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
_player->m_movementInfo = mi;
// 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
vehicle->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE);

View file

@ -50,21 +50,6 @@ ObjectAccessor::~ObjectAccessor()
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*
ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid)
{
@ -74,7 +59,10 @@ ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid)
if(IS_PLAYER_GUID(guid))
return FindPlayer(guid);
return GetCreatureOrPetOrVehicle(u, guid);
if (!u.IsInWorld())
return NULL;
return u.GetMap()->GetCreatureOrPetOrVehicle(guid);
}
Corpse*
@ -182,18 +170,6 @@ ObjectAccessor::SaveAllPlayers()
itr->second->SaveToDB();
}
Pet*
ObjectAccessor::GetPet(uint64 guid)
{
return GetObjectInWorld(guid, (Pet*)NULL);
}
Vehicle*
ObjectAccessor::GetVehicle(uint64 guid)
{
return GetObjectInWorld(guid, (Vehicle*)NULL);
}
Corpse*
ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid)
{
@ -343,11 +319,3 @@ template class HashMapHolder<Corpse>;
/// Define the static member of ObjectAccessor
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 "Object.h"
#include "Player.h"
#include "Corpse.h"
#include <set>
#include <list>
class Creature;
class Corpse;
class Unit;
class GameObject;
class DynamicObject;
class Vehicle;
class WorldObject;
class Map;
@ -90,46 +88,23 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
public:
typedef UNORDERED_MAP<uint64, Corpse* > Player2CorpsesMapType;
template<class T> static T* GetObjectInWorld(uint64 guid, T* /*fake*/)
{
return HashMapHolder<T>::Find(guid);
}
// global
static Player* GetObjectInWorld(uint64 guid, Player* /*fake*/) { return HashMapHolder<Player>::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*/)
{
T* obj = GetObjectInWorld(guid, (T*)NULL);
if(!obj || obj->GetMapId() != mapid) return NULL;
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;
}
// map local object with global search
static Creature* GetObjectInWorld(uint64 guid, Creature* /*fake*/) { return FindHelper<Creature>(guid); }
static GameObject* GetObjectInWorld(uint64 guid, GameObject* /*fake*/) { return FindHelper<GameObject>(guid); }
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
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);
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 Vehicle* GetVehicle(uint64 guid);
static Pet* GetPet(uint64 guid) { return GetObjectInWorld(guid, (Pet*)NULL); }
static Player* FindPlayer(uint64);
Player* FindPlayerByName(const char *name) ;
@ -139,20 +114,11 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
return HashMapHolder<Player>::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);
}
// For call from Player/Corpse AddToWorld/RemoveFromWorld only
void AddObject(Corpse *object) { HashMapHolder<Corpse>::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); }
void SaveAllPlayers();
@ -193,33 +159,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
LockType i_corpseGuard;
};
/// Out of class template specializations
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*/)
inline Unit* ObjectAccessor::GetObjectInWorld(uint64 guid, Unit* /*fake*/)
{
if(!guid)
return NULL;
@ -234,9 +174,9 @@ template <> inline Unit* ObjectAccessor::GetObjectInWorld(uint64 guid, Unit* /*f
}
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

View file

@ -104,6 +104,17 @@ template<> void addUnitState(Creature *obj, CellPair const& cell_pair)
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>
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)
{
T* obj = new T;
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);
if(!obj->LoadFromDB(guid, map))
{

View file

@ -130,10 +130,8 @@ ObjectMgr::ObjectMgr()
m_hiCharGuid = 1;
m_hiCreatureGuid = 1;
m_hiPetGuid = 1;
m_hiVehicleGuid = 1;
m_hiItemGuid = 1;
m_hiGoGuid = 1;
m_hiDoGuid = 1;
m_hiCorpseGuid = 1;
m_hiPetNumber = 1;
m_ItemTextId = 1;
@ -5686,13 +5684,6 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
World::StopNow(ERROR_EXIT_CODE);
}
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:
if(m_hiCharGuid>=0xFFFFFFFE)
{
@ -5714,13 +5705,6 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
World::StopNow(ERROR_EXIT_CODE);
}
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:
ASSERT(0);
}

View file

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

View file

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

View file

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

View file

@ -28,13 +28,6 @@ INSTANTIATE_SINGLETON_1(PoolHandler);
////////////////////////////////////////////////////////////
// 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
template <class T>
void PoolGroup<T>::AddEntry(PoolObject& poolitem, uint32 maxentries)
@ -64,35 +57,49 @@ bool PoolGroup<T>::CheckPool(void)
template <class T>
bool PoolGroup<T>::IsSpawnedObject(uint32 guid)
{
for (uint32 i=0; i<ExplicitlyChanced.size(); ++i)
for (uint32 i = 0; i < ExplicitlyChanced.size(); ++i)
if (ExplicitlyChanced[i].guid == guid)
return ExplicitlyChanced[i].spawned;
for (uint32 i=0; i<EqualChanced.size(); ++i)
for (uint32 i = 0; i < EqualChanced.size(); ++i)
if (EqualChanced[i].guid == guid)
return EqualChanced[i].spawned;
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>
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;
if (roll < 0)
return ExplicitlyChanced[i].guid;
// 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 (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
@ -101,17 +108,13 @@ uint32 PoolGroup<T>::RollOne(void)
template<class T>
void PoolGroup<T>::DespawnObject(uint32 guid)
{
for (size_t i=0; i < EqualChanced.size(); ++i)
for (size_t i = 0; i < EqualChanced.size(); ++i)
{
if (EqualChanced[i].spawned)
{
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;
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
@ -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>
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();
if (!cache || (cache && m_LastDespawnedNode != roll))
int index;
PoolObjectList* store;
RollOne(index, &store, triggerFrom);
if (index == -1)
continue;
if ((*store)[index].guid == lastDespawned)
continue;
if ((*store)[index].guid == triggerFrom)
{
if (cache)
Despawn1Object(m_LastDespawnedNode);
Spawn1Object(roll);
(*store)[index].spawned = ReSpawn1Object(triggerFrom);
triggerFrom = 0;
continue;
}
else
ReSpawn1Object(roll);
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);
(*store)[index].spawned = Spawn1Object((*store)[index].guid);
while (m_SpawnedPoolAmount < limit && IndexList.size() > 0)
if (triggerFrom)
{
uint32 roll = urand(1, IndexList.size()) - 1;
uint32 index = IndexList[roll];
if (!cache || (cache && EqualChanced[index].guid != m_LastDespawnedNode))
{
if (cache)
Despawn1Object(m_LastDespawnedNode);
EqualChanced[index].spawned = Spawn1Object(EqualChanced[index].guid);
}
else
EqualChanced[index].spawned = ReSpawn1Object(EqualChanced[index].guid);
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);
// One spawn one despawn no count increase
DespawnObject(triggerFrom);
lastDespawned = triggerFrom;
triggerFrom = 0;
}
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);
else
++m_SpawnedPoolAmount;
}
}
@ -235,8 +243,7 @@ void PoolGroup<T>::SpawnObject(uint32 limit, bool cache)
template <>
bool PoolGroup<Creature>::Spawn1Object(uint32 guid)
{
CreatureData const* data = objmgr.GetCreatureData(guid);
if (data)
if (CreatureData const* data = objmgr.GetCreatureData(guid))
{
objmgr.AddCreatureToGrid(guid, data);
@ -250,11 +257,10 @@ bool PoolGroup<Creature>::Spawn1Object(uint32 guid)
if (!pCreature->LoadFromDB(guid, map))
{
delete pCreature;
return false;
}
else
{
map->Add(pCreature);
}
}
return true;
}
@ -265,8 +271,7 @@ bool PoolGroup<Creature>::Spawn1Object(uint32 guid)
template <>
bool PoolGroup<GameObject>::Spawn1Object(uint32 guid)
{
GameObjectData const* data = objmgr.GetGOData(guid);
if (data)
if (GameObjectData const* data = objmgr.GetGOData(guid))
{
objmgr.AddGameobjectToGrid(guid, data);
// Spawn if necessary (loaded grids only)
@ -280,6 +285,7 @@ bool PoolGroup<GameObject>::Spawn1Object(uint32 guid)
if (!pGameobject->LoadFromDB(guid, map))
{
delete pGameobject;
return false;
}
else
{
@ -296,7 +302,9 @@ bool PoolGroup<GameObject>::Spawn1Object(uint32 guid)
template <>
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;
}
@ -304,8 +312,7 @@ bool PoolGroup<Pool>::Spawn1Object(uint32 child_pool_id)
template <>
bool PoolGroup<Creature>::ReSpawn1Object(uint32 guid)
{
CreatureData const* data = objmgr.GetCreatureData(guid);
if (data)
if (CreatureData const* data = objmgr.GetCreatureData(guid))
{
if (Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_UNIT), (Creature*)NULL))
pCreature->GetMap()->Add(pCreature);
@ -318,8 +325,7 @@ bool PoolGroup<Creature>::ReSpawn1Object(uint32 guid)
template <>
bool PoolGroup<GameObject>::ReSpawn1Object(uint32 guid)
{
GameObjectData const* data = objmgr.GetGOData(guid);
if (data)
if (GameObjectData const* data = objmgr.GetGOData(guid))
{
if (GameObject* pGameobject = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL))
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);
continue;
}
SpawnPool(pool_entry);
SpawnPool(pool_entry, 0, 0);
SpawnPool(pool_entry, 0, TYPEID_GAMEOBJECT);
SpawnPool(pool_entry, 0, TYPEID_UNIT);
count++;
} while (result->NextRow());
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
// 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())
mPoolPoolGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, cache);
if (!mPoolGameobjectGroups[pool_id].isEmpty())
mPoolGameobjectGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, cache);
if (!mPoolCreatureGroups[pool_id].isEmpty())
mPoolCreatureGroups[pool_id].SpawnObject(mPoolTemplate[pool_id].MaxLimit, cache);
switch (type)
{
case TYPEID_UNIT:
if (!mPoolCreatureGroups[pool_id].isEmpty())
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
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())
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
@ -666,19 +684,10 @@ void PoolHandler::DespawnPool(uint16 pool_id)
// Then the spawn pool call will use this cache to decide
void PoolHandler::UpdatePool(uint16 pool_id, uint32 guid, uint32 type)
{
uint16 motherpoolid = IsPartOfAPool(pool_id, 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);
if (uint16 motherpoolid = IsPartOfAPool(pool_id, 0))
SpawnPool(motherpoolid, 0, 0);
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

View file

@ -40,25 +40,24 @@ struct PoolObject
template <class T>
class PoolGroup
{
typedef std::vector<PoolObject> PoolObjectList;
public:
PoolGroup();
PoolGroup() : m_SpawnedPoolAmount(0) { }
~PoolGroup() {};
bool isEmpty() { return ExplicitlyChanced.empty() && EqualChanced.empty(); }
void AddEntry(PoolObject& poolitem, uint32 maxentries);
bool CheckPool(void);
uint32 RollOne(void);
void RollOne(int32& index, PoolObjectList** store, uint32 triggerFrom);
bool IsSpawnedObject(uint32 guid);
void DespawnObject(uint32 guid=0);
void Despawn1Object(uint32 guid);
void SpawnObject(uint32 limit, bool cache=false);
void SpawnObject(uint32 limit, uint32 triggerFrom);
bool Spawn1Object(uint32 guid);
bool ReSpawn1Object(uint32 guid);
void RemoveOneRelation(uint16 child_pool_id);
private:
typedef std::vector<PoolObject> PoolObjectList;
PoolObjectList ExplicitlyChanced;
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
};
@ -75,7 +74,7 @@ class PoolHandler
uint16 IsPartOfAPool(uint32 guid, uint32 type);
bool IsSpawnedObject(uint16 pool_id, uint32 guid, uint32 type);
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 UpdatePool(uint16 pool_id, uint32 guid, uint32 type);
void Initialize();

View file

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

View file

@ -4509,6 +4509,17 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
}
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:
{
// Rake

View file

@ -2872,7 +2872,7 @@ void Spell::EffectPersistentAA(uint32 i)
int32 duration = GetSpellDuration(m_spellInfo);
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;
return;
@ -3679,7 +3679,7 @@ void Spell::EffectAddFarsight(uint32 i)
DynamicObject* dynObj = new DynamicObject;
// 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;
return;

View file

@ -458,7 +458,7 @@ void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
return;
}
Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
Creature* pet = GetPlayer()->GetMap()->GetCreatureOrPetOrVehicle(guid);
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
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
return;

View file

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

View file

@ -626,7 +626,7 @@ bool ChatHandler::HandleDebugSpawnVehicle(const char* args)
Vehicle *v = new Vehicle;
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;
return false;

View file

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

View file

@ -1,6 +1,6 @@
#ifndef __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_REALMD "required_8332_01_realmd_realmcharacters"
#endif // __REVISION_SQL_H__