From ba77d85a3070d8e80e14a866cf2ac6d2af21b1ab Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 7 Apr 2011 19:22:30 +0400 Subject: [PATCH] [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. --- src/game/Chat.cpp | 2 +- src/game/Creature.cpp | 38 +++++++++++++-------- src/game/Creature.h | 14 ++++++-- src/game/GameEventMgr.cpp | 2 +- src/game/Level2.cpp | 51 ++++++++++++++++++--------- src/game/Object.cpp | 9 ++++- src/game/Pet.cpp | 25 +++++++++----- src/game/Pet.h | 2 +- src/game/PoolManager.cpp | 4 +-- src/game/SpellEffects.cpp | 72 ++++++++++++++++++++++++++------------- src/game/Totem.cpp | 4 +-- src/game/Totem.h | 2 +- src/game/Vehicle.cpp | 6 ++-- src/game/Vehicle.h | 2 +- src/game/debugcmds.cpp | 2 +- src/shared/revision_nr.h | 2 +- 16 files changed, 156 insertions(+), 81 deletions(-) diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index f2fe2946f..5f3a30153 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -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(); } diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 87fd80ad9..a9ad5dcac 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -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); } diff --git a/src/game/Creature.h b/src/game/Creature.h index 7cd3497c9..fff41a419 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -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 diff --git a/src/game/GameEventMgr.cpp b/src/game/GameEventMgr.cpp index 3b25cc630..561f6f9c5 100644 --- a/src/game/GameEventMgr.cpp +++ b/src/game/GameEventMgr.cpp @@ -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); } } diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 1e441cf3b..e00eb9c4b 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -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; diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 34d662700..3eac14831 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -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; diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 4f52fdc08..b46220f48 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -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; diff --git a/src/game/Pet.h b/src/game/Pet.h index a5e39718d..8eb892a83 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -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); diff --git a/src/game/PoolManager.cpp b/src/game/PoolManager.cpp index e12362ca6..b527dc747 100644 --- a/src/game/PoolManager.cpp +++ b/src/game/PoolManager.cpp @@ -269,7 +269,7 @@ void PoolGroup::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::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); } } diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 77695e2d2..859dd7220 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -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(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(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(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(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(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; diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp index 2ec288e1a..778fb18cf 100644 --- a/src/game/Totem.cpp +++ b/src/game/Totem.cpp @@ -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 diff --git a/src/game/Totem.h b/src/game/Totem.h index c9ccbf419..34f067491 100644 --- a/src/game/Totem.h +++ b/src/game/Totem.h @@ -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(); diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp index bf4957bdb..4207837c6 100644 --- a/src/game/Vehicle.cpp +++ b/src/game/Vehicle.cpp @@ -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); diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h index 35a91090d..8e642bf44 100644 --- a/src/game/Vehicle.h +++ b/src/game/Vehicle.h @@ -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 diff --git a/src/game/debugcmds.cpp b/src/game/debugcmds.cpp index c6dc0f309..d91d1ea5b 100644 --- a/src/game/debugcmds.cpp +++ b/src/game/debugcmds.cpp @@ -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; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b68ff286b..d6ff0840f 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11322" + #define REVISION_NR "11323" #endif // __REVISION_NR_H__