[11323] Avoid explicit use HIGHGUID_UNIT as creature high guid in guids or creature creating.

This helper change for allow have in future static spawned vehicles as `creature` table data.

Added CreatureInfo::GetHighGuid() high guid selector, and wrapper CreatureData::GetHighGuid()
for most real cases of usage. Also easy get expected guid form by CreatureData::GetObjectGuid(lowguid).

Also fixed some memory lost cases at creature spawn fail.
This commit is contained in:
VladimirMangos 2011-04-07 19:22:30 +04:00
parent 0dfcbf8051
commit ba77d85a30
16 changed files with 156 additions and 81 deletions

View file

@ -2909,7 +2909,7 @@ ObjectGuid ChatHandler::ExtractGuidFromLink(char** text)
return ObjectGuid();
if (CreatureData const* data = sObjectMgr.GetCreatureData(lowguid))
return ObjectGuid(HIGHGUID_UNIT, data->id, lowguid);
return data->GetObjectGuid(lowguid);
else
return ObjectGuid();
}

View file

@ -49,6 +49,13 @@
// apply implementation of the singletons
#include "Policies/SingletonImp.h"
HighGuid CreatureData::GetHighGuid() const
{
// info existence checked at loading
return ObjectMgr::GetCreatureTemplate(id)->GetHighGuid();
}
TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
{
TrainerSpellMap::const_iterator itr = spellList.find(spell_id);
@ -728,12 +735,12 @@ bool Creature::AIM_Initialize()
return true;
}
bool Creature::Create(uint32 guidlow, CreatureCreatePos& cPos, uint32 Entry, Team team /*= TEAM_NONE*/, const CreatureData *data /*= NULL*/, GameEventCreatureData const* eventData /*= NULL*/)
bool Creature::Create(uint32 guidlow, CreatureCreatePos& cPos, CreatureInfo const* cinfo, Team team /*= TEAM_NONE*/, const CreatureData *data /*= NULL*/, GameEventCreatureData const* eventData /*= NULL*/)
{
SetMap(cPos.GetMap());
SetPhaseMask(cPos.GetPhaseMask(), false);
if (!CreateFromProto(guidlow, Entry, team, data, eventData))
if (!CreateFromProto(guidlow, cinfo, team, data, eventData))
return false;
cPos.SelectFinalPoint(this);
@ -1234,19 +1241,13 @@ float Creature::GetSpellDamageMod(int32 Rank)
}
}
bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, Team team, const CreatureData *data /*=NULL*/, GameEventCreatureData const* eventData /*=NULL*/)
bool Creature::CreateFromProto(uint32 guidlow, CreatureInfo const* cinfo, Team team, const CreatureData *data /*=NULL*/, GameEventCreatureData const* eventData /*=NULL*/)
{
CreatureInfo const *cinfo = ObjectMgr::GetCreatureTemplate(Entry);
if(!cinfo)
{
sLog.outErrorDb("Creature entry %u does not exist.", Entry);
return false;
}
m_originalEntry = Entry;
m_originalEntry = cinfo->Entry;
Object::_Create(guidlow, Entry, HIGHGUID_UNIT);
Object::_Create(guidlow, cinfo->Entry, cinfo->GetHighGuid());
if (!UpdateEntry(Entry, team, data, eventData, false))
if (!UpdateEntry(cinfo->Entry, team, data, eventData, false))
return false;
return true;
@ -1262,15 +1263,22 @@ bool Creature::LoadFromDB(uint32 guidlow, Map *map)
return false;
}
CreatureInfo const *cinfo = ObjectMgr::GetCreatureTemplate(data->id);
if(!cinfo)
{
sLog.outErrorDb("Creature (Entry: %u) not found in table `creature_template`, can't load. ", data->id);
return false;
}
GameEventCreatureData const* eventData = sGameEventMgr.GetCreatureUpdateDataForActiveEvent(guidlow);
// Creature can be loaded already in map if grid has been unloaded while creature walk to another grid
if (map->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, guidlow)))
if (map->GetCreature(data->GetObjectGuid(guidlow)))
return false;
CreatureCreatePos pos(map, data->posX, data->posY, data->posZ, data->orientation, data->phaseMask);
if (!Create(guidlow, pos, data->id, TEAM_NONE, data, eventData))
if (!Create(guidlow, pos, cinfo, TEAM_NONE, data, eventData))
return false;
m_respawnradius = data->spawndist;
@ -2427,7 +2435,7 @@ struct AddCreatureToRemoveListInMapsWorker
void Creature::AddToRemoveListInMaps(uint32 db_guid, CreatureData const* data)
{
AddCreatureToRemoveListInMapsWorker worker(ObjectGuid(HIGHGUID_UNIT, data->id, db_guid));
AddCreatureToRemoveListInMapsWorker worker(data->GetObjectGuid(db_guid));
sMapMgr.DoForAllMapsWithMapId(data->mapid, worker);
}

View file

@ -140,6 +140,12 @@ struct CreatureInfo
uint32 ScriptID;
// helpers
// TODO: return HIGHGUID_UNIT/HIGHGUID_VEHICLE base at currently missing creature template data
HighGuid GetHighGuid() const
{
return HIGHGUID_UNIT;
}
SkillType GetRequiredLootSkill() const
{
if(type_flags & CREATURE_TYPEFLAGS_HERBLOOT)
@ -193,6 +199,10 @@ struct CreatureData
bool is_dead;
uint8 movementType;
uint8 spawnMask;
// helper function
HighGuid GetHighGuid() const;
ObjectGuid GetObjectGuid(uint32 lowguid) const { return ObjectGuid(GetHighGuid(), id, lowguid); }
};
struct CreatureDataAddonAura
@ -443,7 +453,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
void AddToWorld();
void RemoveFromWorld();
bool Create(uint32 guidlow, CreatureCreatePos& cPos, uint32 Entry, Team team = TEAM_NONE, const CreatureData *data = NULL, GameEventCreatureData const* eventData = NULL);
bool Create(uint32 guidlow, CreatureCreatePos& cPos, CreatureInfo const* cinfo, Team team = TEAM_NONE, const CreatureData *data = NULL, GameEventCreatureData const* eventData = NULL);
bool LoadCreatureAddon(bool reload = false);
void SelectLevel(const CreatureInfo *cinfo, float percentHealth = 100.0f, float percentMana = 100.0f);
void LoadEquipment(uint32 equip_entry, bool force=false);
@ -699,7 +709,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
void SetVirtualItem(VirtualItemSlot slot, uint32 item_id) { SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + slot, item_id); }
protected:
bool CreateFromProto(uint32 guidlow,uint32 Entry, Team team, const CreatureData *data = NULL, GameEventCreatureData const* eventData =NULL);
bool CreateFromProto(uint32 guidlow, CreatureInfo const* cinfo, Team team, const CreatureData *data = NULL, GameEventCreatureData const* eventData =NULL);
bool InitEntry(uint32 entry, const CreatureData* data = NULL, GameEventCreatureData const* eventData = NULL);
uint32 m_groupLootTimer; // (msecs)timer used for group loot

View file

@ -902,7 +902,7 @@ void GameEventMgr::UpdateCreatureData(int16 event_id, bool activate)
continue;
// Update if spawned
GameEventUpdateCreatureDataInMapsWorker worker(ObjectGuid(HIGHGUID_UNIT, data->id, itr->first), data, &itr->second, activate);
GameEventUpdateCreatureDataInMapsWorker worker(data->GetObjectGuid(itr->first), data, &itr->second, activate);
sMapMgr.DoForAllMapsWithMapId(data->mapid, worker);
}
}

View file

@ -1558,6 +1558,15 @@ bool ChatHandler::HandleNpcAddCommand(char* args)
if (!ExtractUint32KeyFromLink(&args, "Hcreature_entry", id))
return false;
CreatureInfo const *cinfo = ObjectMgr::GetCreatureTemplate(id);
//FIXME: need vehicle support like GenerateStaticCreatureLowGuid when its will allowed static spawns
if (!cinfo || cinfo->GetHighGuid() != HIGHGUID_UNIT)
{
PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, id);
SetSentErrorMessage(true);
return false;
}
Player *chr = m_session->GetPlayer();
CreatureCreatePos pos(chr, chr->GetOrientation());
Map *map = chr->GetMap();
@ -1573,7 +1582,7 @@ bool ChatHandler::HandleNpcAddCommand(char* args)
return false;
}
if (!pCreature->Create(lowguid, pos, id))
if (!pCreature->Create(lowguid, pos, cinfo))
{
delete pCreature;
return false;
@ -1695,7 +1704,7 @@ bool ChatHandler::HandleNpcAddMoveCommand(char* args)
return false;
}
Creature* pCreature = player->GetMap()->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, lowguid));
Creature* pCreature = player->GetMap()->GetCreature(data->GetObjectGuid(lowguid));
sWaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0);
@ -1796,7 +1805,7 @@ bool ChatHandler::HandleNpcDeleteCommand(char* args)
return false;
if (CreatureData const* data = sObjectMgr.GetCreatureData(lowguid))
unit = m_session->GetPlayer()->GetMap()->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, lowguid));
unit = m_session->GetPlayer()->GetMap()->GetCreature(data->GetObjectGuid(lowguid));
}
else
unit = getSelectedCreature();
@ -1848,7 +1857,7 @@ bool ChatHandler::HandleNpcMoveCommand(char* args)
return false;
}
pCreature = player->GetMap()->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, lowguid));
pCreature = player->GetMap()->GetCreature(data->GetObjectGuid(lowguid));
}
else
lowguid = pCreature->GetGUIDLow();
@ -1931,7 +1940,7 @@ bool ChatHandler::HandleNpcSetMoveTypeCommand(char* args)
return false;
}
pCreature = player->GetMap()->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, lowguid));
pCreature = player->GetMap()->GetCreature(data->GetObjectGuid(lowguid));
}
MovementGeneratorType move_type;
@ -2867,7 +2876,7 @@ bool ChatHandler::HandleWpAddCommand(char* args)
return false;
}
target = m_session->GetPlayer()->GetMap()->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, lowguid));
target = m_session->GetPlayer()->GetMap()->GetCreature(data->GetObjectGuid(lowguid));
if (!target)
{
PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
@ -2901,7 +2910,7 @@ bool ChatHandler::HandleWpAddCommand(char* args)
return false;
}
target = m_session->GetPlayer()->GetMap()->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, lowguid));
target = m_session->GetPlayer()->GetMap()->GetCreature(data->GetObjectGuid(lowguid));
if (!target || target->IsPet())
{
PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
@ -2965,6 +2974,10 @@ bool ChatHandler::HandleWpModifyCommand(char* args)
if (!*args)
return false;
CreatureInfo const* waypointInfo = ObjectMgr::GetCreatureTemplate(VISUAL_WAYPOINT);
if (!waypointInfo || waypointInfo->GetHighGuid() != HIGHGUID_UNIT)
return false; // must exist as normal creature in mangos.sql 'creature_template'
// first arg: add del text emote spell waittime move
char* show_str = strtok(args, " ");
if (!show_str)
@ -3116,7 +3129,7 @@ bool ChatHandler::HandleWpModifyCommand(char* args)
return false;
}
Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, lowguid));
Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(data->GetObjectGuid(lowguid));
if (!npcCreature)
{
@ -3152,7 +3165,7 @@ bool ChatHandler::HandleWpModifyCommand(char* args)
CreatureCreatePos pos(chr, chr->GetOrientation());
if (!wpCreature->Create(map->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, VISUAL_WAYPOINT))
if (!wpCreature->Create(map->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, waypointInfo))
{
PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
delete wpCreature;
@ -3187,7 +3200,7 @@ bool ChatHandler::HandleWpModifyCommand(char* args)
return false;
}
Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, lowguid));
Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(data->GetObjectGuid(lowguid));
// wpCreature
Creature* wpCreature = NULL;
@ -3247,7 +3260,7 @@ bool ChatHandler::HandleWpModifyCommand(char* args)
return false;
}
Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, lowguid));
Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(data->GetObjectGuid(lowguid));
// wpCreature
Creature* wpCreature = NULL;
@ -3264,7 +3277,7 @@ bool ChatHandler::HandleWpModifyCommand(char* args)
CreatureCreatePos pos(chr, chr->GetOrientation());
if (!wpCreature2->Create(map->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, VISUAL_WAYPOINT))
if (!wpCreature2->Create(map->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, waypointInfo))
{
PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
delete wpCreature2;
@ -3312,7 +3325,7 @@ bool ChatHandler::HandleWpModifyCommand(char* args)
sWaypointMgr.SetNodeText(lowguid, point, show_str, arg_str);
Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, lowguid));
Creature* npcCreature = m_session->GetPlayer()->GetMap()->GetCreature(data->GetObjectGuid(lowguid));
if (npcCreature)
{
npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
@ -3360,6 +3373,10 @@ bool ChatHandler::HandleWpShowCommand(char* args)
if (!*args)
return false;
CreatureInfo const* waypointInfo = ObjectMgr::GetCreatureTemplate(VISUAL_WAYPOINT);
if (!waypointInfo || waypointInfo->GetHighGuid() != HIGHGUID_UNIT)
return false; // must exist as normal creature in mangos.sql 'creature_template'
// first arg: on, off, first, last
char* show_str = strtok(args, " ");
if (!show_str)
@ -3412,7 +3429,7 @@ bool ChatHandler::HandleWpShowCommand(char* args)
return false;
}
target = m_session->GetPlayer()->GetMap()->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, lowguid));
target = m_session->GetPlayer()->GetMap()->GetCreature(data->GetObjectGuid(lowguid));
if (!target)
{
@ -3555,7 +3572,7 @@ bool ChatHandler::HandleWpShowCommand(char* args)
Creature* wpCreature = new Creature;
if (!wpCreature->Create(map->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, VISUAL_WAYPOINT))
if (!wpCreature->Create(map->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, waypointInfo))
{
PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
delete wpCreature;
@ -3600,7 +3617,7 @@ bool ChatHandler::HandleWpShowCommand(char* args)
Creature* pCreature = new Creature;
if (!pCreature->Create(map->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, VISUAL_WAYPOINT))
if (!pCreature->Create(map->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, waypointInfo))
{
PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
delete pCreature;
@ -3648,7 +3665,7 @@ bool ChatHandler::HandleWpShowCommand(char* args)
Creature* pCreature = new Creature;
if (!pCreature->Create(map->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, VISUAL_WAYPOINT))
if (!pCreature->Create(map->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, waypointInfo))
{
PSendSysMessage(LANG_WAYPOINT_NOTCREATED, VISUAL_WAYPOINT);
delete pCreature;

View file

@ -1647,6 +1647,13 @@ void WorldObject::AddObjectToRemoveList()
Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime, bool asActiveObject)
{
CreatureInfo const *cinfo = ObjectMgr::GetCreatureTemplate(id);
if(!cinfo)
{
sLog.outErrorDb("WorldObject::SummonCreature: Creature (Entry: %u) not existed for summoner: %s. ", id, GetGuidStr().c_str());
return NULL;
}
TemporarySummon* pCreature = new TemporarySummon(GetObjectGuid());
Team team = TEAM_NONE;
@ -1658,7 +1665,7 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
if (x == 0.0f && y == 0.0f && z == 0.0f)
pos = CreatureCreatePos(this, GetOrientation(), CONTACT_DISTANCE, ang);
if (!pCreature->Create(GetMap()->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, id, team))
if (!pCreature->Create(GetMap()->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, cinfo, team))
{
delete pCreature;
return NULL;

View file

@ -117,6 +117,15 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
return false;
}
CreatureInfo const *creatureInfo = ObjectMgr::GetCreatureTemplate(petentry);
if (!creatureInfo)
{
sLog.outError("Pet entry %u does not exist but used at pet load (owner: %s).", petentry, owner->GetGuidStr().c_str());
delete result;
return false;
}
uint32 summon_spell_id = fields[17].GetUInt32();
SpellEntry const* spellInfo = sSpellStore.LookupEntry(summon_spell_id);
@ -132,8 +141,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
PetType pet_type = PetType(fields[18].GetUInt8());
if(pet_type == HUNTER_PET)
{
CreatureInfo const* creatureInfo = ObjectMgr::GetCreatureTemplate(petentry);
if(!creatureInfo || !creatureInfo->isTameable(owner->CanTameExoticPets()))
if (!creatureInfo->isTameable(owner->CanTameExoticPets()))
{
delete result;
return false;
@ -154,7 +162,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
CreatureCreatePos pos(owner, owner->GetOrientation(), PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
uint32 guid = pos.GetMap()->GenerateLocalLowGuid(HIGHGUID_PET);
if (!Create(guid, pos, petentry, pet_number))
if (!Create(guid, pos, creatureInfo, pet_number))
{
delete result;
return false;
@ -164,6 +172,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
setFaction(owner->getFaction());
SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id);
// reget for sure use real creature info selected for Pet at load/creating
CreatureInfo const *cinfo = GetCreatureInfo();
if (cinfo->type == CREATURE_TYPE_CRITTER)
{
@ -837,7 +846,7 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
BASIC_LOG("Create pet");
uint32 pet_number = sObjectMgr.GeneratePetNumber();
if (!Create(guid, pos, creature->GetEntry(), pet_number))
if (!Create(guid, pos, creature->GetCreatureInfo(), pet_number))
return false;
CreatureInfo const *cinfo = GetCreatureInfo();
@ -1980,16 +1989,16 @@ bool Pet::IsPermanentPetFor(Player* owner)
}
}
bool Pet::Create(uint32 guidlow, CreatureCreatePos& cPos, uint32 Entry, uint32 pet_number)
bool Pet::Create(uint32 guidlow, CreatureCreatePos& cPos, CreatureInfo const* cinfo, uint32 pet_number)
{
SetMap(cPos.GetMap());
SetPhaseMask(cPos.GetPhaseMask(), false);
Object::_Create(guidlow, pet_number, HIGHGUID_PET);
m_originalEntry = Entry;
m_originalEntry = cinfo->Entry;
if (!InitEntry(Entry))
if (!InitEntry(cinfo->Entry))
return false;
cPos.SelectFinalPoint(this);
@ -1999,7 +2008,7 @@ bool Pet::Create(uint32 guidlow, CreatureCreatePos& cPos, uint32 Entry, uint32 p
SetSheath(SHEATH_STATE_MELEE);
if(getPetType() == MINI_PET) // always non-attackable
if (getPetType() == MINI_PET) // always non-attackable
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
return true;

View file

@ -149,7 +149,7 @@ class Pet : public Creature
bool IsPermanentPetFor(Player* owner); // pet have tab in character windows and set UNIT_FIELD_PETNUMBER
bool Create (uint32 guidlow, CreatureCreatePos& cPos, uint32 Entry, uint32 pet_number);
bool Create (uint32 guidlow, CreatureCreatePos& cPos, CreatureInfo const* cinfo, uint32 pet_number);
bool CreateBaseAtCreature(Creature* creature);
bool LoadPetFromDB( Player* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false );
void SavePetToDB(PetSaveMode mode);

View file

@ -269,7 +269,7 @@ void PoolGroup<Creature>::Despawn1Object(MapPersistentState& mapState, uint32 gu
dataMapState->RemoveCreatureFromGrid(guid, data);
if (Map* dataMap = dataMapState->GetMap())
if (Creature* pCreature = dataMap->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, guid)))
if (Creature* pCreature = dataMap->GetCreature(data->GetObjectGuid(guid)))
pCreature->AddObjectToRemoveList();
}
}
@ -485,7 +485,7 @@ void PoolGroup<Creature>::ReSpawn1Object(MapPersistentState& mapState, PoolObjec
// for non-instanceable maps pool spawn can be at different map from provided mapState
if (MapPersistentState* dataMapState = mapState.GetMapId() == data->mapid ? &mapState : sMapPersistentStateMgr.GetPersistentState(data->mapid, 0))
if (Map* dataMap = dataMapState->GetMap())
if (Creature* pCreature = dataMap->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, obj->guid)))
if (Creature* pCreature = dataMap->GetCreature(data->GetObjectGuid(obj->guid)))
pCreature->GetMap()->Add(pCreature);
}
}

View file

@ -4510,6 +4510,14 @@ void Spell::DoSummon(SpellEffectIndex eff_idx)
uint32 pet_entry = m_spellInfo->EffectMiscValue[eff_idx];
if (!pet_entry)
return;
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(pet_entry);
if (!cInfo)
{
sLog.outErrorDb("Spell::DoSummon: creature entry %u not found for spell %u.", pet_entry, m_spellInfo->Id);
return;
}
uint32 level = m_caster->getLevel();
Pet* spawnCreature = new Pet(SUMMON_PET);
@ -4534,9 +4542,9 @@ void Spell::DoSummon(SpellEffectIndex eff_idx)
Map *map = m_caster->GetMap();
uint32 pet_number = sObjectMgr.GeneratePetNumber();
if (!spawnCreature->Create(map->GenerateLocalLowGuid(HIGHGUID_PET), pos, m_spellInfo->EffectMiscValue[eff_idx], pet_number))
if (!spawnCreature->Create(map->GenerateLocalLowGuid(HIGHGUID_PET), pos, cInfo, pet_number))
{
sLog.outErrorDb("Spell::EffectSummon: no such creature entry %u",m_spellInfo->EffectMiscValue[eff_idx]);
sLog.outErrorDb("Spell::EffectSummon: can't create creature with entry %u for spell %u", cInfo->equipmentId, m_spellInfo->Id);
delete spawnCreature;
return;
}
@ -4916,6 +4924,13 @@ void Spell::DoSummonGuardian(SpellEffectIndex eff_idx, uint32 forceFaction)
if (!propEntry)
return;
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(pet_entry);
if (!cInfo)
{
sLog.outErrorDb("Spell::DoSummonGuardian: creature entry %u not found for spell %u.", pet_entry, m_spellInfo->Id);
return;
}
PetType petType = propEntry->Title == UNITNAME_SUMMON_TITLE_COMPANION ? PROTECTOR_PET : GUARDIAN_PET;
// second direct cast unsummon guardian(s) (guardians without like functionality have cooldown > spawn time)
@ -4988,9 +5003,9 @@ void Spell::DoSummonGuardian(SpellEffectIndex eff_idx, uint32 forceFaction)
Map *map = m_caster->GetMap();
uint32 pet_number = sObjectMgr.GeneratePetNumber();
if (!spawnCreature->Create(map->GenerateLocalLowGuid(HIGHGUID_PET), pos, m_spellInfo->EffectMiscValue[eff_idx], pet_number))
if (!spawnCreature->Create(map->GenerateLocalLowGuid(HIGHGUID_PET), pos, cInfo, pet_number))
{
sLog.outError("no such creature entry %u", m_spellInfo->EffectMiscValue[eff_idx]);
sLog.outError("Spell::DoSummonGuardian: can't create creature entry %u for spell %u.", pet_entry, m_spellInfo->Id);
delete spawnCreature;
return;
}
@ -5426,33 +5441,28 @@ void Spell::EffectSummonPet(SpellEffectIndex eff_idx)
return;
}
// not error in case fail hunter call pet
if (!petentry)
return;
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(petentry);
if(!cInfo)
{
sLog.outErrorDb("EffectSummonPet: creature entry %u not found.", petentry);
return;
}
Pet* NewSummon = new Pet;
// petentry==0 for hunter "call pet" (current pet summoned if any)
if(m_caster->GetTypeId() == TYPEID_PLAYER && NewSummon->LoadPetFromDB((Player*)m_caster, petentry))
if (m_caster->GetTypeId() == TYPEID_PLAYER && NewSummon->LoadPetFromDB((Player*)m_caster, petentry))
return;
// not error in case fail hunter call pet
if (!petentry)
{
delete NewSummon;
return;
}
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(petentry);
if(!cInfo)
{
sLog.outError("EffectSummonPet: creature entry %u not found.", petentry);
delete NewSummon;
return;
}
CreatureCreatePos pos(m_caster, m_caster->GetOrientation());
Map *map = m_caster->GetMap();
uint32 pet_number = sObjectMgr.GeneratePetNumber();
if (!NewSummon->Create(map->GenerateLocalLowGuid(HIGHGUID_PET), pos, petentry, pet_number))
if (!NewSummon->Create(map->GenerateLocalLowGuid(HIGHGUID_PET), pos, cInfo, pet_number))
{
delete NewSummon;
return;
@ -7614,9 +7624,16 @@ void Spell::DoSummonTotem(SpellEffectIndex eff_idx, uint8 slot_dbc)
CreatureCreatePos pos(m_caster, m_caster->GetOrientation(), 2.0f, angle);
CreatureInfo const *cinfo = ObjectMgr::GetCreatureTemplate(m_spellInfo->EffectMiscValue[eff_idx]);
if (!cinfo)
{
sLog.outErrorDb("Creature entry %u does not exist but used in spell %u totem summon.", m_spellInfo->Id, m_spellInfo->EffectMiscValue[eff_idx]);
return;
}
Totem* pTotem = new Totem;
if (!pTotem->Create(m_caster->GetMap()->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, m_spellInfo->EffectMiscValue[eff_idx], m_caster))
if (!pTotem->Create(m_caster->GetMap()->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, cinfo, m_caster))
{
delete pTotem;
return;
@ -8100,6 +8117,13 @@ void Spell::DoSummonCritter(SpellEffectIndex eff_idx, uint32 forceFaction)
if(!pet_entry)
return;
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(pet_entry);
if (!cInfo)
{
sLog.outErrorDb("Spell::DoSummonCritter: creature entry %u not found for spell %u.", pet_entry, m_spellInfo->Id);
return;
}
Pet* old_critter = m_caster->GetMiniPet();
// for same pet just despawn (player unsummon command)
@ -8122,7 +8146,7 @@ void Spell::DoSummonCritter(SpellEffectIndex eff_idx, uint32 forceFaction)
Map *map = m_caster->GetMap();
uint32 pet_number = sObjectMgr.GeneratePetNumber();
if (!critter->Create(map->GenerateLocalLowGuid(HIGHGUID_PET), pos, pet_entry, pet_number))
if (!critter->Create(map->GenerateLocalLowGuid(HIGHGUID_PET), pos, cInfo, pet_number))
{
sLog.outError("Spell::EffectSummonCritter, spellid %u: no such creature entry %u", m_spellInfo->Id, pet_entry);
delete critter;

View file

@ -32,14 +32,14 @@ Totem::Totem() : Creature(CREATURE_SUBTYPE_TOTEM)
m_type = TOTEM_PASSIVE;
}
bool Totem::Create(uint32 guidlow, CreatureCreatePos& cPos, uint32 Entry, Unit* owner)
bool Totem::Create(uint32 guidlow, CreatureCreatePos& cPos, CreatureInfo const* cinfo, Unit* owner)
{
SetMap(cPos.GetMap());
SetPhaseMask(cPos.GetPhaseMask(), false);
Team team = owner->GetTypeId() == TYPEID_PLAYER ? ((Player*)owner)->GetTeam() : TEAM_NONE;
if (!CreateFromProto(guidlow, Entry, team))
if (!CreateFromProto(guidlow, cinfo, team))
return false;
// special model selection case for totems

View file

@ -33,7 +33,7 @@ class Totem : public Creature
public:
explicit Totem();
virtual ~Totem(){};
bool Create(uint32 guidlow, CreatureCreatePos& cPos, uint32 Entry, Unit* owner);
bool Create(uint32 guidlow, CreatureCreatePos& cPos, CreatureInfo const* cinfo, Unit* owner);
void Update(uint32 update_diff, uint32 time );
void Summon(Unit* owner);
void UnSummon();

View file

@ -61,14 +61,14 @@ void Vehicle::Update( uint32 update_diff, uint32 diff)
Creature::Update(update_diff, diff);
}
bool Vehicle::Create(uint32 guidlow, CreatureCreatePos& cPos, uint32 Entry, uint32 vehicleId, Team team)
bool Vehicle::Create(uint32 guidlow, CreatureCreatePos& cPos, CreatureInfo const* cinfo, uint32 vehicleId, Team team)
{
SetMap(cPos.GetMap());
SetPhaseMask(cPos.GetPhaseMask(), false);
Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE);
Object::_Create(guidlow, cinfo->Entry, HIGHGUID_VEHICLE);
if(!InitEntry(Entry))
if (!InitEntry(cinfo->Entry))
return false;
cPos.SelectFinalPoint(this);

View file

@ -34,7 +34,7 @@ class Vehicle : public Creature
void AddToWorld();
void RemoveFromWorld();
bool Create(uint32 guidlow, CreatureCreatePos& cPos, uint32 Entry, uint32 vehicleId, Team team);
bool Create(uint32 guidlow, CreatureCreatePos& cPos, CreatureInfo const* cinfo, uint32 vehicleId, Team team);
void SetDeathState(DeathState s); // overwrite virtual Creature::SetDeathState and Unit::SetDeathState
void Update(uint32 update_diff, uint32 diff); // overwrite virtual Creature::Update and Unit::Update

View file

@ -669,7 +669,7 @@ bool ChatHandler::HandleDebugSpawnVehicleCommand(char* args)
CreatureCreatePos pos(chr, chr->GetOrientation());
if (!v->Create(pos.GetMap()->GenerateLocalLowGuid(HIGHGUID_VEHICLE), pos, entry, id, chr->GetTeam()))
if (!v->Create(pos.GetMap()->GenerateLocalLowGuid(HIGHGUID_VEHICLE), pos, ci, id, chr->GetTeam()))
{
delete v;
return false;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "11322"
#define REVISION_NR "11323"
#endif // __REVISION_NR_H__