diff options
author | leak <leakzx@googlemail.com> | 2011-04-28 22:46:40 +0200 |
---|---|---|
committer | leak <leakzx@googlemail.com> | 2011-04-28 22:46:40 +0200 |
commit | c8413a7f27cdb0de2f93d2437decdbc1628cb69e (patch) | |
tree | b160ee8df25d3246f54de52abebc473bb0991295 /src | |
parent | a82654debd8fd00fec3f2024290876ab0d6dd175 (diff) |
Core/ObjectMgr: Refactor sCreatureDataAddonStorage
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/Entities/Creature/Creature.cpp | 22 | ||||
-rwxr-xr-x | src/server/game/Entities/Creature/Creature.h | 16 | ||||
-rwxr-xr-x | src/server/game/Globals/ObjectMgr.cpp | 235 | ||||
-rwxr-xr-x | src/server/game/Globals/ObjectMgr.h | 13 | ||||
-rwxr-xr-x | src/server/shared/Database/SQLStorage.cpp | 2 |
5 files changed, 84 insertions, 204 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index a8ed317f7d5..f8e0c6224ce 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -2025,11 +2025,11 @@ bool Creature::canCreatureAttack(Unit const *pVictim, bool force) const return pVictim->IsInDist(&m_homePosition, dist); } -CreatureDataAddon const* Creature::GetCreatureAddon() const +CreatureAddon const* Creature::GetCreatureAddon() const { if (m_DBTableGuid) { - if (CreatureDataAddon const* addon = ObjectMgr::GetCreatureAddon(m_DBTableGuid)) + if (CreatureAddon const* addon = sObjectMgr->GetCreatureAddon(m_DBTableGuid)) return addon; } @@ -2040,7 +2040,7 @@ CreatureDataAddon const* Creature::GetCreatureAddon() const //creature_addon table bool Creature::LoadCreaturesAddon(bool reload) { - CreatureDataAddon const *cainfo = GetCreatureAddon(); + CreatureAddon const *cainfo = GetCreatureAddon(); if (!cainfo) return false; @@ -2083,28 +2083,28 @@ bool Creature::LoadCreaturesAddon(bool reload) if (cainfo->path_id != 0) m_path_id = cainfo->path_id; - if (cainfo->auras) + if (!cainfo->auras.empty()) { - for (CreatureDataAddonAura const* cAura = cainfo->auras; cAura->spell_id; ++cAura) + for (std::vector<uint32>::const_iterator itr = cainfo->auras.begin(); itr != cainfo->auras.end(); ++itr) { - SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(cAura->spell_id); + SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(*itr); if (!AdditionalSpellInfo) { - sLog->outErrorDb("Creature (GUID: %u Entry: %u) has wrong spell %u defined in `auras` field.",GetGUIDLow(),GetEntry(),cAura->spell_id); + sLog->outErrorDb("Creature (GUID: %u Entry: %u) has wrong spell %u defined in `auras` field.", GetGUIDLow(), GetEntry(), *itr); continue; } // skip already applied aura - if (HasAura(cAura->spell_id)) + if (HasAura(*itr)) { if (!reload) - sLog->outErrorDb("Creature (GUID: %u Entry: %u) has duplicate aura (spell %u) in `auras` field.",GetGUIDLow(),GetEntry(),cAura->spell_id); + sLog->outErrorDb("Creature (GUID: %u Entry: %u) has duplicate aura (spell %u) in `auras` field.", GetGUIDLow(), GetEntry(), *itr); continue; } - AddAura(AdditionalSpellInfo, cAura->effectMask, this); - sLog->outDebug(LOG_FILTER_UNITS, "Spell: %u with AuraEffectMask %u added to creature (GUID: %u Entry: %u)", cAura->spell_id, cAura->effectMask,GetGUIDLow(),GetEntry()); + AddAura(*itr, this); + sLog->outDebug(LOG_FILTER_UNITS, "Spell: %u added to creature (GUID: %u Entry: %u)", *itr, GetGUIDLow(), GetEntry()); } } return true; diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 9dc3b00791a..d3f26590f07 100755 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -263,14 +263,8 @@ struct CreatureData bool dbData; }; -struct CreatureDataAddonAura -{ - uint32 spell_id; - uint8 effectMask; -}; - -// from `creature_addon` table -struct CreatureDataAddon +// `creature_addon` table +struct CreatureAddon { uint32 guidOrEntry; uint32 path_id; @@ -278,9 +272,11 @@ struct CreatureDataAddon uint32 bytes1; uint32 bytes2; uint32 emote; - CreatureDataAddonAura const* auras; // loaded as char* "spell1 eff1 spell2 eff2 ... " + std::vector<uint32> auras; }; +typedef UNORDERED_MAP<uint32, CreatureAddon> CreatureAddonContainer; + struct CreatureModelInfo { float bounding_radius; @@ -533,7 +529,7 @@ class Creature : public Unit, public GridObject<Creature> CreatureInfo const *GetCreatureInfo() const { return m_creatureInfo; } CreatureData const *GetCreatureData() const { return m_creatureData; } - CreatureDataAddon const* GetCreatureAddon() const; + CreatureAddon const* GetCreatureAddon() const; std::string GetAIName() const; std::string GetScriptName() const; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 10fe9dd918d..8e5b784dc09 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -860,165 +860,84 @@ void ObjectMgr::CheckCreatureTemplate(CreatureInfo const* cInfo) const_cast<CreatureInfo*>(cInfo)->dmg_multiplier *= Creature::_GetDamageMod(cInfo->rank); } -void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr) +void ObjectMgr::LoadCreatureAddons() { - // Now add the auras, format "spellid effectindex spellid effectindex..." - char *p,*s; - std::map<uint32, uint32> val; - s=p=(char*)reinterpret_cast<char const*>(addon->auras); - if (p) - { - uint32 currSpellId = 0; - bool spell = true; - while (p[0] != 0) - { - ++p; - if (p[0] == ' ' || p[0] == 0) - { - if (spell) - currSpellId = atoi(s); - else - { - uint8 eff = atoi(s); - if (eff >=3) - { - sLog->outErrorDb("Creature (%s: %u) has wrong `auras` data in `%s`(too high aura effect: %d for spell: %d)",guidEntryStr,addon->guidOrEntry,table,eff,currSpellId); - } - val[currSpellId] |= 1<<eff; - } - spell = !spell; - if (p[0] == 0) - break; - s=++p; - } - } + uint32 oldMSTime = getMSTime(); - // free char* loaded memory - delete[] (char*)reinterpret_cast<char const*>(addon->auras); + // 0 1 2 3 4 5 6 + QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, bytes1, bytes2, emote, auras FROM creature_addon"); - // wrong list - if (!spell) - { - addon->auras = NULL; - sLog->outErrorDb("Creature (%s: %u) has wrong `auras` data in `%s`.",guidEntryStr,addon->guidOrEntry,table); - return; - } - } - - // empty list - if (val.empty()) + if (!result) { - addon->auras = NULL; + sLog->outString(">> Loaded 0 creature addon definitions. DB table `creature_addon` is empty."); + sLog->outString(); return; } - // replace by new structures array - const_cast<CreatureDataAddonAura*&>(addon->auras) = new CreatureDataAddonAura[val.size()+1]; - - uint32 i=0; - for (std::map<uint32, uint32>::iterator itr = val.begin(); itr != val.end();++itr) + uint32 count = 0; + do { - CreatureDataAddonAura& cAura = const_cast<CreatureDataAddonAura&>(addon->auras[i]); - cAura.spell_id = itr->first; - cAura.effectMask = itr->second; - if (cAura.effectMask > 7 || !cAura.effectMask) - { - sLog->outErrorDb("Creature (%s: %u) has wrong effect for spell %u in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.spell_id,table); - continue; - } - SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(cAura.spell_id); - if (!AdditionalSpellInfo) + Field *fields = result->Fetch(); + + uint32 guid = fields[0].GetUInt32(); + + if (mCreatureDataMap.find(guid) == mCreatureDataMap.end()) { - sLog->outErrorDb("Creature (%s: %u) has wrong spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.spell_id,table); + sLog->outErrorDb("Creature (GUID: %u) does not exist but has a record in `creature_addon`", guid); continue; } - for (uint8 eff = 0; eff < MAX_SPELL_EFFECTS; ++eff) + + CreatureAddon creatureAddon; + + creatureAddon.path_id = fields[1].GetUInt32(); + creatureAddon.mount = fields[2].GetUInt32(); + creatureAddon.bytes1 = fields[3].GetUInt32(); + creatureAddon.bytes2 = fields[4].GetUInt32(); + creatureAddon.emote = fields[5].GetUInt32(); + + Tokens tokens(fields[6].GetString(), ' '); + uint8 i = 0; + creatureAddon.auras.resize(tokens.size()); + for (Tokens::iterator itr = tokens.begin(); itr != tokens.end(); ++itr) { - if ((1<<eff) & cAura.effectMask) + SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(uint32(atol(*itr))); + if (!AdditionalSpellInfo) { - if (!AdditionalSpellInfo->Effect[eff] || !AdditionalSpellInfo->EffectApplyAuraName[eff]) - { - sLog->outErrorDb("Creature (%s: %u) has not aura effect %u of spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,eff,cAura.spell_id,table); - continue; - } - else if (AdditionalSpellInfo->Effect[eff] == SPELL_EFFECT_PERSISTENT_AREA_AURA) - { - sLog->outErrorDb("Creature (%s: %u) has persistent area aura effect %u of spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,eff,cAura.spell_id,table); - continue; - } + sLog->outErrorDb("Creature (GUID: %u) has wrong spell %u defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr))); + continue; } + creatureAddon.auras[i++] = uint32(atol(*itr)); } - ++i; - } - - // fill terminator element (after last added) - CreatureDataAddonAura& endAura = const_cast<CreatureDataAddonAura&>(addon->auras[i]); - endAura.spell_id = 0; - endAura.effectMask = 0; -} - -uint32 ObjectMgr::LoadCreatureAddons(SQLStorage& creatureaddons, char const* entryName) -{ - creatureaddons.Load(); - - // check data correctness and convert 'auras' - for (uint32 i = 1; i < creatureaddons.MaxEntry; ++i) - { - CreatureDataAddon const* addon = creatureaddons.LookupEntry<CreatureDataAddon>(i); - if (!addon) - continue; - - if (addon->mount) + if (creatureAddon.mount) { - if (!sCreatureDisplayInfoStore.LookupEntry(addon->mount)) + if (!sCreatureDisplayInfoStore.LookupEntry(creatureAddon.mount)) { - sLog->outErrorDb("Creature (%s %u) have invalid displayInfoId for mount (%u) defined in `%s`.", entryName, addon->guidOrEntry, addon->mount, creatureaddons.GetTableName()); - const_cast<CreatureDataAddon*>(addon)->mount = 0; + sLog->outErrorDb("Creature (GUID: %u) has invalid displayInfoId (%u) for mount defined in `creature_addon`", guid, creatureAddon.mount); + creatureAddon.mount = 0; } } - if (!sEmotesStore.LookupEntry(addon->emote)) - sLog->outErrorDb("Creature (%s %u) have invalid emote (%u) defined in `%s`.", entryName, addon->guidOrEntry, addon->emote, creatureaddons.GetTableName()); + if (!sEmotesStore.LookupEntry(creatureAddon.emote)) + sLog->outErrorDb("Creature (GUID: %u) has invalid emote (%u) defined in `creature_addon`.", guid, creatureAddon.emote); - /*if (addon->move_flags & (MONSTER_MOVE_UNK1|MONSTER_MOVE_UNK4)) - { - sLog->outErrorDb("Creature (%s %u) movement flags mask defined in `%s` include forbidden flags (" I32FMT ") that can crash client, cleanup at load.", entryName, addon->guidOrEntry, creatureaddons.GetTableName(), (MONSTER_MOVE_UNK1|MONSTER_MOVE_UNK4)); - const_cast<CreatureDataAddon*>(addon)->move_flags &= ~(MONSTER_MOVE_UNK1|MONSTER_MOVE_UNK4); - }*/ + CreatureAddonStore[guid] = creatureAddon; - ConvertCreatureAddonAuras(const_cast<CreatureDataAddon*>(addon), creatureaddons.GetTableName(), entryName); + ++count; } + while (result->NextRow()); - return creatureaddons.RecordCount; + sLog->outString(">> Loaded %u creature addons in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); + sLog->outString(); } -void ObjectMgr::LoadCreatureAddons() +CreatureAddon const * ObjectMgr::GetCreatureAddon(uint32 lowguid) { - uint32 oldMSTime = getMSTime(); - - uint32 count = LoadCreatureAddons(sCreatureInfoAddonStorage,"Entry"); - - // check entry ids - for (uint32 i = 1; i < sCreatureInfoAddonStorage.MaxEntry; ++i) - if (CreatureDataAddon const* addon = sCreatureInfoAddonStorage.LookupEntry<CreatureDataAddon>(i)) - if (!sCreatureStorage.LookupEntry<CreatureInfo>(addon->guidOrEntry)) - sLog->outErrorDb("Creature (Entry: %u) does not exist but has a record in `%s`",addon->guidOrEntry, sCreatureInfoAddonStorage.GetTableName()); - - sLog->outString(">> Loaded %u creature template addons in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - sLog->outString(); - - sLog->outString("Loading Creature Addon Data..."); - count = LoadCreatureAddons(sCreatureDataAddonStorage,"GUID"); - - // check entry ids - for (uint32 i = 1; i < sCreatureDataAddonStorage.MaxEntry; ++i) - if (CreatureDataAddon const* addon = sCreatureDataAddonStorage.LookupEntry<CreatureDataAddon>(i)) - if (mCreatureDataMap.find(addon->guidOrEntry) == mCreatureDataMap.end()) - sLog->outErrorDb("Creature (GUID: %u) does not exist but has a record in `creature_addon`",addon->guidOrEntry); + CreatureAddonContainer::const_iterator itr = CreatureAddonStore.find(lowguid); + if (itr != CreatureAddonStore.end()) + return &(itr->second); - sLog->outString(">> Loaded %u creature addons in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - sLog->outString(); + return NULL; } EquipmentInfo const* ObjectMgr::GetEquipmentInfo(uint32 entry) @@ -1457,16 +1376,12 @@ void ObjectMgr::LoadCreatures() { uint32 oldMSTime = getMSTime(); - uint32 count = 0; - // 0 1 2 3 - QueryResult result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid," - // 4 5 6 7 8 9 10 11 - "equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint," - // 12 13 14 15 16 17 18 19 - "curhealth, curmana, DeathState, MovementType, spawnMask, phaseMask, eventEntry, pool_entry," - // 20 21 22 - "creature.npcflag, creature.unit_flags, creature.dynamicflags " - "FROM creature LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid " + // 0 1 2 3 4 5 6 7 8 9 10 + QueryResult result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, " + // 11 12 13 14 15 16 17 18 19 20 21 22 + "currentwaypoint, curhealth, curmana, DeathState, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags " + "FROM creature " + "LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid " "LEFT OUTER JOIN pool_creature ON creature.guid = pool_creature.guid"); if (!result) @@ -1476,7 +1391,7 @@ void ObjectMgr::LoadCreatures() return; } - // build single time for check creature data + // Build single time for check creature data std::set<uint32> difficultyCreatures[MAX_DIFFICULTY - 1]; for (uint32 i = 0; i < sCreatureStorage.MaxEntry; ++i) if (CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(i)) @@ -1484,7 +1399,7 @@ void ObjectMgr::LoadCreatures() if (cInfo->DifficultyEntry[diff]) difficultyCreatures[diff].insert(cInfo->DifficultyEntry[diff]); - // build single time for check spawnmask + // Build single time for check spawnmask std::map<uint32,uint32> spawnMasks; for (uint32 i = 0; i < sMapStore.GetNumRows(); ++i) if (sMapStore.LookupEntry(i)) @@ -1492,9 +1407,7 @@ void ObjectMgr::LoadCreatures() if (GetMapDifficultyData(i,Difficulty(k))) spawnMasks[i] |= (1 << k); - //TODO: remove this - //sGameEventMgr->mGameEventCreatureGuids.resize(52*2-1); - + uint32 count = 0; do { Field *fields = result->Fetch(); @@ -1557,17 +1470,8 @@ void ObjectMgr::LoadCreatures() if (!ok) continue; - // I do not know why but in db most display id are not zero - /*if (data.displayid == 11686 || data.displayid == 24719) - { - (const_cast<CreatureInfo*>(cInfo))->flags_extra |= CREATURE_FLAG_EXTRA_TRIGGER; - } - 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; - */ - - if (data.equipmentId > 0) // -1 no equipment, 0 use default + // -1 no equipment, 0 use default + if (data.equipmentId > 0) { if (!GetEquipmentInfo(data.equipmentId)) { @@ -1618,28 +1522,15 @@ void ObjectMgr::LoadCreatures() data.npcflag &= ~UNIT_NPC_FLAG_SPELLCLICK; } - //if (entry == 32307 || entry == 32308) - /*if (entry == 30739 || entry == 30740) - { - gameEvent = 51; - uint32 guid2 = sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT); - CreatureData& data2 = mCreatureDataMap[guid2]; - data2 = data; -// data2.id = (entry == 32307 ? 32308 : 32307); - data2.id = (entry == 30739 ? 30740 : 30739); - data2.displayid = 0; - sGameEventMgr->mGameEventCreatureGuids[51+51].push_back(guid); - sGameEventMgr->mGameEventCreatureGuids[51+50].push_back(guid2); - }*/ - - if (gameEvent == 0 && PoolId == 0) // if not this is to be managed by GameEvent System or Pool system + // Add to grid if not managed by the game event or pool system + if (gameEvent == 0 && PoolId == 0) AddCreatureToGrid(guid, &data); ++count; } while (result->NextRow()); - sLog->outString(">> Loaded %u creatures in %u ms", (uint32)mCreatureDataMap.size(), GetMSTimeDiffToNow(oldMSTime)); + sLog->outString(">> Loaded %u creatures in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); sLog->outString(); } diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 2c3fc1a05e1..e3d706f61dd 100755 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -45,7 +45,6 @@ #include <functional> extern SQLStorage sCreatureStorage; -extern SQLStorage sCreatureDataAddonStorage; extern SQLStorage sCreatureInfoAddonStorage; extern SQLStorage sGOStorage; @@ -679,14 +678,11 @@ class ObjectMgr uint32 ChooseDisplayId(uint32 team, const CreatureInfo *cinfo, const CreatureData *data = NULL); static void ChooseCreatureFlags(const CreatureInfo *cinfo, uint32& npcflag, uint32& unit_flags, uint32& dynamicflags, const CreatureData *data = NULL); EquipmentInfo const *GetEquipmentInfo(uint32 entry); - static CreatureDataAddon const *GetCreatureAddon(uint32 lowguid) - { - return sCreatureDataAddonStorage.LookupEntry<CreatureDataAddon>(lowguid); - } + CreatureAddon const *GetCreatureAddon(uint32 lowguid); - static CreatureDataAddon const *GetCreatureTemplateAddon(uint32 entry) + static CreatureAddon const *GetCreatureTemplateAddon(uint32 entry) { - return sCreatureInfoAddonStorage.LookupEntry<CreatureDataAddon>(entry); + return sCreatureInfoAddonStorage.LookupEntry<CreatureAddon>(entry); } ItemTemplate const* GetItemTemplate(uint32 entry); @@ -1371,8 +1367,6 @@ class ObjectMgr private: void LoadScripts(ScriptsType type); void CheckScripts(ScriptsType type, std::set<int32>& ids); - uint32 LoadCreatureAddons(SQLStorage& creatureaddons, char const* entryName); - void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr); void LoadQuestRelationsHelper(QuestRelations& map, std::string table, bool starter, bool go); void PlayerCreateInfoAddItemHelper(uint32 race_, uint32 class_, uint32 itemId, int32 count); @@ -1409,6 +1403,7 @@ class ObjectMgr MapObjectGuids mMapObjectGuids; CreatureDataMap mCreatureDataMap; CreatureModelContainer CreatureModelStore; + CreatureAddonContainer CreatureAddonStore; EquipmentInfoContainer EquipmentInfoStore; LinkedRespawnMap mLinkedRespawnMap; CreatureLocaleMap mCreatureLocaleMap; diff --git a/src/server/shared/Database/SQLStorage.cpp b/src/server/shared/Database/SQLStorage.cpp index 0ed1986486e..439b1c5892c 100755 --- a/src/server/shared/Database/SQLStorage.cpp +++ b/src/server/shared/Database/SQLStorage.cpp @@ -21,13 +21,11 @@ const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifffliiiiiiiliiisi"; const char CreatureInfodstfmt[]="iiiiiiiiiisssibbiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifffliiiiiiiliiiii"; -const char CreatureDataAddonInfofmt[]="iiiiiis"; const char CreatureInfoAddonInfofmt[]="iiiiiis"; const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiissi"; const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisii"; SQLStorage sCreatureStorage(CreatureInfosrcfmt, CreatureInfodstfmt, "entry","creature_template"); -SQLStorage sCreatureDataAddonStorage(CreatureDataAddonInfofmt,"guid","creature_addon"); SQLStorage sCreatureInfoAddonStorage(CreatureInfoAddonInfofmt,"entry","creature_template_addon"); SQLStorage sGOStorage(GameObjectInfosrcfmt, GameObjectInfodstfmt, "entry","gameobject_template"); |