aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/FULL/world_spell_full.sql8
-rw-r--r--sql/updates/5410_world_sql_dbc.sql101
-rw-r--r--sql/world.sql103
-rw-r--r--src/game/DBCStores.cpp12
-rw-r--r--src/game/DBCStructure.h2
-rw-r--r--src/game/DBCfmt.h4
-rw-r--r--src/game/SpellAuras.cpp21
-rw-r--r--src/game/Unit.cpp22
-rw-r--r--src/game/Unit.h1
-rw-r--r--src/shared/Database/DBCFileLoader.cpp15
-rw-r--r--src/shared/Database/DBCFileLoader.h7
-rw-r--r--src/shared/Database/DBCStore.h181
-rw-r--r--src/shared/Database/Field.h11
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; }