aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/7815_world_spelldifficulty_dbc.sql9
-rw-r--r--src/game/Creature.cpp12
-rw-r--r--src/game/Creature.h1
-rw-r--r--src/game/CreatureAIImpl.h7
-rw-r--r--src/game/DBCStores.cpp20
-rw-r--r--src/game/DBCStores.h1
-rw-r--r--src/game/DBCStructure.h6
-rw-r--r--src/game/DBCfmt.h3
-rw-r--r--src/game/SpellMgr.h45
-rw-r--r--src/game/UnitAI.cpp6
-rw-r--r--src/game/UnitAI.h4
11 files changed, 110 insertions, 4 deletions
diff --git a/sql/updates/7815_world_spelldifficulty_dbc.sql b/sql/updates/7815_world_spelldifficulty_dbc.sql
new file mode 100644
index 00000000000..2c91beaefbb
--- /dev/null
+++ b/sql/updates/7815_world_spelldifficulty_dbc.sql
@@ -0,0 +1,9 @@
+DROP TABLE IF EXISTS `spelldifficulty_dbc`;
+CREATE TABLE `spelldifficulty_dbc` (
+ `id` int(11) unsigned NOT NULL DEFAULT '0',
+ `spellid0` int(11) unsigned NOT NULL DEFAULT '0',
+ `spellid1` int(11) unsigned NOT NULL DEFAULT '0',
+ `spellid2` int(11) unsigned NOT NULL DEFAULT '0',
+ `spellid3` int(11) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 66400709036..4dd05fbaf87 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -2211,6 +2211,18 @@ void Creature::GetRespawnCoord(float &x, float &y, float &z, float* ori, float*
*dist = 0;
}
+uint32 Creature::GetSpellIdForDifficulty(uint32 spellId)
+{
+ //search for instance mode spell
+ if (GetMap() && GetMap()->IsDungeon())
+ {
+ spellId = spellmgr.GetSpellIdForDifficultyFromSpellid(spellId, Difficulty(GetMap()->GetSpawnMode()));
+ }
+ else
+ sLog.outDebug("Unit::GetSpellIdForDifficulty called for non-instanced creature");
+ return spellId;
+}
+
void Creature::AllLootRemovedFromCorpse()
{
if (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE))
diff --git a/src/game/Creature.h b/src/game/Creature.h
index 3ffaa5e401f..0866877a3f5 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -418,6 +418,7 @@ class Creature : public Unit, public GridObject<Creature>
void Update(uint32 time); // overwrited Unit::Update
void GetRespawnCoord(float &x, float &y, float &z, float* ori = NULL, float* dist =NULL) const;
uint32 GetEquipmentId() const { return GetCreatureInfo()->equipmentId; }
+ uint32 GetSpellIdForDifficulty(uint32 spellId);
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h
index a6cb52dedc5..2499c632ca8 100644
--- a/src/game/CreatureAIImpl.h
+++ b/src/game/CreatureAIImpl.h
@@ -22,6 +22,7 @@
#include "Platform/Define.h"
#include "TemporarySummon.h"
#include "CreatureAI.h"
+#include "SpellMgr.h"
template<class T>
inline
@@ -592,11 +593,15 @@ inline bool CreatureAI::_EnterEvadeMode()
return true;
}
-inline void UnitAI::DoCast(Unit* victim, uint32 spellId, bool triggered)
+inline void UnitAI::DoCast(Unit* victim, uint32 spellId, bool triggered, bool useMode)
{
if (!victim || (me->hasUnitState(UNIT_STAT_CASTING) && !triggered))
return;
+ //search for instance mode spell
+ if(useMode && me->ToCreature())
+ spellId = me->ToCreature()->GetSpellIdForDifficulty(spellId);
+
me->CastSpell(victim, spellId, triggered);
}
diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp
index a66fc887ce3..1b487262c13 100644
--- a/src/game/DBCStores.cpp
+++ b/src/game/DBCStores.cpp
@@ -128,6 +128,7 @@ SpellCategoryStore sSpellCategoryStore;
PetFamilySpellsStore sPetFamilySpellsStore;
DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore(SpellCastTimefmt);
+DBCStorage <SpellDifficultyEntry> sSpellDifficultyStore(SpellDifficultyfmt);
DBCStorage <SpellDurationEntry> sSpellDurationStore(SpellDurationfmt);
DBCStorage <SpellFocusObjectEntry> sSpellFocusObjectStore(SpellFocusObjectfmt);
DBCStorage <SpellRadiusEntry> sSpellRadiusStore(SpellRadiusfmt);
@@ -384,6 +385,7 @@ void LoadDBCStores(const std::string& dataPath)
}
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCastTimesStore, dbcPath,"SpellCastTimes.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDifficultyStore, dbcPath,"SpellDifficulty.dbc", &CustomSpellDifficultyfmt, &CustomSpellDifficultyIndex);
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDurationStore, dbcPath,"SpellDuration.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellFocusObjectStore, dbcPath,"SpellFocusObject.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentStore,dbcPath,"SpellItemEnchantment.dbc");
@@ -396,6 +398,24 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc");
+ // Create Spelldifficulty searcher
+ for (uint32 i = 0; i < sSpellDifficultyStore.GetNumRows(); ++i)
+ {
+ SpellDifficultyEntry const *spellDiff = sSpellDifficultyStore.LookupEntry(i);
+ if (!spellDiff)
+ continue;
+ for(int x = 0; x < MAX_DIFFICULTY; ++x)
+ {
+ if(spellDiff->SpellID[x] <= 0 || !sSpellStore.LookupEntry(spellDiff->SpellID[x]))
+ {
+ if(spellDiff->SpellID[x] > 0)//don't drop error if spell is <= 0, not all modes have spells and there are unknown negative values
+ sLog.outDebug("spelldifficulty_dbc: spell %i at field id:%u at spellid%i does not exist in SpellStore (spell.dbc), skipped loading", spellDiff->SpellID[x], spellDiff->ID, x);
+ continue;
+ }
+ spellmgr.SetSpellDifficultyId(uint32(spellDiff->SpellID[x]), spellDiff->ID);
+ }
+ }
+
// create talent spells set
for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i)
{
diff --git a/src/game/DBCStores.h b/src/game/DBCStores.h
index b6b1380517f..e1d0c3e7721 100644
--- a/src/game/DBCStores.h
+++ b/src/game/DBCStores.h
@@ -129,6 +129,7 @@ extern DBCStorage <SkillLineEntry> sSkillLineStore;
extern DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore;
extern DBCStorage <SoundEntriesEntry> sSoundEntriesStore;
extern DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore;
+extern DBCStorage <SpellDifficultyEntry> sSpellDifficultyStore;
extern DBCStorage <SpellDurationEntry> sSpellDurationStore;
extern DBCStorage <SpellFocusObjectEntry> sSpellFocusObjectStore;
extern DBCStorage <SpellItemEnchantmentEntry> sSpellItemEnchantmentStore;
diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
index 6105a86bdcc..1e6a349c2ea 100644
--- a/src/game/DBCStructure.h
+++ b/src/game/DBCStructure.h
@@ -1545,6 +1545,12 @@ struct SpellCastTimesEntry
//int32 MinCastTime; // 3 unsure
};
+struct SpellDifficultyEntry
+{
+ uint32 ID; // 0
+ int32 SpellID[MAX_DIFFICULTY]; // 1-4 instance modes: 10N,25N,10H,25H or Normal/Heroic if only 1-2 is set, if 3-4 is 0 then Mode-2
+};
+
struct SpellFocusObjectEntry
{
uint32 ID; // 0
diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h
index e1c705887fd..104099e83d9 100644
--- a/src/game/DBCfmt.h
+++ b/src/game/DBCfmt.h
@@ -89,6 +89,9 @@ const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxx
const char SkillLineAbilityfmt[]="niiiixxiiiiixx";
const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const char SpellCastTimefmt[]="nixx";
+const char SpellDifficultyfmt[]="niiii";
+const std::string CustomSpellDifficultyfmt="ppppp";
+const std::string CustomSpellDifficultyIndex="id";
const char SpellDurationfmt[]="niii";
const char SpellEntryfmt[]="niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxxxxxx";
const std::string CustomSpellEntryfmt="pappppppppaaaaaapaaaaaaaaaaapaaapapppppppaaaaapaapaaaaaaaaaaaaaaaaaappppppppppppppppppppppppppppppppppppppppppaaaaaapppppppppaaapppppppppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaappppppppapppaaaaappaaaaaaa";
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 273bec9c406..ab4eee6dd10 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -813,6 +813,8 @@ typedef std::pair<SkillLineAbilityMap::const_iterator,SkillLineAbilityMap::const
typedef std::multimap<uint32, uint32> PetLevelupSpellSet;
typedef std::map<uint32, PetLevelupSpellSet> PetLevelupSpellMap;
+typedef std::map<uint32, uint32> SpellDifficultySearcherMap;
+
struct PetDefaultSpellsEntry
{
uint32 spellid[MAX_CREATURE_SPELL_DATA_SLOT];
@@ -1013,6 +1015,46 @@ class SpellMgr
return NULL;
}
+ // Spell Difficulty data
+ uint32 GetSpellIdForDifficultyFromSpellid(uint32 spellId, Difficulty mapDiff)
+ {
+ /*SpellEntry const* spell = sSpellStore.LookupEntry(spellId);
+ if (!spell)
+ return spellId;//CastSpell() will handle incorrect spells
+ */
+ uint32 mode = uint32(mapDiff);
+ if(mode >= MAX_DIFFICULTY)
+ {
+ sLog.outError("GetSpellIdForDifficultyFromSpellid: Incorrect Difficulty for spell %u.", spellId);
+ return spellId;//return source spell
+ }
+ uint32 SpellDiffId = GetSpellDifficultyId(spellId);
+ if(!SpellDiffId)
+ {
+ sLog.outDebug("GetSpellIdForDifficultyFromSpellid: Difficulty not found for spell %u.", spellId);
+ return spellId;//return source spell, it has only REGULAR_DIFFICULTY
+ }
+ SpellDifficultyEntry const *SpellDiff = sSpellDifficultyStore.LookupEntry(SpellDiffId);
+ if (!SpellDiff)
+ {
+ sLog.outDebug("GetSpellIdForDifficultyFromSpellid: SpellDifficultyEntry not found for spell %u. This Should never happen.", spellId);
+ return spellId;//return source spell
+ }
+ if(SpellDiff->SpellID[mode] <= 0 && mode > DUNGEON_DIFFICULTY_HEROIC)
+ {
+ uint8 baseMode = mode;
+ mode -= 2;
+ sLog.outDebug("GetSpellForDifficultyFromSpellid: spell %u mode %u spell is NULL, using mode %u", spellId, baseMode, mode);
+ }
+ if(SpellDiff->SpellID[mode] <= 0)
+ {
+ sLog.outErrorDb("GetSpellForDifficultyFromSpellid: spell %u mode %u spell is 0. Check spelldifficulty_dbc!", spellId, mode);
+ return spellId;
+ }
+ sLog.outDebug("GetSpellForDifficultyFromSpellid: spellid for spell %u in %u mode is %u ", spellId, mode, uint32(SpellDiff->SpellID[mode]));
+ return uint32(SpellDiff->SpellID[mode]);
+ }
+
// Spell target coordinates
SpellTargetPosition const* GetSpellTargetPosition(uint32 spell_id) const
{
@@ -1271,6 +1313,8 @@ class SpellMgr
return false;
return true;
}
+ uint32 GetSpellDifficultyId(uint32 spellId) { return mSpellDifficultySearcherMap[spellId] ? mSpellDifficultySearcherMap[spellId] : 0; }
+ void SetSpellDifficultyId(uint32 spellId, uint32 id) { mSpellDifficultySearcherMap[spellId] = id; }
const SpellsRequiringSpellMap GetSpellsRequiringSpell()
{
@@ -1345,6 +1389,7 @@ class SpellMgr
SpellAreaForQuestMap mSpellAreaForQuestEndMap;
SpellAreaForAuraMap mSpellAreaForAuraMap;
SpellAreaForAreaMap mSpellAreaForAreaMap;
+ SpellDifficultySearcherMap mSpellDifficultySearcherMap;
};
#define spellmgr SpellMgr::Instance()
diff --git a/src/game/UnitAI.cpp b/src/game/UnitAI.cpp
index b66b725d462..4fd4693885e 100644
--- a/src/game/UnitAI.cpp
+++ b/src/game/UnitAI.cpp
@@ -193,8 +193,12 @@ void UnitAI::DoCastToAllHostilePlayers(uint32 spellid, bool triggered)
return;
}
-void UnitAI::DoCast(uint32 spellId)
+void UnitAI::DoCast(uint32 spellId, bool useMode)
{
+ //search for instance mode spell
+ if(useMode && me->ToCreature())
+ spellId = me->ToCreature()->GetSpellIdForDifficulty(spellId);
+
Unit *target = NULL;
//sLog.outError("aggre %u %u", spellId, (uint32)AISpellInfo[spellId].target);
switch(AISpellInfo[spellId].target)
diff --git a/src/game/UnitAI.h b/src/game/UnitAI.h
index 81f4442cfbd..f0e4c996c84 100644
--- a/src/game/UnitAI.h
+++ b/src/game/UnitAI.h
@@ -126,8 +126,8 @@ class UnitAI
void AttackStartCaster(Unit *victim, float dist);
void DoAddAuraToAllHostilePlayers(uint32 spellid);
- void DoCast(uint32 spellId);
- void DoCast(Unit* victim, uint32 spellId, bool triggered = false);
+ void DoCast(uint32 spellId, bool useMode = false);
+ void DoCast(Unit* victim, uint32 spellId, bool triggered = false, bool useMode = false);
void DoCastToAllHostilePlayers(uint32 spellid, bool triggered = false);
void DoCastVictim(uint32 spellId, bool triggered = false);
void DoCastAOE(uint32 spellId, bool triggered = false);