Core/ObjectMgr: Refactor sCreatureDataAddonStorage

This commit is contained in:
leak
2011-04-28 22:46:40 +02:00
parent a82654debd
commit c8413a7f27
6 changed files with 153 additions and 222 deletions
@@ -0,0 +1,51 @@
CREATE TABLE `temp_auras` (
`spell` MEDIUMINT(8) UNSIGNED NOT NULL
) ENGINE=MYISAM DEFAULT CHARSET=utf8;
DELIMITER %%
CREATE FUNCTION `ConvertAuras`(`auras` VARCHAR(1024))
RETURNS VARCHAR(1024) CHARSET utf8
DETERMINISTIC
BEGIN
DECLARE tmp VARCHAR(1024);
DECLARE curr VARCHAR(10);
DECLARE k INT;
DECLARE pos INT;
DECLARE startp INT;
SET @k = 0;
SET @tmp = '';
SET @startp = 1;
SET @pos = LOCATE(' ', auras);
DELETE FROM temp_auras;
WHILE @pos > 0 DO
IF @k = 0 THEN
SET @curr = SUBSTR(auras, @startp, @pos - @startp);
IF NOT EXISTS(SELECT spell FROM temp_auras WHERE spell = @curr) THEN
SET @tmp = CONCAT(@tmp, @curr, ' ');
INSERT INTO temp_auras VALUES(@curr);
END IF;
END IF;
SET @k = 1-@k;
SET @startp = @pos+1;
SET @pos = LOCATE(' ', auras, @startp);
END WHILE;
SET @tmp = RTRIM(@tmp);
RETURN @tmp;
END%%
DELIMITER ;
UPDATE `creature_addon` SET `auras` = REPLACE(`auras`, ' ', ' ');
UPDATE `creature_addon` SET `auras` = TRIM(`auras`);
UPDATE `creature_addon` SET `auras` = NULL WHERE `auras` = '';
UPDATE `creature_addon` SET `auras` = ConvertAuras(`auras`) WHERE `auras` IS NOT NULL;
DROP FUNCTION `ConvertAuras`;
DROP TABLE `temp_auras`;
+11 -11
View File
@@ -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;
+6 -10
View File
@@ -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;
+81 -190
View File
@@ -860,167 +860,86 @@ 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)
{
// 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;
}
}
// free char* loaded memory
delete[] (char*)reinterpret_cast<char const*>(addon->auras);
// 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())
{
addon->auras = NULL;
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)
{
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)
{
sLog->outErrorDb("Creature (%s: %u) has wrong spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.spell_id,table);
continue;
}
for (uint8 eff = 0; eff < MAX_SPELL_EFFECTS; ++eff)
{
if ((1<<eff) & cAura.effectMask)
{
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;
}
}
}
++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 (!sCreatureDisplayInfoStore.LookupEntry(addon->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;
}
}
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 (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);
}*/
ConvertCreatureAddonAuras(const_cast<CreatureDataAddon*>(addon), creatureaddons.GetTableName(), entryName);
}
return creatureaddons.RecordCount;
}
void ObjectMgr::LoadCreatureAddons()
{
uint32 oldMSTime = getMSTime();
uint32 count = LoadCreatureAddons(sCreatureInfoAddonStorage,"Entry");
// 0 1 2 3 4 5 6
QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, bytes1, bytes2, emote, auras FROM creature_addon");
// 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());
if (!result)
{
sLog->outString(">> Loaded 0 creature addon definitions. DB table `creature_addon` is empty.");
sLog->outString();
return;
}
sLog->outString(">> Loaded %u creature template addons in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
uint32 count = 0;
do
{
Field *fields = result->Fetch();
sLog->outString("Loading Creature Addon Data...");
count = LoadCreatureAddons(sCreatureDataAddonStorage,"GUID");
uint32 guid = fields[0].GetUInt32();
// 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);
if (mCreatureDataMap.find(guid) == mCreatureDataMap.end())
{
sLog->outErrorDb("Creature (GUID: %u) does not exist but has a record in `creature_addon`", guid);
continue;
}
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)
{
SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(uint32(atol(*itr)));
if (!AdditionalSpellInfo)
{
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));
}
if (creatureAddon.mount)
{
if (!sCreatureDisplayInfoStore.LookupEntry(creatureAddon.mount))
{
sLog->outErrorDb("Creature (GUID: %u) has invalid displayInfoId (%u) for mount defined in `creature_addon`", guid, creatureAddon.mount);
creatureAddon.mount = 0;
}
}
if (!sEmotesStore.LookupEntry(creatureAddon.emote))
sLog->outErrorDb("Creature (GUID: %u) has invalid emote (%u) defined in `creature_addon`.", guid, creatureAddon.emote);
CreatureAddonStore[guid] = creatureAddon;
++count;
}
while (result->NextRow());
sLog->outString(">> Loaded %u creature addons in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
}
CreatureAddon const * ObjectMgr::GetCreatureAddon(uint32 lowguid)
{
CreatureAddonContainer::const_iterator itr = CreatureAddonStore.find(lowguid);
if (itr != CreatureAddonStore.end())
return &(itr->second);
return NULL;
}
EquipmentInfo const* ObjectMgr::GetEquipmentInfo(uint32 entry)
{
EquipmentInfoContainer::const_iterator itr = EquipmentInfoStore.find(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();
}
+4 -9
View File
@@ -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;
@@ -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");