mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
[11587] Use SkillRaceClassInfo.dbc data for check spell training.
* Show race/class specific min level in trainer list (for weapon master for example) and use it for check spell traing possibility. * Hide for specific race/class some spells marked by flag ABILITY_SKILL_NONTRAINABLE This possible in cases when spell available for race/class but learned from talent/etc and then don't must be show for race/calss pair in trainer list. Single case in 3.3.5a. * Add to code tables for profession ranks for seelct correct rank related reqlevel and check DB side data for it. Note: DB reqlevel values redundant for profession rank spells now. * Use for reqlevel selection (if DB value not provided) learned spell insteed cast-spell spellLevel field. This let in more cases select training reqlevel without provided DB value. For LogFilter_DbStrictedCheck = 0 mode output data about like redundant reqlevel values in traner tables.
This commit is contained in:
parent
c2199e7030
commit
108a167c46
13 changed files with 179 additions and 29 deletions
|
|
@ -313,6 +313,11 @@ enum AbilytyLearnType
|
|||
ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL = 2
|
||||
};
|
||||
|
||||
enum AbilitySkillFlags
|
||||
{
|
||||
ABILITY_SKILL_NONTRAINABLE = 0x100
|
||||
};
|
||||
|
||||
enum ItemEnchantmentType
|
||||
{
|
||||
ITEM_ENCHANTMENT_TYPE_NONE = 0,
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore(ScalingStatValuesfmt
|
|||
|
||||
DBCStorage <SkillLineEntry> sSkillLineStore(SkillLinefmt);
|
||||
DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore(SkillLineAbilityfmt);
|
||||
DBCStorage <SkillRaceClassInfoEntry> sSkillRaceClassInfoStore(SkillRaceClassInfofmt);
|
||||
|
||||
DBCStorage <SoundEntriesEntry> sSoundEntriesStore(SoundEntriesfmt);
|
||||
|
||||
|
|
@ -361,7 +362,7 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
const uint32 DBCFilesCount = 91;
|
||||
const uint32 DBCFilesCount = 92;
|
||||
|
||||
barGoLink bar( (int)DBCFilesCount );
|
||||
|
||||
|
|
@ -477,6 +478,7 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatValuesStore, dbcPath,"ScalingStatValues.dbc");
|
||||
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,sSkillRaceClassInfoStore, dbcPath,"SkillRaceClassInfo.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSoundEntriesStore, dbcPath,"SoundEntries.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellStore, dbcPath,"Spell.dbc");
|
||||
for(uint32 i = 1; i < sSpellStore.GetNumRows(); ++i)
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ extern DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore;
|
|||
extern DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore;
|
||||
extern DBCStorage <SkillLineEntry> sSkillLineStore;
|
||||
extern DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore;
|
||||
extern DBCStorage <SkillRaceClassInfoEntry> sSkillRaceClassInfoStore;
|
||||
extern DBCStorage <SoundEntriesEntry> sSoundEntriesStore;
|
||||
extern DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore;
|
||||
extern DBCStorage <SpellDifficultyEntry> sSpellDifficultyStore;
|
||||
|
|
|
|||
|
|
@ -1434,17 +1434,17 @@ struct ScalingStatValuesEntry
|
|||
uint32 displayOrder; // 19 m_sortIndex
|
||||
};*/
|
||||
|
||||
/*struct SkillRaceClassInfoEntry
|
||||
struct SkillRaceClassInfoEntry
|
||||
{
|
||||
uint32 id; // 0 m_ID
|
||||
//uint32 id; // 0 m_ID
|
||||
uint32 skillId; // 1 m_skillID
|
||||
uint32 raceMask; // 2 m_raceMask
|
||||
uint32 classMask; // 3 m_classMask
|
||||
uint32 flags; // 4 m_flags
|
||||
uint32 reqLevel; // 5 m_minLevel
|
||||
uint32 skillTierId; // 6 m_skillTierID
|
||||
uint32 skillCostID; // 7 m_skillCostIndex
|
||||
};*/
|
||||
//uint32 skillTierId; // 6 m_skillTierID
|
||||
//uint32 skillCostID; // 7 m_skillCostIndex
|
||||
};
|
||||
|
||||
/*struct SkillTiersEntry{
|
||||
uint32 id; // 0 m_ID
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii";
|
|||
const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiixiiii";
|
||||
const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxi";
|
||||
const char SkillLineAbilityfmt[]="niiiixxiiiiixx";
|
||||
const char SkillRaceClassInfofmt[]="diiiiixx";
|
||||
const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
const char SpellCastTimefmt[]="nixx";
|
||||
const char SpellDurationfmt[]="niii";
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ void WorldSession::SendTrainerList(ObjectGuid guid)
|
|||
}
|
||||
|
||||
|
||||
static void SendTrainerSpellHelper(WorldPacket& data, TrainerSpell const* tSpell, TrainerSpellState state, float fDiscountMod, bool can_learn_primary_prof)
|
||||
static void SendTrainerSpellHelper(WorldPacket& data, TrainerSpell const* tSpell, TrainerSpellState state, float fDiscountMod, bool can_learn_primary_prof, uint32 skillReqLevel)
|
||||
{
|
||||
bool primary_prof_first_rank = sSpellMgr.IsPrimaryProfessionFirstRankSpell(tSpell->learnedSpell);
|
||||
SpellChainNode const* chain_node = sSpellMgr.GetSpellChainNode(tSpell->learnedSpell);
|
||||
|
|
@ -131,7 +131,7 @@ static void SendTrainerSpellHelper(WorldPacket& data, TrainerSpell const* tSpell
|
|||
data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0);
|
||||
// primary prof. learn confirmation dialog
|
||||
data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state
|
||||
data << uint8(tSpell->reqLevel);
|
||||
data << uint8(skillReqLevel ? skillReqLevel : tSpell->reqLevel);
|
||||
data << uint32(tSpell->reqSkill);
|
||||
data << uint32(tSpell->reqSkillValue);
|
||||
data << uint32(!tSpell->IsCastable() && chain_node ? (chain_node->prev ? chain_node->prev : chain_node->req) : 0);
|
||||
|
|
@ -193,12 +193,13 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle)
|
|||
{
|
||||
TrainerSpell const* tSpell = &itr->second;
|
||||
|
||||
if(!_player->IsSpellFitByClassAndRace(tSpell->learnedSpell))
|
||||
uint32 skillReqLevel = 0;
|
||||
if(!_player->IsSpellFitByClassAndRace(tSpell->learnedSpell, &skillReqLevel))
|
||||
continue;
|
||||
|
||||
TrainerSpellState state = _player->GetTrainerSpellState(tSpell);
|
||||
|
||||
SendTrainerSpellHelper(data, tSpell, state, fDiscountMod, can_learn_primary_prof);
|
||||
SendTrainerSpellHelper(data, tSpell, state, fDiscountMod, can_learn_primary_prof, skillReqLevel);
|
||||
|
||||
++count;
|
||||
}
|
||||
|
|
@ -210,12 +211,13 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle)
|
|||
{
|
||||
TrainerSpell const* tSpell = &itr->second;
|
||||
|
||||
if(!_player->IsSpellFitByClassAndRace(tSpell->learnedSpell))
|
||||
uint32 skillReqLevel = 0;
|
||||
if(!_player->IsSpellFitByClassAndRace(tSpell->learnedSpell, &skillReqLevel))
|
||||
continue;
|
||||
|
||||
TrainerSpellState state = _player->GetTrainerSpellState(tSpell);
|
||||
|
||||
SendTrainerSpellHelper(data, tSpell, state, fDiscountMod, can_learn_primary_prof);
|
||||
SendTrainerSpellHelper(data, tSpell, state, fDiscountMod, can_learn_primary_prof, skillReqLevel);
|
||||
|
||||
++count;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8041,13 +8041,13 @@ void ObjectMgr::LoadTrainers(char const* tableName, bool isTemplates)
|
|||
SpellEntry const *spellinfo = sSpellStore.LookupEntry(spell);
|
||||
if (!spellinfo)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` for trainer (Entry: %u ) has non existing spell %u, ignore", tableName, entry, spell);
|
||||
sLog.outErrorDb("Table `%s` (Entry: %u ) has non existing spell %u, ignore", tableName, entry, spell);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!SpellMgr::IsSpellValid(spellinfo))
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` for trainer (Entry: %u) has broken learning spell %u, ignore", tableName, entry, spell);
|
||||
sLog.outErrorDb("Table `%s` (Entry: %u) has broken learning spell %u, ignore", tableName, entry, spell);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -8085,7 +8085,7 @@ void ObjectMgr::LoadTrainers(char const* tableName, bool isTemplates)
|
|||
{
|
||||
if (tSpells->spellList.find(spell) != tSpells->spellList.end())
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` for trainer (Entry: %u) has spell %u listed in trainer template %u, ignore", tableName, entry, spell, cInfo->trainerId);
|
||||
sLog.outErrorDb("Table `%s` (Entry: %u) has spell %u listed in trainer template %u, ignore", tableName, entry, spell, cInfo->trainerId);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -8100,25 +8100,52 @@ void ObjectMgr::LoadTrainers(char const* tableName, bool isTemplates)
|
|||
trainerSpell.reqSkillValue = fields[4].GetUInt32();
|
||||
trainerSpell.reqLevel = fields[5].GetUInt32();
|
||||
|
||||
if(!trainerSpell.reqLevel)
|
||||
trainerSpell.reqLevel = spellinfo->spellLevel;
|
||||
|
||||
// calculate learned spell for profession case when stored cast-spell
|
||||
trainerSpell.learnedSpell = spell;
|
||||
for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
if (spellinfo->Effect[i] != SPELL_EFFECT_LEARN_SPELL)
|
||||
continue;
|
||||
if (SpellMgr::IsProfessionOrRidingSpell(spellinfo->EffectTriggerSpell[i]))
|
||||
if (spellinfo->Effect[i] == SPELL_EFFECT_LEARN_SPELL &&
|
||||
SpellMgr::IsProfessionOrRidingSpell(spellinfo->EffectTriggerSpell[i]))
|
||||
{
|
||||
trainerSpell.learnedSpell = spellinfo->EffectTriggerSpell[i];
|
||||
// prof spells sometime only additions to main spell learn that have level data
|
||||
for(int j = 0; j < MAX_EFFECT_INDEX; ++j)
|
||||
{
|
||||
if (spellinfo->Effect[j] == SPELL_EFFECT_LEARN_SPELL)
|
||||
{
|
||||
trainerSpell.learnedSpell = spellinfo->EffectTriggerSpell[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// already checked as valid spell so exist.
|
||||
SpellEntry const *learnSpellinfo = sSpellStore.LookupEntry(trainerSpell.learnedSpell);
|
||||
if (trainerSpell.reqLevel)
|
||||
{
|
||||
if (trainerSpell.reqLevel == learnSpellinfo->spellLevel)
|
||||
ERROR_DB_STRICT_LOG("Table `%s` (Entry: %u) has redundant reqlevel %u (=spell level) for spell %u", tableName, entry, trainerSpell.reqLevel, spell);
|
||||
}
|
||||
else
|
||||
trainerSpell.reqLevel = learnSpellinfo->spellLevel;
|
||||
|
||||
if (SpellMgr::IsProfessionSpell(trainerSpell.learnedSpell))
|
||||
{
|
||||
data.trainerType = 2;
|
||||
|
||||
uint32 minLevel = sSpellMgr.GetProfessionSpellMinLevel(trainerSpell.learnedSpell);
|
||||
if (trainerSpell.reqLevel)
|
||||
{
|
||||
if (minLevel == trainerSpell.reqLevel)
|
||||
ERROR_DB_STRICT_LOG("Table `%s` (Entry: %u) has redundant reqlevel %u (=prof reqlevel) for spell %u", tableName, entry, trainerSpell.reqLevel, spell);
|
||||
else
|
||||
sLog.outErrorDb("Table `%s` (Entry: %u) has wrong redundant reqlevel %u (<>prof reqlevel %u) for spell %u", tableName, entry, trainerSpell.reqLevel, minLevel, spell);
|
||||
}
|
||||
else
|
||||
trainerSpell.reqLevel = minLevel;
|
||||
}
|
||||
|
||||
++count;
|
||||
|
||||
} while (result->NextRow());
|
||||
|
|
|
|||
|
|
@ -20556,7 +20556,16 @@ float Player::GetReputationPriceDiscount( Creature const* pCreature ) const
|
|||
return 1.0f - 0.05f* (rank - REP_NEUTRAL);
|
||||
}
|
||||
|
||||
bool Player::IsSpellFitByClassAndRace( uint32 spell_id ) const
|
||||
/**
|
||||
* Check spell availability for training base at SkillLineAbility/SkillRaceClassInfo data.
|
||||
* Checked allowed race/class and dependent from race/class allowed min level
|
||||
*
|
||||
* @param spell_id checked spell id
|
||||
* @param pReqlevel if arg provided then function work in view mode (level check not applied but detected minlevel returned to var by arg pointer.
|
||||
if arg not provided then considered train action mode and level checked
|
||||
* @return true if spell available for show in trainer list (with skip level check) or training.
|
||||
*/
|
||||
bool Player::IsSpellFitByClassAndRace(uint32 spell_id, uint32* pReqlevel /*= NULL*/) const
|
||||
{
|
||||
uint32 racemask = getRaceMask();
|
||||
uint32 classmask = getClassMask();
|
||||
|
|
@ -20567,14 +20576,40 @@ bool Player::IsSpellFitByClassAndRace( uint32 spell_id ) const
|
|||
|
||||
for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx)
|
||||
{
|
||||
SkillLineAbilityEntry const* abilityEntry = _spell_idx->second;
|
||||
// skip wrong race skills
|
||||
if (_spell_idx->second->racemask && (_spell_idx->second->racemask & racemask) == 0)
|
||||
if (abilityEntry->racemask && (abilityEntry->racemask & racemask) == 0)
|
||||
continue;
|
||||
|
||||
// skip wrong class skills
|
||||
if (_spell_idx->second->classmask && (_spell_idx->second->classmask & classmask) == 0)
|
||||
if (abilityEntry->classmask && (abilityEntry->classmask & classmask) == 0)
|
||||
continue;
|
||||
|
||||
SkillRaceClassInfoMapBounds bounds = sSpellMgr.GetSkillRaceClassInfoMapBounds(abilityEntry->skillId);
|
||||
for (SkillRaceClassInfoMap::const_iterator itr = bounds.first; itr != bounds.second; ++itr)
|
||||
{
|
||||
SkillRaceClassInfoEntry const* skillRCEntry = itr->second;
|
||||
if ((skillRCEntry->raceMask & racemask) && (skillRCEntry->classMask & classmask))
|
||||
{
|
||||
if (skillRCEntry->flags & ABILITY_SKILL_NONTRAINABLE)
|
||||
return false;
|
||||
|
||||
if (pReqlevel) // show trainers list case
|
||||
{
|
||||
if (skillRCEntry->reqLevel)
|
||||
{
|
||||
*pReqlevel = skillRCEntry->reqLevel;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else // check availble case at train
|
||||
{
|
||||
if (skillRCEntry->reqLevel && getLevel() < skillRCEntry->reqLevel)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1576,7 +1576,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
bool HasSpell(uint32 spell) const;
|
||||
bool HasActiveSpell(uint32 spell) const; // show in spellbook
|
||||
TrainerSpellState GetTrainerSpellState(TrainerSpell const* trainer_spell) const;
|
||||
bool IsSpellFitByClassAndRace( uint32 spell_id ) const;
|
||||
bool IsSpellFitByClassAndRace(uint32 spell_id, uint32* pReqlevel = NULL) const;
|
||||
bool IsNeedCastPassiveLikeSpellAtLearn(SpellEntry const* spellInfo) const;
|
||||
bool IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -2426,6 +2426,42 @@ bool SpellMgr::IsPrimaryProfessionSpell(uint32 spellId)
|
|||
return IsPrimaryProfessionSkill(skill);
|
||||
}
|
||||
|
||||
uint32 SpellMgr::GetProfessionSpellMinLevel(uint32 spellId)
|
||||
{
|
||||
uint32 s2l[8][3] =
|
||||
{ // 0 - gather 1 - non-gather 2 - fish
|
||||
/*0*/ { 0, 5, 5 },
|
||||
/*1*/ { 0, 5, 5 },
|
||||
/*2*/ { 0, 10, 10 },
|
||||
/*3*/ { 10, 20, 10 },
|
||||
/*4*/ { 25, 35, 10 },
|
||||
/*5*/ { 40, 50, 10 },
|
||||
/*6*/ { 55, 65, 10 },
|
||||
/*7*/ { 75, 75, 10 },
|
||||
};
|
||||
|
||||
uint32 rank = GetSpellRank(spellId);
|
||||
if (rank >= 8)
|
||||
return 0;
|
||||
|
||||
SkillLineAbilityMapBounds bounds = GetSkillLineAbilityMapBounds(spellId);
|
||||
if (bounds.first == bounds.second)
|
||||
return 0;
|
||||
|
||||
switch (bounds.first->second->skillId)
|
||||
{
|
||||
case SKILL_FISHING:
|
||||
return s2l[rank][2];
|
||||
case SKILL_HERBALISM:
|
||||
case SKILL_MINING:
|
||||
case SKILL_SKINNING:
|
||||
return s2l[rank][0];
|
||||
default:
|
||||
return s2l[rank][1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SpellMgr::IsPrimaryProfessionFirstRankSpell(uint32 spellId) const
|
||||
{
|
||||
return IsPrimaryProfessionSpell(spellId) && GetSpellRank(spellId)==1;
|
||||
|
|
@ -3931,6 +3967,33 @@ void SpellMgr::LoadSkillLineAbilityMap()
|
|||
sLog.outString(">> Loaded %u SkillLineAbility MultiMap Data", count);
|
||||
}
|
||||
|
||||
void SpellMgr::LoadSkillRaceClassInfoMap()
|
||||
{
|
||||
mSkillRaceClassInfoMap.clear();
|
||||
|
||||
barGoLink bar( (int)sSkillRaceClassInfoStore.GetNumRows() );
|
||||
uint32 count = 0;
|
||||
|
||||
for (uint32 i = 0; i < sSkillRaceClassInfoStore.GetNumRows(); ++i)
|
||||
{
|
||||
bar.step();
|
||||
SkillRaceClassInfoEntry const *skillRCInfo = sSkillRaceClassInfoStore.LookupEntry(i);
|
||||
if (!skillRCInfo)
|
||||
continue;
|
||||
|
||||
// not all skills really listed in ability skills list
|
||||
if (!sSkillLineStore.LookupEntry(skillRCInfo->skillId))
|
||||
continue;
|
||||
|
||||
mSkillRaceClassInfoMap.insert(SkillRaceClassInfoMap::value_type(skillRCInfo->skillId,skillRCInfo));
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u SkillRaceClassInfo MultiMap Data", count);
|
||||
}
|
||||
|
||||
void SpellMgr::CheckUsedSpells(char const* table)
|
||||
{
|
||||
uint32 countSpells = 0;
|
||||
|
|
|
|||
|
|
@ -802,6 +802,9 @@ typedef std::pair<SpellLearnSpellMap::const_iterator,SpellLearnSpellMap::const_i
|
|||
typedef std::multimap<uint32, SkillLineAbilityEntry const*> SkillLineAbilityMap;
|
||||
typedef std::pair<SkillLineAbilityMap::const_iterator,SkillLineAbilityMap::const_iterator> SkillLineAbilityMapBounds;
|
||||
|
||||
typedef std::multimap<uint32, SkillRaceClassInfoEntry const*> SkillRaceClassInfoMap;
|
||||
typedef std::pair<SkillRaceClassInfoMap::const_iterator,SkillRaceClassInfoMap::const_iterator> SkillRaceClassInfoMapBounds;
|
||||
|
||||
typedef std::multimap<uint32, uint32> PetLevelupSpellSet;
|
||||
typedef std::map<uint32, PetLevelupSpellSet> PetLevelupSpellMap;
|
||||
|
||||
|
|
@ -1047,6 +1050,7 @@ class SpellMgr
|
|||
static bool IsProfessionSpell(uint32 spellId);
|
||||
static bool IsPrimaryProfessionSpell(uint32 spellId);
|
||||
bool IsPrimaryProfessionFirstRankSpell(uint32 spellId) const;
|
||||
uint32 GetProfessionSpellMinLevel(uint32 spellId);
|
||||
|
||||
bool IsSkillBonusSpell(uint32 spellId) const;
|
||||
|
||||
|
|
@ -1065,6 +1069,11 @@ class SpellMgr
|
|||
return mSkillLineAbilityMap.equal_range(spell_id);
|
||||
}
|
||||
|
||||
SkillRaceClassInfoMapBounds GetSkillRaceClassInfoMapBounds(uint32 skill_id) const
|
||||
{
|
||||
return mSkillRaceClassInfoMap.equal_range(skill_id);
|
||||
}
|
||||
|
||||
PetAura const* GetPetAura(uint32 spell_id, SpellEffectIndex eff)
|
||||
{
|
||||
SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find((spell_id<<8) + eff);
|
||||
|
|
@ -1140,6 +1149,7 @@ class SpellMgr
|
|||
void LoadSpellTargetPositions();
|
||||
void LoadSpellThreats();
|
||||
void LoadSkillLineAbilityMap();
|
||||
void LoadSkillRaceClassInfoMap();
|
||||
void LoadSpellPetAuras();
|
||||
void LoadPetLevelupSpellMap();
|
||||
void LoadPetDefaultSpells();
|
||||
|
|
@ -1160,6 +1170,7 @@ class SpellMgr
|
|||
SpellProcItemEnchantMap mSpellProcItemEnchantMap;
|
||||
SpellBonusMap mSpellBonusMap;
|
||||
SkillLineAbilityMap mSkillLineAbilityMap;
|
||||
SkillRaceClassInfoMap mSkillRaceClassInfoMap;
|
||||
SpellPetAuraMap mSpellPetAuraMap;
|
||||
PetLevelupSpellMap mPetLevelupSpellMap;
|
||||
PetDefaultSpellsMap mPetDefaultSpellsMap; // only spells not listed in related mPetLevelupSpellMap entry
|
||||
|
|
|
|||
|
|
@ -952,6 +952,9 @@ void World::SetInitialWorldSettings()
|
|||
sLog.outString("Loading SkillLineAbilityMultiMap Data...");
|
||||
sSpellMgr.LoadSkillLineAbilityMap();
|
||||
|
||||
sLog.outString("Loading SkillRaceClassInfoMultiMap Data...");
|
||||
sSpellMgr.LoadSkillRaceClassInfoMap();
|
||||
|
||||
///- Clean up and pack instances
|
||||
sLog.outString( "Cleaning up instances..." );
|
||||
sMapPersistentStateMgr.CleanupInstances(); // must be called before `creature_respawn`/`gameobject_respawn` tables
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "11586"
|
||||
#define REVISION_NR "11587"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue