diff options
author | QAston <none@none> | 2009-08-27 17:44:30 +0200 |
---|---|---|
committer | QAston <none@none> | 2009-08-27 17:44:30 +0200 |
commit | 6b703d600bd08fa642a2e121fb53d5749d677076 (patch) | |
tree | fb9841c1ce09e9f83542c84340f97ded510db85a | |
parent | 562b4fc0a4cc748df4a5732771a8b83b8af093c1 (diff) |
*Add `spell_dbc` table to store dbc entries not present in client
*Remove workaround from Demonic Circle code and use the sql table instead.
--HG--
branch : trunk
-rw-r--r-- | sql/FULL/world_spell_full.sql | 8 | ||||
-rw-r--r-- | sql/updates/5410_world_sql_dbc.sql | 101 | ||||
-rw-r--r-- | sql/world.sql | 103 | ||||
-rw-r--r-- | src/game/DBCStores.cpp | 12 | ||||
-rw-r--r-- | src/game/DBCStructure.h | 2 | ||||
-rw-r--r-- | src/game/DBCfmt.h | 4 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 21 | ||||
-rw-r--r-- | src/game/Unit.cpp | 22 | ||||
-rw-r--r-- | src/game/Unit.h | 1 | ||||
-rw-r--r-- | src/shared/Database/DBCFileLoader.cpp | 15 | ||||
-rw-r--r-- | src/shared/Database/DBCFileLoader.h | 7 | ||||
-rw-r--r-- | src/shared/Database/DBCStore.h | 181 | ||||
-rw-r--r-- | src/shared/Database/Field.h | 11 |
13 files changed, 440 insertions, 48 deletions
diff --git a/sql/FULL/world_spell_full.sql b/sql/FULL/world_spell_full.sql index cebeef42aaa..fbcf3db0020 100644 --- a/sql/FULL/world_spell_full.sql +++ b/sql/FULL/world_spell_full.sql @@ -1846,6 +1846,14 @@ INSERT INTO `spell_bonus_data` (`entry`, `direct_bonus`, `dot_bonus`, `ap_bonus` (6343, -1, -1, 0.12, -1, 'Warrior - Thunder Clap'); -- -------- +-- SPELL DBC +-- -------- + +TRUNCATE TABLE `spell_dbc`; +INSERT INTO `spell_dbc` (`Id`, `DurationIndex`, `Effect1`, `EffectImplicitTargetA1`, `EffectApplyAuraName1`, `Comment`) VALUES +(62388, 21, 6, 1, 4, 'Demonic Circle: Teleport(48020) - casterAuraSpell'); + +-- -------- -- SPELL ELIXIR -- -------- diff --git a/sql/updates/5410_world_sql_dbc.sql b/sql/updates/5410_world_sql_dbc.sql new file mode 100644 index 00000000000..31f648dcad4 --- /dev/null +++ b/sql/updates/5410_world_sql_dbc.sql @@ -0,0 +1,101 @@ +DROP TABLE IF EXISTS `spell_dbc`; +CREATE TABLE `spell_dbc` ( + `Id` INT UNSIGNED NOT NULL, + `Dispel` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `Mechanic` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `Attributes` INT UNSIGNED NOT NULL DEFAULT 0, + `AttributesEx` INT UNSIGNED NOT NULL DEFAULT 0, + `AttributesEx2` INT UNSIGNED NOT NULL DEFAULT 0, + `AttributesEx3` INT UNSIGNED NOT NULL DEFAULT 0, + `AttributesEx4` INT UNSIGNED NOT NULL DEFAULT 0, + `AttributesEx5` INT UNSIGNED NOT NULL DEFAULT 0, + `Targets` INT UNSIGNED NOT NULL DEFAULT 0, + `CastingTimeIndex` TINYINT UNSIGNED NOT NULL DEFAULT 1, + `AuraInterruptFlags` INT UNSIGNED NOT NULL DEFAULT 0, + `ProcFlags` INT UNSIGNED NOT NULL DEFAULT 0, + `ProcChance` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `ProcCharges` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `MaxLevel` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `BaseLevel` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `SpellLevel` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `DurationIndex` SMALLINT UNSIGNED NOT NULL DEFAULT 0, + `RangeIndex` TINYINT UNSIGNED NOT NULL DEFAULT 1, + `StackAmount` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EquippedItemClass` INT NOT NULL DEFAULT -1, + `EquippedItemSubClassMask` INT NOT NULL DEFAULT 0 DEFAULT 0, + `EquippedItemInventoryTypeMask` INT NOT NULL DEFAULT 0 DEFAULT 0, + `Effect1` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `Effect2` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `Effect3` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectDieSides1` INT NOT NULL DEFAULT 0, + `EffectDieSides2` INT NOT NULL DEFAULT 0, + `EffectDieSides3` INT NOT NULL DEFAULT 0, + `EffectBaseDice1` INT NOT NULL DEFAULT 0, + `EffectBaseDice2` INT NOT NULL DEFAULT 0, + `EffectBaseDice3` INT NOT NULL DEFAULT 0, + `EffectDicePerLevel1` FLOAT NOT NULL DEFAULT 0, + `EffectDicePerLevel2` FLOAT NOT NULL DEFAULT 0, + `EffectDicePerLevel3` FLOAT NOT NULL DEFAULT 0, + `EffectRealPointsPerLevel1` FLOAT NOT NULL DEFAULT 0, + `EffectRealPointsPerLevel2` FLOAT NOT NULL DEFAULT 0, + `EffectRealPointsPerLevel3` FLOAT NOT NULL DEFAULT 0, + `EffectBasePoints1` INT NOT NULL DEFAULT 0, + `EffectBasePoints2` INT NOT NULL DEFAULT 0, + `EffectBasePoints3` INT NOT NULL DEFAULT 0, + `EffectMechanic1` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectMechanic2` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectMechanic3` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectImplicitTargetA1` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectImplicitTargetA2` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectImplicitTargetA3` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectImplicitTargetB1` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectImplicitTargetB2` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectImplicitTargetB3` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectRadiusIndex1` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectRadiusIndex2` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectRadiusIndex3` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectApplyAuraName1` SMALLINT UNSIGNED NOT NULL DEFAULT 0, + `EffectApplyAuraName2` SMALLINT UNSIGNED NOT NULL DEFAULT 0, + `EffectApplyAuraName3` SMALLINT UNSIGNED NOT NULL DEFAULT 0, + `EffectAmplitude1` INT NOT NULL DEFAULT 0, + `EffectAmplitude2` INT NOT NULL DEFAULT 0, + `EffectAmplitude3` INT NOT NULL DEFAULT 0, + `EffectMultipleValue1` FLOAT NOT NULL DEFAULT 0, + `EffectMultipleValue2` FLOAT NOT NULL DEFAULT 0, + `EffectMultipleValue3` FLOAT NOT NULL DEFAULT 0, + `EffectMiscValue1` INT NOT NULL DEFAULT 0, + `EffectMiscValue2` INT NOT NULL DEFAULT 0, + `EffectMiscValue3` INT NOT NULL DEFAULT 0, + `EffectMiscValueB1` INT NOT NULL DEFAULT 0, + `EffectMiscValueB2` INT NOT NULL DEFAULT 0, + `EffectMiscValueB3` INT NOT NULL DEFAULT 0, + `EffectTriggerSpell1` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectTriggerSpell2` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectTriggerSpell3` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskA1` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskA2` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskA3` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskB1` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskB2` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskB3` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskC1` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskC2` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskC3` INT UNSIGNED NOT NULL DEFAULT 0, + `MaxTargetLevel` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `SpellFamilyName` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `SpellFamilyFlags1` INT UNSIGNED NOT NULL DEFAULT 0, + `SpellFamilyFlags2` INT UNSIGNED NOT NULL DEFAULT 0, + `SpellFamilyFlags3` INT UNSIGNED NOT NULL DEFAULT 0, + `MaxAffectedTargets` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `DmgClass` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `PreventionType` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `DmgMultiplier1` FLOAT NOT NULL DEFAULT 0, + `DmgMultiplier2` FLOAT NOT NULL DEFAULT 0, + `DmgMultiplier3` FLOAT NOT NULL DEFAULT 0, + `AreaGroupId` INT NOT NULL DEFAULT 0, + `SchoolMask` INT UNSIGNED NOT NULL DEFAULT 0, + `Comment` TEXT NOT NULL, + PRIMARY KEY (`id`) +)ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Custom spell.dbc entries'; + +INSERT INTO `spell_dbc` (`Id`, `DurationIndex`, `Effect1`, `EffectImplicitTargetA1`, `EffectApplyAuraName1`, `Comment`) VALUES (62388, 21, 6, 1, 4, 'Demonic Circle: Teleport(48020) - casterAuraSpell'); diff --git a/sql/world.sql b/sql/world.sql index e4ee3ea2b3a..1e9831d856c 100644 --- a/sql/world.sql +++ b/sql/world.sql @@ -2741,6 +2741,109 @@ CREATE TABLE `spell_bonus_data` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- +-- Table structure for table `spell_dbc` +-- +DROP TABLE IF EXISTS `spell_dbc`; +CREATE TABLE `spell_dbc` ( + `Id` INT UNSIGNED NOT NULL, + `Dispel` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `Mechanic` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `Attributes` INT UNSIGNED NOT NULL DEFAULT 0, + `AttributesEx` INT UNSIGNED NOT NULL DEFAULT 0, + `AttributesEx2` INT UNSIGNED NOT NULL DEFAULT 0, + `AttributesEx3` INT UNSIGNED NOT NULL DEFAULT 0, + `AttributesEx4` INT UNSIGNED NOT NULL DEFAULT 0, + `AttributesEx5` INT UNSIGNED NOT NULL DEFAULT 0, + `Targets` INT UNSIGNED NOT NULL DEFAULT 0, + `CastingTimeIndex` TINYINT UNSIGNED NOT NULL DEFAULT 1, + `AuraInterruptFlags` INT UNSIGNED NOT NULL DEFAULT 0, + `ProcFlags` INT UNSIGNED NOT NULL DEFAULT 0, + `ProcChance` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `ProcCharges` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `MaxLevel` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `BaseLevel` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `SpellLevel` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `DurationIndex` SMALLINT UNSIGNED NOT NULL DEFAULT 0, + `RangeIndex` TINYINT UNSIGNED NOT NULL DEFAULT 1, + `StackAmount` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EquippedItemClass` INT NOT NULL DEFAULT -1, + `EquippedItemSubClassMask` INT NOT NULL DEFAULT 0 DEFAULT 0, + `EquippedItemInventoryTypeMask` INT NOT NULL DEFAULT 0 DEFAULT 0, + `Effect1` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `Effect2` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `Effect3` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectDieSides1` INT NOT NULL DEFAULT 0, + `EffectDieSides2` INT NOT NULL DEFAULT 0, + `EffectDieSides3` INT NOT NULL DEFAULT 0, + `EffectBaseDice1` INT NOT NULL DEFAULT 0, + `EffectBaseDice2` INT NOT NULL DEFAULT 0, + `EffectBaseDice3` INT NOT NULL DEFAULT 0, + `EffectDicePerLevel1` FLOAT NOT NULL DEFAULT 0, + `EffectDicePerLevel2` FLOAT NOT NULL DEFAULT 0, + `EffectDicePerLevel3` FLOAT NOT NULL DEFAULT 0, + `EffectRealPointsPerLevel1` FLOAT NOT NULL DEFAULT 0, + `EffectRealPointsPerLevel2` FLOAT NOT NULL DEFAULT 0, + `EffectRealPointsPerLevel3` FLOAT NOT NULL DEFAULT 0, + `EffectBasePoints1` INT NOT NULL DEFAULT 0, + `EffectBasePoints2` INT NOT NULL DEFAULT 0, + `EffectBasePoints3` INT NOT NULL DEFAULT 0, + `EffectMechanic1` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectMechanic2` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectMechanic3` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectImplicitTargetA1` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectImplicitTargetA2` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectImplicitTargetA3` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectImplicitTargetB1` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectImplicitTargetB2` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectImplicitTargetB3` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectRadiusIndex1` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectRadiusIndex2` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectRadiusIndex3` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `EffectApplyAuraName1` SMALLINT UNSIGNED NOT NULL DEFAULT 0, + `EffectApplyAuraName2` SMALLINT UNSIGNED NOT NULL DEFAULT 0, + `EffectApplyAuraName3` SMALLINT UNSIGNED NOT NULL DEFAULT 0, + `EffectAmplitude1` INT NOT NULL DEFAULT 0, + `EffectAmplitude2` INT NOT NULL DEFAULT 0, + `EffectAmplitude3` INT NOT NULL DEFAULT 0, + `EffectMultipleValue1` FLOAT NOT NULL DEFAULT 0, + `EffectMultipleValue2` FLOAT NOT NULL DEFAULT 0, + `EffectMultipleValue3` FLOAT NOT NULL DEFAULT 0, + `EffectMiscValue1` INT NOT NULL DEFAULT 0, + `EffectMiscValue2` INT NOT NULL DEFAULT 0, + `EffectMiscValue3` INT NOT NULL DEFAULT 0, + `EffectMiscValueB1` INT NOT NULL DEFAULT 0, + `EffectMiscValueB2` INT NOT NULL DEFAULT 0, + `EffectMiscValueB3` INT NOT NULL DEFAULT 0, + `EffectTriggerSpell1` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectTriggerSpell2` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectTriggerSpell3` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskA1` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskA2` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskA3` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskB1` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskB2` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskB3` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskC1` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskC2` INT UNSIGNED NOT NULL DEFAULT 0, + `EffectSpellClassMaskC3` INT UNSIGNED NOT NULL DEFAULT 0, + `MaxTargetLevel` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `SpellFamilyName` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `SpellFamilyFlags1` INT UNSIGNED NOT NULL DEFAULT 0, + `SpellFamilyFlags2` INT UNSIGNED NOT NULL DEFAULT 0, + `SpellFamilyFlags3` INT UNSIGNED NOT NULL DEFAULT 0, + `MaxAffectedTargets` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `DmgClass` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `PreventionType` TINYINT UNSIGNED NOT NULL DEFAULT 0, + `DmgMultiplier1` FLOAT NOT NULL DEFAULT 0, + `DmgMultiplier2` FLOAT NOT NULL DEFAULT 0, + `DmgMultiplier3` FLOAT NOT NULL DEFAULT 0, + `AreaGroupId` INT NOT NULL DEFAULT 0, + `SchoolMask` INT UNSIGNED NOT NULL DEFAULT 0, + `Comment` TEXT NOT NULL, + PRIMARY KEY (`id`) +)ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Custom spell.dbc entries'; + +-- -- Table structure for table `spell_disabled` -- diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp index 60236f786c7..a6b647b2ea8 100644 --- a/src/game/DBCStores.cpp +++ b/src/game/DBCStores.cpp @@ -165,13 +165,17 @@ static bool LoadDBC_assert_print(uint32 fsize,uint32 rsize, const std::string& f } template<class T> -inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList& errlist, DBCStorage<T>& storage, const std::string& dbc_path, const std::string& filename) +inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList& errlist, DBCStorage<T>& storage, const std::string& dbc_path, const std::string& filename, const std::string * custom_entries = NULL, const std::string * idname = NULL) { // compatibility format and C++ structure sizes assert(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDBC_assert_print(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()),sizeof(T),filename)); std::string dbc_filename = dbc_path + filename; - if(storage.Load(dbc_filename.c_str())) + SqlDbc * sql = NULL; + if (custom_entries) + sql = new SqlDbc(&filename,custom_entries, idname,storage.GetFormat()); + + if(storage.Load(dbc_filename.c_str(), sql)) { bar.step(); for(uint8 i = 0; i < MAX_LOCALE; ++i) @@ -198,6 +202,8 @@ inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList else errlist.push_back(dbc_filename); } + if (sql) + delete sql; } void LoadDBCStores(const std::string& dataPath) @@ -316,7 +322,7 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineStore, dbcPath,"SkillLine.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineAbilityStore, dbcPath,"SkillLineAbility.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSoundEntriesStore, dbcPath,"SoundEntries.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellStore, dbcPath,"Spell.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellStore, dbcPath,"Spell.dbc", &CustomSpellEntryfmt, &CustomSpellEntryIndex); for(uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) { SpellEntry const * spell = sSpellStore.LookupEntry(i); diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index a8b5d3ef177..ca903346815 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -1336,7 +1336,7 @@ struct SpellEntry uint32 Category; // 1 m_category uint32 Dispel; // 2 m_dispelType uint32 Mechanic; // 3 m_mechanic - uint32 Attributes; // 4 m_attribute + uint32 Attributes; // 4 m_attributes uint32 AttributesEx; // 5 m_attributesEx uint32 AttributesEx2; // 6 m_attributesExB uint32 AttributesEx3; // 7 m_attributesExC diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h index 6522a85406a..91fc4e5cc01 100644 --- a/src/game/DBCfmt.h +++ b/src/game/DBCfmt.h @@ -86,7 +86,9 @@ const char SkillLineAbilityfmt[]="niiiixxiiiiixx"; const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; const char SpellCastTimefmt[]="nixx"; const char SpellDurationfmt[]="niii"; -const char SpellEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixx"; +const char SpellEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixx"; +const std::string CustomSpellEntryfmt="pappppppppaaapaaaaaaaaaaapaaapapppppppaaaaapaapaaaaaaaaaaaaaaaaaappppppppppppppppppppppppppppppppppppppppppaaaaaapppppppppaaapppppppppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaappppppppapppaaaaappaaa"; +const std::string CustomSpellEntryIndex = "Id"; const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx"; const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiixxx"; const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX"; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 9182d5d141f..e586061a61f 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -4468,9 +4468,6 @@ void AuraEffect::HandleAuraPeriodicDummy(bool apply, bool Real, bool changeAmoun if(!Real && !changeAmount) return; - // For prevent double apply bonuses - bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading()); - Unit* caster = GetCaster(); SpellEntry const*spell = GetSpellProto(); @@ -4496,17 +4493,14 @@ void AuraEffect::HandleAuraPeriodicDummy(bool apply, bool Real, bool changeAmoun { // Demonic Circle case 48018: - if (apply) - // set to false at initial cast to enable button at next enable in periodic handler - m_target->SendAuraVisualForSelf(false,62388); - else + if (!apply) { // Do not remove GO when aura is removed by stack // to prevent remove GO added by new spell // old one is already removed if (GetParentAura()->GetRemoveMode()!=AURA_REMOVE_BY_STACK) m_target->RemoveGameObject(spell->Id,true); - m_target->SendAuraVisualForSelf(false,62388); + m_target->RemoveAura(62388); } break; } @@ -6380,8 +6374,15 @@ void AuraEffect::PeriodicDummyTick() // Demonic Circle case 48018: if(GameObject* obj = m_target->GetGameObject(spell->Id)) - // We must take a range of teleport spell, not summon. - m_target->SendAuraVisualForSelf(m_target->IsWithinDist(obj, GetSpellMaxRange(48020, true)), 62388, 1); + { + if (m_target->IsWithinDist(obj, GetSpellMaxRange(48020, true))) + { + if (!m_target->HasAura(62388)) + m_target->CastSpell(m_target, 62388, true); + } + else + m_target->RemoveAura(62388); + } return; } break; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index d505cdab965..1afbcbc652b 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3666,25 +3666,6 @@ int32 Unit::GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_ return modifier; } -void Unit::SendAuraVisualForSelf(bool apply, uint32 id, uint8 effmask) -{ - WorldPacket data(SMSG_AURA_UPDATE); - data.append(GetPackGUID()); - // use always free 64+ slots - data << uint8(MAX_AURAS); - if (!apply) - { - data << uint32(0); - SendMessageToSet(&data, true); - return; - } - data << uint32(id); - data << uint8(AFLAG_CASTER | AFLAG_POSITIVE | effmask); - data << uint8(getLevel()); - data << uint8(1); - SendMessageToSet(&data, true); -} - bool Unit::AddAura(Aura *Aur, bool handleEffects) { // aura doesn't apply effects-return @@ -4274,9 +4255,6 @@ bool Unit::HasAura(uint32 spellId, uint64 caster) const //Special case for non existing spell if (spellId==61988) return HasAura(61987, caster) || HasAura(25771, caster); - // Demonic Circle - special aura for client - else if (spellId==62388) - return HasAura(48018, caster); if (Aura * aur = GetAura(spellId, caster)) return true; diff --git a/src/game/Unit.h b/src/game/Unit.h index 4ac99da3361..fad4dd2d41c 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1642,7 +1642,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject } void SetVisibleAura(uint8 slot, Aura * aur){ m_visibleAuras[slot]=aur; } void RemoveVisibleAura(uint8 slot){ m_visibleAuras.erase(slot); } - void SendAuraVisualForSelf(bool apply, uint32 id, uint8 effmask = 0); AuraMap & GetAuras() { return m_Auras; } AuraMap const& GetAuras() const { return m_Auras; } diff --git a/src/shared/Database/DBCFileLoader.cpp b/src/shared/Database/DBCFileLoader.cpp index 23f602f5c93..e7ebeedecfb 100644 --- a/src/shared/Database/DBCFileLoader.cpp +++ b/src/shared/Database/DBCFileLoader.cpp @@ -137,7 +137,7 @@ uint32 DBCFileLoader::GetFormatRecordSize(const char * format,int32* index_pos) return recordsize; } -char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable) +char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable, uint32 sqlRecordCount, uint32 sqlHighestIndex, char *& sqlDataTable) { /* format STRING, NA, FLOAT,NA,INT <=> @@ -168,6 +168,10 @@ char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char** if(ind>maxi)maxi=ind; } + // If higher index avalible from sql - use it instead of dbcs + if (sqlHighestIndex > maxi) + maxi = sqlHighestIndex; + ++maxi; records=maxi; indexTable=new ptr[maxi]; @@ -175,15 +179,15 @@ char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char** } else { - records = recordCount; - indexTable = new ptr[recordCount]; + records = recordCount + sqlRecordCount; + indexTable = new ptr[recordCount+ sqlRecordCount]; } - char* dataTable= new char[recordCount*recordsize]; + char* dataTable= new char[(recordCount + sqlRecordCount)*recordsize]; uint32 offset=0; - for(uint32 y =0;y<recordCount;y++) + for(uint32 y =0;y<recordCount;++y) { if(i>=0) { @@ -216,6 +220,7 @@ char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char** } } } + sqlDataTable = dataTable + offset; return dataTable; } diff --git a/src/shared/Database/DBCFileLoader.h b/src/shared/Database/DBCFileLoader.h index 13562148dfc..ef29af84bc1 100644 --- a/src/shared/Database/DBCFileLoader.h +++ b/src/shared/Database/DBCFileLoader.h @@ -32,7 +32,9 @@ enum FT_BYTE='b', //uint8 FT_SORT='d', //sorted by this field, field is not included FT_IND='n', //the same,but parsed to data - FT_LOGIC='l' //Logical (boolean) + FT_LOGIC='l', //Logical (boolean) + FT_SQL_PRESENT='p', //Used in sql format to mark column present in sql dbc + FT_SQL_ABSENT='a' //Used in sql format to mark column absent in sql dbc }; class DBCFileLoader @@ -88,10 +90,11 @@ class DBCFileLoader /// Get begin iterator over records uint32 GetNumRows() const { return recordCount;} + uint32 GetRowSize() const { return recordSize;} uint32 GetCols() const { return fieldCount; } uint32 GetOffset(size_t id) const { return (fieldsOffset != NULL && id < fieldCount) ? fieldsOffset[id] : 0; } bool IsLoaded() {return (data!=NULL);} - char* AutoProduceData(const char* fmt, uint32& count, char**& indexTable); + char* AutoProduceData(const char* fmt, uint32& count, char**& indexTable, uint32 sqlRecordCount, uint32 sqlHighestIndex, char *& sqlDataTable); char* AutoProduceStrings(const char* fmt, char* dataTable); static uint32 GetFormatRecordSize(const char * format, int32 * index_pos = NULL); private: diff --git a/src/shared/Database/DBCStore.h b/src/shared/Database/DBCStore.h index 523d5c5a0b3..ee9c092708d 100644 --- a/src/shared/Database/DBCStore.h +++ b/src/shared/Database/DBCStore.h @@ -20,6 +20,8 @@ #define DBCSTORE_H #include "DBCFileLoader.h" +#include "Log.h" +struct SqlDbc; template<class T> class DBCStorage @@ -34,17 +36,152 @@ class DBCStorage char const* GetFormat() const { return fmt; } uint32 GetFieldCount() const { return fieldCount; } - bool Load(char const* fn) + bool Load(char const* fn, SqlDbc * sql) { DBCFileLoader dbc; // Check if load was sucessful, only then continue if(!dbc.Load(fn, fmt)) return false; + uint32 sqlRecordCount = 0; + uint32 sqlHighestIndex = 0; + Field *fields = NULL; + QueryResult *result = NULL; + // Load data from sql + if (sql) + { + std::string query = "SELECT * FROM `" + sql->sqlTableName; + if (sql->indexPos >= 0) + query +="` ORDER BY + `" + *sql->indexName + "` DESC"; + query += ";"; + + result = WorldDatabase.Query(query.c_str()); + if (result) + { + sqlRecordCount = result->GetRowCount(); + if (sql->indexPos >= 0) + { + fields = result->Fetch(); + sqlHighestIndex = fields[sql->sqlIndexPos].GetUInt32(); + } + // Check if sql index pos is valid + if (int32(result->GetFieldCount()-1) < sql->sqlIndexPos) + { + sLog.outError("Invalid index pos for dbc:'%s'", sql->sqlTableName.c_str()); + return false; + } + } + } + char * sqlDataTable; fieldCount = dbc.GetCols(); - m_dataTable = (T*)dbc.AutoProduceData(fmt,nCount,(char**&)indexTable); + m_dataTable = (T*)dbc.AutoProduceData(fmt,nCount,(char**&)indexTable, sqlRecordCount, sqlHighestIndex, sqlDataTable); + m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt,(char*)m_dataTable)); + // Insert sql data into arrays + if (result) + { + if (indexTable) + { + uint32 offset = 0; + uint32 rowIndex = dbc.GetNumRows(); + do + { + if (!fields) + fields = result->Fetch(); + + if(sql->indexPos >= 0) + { + uint32 id = fields[sql->sqlIndexPos].GetUInt32(); + if (indexTable[id]) + { + sLog.outError("Index %d already exists in dbc:'%s'", id, sql->sqlTableName.c_str()); + return false; + } + indexTable[id]=(T*)&sqlDataTable[offset]; + } + else + indexTable[rowIndex]=(T*)&sqlDataTable[offset]; + uint32 columnNumber = 0; + uint32 sqlColumnNumber = 0; + + for(;columnNumber < sql->formatString->size();++columnNumber) + { + if ((*sql->formatString)[columnNumber] == FT_SQL_ABSENT) + { + switch(fmt[columnNumber]) + { + case FT_FLOAT: + *((float*)(&sqlDataTable[offset]))= 0.0f; + offset+=4; + break; + case FT_IND: + case FT_INT: + *((uint32*)(&sqlDataTable[offset]))=uint32(0); + offset+=4; + break; + case FT_BYTE: + *((uint8*)(&sqlDataTable[offset]))=uint8(0); + offset+=1; + break; + case FT_STRING: + // Beginning of the pool - empty string + *((char**)(&sqlDataTable[offset]))=m_stringPoolList.back(); + offset+=sizeof(char*); + break; + } + } + else if ((*sql->formatString)[columnNumber] == FT_SQL_PRESENT) + { + bool validSqlColumn = true; + switch(fmt[columnNumber]) + { + case FT_FLOAT: + *((float*)(&sqlDataTable[offset]))=fields[sqlColumnNumber].GetFloat(); + offset+=4; + break; + case FT_IND: + case FT_INT: + *((uint32*)(&sqlDataTable[offset]))=fields[sqlColumnNumber].GetUInt32(); + offset+=4; + break; + case FT_BYTE: + *((uint8*)(&sqlDataTable[offset]))=fields[sqlColumnNumber].GetUInt8(); + offset+=1; + break; + case FT_STRING: + sLog.outError("Unsupported data type in table '%s' at char %d", sql->sqlTableName.c_str(), columnNumber); + delete result; + return false; + case FT_SORT: + break; + default: + validSqlColumn = false; + } + if (validSqlColumn) + sqlColumnNumber++; + } + else + { + sLog.outError("Incorrect sql format string '%s' at char %d", sql->sqlTableName.c_str(), columnNumber); + delete result; + return false; + } + } + if (sqlColumnNumber != (result->GetFieldCount()-1)) + { + sLog.outError("SQL and DBC format strings are not matching for table: '%s'", sql->sqlTableName.c_str()); + delete result; + return false; + } + + fields = NULL; + ++rowIndex; + }while (result->NextRow()); + } + delete result; + } + // error in dbc file at loading if NULL return indexTable!=NULL; } @@ -84,11 +221,49 @@ class DBCStorage } private: + char const* fmt; uint32 nCount; uint32 fieldCount; - char const* fmt; T** indexTable; T* m_dataTable; StringPoolList m_stringPoolList; }; + +struct SqlDbc +{ + const std::string * formatString; + const std::string * indexName; + std::string sqlTableName; + int32 indexPos; + int32 sqlIndexPos; + SqlDbc(const std::string * _filename, const std::string * _format, const std::string * _idname, const char * fmt) + :formatString(_format),sqlIndexPos(0), indexName (_idname) + { + // Convert dbc file name to sql table name + sqlTableName = *_filename; + for (uint32 i = 0;i< sqlTableName.size();++i) + { + if (isalpha(sqlTableName[i])) + sqlTableName[i] = tolower(sqlTableName[i]); + else if (sqlTableName[i] == '.') + sqlTableName[i] = '_'; + } + + // Get sql index position + DBCFileLoader::GetFormatRecordSize(fmt, &indexPos); + if (indexPos>=0) + { + for(uint32 x=0;x < formatString->size();x++) + { + // Count only fields present in sql + if ((*formatString)[x] == FT_SQL_PRESENT) + { + if (x == indexPos) + break; + ++sqlIndexPos; + } + } + } + } +}; #endif diff --git a/src/shared/Database/Field.h b/src/shared/Database/Field.h index f365a96df64..d1238f838a5 100644 --- a/src/shared/Database/Field.h +++ b/src/shared/Database/Field.h @@ -65,6 +65,17 @@ class Field else return 0; } + uint64 GetInt64() const + { + if(mValue) + { + int64 value; + sscanf(mValue,SI64FMTD,&value); + return value; + } + else + return 0; + } void SetType(enum DataTypes type) { mType = type; } |