diff options
Diffstat (limited to 'src/game/ObjectMgr.cpp')
-rw-r--r-- | src/game/ObjectMgr.cpp | 88 |
1 files changed, 61 insertions, 27 deletions
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 3c0e645b81e..f090a95af8e 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -614,28 +614,43 @@ void ObjectMgr::LoadCreatureTemplates() if(!factionTemplate) sLog.outErrorDb("Creature (Entry: %u) has non-existing faction_H template (%u)", cInfo->Entry, cInfo->faction_H); - // check model ids, supplying and sending non-existent ids to the client might crash them - if(cInfo->Modelid_A1 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid_A1)) - { - sLog.outErrorDb("Creature (Entry: %u) has non-existing Modelid_A1 (%u), setting it to 0", cInfo->Entry, cInfo->Modelid_A1); - const_cast<CreatureInfo*>(cInfo)->Modelid_A1 = 0; - } - if(cInfo->Modelid_A2 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid_A2)) - { - sLog.outErrorDb("Creature (Entry: %u) has non-existing Modelid_A2 (%u), setting it to 0", cInfo->Entry, cInfo->Modelid_A2); - const_cast<CreatureInfo*>(cInfo)->Modelid_A2 = 0; - } - if(cInfo->Modelid_H1 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid_H1)) + // used later for scale + CreatureDisplayInfoEntry const* displayEntryA = cInfo->DisplayID_A ? sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A) : NULL; + if(cInfo->DisplayID_A && !displayEntryA) + sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_A id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_A); + + if(cInfo->DisplayID_A2) { - sLog.outErrorDb("Creature (Entry: %u) has non-existing Modelid_H1 (%u), setting it to 0", cInfo->Entry, cInfo->Modelid_H1); - const_cast<CreatureInfo*>(cInfo)->Modelid_H1 = 0; + CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_A2); + if(!displayEntry) + { + sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_A2 id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_A2); + const_cast<CreatureInfo*>(cInfo)->DisplayID_A2 = 0; + } } - if(cInfo->Modelid_H2 && !sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->Modelid_H2)) + + // used later for scale + CreatureDisplayInfoEntry const* displayEntryH = cInfo->DisplayID_H ? sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_H) : NULL; + if(cInfo->DisplayID_H && !displayEntryH) + sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_H id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_H); + + if(cInfo->DisplayID_H2) { - sLog.outErrorDb("Creature (Entry: %u) has non-existing Modelid_H2 (%u), setting it to 0", cInfo->Entry, cInfo->Modelid_H2); - const_cast<CreatureInfo*>(cInfo)->Modelid_H2 = 0; + CreatureDisplayInfoEntry const* displayEntry = sCreatureDisplayInfoStore.LookupEntry(cInfo->DisplayID_H2); + if(!displayEntry) + { + sLog.outErrorDb("Creature (Entry: %u) has non-existing DisplayID_H2 id (%u), can crash client", cInfo->Entry, cInfo->DisplayID_H2); + const_cast<CreatureInfo*>(cInfo)->DisplayID_H2 = 0; + } } + CreatureModelInfo const* minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_A); + if (!minfo) + sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_A (%u)", cInfo->Entry, cInfo->DisplayID_A); + minfo = sCreatureModelStorage.LookupEntry<CreatureModelInfo>(cInfo->DisplayID_H); + if (!minfo) + sLog.outErrorDb("Creature (Entry: %u) has non-existing modelId_H (%u)", cInfo->Entry, cInfo->DisplayID_H); + if (cInfo->unit_class && ((1 << (cInfo->unit_class-1)) & CLASSMASK_ALL_CREATURES) == 0) sLog.outErrorDb("Creature (Entry: %u) has invalid unit_class(%u) for creature_template", cInfo->Entry, cInfo->unit_class); @@ -806,7 +821,10 @@ void ObjectMgr::LoadCreatureAddons() if (addon->mount) { if (!sCreatureDisplayInfoStore.LookupEntry(addon->mount)) + { sLog.outErrorDb("Creature (Entry %u) have invalid displayInfoId for mount (%u) defined in `creature_template_addon`.",addon->guidOrEntry, addon->mount); + const_cast<CreatureDataAddon*>(addon)->mount = 0; + } } if (!sEmotesStore.LookupEntry(addon->emote)) @@ -833,7 +851,10 @@ void ObjectMgr::LoadCreatureAddons() if (addon->mount) { if (!sCreatureDisplayInfoStore.LookupEntry(addon->mount)) + { sLog.outErrorDb("Creature (GUID %u) have invalid displayInfoId for mount (%u) defined in `creature_addon`.",addon->guidOrEntry, addon->mount); + const_cast<CreatureDataAddon*>(addon)->mount = 0; + } } if (!sEmotesStore.LookupEntry(addon->emote)) @@ -1130,8 +1151,8 @@ void ObjectMgr::LoadCreatures() { (const_cast<CreatureInfo*>(cInfo))->flags_extra |= CREATURE_FLAG_EXTRA_TRIGGER; } - else if(data.displayid == cInfo->Modelid_A1 || data.displayid == cInfo->Modelid_A2 - || data.displayid == cInfo->Modelid_H1 || data.displayid == cInfo->Modelid_H2) + else if(data.displayid == cInfo->DisplayID_A || data.displayid == cInfo->DisplayID_A2 + || data.displayid == cInfo->DisplayID_H || data.displayid == cInfo->DisplayID_H2) data.displayid = 0; */ @@ -1387,6 +1408,12 @@ void ObjectMgr::LoadGameobjects() continue; } + if(gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId)) + { + sLog.outErrorDb("Gameobject (GUID: %u Entry %u GoType: %u) have invalid displayId (%u), not loaded.",guid, entry, gInfo->type, gInfo->displayId); + continue; + } + GameObjectData& data = mGameObjectDataMap[guid]; data.id = entry; @@ -1833,7 +1860,6 @@ void ObjectMgr::LoadItemPrototypes() } { - // can be used in equip slot, as page read use in inventory, or spell casting at use bool req = proto->InventoryType!=INVTYPE_NON_EQUIP || proto->PageText; if(!req) @@ -1887,7 +1913,7 @@ void ObjectMgr::LoadItemPrototypes() const_cast<ItemPrototype*>(proto)->MaxCount = -1; } - if(proto->Stackable==0) + if(proto->Stackable == 0) { sLog.outErrorDb("Item (Entry: %u) has wrong value in stackable (%i), replace by default 1.",i,proto->Stackable); const_cast<ItemPrototype*>(proto)->Stackable = 1; @@ -1897,10 +1923,10 @@ void ObjectMgr::LoadItemPrototypes() sLog.outErrorDb("Item (Entry: %u) has too large negative in stackable (%i), replace by value (-1) no stacking limits.",i,proto->Stackable); const_cast<ItemPrototype*>(proto)->Stackable = -1; } - else if(proto->Stackable > 255) + else if(proto->Stackable > 1000) { - sLog.outErrorDb("Item (Entry: %u) has too large value in stackable (%u), replace by hardcoded upper limit (255).",i,proto->Stackable); - const_cast<ItemPrototype*>(proto)->Stackable = 255; + sLog.outErrorDb("Item (Entry: %u) has too large value in stackable (%u), replace by hardcoded upper limit (1000).",i,proto->Stackable); + const_cast<ItemPrototype*>(proto)->Stackable = 1000; } if(proto->StatsCount > MAX_ITEM_PROTO_STATS) @@ -2092,7 +2118,7 @@ void ObjectMgr::LoadItemPrototypes() if(proto->TotemCategory && !sTotemCategoryStore.LookupEntry(proto->TotemCategory)) sLog.outErrorDb("Item (Entry: %u) has wrong TotemCategory (%u)",i,proto->TotemCategory); - for (int j = 0; j < MAX_ITEM_PROTO_SOCKETS; j++) + for (int j = 0; j < MAX_ITEM_PROTO_SOCKETS; ++j) { if(proto->Socket[j].Color && (proto->Socket[j].Color & SOCKET_COLOR_ALL) != proto->Socket[j].Color) { @@ -2115,6 +2141,12 @@ void ObjectMgr::LoadItemPrototypes() sLog.outErrorDb("Item (Entry: %u) has wrong LimitCategory value (%u)",i,proto->ItemLimitCategory); const_cast<ItemPrototype*>(proto)->ItemLimitCategory = 0; } + + if(proto->HolidayId && !sHolidaysStore.LookupEntry(proto->HolidayId)) + { + sLog.outErrorDb("Item (Entry: %u) has wrong HolidayId value (%u)", i, proto->HolidayId); + const_cast<ItemPrototype*>(proto)->HolidayId = 0; + } } } @@ -5077,7 +5109,7 @@ uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team, bool allowed_alt_team /* CreatureInfo const *ci = GetCreatureTemplate(mount_entry); if(ci) - mount_id = ci->Modelid_A1; + mount_id = ci->DisplayID_A; } if (team == HORDE) { @@ -5088,7 +5120,7 @@ uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team, bool allowed_alt_team /* CreatureInfo const *ci = GetCreatureTemplate(mount_entry); if(ci) - mount_id = ci->Modelid_H1; + mount_id = ci->DisplayID_H; } } @@ -6011,6 +6043,8 @@ void ObjectMgr::LoadGameobjectInfo() if (!goInfo) continue; + // some GO types have unused go template, check goInfo->displayId at GO spawn data loading or ignore + switch(goInfo->type) { case GAMEOBJECT_TYPE_DOOR: //0 |