diff options
author | Rat <gmstreetrat@gmail.com> | 2014-11-16 14:20:01 +0100 |
---|---|---|
committer | Rat <gmstreetrat@gmail.com> | 2014-11-16 14:20:01 +0100 |
commit | 588143b9b69a81eee69d5fb3b9690c8aafc1a38f (patch) | |
tree | a5ff6545b7360592475e4272147216a43218e91c /src | |
parent | c375748b7636fe88f1daf37197dc9da3d4a674a1 (diff) |
Core/Spells: Spell system updates (don't even try to compile this)
Diffstat (limited to 'src')
42 files changed, 637 insertions, 595 deletions
diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index 33772c2c165..2425367a3da 100644 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -282,7 +282,7 @@ void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/) } SpellTargetSelector::SpellTargetSelector(Unit* caster, uint32 spellId) : - _caster(caster), _spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(sSpellMgr->GetSpellInfo(spellId), caster)) + _caster(caster), _spellInfo(sSpellMgr->GetSpellInfo(spellId)) { ASSERT(_spellInfo); } diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index 5bf3c41df41..6d8e5d67ebb 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -282,9 +282,9 @@ struct ScriptedAI : public CreatureAI { switch (_difficulty) { - case DUNGEON_DIFFICULTY_NORMAL: + case DIFFICULTY_NORMAL: return normal5; - case DUNGEON_DIFFICULTY_HEROIC: + case DIFFICULTY_HEROIC: return heroic10; default: break; @@ -298,9 +298,9 @@ struct ScriptedAI : public CreatureAI { switch (_difficulty) { - case RAID_DIFFICULTY_10MAN_NORMAL: + case DIFFICULTY_10_N: return normal10; - case RAID_DIFFICULTY_25MAN_NORMAL: + case DIFFICULTY_25_N: return normal25; default: break; @@ -314,13 +314,13 @@ struct ScriptedAI : public CreatureAI { switch (_difficulty) { - case RAID_DIFFICULTY_10MAN_NORMAL: + case DIFFICULTY_10_N: return normal10; - case RAID_DIFFICULTY_25MAN_NORMAL: + case DIFFICULTY_25_N: return normal25; - case RAID_DIFFICULTY_10MAN_HEROIC: + case DIFFICULTY_10_HC: return heroic10; - case RAID_DIFFICULTY_25MAN_HEROIC: + case DIFFICULTY_25_HC: return heroic25; default: break; diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 8fe96be26fb..ba36c8bc052 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -2533,7 +2533,7 @@ bool AchievementMgr<T>::RequirementsSatisfied(AchievementCriteriaEntry const* ac if (!achievIdForDungeon[j][2]) break; // for } - else if (referencePlayer->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_NORMAL) + else if (referencePlayer->GetDungeonDifficulty() == DIFFICULTY_NORMAL) { // dungeon in normal mode accepted if (!achievIdForDungeon[j][1]) diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp index a7cf8478704..65c5ec6873a 100644 --- a/src/server/game/Conditions/DisableMgr.cpp +++ b/src/server/game/Conditions/DisableMgr.cpp @@ -134,11 +134,11 @@ void LoadDisables() break; case MAP_INSTANCE: case MAP_RAID: - if (flags & DUNGEON_STATUSFLAG_HEROIC && !GetMapDifficultyData(entry, DUNGEON_DIFFICULTY_HEROIC)) + if (flags & DUNGEON_STATUSFLAG_HEROIC && !GetMapDifficultyData(entry, DIFFICULTY_HEROIC)) flags -= DUNGEON_STATUSFLAG_HEROIC; - if (flags & RAID_STATUSFLAG_10MAN_HEROIC && !GetMapDifficultyData(entry, RAID_DIFFICULTY_10MAN_HEROIC)) + if (flags & RAID_STATUSFLAG_10MAN_HEROIC && !GetMapDifficultyData(entry, DIFFICULTY_10_HC)) flags -= RAID_STATUSFLAG_10MAN_HEROIC; - if (flags & RAID_STATUSFLAG_25MAN_HEROIC && !GetMapDifficultyData(entry, RAID_DIFFICULTY_25MAN_HEROIC)) + if (flags & RAID_STATUSFLAG_25MAN_HEROIC && !GetMapDifficultyData(entry, DIFFICULTY_25_HC)) flags -= RAID_STATUSFLAG_25MAN_HEROIC; if (!flags) isFlagInvalid = true; @@ -354,13 +354,13 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags GetDownscaledMapDifficultyData(entry, targetDifficulty); switch (targetDifficulty) { - case DUNGEON_DIFFICULTY_NORMAL: + case DIFFICULTY_NORMAL: return (disabledModes & DUNGEON_STATUSFLAG_NORMAL) != 0; - case DUNGEON_DIFFICULTY_HEROIC: + case DIFFICULTY_HEROIC: return (disabledModes & DUNGEON_STATUSFLAG_HEROIC) != 0; - case RAID_DIFFICULTY_10MAN_HEROIC: + case DIFFICULTY_10_HC: return (disabledModes & RAID_STATUSFLAG_10MAN_HEROIC) != 0; - case RAID_DIFFICULTY_25MAN_HEROIC: + case DIFFICULTY_25_HC: return (disabledModes & RAID_STATUSFLAG_25MAN_HEROIC) != 0; } } diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index d4831127183..7d2fd1c2b95 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -337,16 +337,26 @@ enum AreaFlags enum Difficulty { - REGULAR_DIFFICULTY = 0, - - DUNGEON_DIFFICULTY_NORMAL = 0, - DUNGEON_DIFFICULTY_HEROIC = 1, - DUNGEON_DIFFICULTY_EPIC = 2, - - RAID_DIFFICULTY_10MAN_NORMAL = 0, - RAID_DIFFICULTY_25MAN_NORMAL = 1, - RAID_DIFFICULTY_10MAN_HEROIC = 2, - RAID_DIFFICULTY_25MAN_HEROIC = 3 + DIFFICULTY_NONE = 0, + DIFFICULTY_NORMAL = 1, + DIFFICULTY_HEROIC = 2, + DIFFICULTY_10_N = 3, + DIFFICULTY_25_N = 4, + DIFFICULTY_10_HC = 5, + DIFFICULTY_25_HC = 6, + DIFFICULTY_LFR = 7, + DIFFICULTY_CHALLENGE = 8, + DIFFICULTY_40 = 9, + DIFFICULTY_HC_SCENARIO = 11, + DIFFICULTY_N_SCENARIO = 12, + DIFFICULTY_NORMAL2 = 14, + DIFFICULTY_HEROIC2 = 15, + DIFFICULTY_MYTHIC = 16, + DIFFICULTY_LFR2 = 17, + DIFFICULTY_EVENT = 18, + DIFFICULTY_EVENT2 = 19, + DIFFICULTY_EVENT_SCENARIO = 20, + DIFFICULTY_MAX = 21, }; #define RAID_DIFFICULTY_MASK_25MAN 1 // since 25man difficulties are 1 and 3, we can check them like that @@ -357,18 +367,18 @@ enum Difficulty enum SpawnMask { - SPAWNMASK_CONTINENT = (1 << REGULAR_DIFFICULTY), // any maps without spawn modes + SPAWNMASK_CONTINENT = (1 << DIFFICULTY_NONE), // any maps without spawn modes - SPAWNMASK_DUNGEON_NORMAL = (1 << DUNGEON_DIFFICULTY_NORMAL), - SPAWNMASK_DUNGEON_HEROIC = (1 << DUNGEON_DIFFICULTY_HEROIC), + SPAWNMASK_DUNGEON_NORMAL = (1 << DIFFICULTY_NORMAL), + SPAWNMASK_DUNGEON_HEROIC = (1 << DIFFICULTY_HEROIC), SPAWNMASK_DUNGEON_ALL = (SPAWNMASK_DUNGEON_NORMAL | SPAWNMASK_DUNGEON_HEROIC), - SPAWNMASK_RAID_10MAN_NORMAL = (1 << RAID_DIFFICULTY_10MAN_NORMAL), - SPAWNMASK_RAID_25MAN_NORMAL = (1 << RAID_DIFFICULTY_25MAN_NORMAL), + SPAWNMASK_RAID_10MAN_NORMAL = (1 << DIFFICULTY_10_N), + SPAWNMASK_RAID_25MAN_NORMAL = (1 << DIFFICULTY_25_N), SPAWNMASK_RAID_NORMAL_ALL = (SPAWNMASK_RAID_10MAN_NORMAL | SPAWNMASK_RAID_25MAN_NORMAL), - SPAWNMASK_RAID_10MAN_HEROIC = (1 << RAID_DIFFICULTY_10MAN_HEROIC), - SPAWNMASK_RAID_25MAN_HEROIC = (1 << RAID_DIFFICULTY_25MAN_HEROIC), + SPAWNMASK_RAID_10MAN_HEROIC = (1 << DIFFICULTY_10_HC), + SPAWNMASK_RAID_25MAN_HEROIC = (1 << DIFFICULTY_25_HC), SPAWNMASK_RAID_HEROIC_ALL = (SPAWNMASK_RAID_10MAN_HEROIC | SPAWNMASK_RAID_25MAN_HEROIC), SPAWNMASK_RAID_ALL = (SPAWNMASK_RAID_NORMAL_ALL | SPAWNMASK_RAID_HEROIC_ALL) diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index a4dd3db66a9..db35db880be 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -891,7 +891,7 @@ MapDifficulty const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &di MapDifficulty const* mapDiff = GetMapDifficultyData(mapId, Difficulty(tmpDiff)); if (!mapDiff) { - if (tmpDiff > RAID_DIFFICULTY_25MAN_NORMAL) // heroic, downscale to normal + if (tmpDiff > DIFFICULTY_25_N) // heroic, downscale to normal tmpDiff -= 2; else tmpDiff -= 1; // any non-normal mode for raids like tbc (only one mode) diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 3bf632001b0..803e2dcf96b 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -1800,8 +1800,8 @@ struct SpellEffectEntry float BonusCoefficientFromAP; // 30 }; -#define MAX_SPELL_EFFECTS 3 -#define MAX_EFFECT_MASK 7 +#define MAX_SPELL_EFFECTS 32 +#define MAX_EFFECT_MASK 0xFFFFFFFF // SpellAuraOptions.dbc struct SpellAuraOptionsEntry diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 863324f278c..7099d38d428 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -1406,7 +1406,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId) } // Update achievements - if (dungeon->difficulty == DUNGEON_DIFFICULTY_HEROIC) + if (dungeon->difficulty == DIFFICULTY_HEROIC) player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, 1); LfgReward const* reward = GetRandomDungeonReward(rDungeonId, player->getLevel()); @@ -1594,7 +1594,7 @@ LfgLockMap const LFGMgr::GetLockedDungeons(ObjectGuid guid) lockStatus = LFG_LOCKSTATUS_INSUFFICIENT_EXPANSION; else if (DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, dungeon->map, player)) lockStatus = LFG_LOCKSTATUS_RAID_LOCKED; - else if (dungeon->difficulty > DUNGEON_DIFFICULTY_NORMAL && player->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty))) + else if (dungeon->difficulty > DIFFICULTY_NORMAL && player->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty))) lockStatus = LFG_LOCKSTATUS_RAID_LOCKED; else if (dungeon->minlevel > level) lockStatus = LFG_LOCKSTATUS_TOO_LOW_LEVEL; diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index dea8d996c53..4fbd60202c3 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -268,7 +268,7 @@ struct LfgPlayerBoot struct LFGDungeonData { LFGDungeonData(): id(0), name(""), map(0), type(0), expansion(0), group(0), minlevel(0), - maxlevel(0), difficulty(REGULAR_DIFFICULTY), seasonal(false), x(0.0f), y(0.0f), z(0.0f), o(0.0f), + maxlevel(0), difficulty(DIFFICULTY_NONE), seasonal(false), x(0.0f), y(0.0f), z(0.0f), o(0.0f), requiredItemLevel(0) { } LFGDungeonData(LFGDungeonEntry const* dbc): id(dbc->ID), name(dbc->Name_lang), map(dbc->MapID), diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 7fb3822c888..25c1acddfdc 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -283,7 +283,7 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/) } // for instances heroic to normal, other cases attempt to retrieve previous difficulty - if (diff >= RAID_DIFFICULTY_10MAN_HEROIC && GetMap()->IsRaid()) + if (diff >= DIFFICULTY_10_HC && GetMap()->IsRaid()) diff -= 2; // to normal raid difficulty cases else --diff; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 1026681cd81..3866d28dae8 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -784,9 +784,9 @@ Player::Player(WorldSession* session): Unit(true) m_HomebindTimer = 0; m_InstanceValid = true; - m_dungeonDifficulty = DUNGEON_DIFFICULTY_NORMAL; - m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL; - m_raidMapDifficulty = RAID_DIFFICULTY_10MAN_NORMAL; + m_dungeonDifficulty = DIFFICULTY_NORMAL; + m_raidDifficulty = DIFFICULTY_10_N; + m_raidMapDifficulty = DIFFICULTY_10_N; m_lastPotionId = 0; _talentMgr = new PlayerTalentInfo(); @@ -16997,10 +16997,10 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) uint32 dungeonDiff = fields[39].GetUInt8() & 0x0F; if (dungeonDiff >= MAX_DUNGEON_DIFFICULTY) - dungeonDiff = DUNGEON_DIFFICULTY_NORMAL; + dungeonDiff = DIFFICULTY_NORMAL; uint32 raidDiff = (fields[39].GetUInt8() >> 4) & 0x0F; if (raidDiff >= MAX_RAID_DIFFICULTY) - raidDiff = RAID_DIFFICULTY_10MAN_NORMAL; + raidDiff = DIFFICULTY_10_N; SetDungeonDifficulty(Difficulty(dungeonDiff)); // may be changed in _LoadGroup SetRaidDifficulty(Difficulty(raidDiff)); // may be changed in _LoadGroup @@ -18711,7 +18711,7 @@ void Player::SendRaidInfo() if (itr->second.perm) { InstanceSave* save = itr->second.save; - bool isHeroic = save->GetDifficulty() == RAID_DIFFICULTY_10MAN_HEROIC || save->GetDifficulty() == RAID_DIFFICULTY_25MAN_HEROIC; + bool isHeroic = save->GetDifficulty() == DIFFICULTY_10_HC || save->GetDifficulty() == DIFFICULTY_25_HC; uint32 completedEncounters = 0; if (Map* map = sMapMgr->FindMap(save->GetMapId(), save->GetInstanceId())) if (InstanceScript* instanceScript = ((InstanceMap*)map)->GetInstanceScript()) @@ -20174,7 +20174,7 @@ void Player::ResetInstances(uint8 method, bool isRaid) if (method == INSTANCE_RESET_ALL) { // the "reset all instances" method can only reset normal maps - if (entry->IsRaid() || diff == DUNGEON_DIFFICULTY_HEROIC) + if (entry->IsRaid() || diff == DIFFICULTY_HEROIC) { ++itr; continue; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index b28d26af2c9..f075578621a 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -123,6 +123,36 @@ enum SpellValueMod SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, + SPELLVALUE_BASE_POINT3, + SPELLVALUE_BASE_POINT4, + SPELLVALUE_BASE_POINT5, + SPELLVALUE_BASE_POINT6, + SPELLVALUE_BASE_POINT7, + SPELLVALUE_BASE_POINT8, + SPELLVALUE_BASE_POINT9, + SPELLVALUE_BASE_POINT10, + SPELLVALUE_BASE_POINT11, + SPELLVALUE_BASE_POINT12, + SPELLVALUE_BASE_POINT13, + SPELLVALUE_BASE_POINT14, + SPELLVALUE_BASE_POINT15, + SPELLVALUE_BASE_POINT16, + SPELLVALUE_BASE_POINT17, + SPELLVALUE_BASE_POINT18, + SPELLVALUE_BASE_POINT19, + SPELLVALUE_BASE_POINT20, + SPELLVALUE_BASE_POINT21, + SPELLVALUE_BASE_POINT22, + SPELLVALUE_BASE_POINT23, + SPELLVALUE_BASE_POINT24, + SPELLVALUE_BASE_POINT25, + SPELLVALUE_BASE_POINT26, + SPELLVALUE_BASE_POINT27, + SPELLVALUE_BASE_POINT28, + SPELLVALUE_BASE_POINT29, + SPELLVALUE_BASE_POINT30, + SPELLVALUE_BASE_POINT31, + SPELLVALUE_BASE_POINT_END, SPELLVALUE_RADIUS_MOD, SPELLVALUE_MAX_TARGETS, SPELLVALUE_AURA_STACK diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index c4e4b6f21ae..894f87f6145 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -54,7 +54,7 @@ Loot* Roll::getLoot() } Group::Group() : m_leaderGuid(), m_leaderName(""), m_groupType(GROUPTYPE_NORMAL), -m_dungeonDifficulty(DUNGEON_DIFFICULTY_NORMAL), m_raidDifficulty(RAID_DIFFICULTY_10MAN_NORMAL), +m_dungeonDifficulty(DIFFICULTY_NORMAL), m_raidDifficulty(DIFFICULTY_10_N), m_bgGroup(NULL), m_bfGroup(NULL), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(), m_masterLooterGuid(), m_subGroupsCounts(NULL), m_guid(), m_counter(0), m_maxEnchantingLevel(0), m_dbStoreId(0) { @@ -111,8 +111,8 @@ bool Group::Create(Player* leader) m_looterGuid = leaderGuid; m_masterLooterGuid.Clear(); - m_dungeonDifficulty = DUNGEON_DIFFICULTY_NORMAL; - m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL; + m_dungeonDifficulty = DIFFICULTY_NORMAL; + m_raidDifficulty = DIFFICULTY_10_N; if (!isBGGroup() && !isBFGroup()) { @@ -182,13 +182,13 @@ void Group::LoadGroupFromDB(Field* fields) uint32 diff = fields[13].GetUInt8(); if (diff >= MAX_DUNGEON_DIFFICULTY) - m_dungeonDifficulty = DUNGEON_DIFFICULTY_NORMAL; + m_dungeonDifficulty = DIFFICULTY_NORMAL; else m_dungeonDifficulty = Difficulty(diff); uint32 r_diff = fields[14].GetUInt8(); if (r_diff >= MAX_RAID_DIFFICULTY) - m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL; + m_raidDifficulty = DIFFICULTY_10_N; else m_raidDifficulty = Difficulty(r_diff); @@ -2008,7 +2008,7 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo) if (method == INSTANCE_RESET_ALL) { // the "reset all instances" method can only reset normal maps - if (entry->IsRaid() || diff == DUNGEON_DIFFICULTY_HEROIC) + if (entry->IsRaid() || diff == DIFFICULTY_HEROIC) { ++itr; continue; diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp index 9aef1b62f7c..27b362faf90 100644 --- a/src/server/game/Instances/InstanceSaveMgr.cpp +++ b/src/server/game/Instances/InstanceSaveMgr.cpp @@ -96,7 +96,7 @@ InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instance { // initialize reset time // for normal instances if no creatures are killed the instance will reset in two hours - if (entry->IsRaid() || difficulty > DUNGEON_DIFFICULTY_NORMAL) + if (entry->IsRaid() || difficulty > DIFFICULTY_NORMAL) resetTime = GetResetTimeFor(mapId, difficulty); else { @@ -213,7 +213,7 @@ time_t InstanceSave::GetResetTimeForDB() { // only save the reset time for normal instances const MapEntry* entry = sMapStore.LookupEntry(GetMapId()); - if (!entry || entry->IsRaid() || GetDifficulty() == DUNGEON_DIFFICULTY_HEROIC) + if (!entry || entry->IsRaid() || GetDifficulty() == DIFFICULTY_HEROIC) return 0; else return GetResetTime(); diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h index b2c86d5152b..70db53ced8d 100644 --- a/src/server/game/Instances/InstanceSaveMgr.h +++ b/src/server/game/Instances/InstanceSaveMgr.h @@ -175,7 +175,7 @@ class InstanceSaveManager uint16 mapid; uint16 instanceId; - InstResetEvent() : type(0), difficulty(DUNGEON_DIFFICULTY_NORMAL), mapid(0), instanceId(0) { } + InstResetEvent() : type(0), difficulty(DIFFICULTY_NORMAL), mapid(0), instanceId(0) { } InstResetEvent(uint8 t, uint32 _mapid, Difficulty d, uint16 _instanceid) : type(t), difficulty(d), mapid(_mapid), instanceId(_instanceid) { } bool operator == (const InstResetEvent& e) const { return e.instanceId == instanceId; } diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 091fbb95aa5..7b7a0d5558d 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -386,15 +386,15 @@ class Map : public GridRefManager<NGridType> // have meaning only for instanced map (that have set real difficulty) Difficulty GetDifficulty() const { return Difficulty(GetSpawnMode()); } - bool IsRegularDifficulty() const { return GetDifficulty() == REGULAR_DIFFICULTY; } + bool IsRegularDifficulty() const { return GetDifficulty() == DIFFICULTY_NONE; } MapDifficulty const* GetMapDifficulty() const; bool Instanceable() const { return i_mapEntry && i_mapEntry->Instanceable(); } bool IsDungeon() const { return i_mapEntry && i_mapEntry->IsDungeon(); } bool IsNonRaidDungeon() const { return i_mapEntry && i_mapEntry->IsNonRaidDungeon(); } bool IsRaid() const { return i_mapEntry && i_mapEntry->IsRaid(); } - bool IsRaidOrHeroicDungeon() const { return IsRaid() || i_spawnMode > DUNGEON_DIFFICULTY_NORMAL; } - bool IsHeroic() const { return IsRaid() ? i_spawnMode >= RAID_DIFFICULTY_10MAN_HEROIC : i_spawnMode >= DUNGEON_DIFFICULTY_HEROIC; } + bool IsRaidOrHeroicDungeon() const { return IsRaid() || i_spawnMode > DIFFICULTY_NORMAL; } + bool IsHeroic() const { return IsRaid() ? i_spawnMode >= DIFFICULTY_10_HC : i_spawnMode >= DIFFICULTY_HEROIC; } bool Is25ManRaid() const { return IsRaid() && i_spawnMode & RAID_DIFFICULTY_MASK_25MAN; } // since 25man difficulties are 1 and 3, we can check them like that bool IsBattleground() const { return i_mapEntry && i_mapEntry->IsBattleground(); } bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); } diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp index 8dfa4449e12..48e5161bcf1 100644 --- a/src/server/game/Maps/MapInstanced.cpp +++ b/src/server/game/Maps/MapInstanced.cpp @@ -27,7 +27,7 @@ #include "Group.h" #include "Player.h" -MapInstanced::MapInstanced(uint32 id, time_t expiry) : Map(id, expiry, 0, DUNGEON_DIFFICULTY_NORMAL) +MapInstanced::MapInstanced(uint32 id, time_t expiry) : Map(id, expiry, 0, DIFFICULTY_NORMAL) { // fill with zero memset(&GridMapReference, 0, MAX_NUMBER_OF_GRIDS*MAX_NUMBER_OF_GRIDS*sizeof(uint16)); @@ -227,7 +227,7 @@ BattlegroundMap* MapInstanced::CreateBattleground(uint32 InstanceId, Battlegroun TC_LOG_DEBUG("maps", "MapInstanced::CreateBattleground: map bg %d for %d created.", InstanceId, GetId()); - BattlegroundMap* map = new BattlegroundMap(GetId(), GetGridExpiry(), InstanceId, this, REGULAR_DIFFICULTY); + BattlegroundMap* map = new BattlegroundMap(GetId(), GetGridExpiry(), InstanceId, this, DIFFICULTY_NONE); ASSERT(map->IsBattlegroundOrArena()); map->SetBG(bg); bg->SetBgMap(map); diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index ac9e5918442..92d7335c7de 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -78,7 +78,7 @@ Map* MapManager::CreateBaseMap(uint32 id) map = new MapInstanced(id, i_gridCleanUpDelay); else { - map = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY); + map = new Map(id, i_gridCleanUpDelay, 0, DIFFICULTY_NONE); map->LoadRespawnTimes(); } diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 9e8b5ca00f3..22bc3b079a3 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -27,7 +27,36 @@ enum SpellEffIndex { EFFECT_0 = 0, EFFECT_1 = 1, - EFFECT_2 = 2 + EFFECT_2 = 2, + EFFECT_3 = 3, + EFFECT_4 = 4, + EFFECT_5 = 5, + EFFECT_6 = 6, + EFFECT_7 = 7, + EFFECT_8 = 8, + EFFECT_9 = 9, + EFFECT_10 = 10, + EFFECT_11 = 11, + EFFECT_12 = 12, + EFFECT_13 = 13, + EFFECT_14 = 14, + EFFECT_15 = 15, + EFFECT_16 = 16, + EFFECT_17 = 17, + EFFECT_18 = 18, + EFFECT_19 = 19, + EFFECT_20 = 20, + EFFECT_21 = 21, + EFFECT_22 = 22, + EFFECT_23 = 23, + EFFECT_24 = 24, + EFFECT_25 = 25, + EFFECT_26 = 26, + EFFECT_27 = 27, + EFFECT_28 = 28, + EFFECT_29 = 29, + EFFECT_30 = 30, + EFFECT_31 = 31 }; // used in script definitions @@ -973,7 +1002,7 @@ enum Team TEAM_OTHER = 0 // if ReputationListId > 0 && Flags != FACTION_FLAG_TEAM_HEADER }; -enum SpellEffects +enum SpellEffectName { SPELL_EFFECT_INSTAKILL = 1, SPELL_EFFECT_SCHOOL_DAMAGE = 2, diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 8583d055123..5c247d86fa3 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -509,18 +509,20 @@ void SpellCastTargets::OutDebug() const SpellValue::SpellValue(SpellInfo const* proto) { - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - EffectBasePoints[i] = proto->Effects[i].BasePoints; + // todo 6.x + //for (uint32 i = 0; i < proto->Effects.size(); ++i) + // EffectBasePoints[i] = proto->Effects[i].BasePoints; MaxAffectedTargets = proto->MaxAffectedTargets; RadiusMod = 1.0f; AuraStackAmount = 1; } Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID, bool skipCheck) : -m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)), -m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster) -, m_spellValue(new SpellValue(m_spellInfo)), m_preGeneratedPath(PathGenerator(m_caster)) +m_spellInfo(info), m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster), +m_spellValue(new SpellValue(m_spellInfo)), m_preGeneratedPath(PathGenerator(m_caster)) { + difficultyEffects = info->GetEffectsForDifficulty(caster->GetMap()->GetDifficulty()); + m_customError = SPELL_CUSTOM_ERROR_NONE; m_skipCheck = skipCheck; m_selfContainer = NULL; @@ -764,36 +766,37 @@ void Spell::SelectSpellTargets() SelectExplicitTargets(); uint32 processedAreaEffectsMask = 0; - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + + for (SpellEffectInfo const* effect : GetEffects()) { // not call for empty effect. // Also some spells use not used effect targets for store targets for dummy effect in triggered spells - if (!m_spellInfo->Effects[i].IsEffect()) + if (!effect->IsEffect()) continue; // set expected type of implicit targets to be sent to client - uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType()); + uint32 implicitTargetMask = GetTargetFlagMask(effect->TargetA.GetObjectType()) | GetTargetFlagMask(effect->TargetB.GetObjectType()); if (implicitTargetMask & TARGET_FLAG_UNIT) m_targets.SetTargetFlag(TARGET_FLAG_UNIT); if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM)) m_targets.SetTargetFlag(TARGET_FLAG_GAMEOBJECT); - SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask); - SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask); + SelectEffectImplicitTargets(SpellEffIndex(effect->EffectIndex), effect->TargetA, processedAreaEffectsMask); + SelectEffectImplicitTargets(SpellEffIndex(effect->EffectIndex), effect->TargetB, processedAreaEffectsMask); // Select targets of effect based on effect type // those are used when no valid target could be added for spell effect based on spell target type // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL) // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON) // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS) - SelectEffectTypeImplicitTargets(i); + SelectEffectTypeImplicitTargets(effect->EffectIndex); if (m_targets.HasDst()) - AddDestTarget(*m_targets.GetDst(), i); + AddDestTarget(*m_targets.GetDst(), effect->EffectIndex); if (m_spellInfo->IsChanneled()) { - uint8 mask = (1 << i); + uint32 mask = (1 << effect->EffectIndex); for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) { if (ihit->effectMask & mask) @@ -864,17 +867,19 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar if (effectMask & processedEffectMask) return; // choose which targets we can select at once - for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j) + for (SpellEffectInfo const* effect : GetEffects()) { - SpellEffectInfo const* effects = GetSpellInfo()->Effects; - if (effects[j].IsEffect() && - effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() && - effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() && - effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions && - effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) && - CheckScriptEffectImplicitTargets(effIndex, j)) + //for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j) + if (effect->EffectIndex <= uint32(effIndex)) + continue; + if (effect->IsEffect() && + effect->TargetA.GetTarget() == effect->TargetA.GetTarget() && + effect->TargetB.GetTarget() == effect->TargetB.GetTarget() && + effect->ImplicitTargetConditions == effect->ImplicitTargetConditions && + effect->CalcRadius(m_caster) == effect->CalcRadius(m_caster) && + CheckScriptEffectImplicitTargets(effIndex, effect->EffectIndex)) { - effectMask |= 1 << j; + effectMask |= 1 << effect->EffectIndex; } } processedEffectMask |= effectMask; @@ -1009,6 +1014,10 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar return; } + SpellEffectInfo const* effect = GetEffect(effIndex); + if (!effect) + return; + float range = 0.0f; switch (targetType.GetCheckType()) { @@ -1030,7 +1039,7 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar break; } - ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions; + ConditionList* condList = effect->ImplicitTargetConditions; // handle emergency case - try to use other provided targets if no conditions provided if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty())) @@ -1116,9 +1125,12 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge std::list<WorldObject*> targets; SpellTargetObjectTypes objectType = targetType.GetObjectType(); SpellTargetCheckTypes selectionType = targetType.GetCheckType(); - ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions; + SpellEffectInfo const* effect = GetEffect(effIndex); + if (!effect) + return; + ConditionList* condList = effect->ImplicitTargetConditions; float coneAngle = float(M_PI) / 2; - float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod; + float radius = effect->CalcRadius(m_caster) * m_spellValue->RadiusMod; if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList)) { @@ -1199,8 +1211,11 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge } std::list<WorldObject*> targets; - float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod; - SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions); + SpellEffectInfo const* effect = GetEffect(effIndex); + if (!effect) + return; + float radius = effect->CalcRadius(m_caster) * m_spellValue->RadiusMod; + SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), effect->ImplicitTargetConditions); CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType); @@ -1236,7 +1251,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex)) { /// @todo fix this check - if (m_spellInfo->HasEffect(SPELL_EFFECT_TELEPORT_UNITS) || m_spellInfo->HasEffect(SPELL_EFFECT_BIND)) + if (HasEffect(SPELL_EFFECT_TELEPORT_UNITS) || HasEffect(SPELL_EFFECT_BIND)) dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId); else if (st->target_mapId == m_caster->GetMapId()) dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation); @@ -1284,23 +1299,26 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici } default: { - float dist; - float angle = targetType.CalcDirectionAngle(); - float objSize = m_caster->GetObjectSize(); - if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON) - dist = PET_FOLLOW_DIST; - else - dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); + if (SpellEffectInfo const* effect = GetEffect(effIndex)) + { + float dist; + float angle = targetType.CalcDirectionAngle(); + float objSize = m_caster->GetObjectSize(); + if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON) + dist = PET_FOLLOW_DIST; + else + dist = effect->CalcRadius(m_caster); - if (dist < objSize) - dist = objSize; - else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM) - dist = objSize + (dist - objSize) * float(rand_norm()); + if (dist < objSize) + dist = objSize; + else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM) + dist = objSize + (dist - objSize) * float(rand_norm()); - Position pos = dest._position; - m_caster->MovePositionToFirstCollision(pos, dist, angle); + Position pos = dest._position; + m_caster->MovePositionToFirstCollision(pos, dist, angle); - dest.Relocate(pos); + dest.Relocate(pos); + } break; } } @@ -1323,18 +1341,21 @@ void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplici break; default: { - float angle = targetType.CalcDirectionAngle(); - float objSize = target->GetObjectSize(); - float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); - if (dist < objSize) - dist = objSize; - else if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM) - dist = objSize + (dist - objSize) * float(rand_norm()); - - Position pos = dest._position; - target->MovePositionToFirstCollision(pos, dist, angle); - - dest.Relocate(pos); + if (SpellEffectInfo const* effect = GetEffect(effIndex)) + { + float angle = targetType.CalcDirectionAngle(); + float objSize = target->GetObjectSize(); + float dist = effect->CalcRadius(m_caster); + if (dist < objSize) + dist = objSize; + else if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM) + dist = objSize + (dist - objSize) * float(rand_norm()); + + Position pos = dest._position; + target->MovePositionToFirstCollision(pos, dist, angle); + + dest.Relocate(pos); + } break; } } @@ -1365,15 +1386,18 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT return; default: { - float angle = targetType.CalcDirectionAngle(); - float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); - if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM) - dist *= float(rand_norm()); + if (SpellEffectInfo const* effect = GetEffect(effIndex)) + { + float angle = targetType.CalcDirectionAngle(); + float dist = effect->CalcRadius(m_caster); + if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM) + dist *= float(rand_norm()); - Position pos = dest._position; - m_caster->MovePositionToFirstCollision(pos, dist, angle); + Position pos = dest._position; + m_caster->MovePositionToFirstCollision(pos, dist, angle); - dest.Relocate(pos); + dest.Relocate(pos); + } break; } } @@ -1451,21 +1475,25 @@ void Spell::SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImpli void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask) { - uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTargets; + SpellEffectInfo const* effect = GetEffect(effIndex); + if (!effect) + return; + + uint32 maxTargets = effect->ChainTargets; if (Player* modOwner = m_caster->GetSpellModOwner()) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this); if (maxTargets > 1) { // mark damage multipliers as used - for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k) - if (effMask & (1 << k)) - m_damageMultipliers[k] = 1.0f; + for (SpellEffectInfo const* eff : GetEffects()) + if (effMask & (1 << eff->EffectIndex)) + m_damageMultipliers[eff->EffectIndex] = 1.0f; m_applyMultiplierMask |= effMask; std::list<WorldObject*> targets; SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType() - , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY); + , effect->ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY); // Chain primary target is added earlier CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType); @@ -1644,11 +1672,14 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex) veh->SetLastShootPos(*m_targets.GetDstPos()); } -void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex) +void Spell::SelectEffectTypeImplicitTargets(uint32 effIndex) { // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER /// @todo this is a workaround - target shouldn't be stored in target map for those spells - switch (m_spellInfo->Effects[effIndex].Effect) + SpellEffectInfo const* effect = GetEffect(effIndex); + if (!effect) + return; + switch (effect->Effect) { case SPELL_EFFECT_SUMMON_RAF_FRIEND: case SPELL_EFFECT_SUMMON_PLAYER: @@ -1667,17 +1698,17 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex) } // select spell implicit targets based on effect type - if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType()) + if (!effect->GetImplicitTargetType()) return; - uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask(); + uint32 targetMask = effect->GetMissingTargetMask(); if (!targetMask) return; WorldObject* target = NULL; - switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType()) + switch (effect->GetImplicitTargetType()) { // add explicit object target or self to the target map case EFFECT_IMPLICIT_TARGET_EXPLICIT: @@ -2012,9 +2043,9 @@ void Spell::CleanupTargetList() void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= true*/, bool implicit /*= true*/, Position const* losPosition /*= nullptr*/) { - for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) - if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex, losPosition)) - effectMask &= ~(1 << effIndex); + for (SpellEffectInfo const* effect : GetEffects()) + if (!effect->IsEffect() || !CheckEffectTarget(target, effect->EffectIndex, losPosition)) + effectMask &= ~(1 << effect->EffectIndex); // no effects left if (!effectMask) @@ -2025,9 +2056,9 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= return; // Check for effect immune skip if immuned - for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) - if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex)) - effectMask &= ~(1 << effIndex); + for (SpellEffectInfo const* effect : GetEffects()) + if (target->IsImmunedToSpellEffect(m_spellInfo, effect->EffectIndex)) + effectMask &= ~(1 << effect->EffectIndex); ObjectGuid targetGUID = target->GetGUID(); @@ -2120,19 +2151,19 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= void Spell::AddGOTarget(GameObject* go, uint32 effectMask) { - for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) + for (SpellEffectInfo const* effect : GetEffects()) { - if (!m_spellInfo->Effects[effIndex].IsEffect()) - effectMask &= ~(1 << effIndex); + if (!effect->IsEffect()) + effectMask &= ~(1 << effect->EffectIndex); else { - switch (m_spellInfo->Effects[effIndex].Effect) + switch (effect->Effect) { case SPELL_EFFECT_GAMEOBJECT_DAMAGE: case SPELL_EFFECT_GAMEOBJECT_REPAIR: case SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE: if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) - effectMask &= ~(1 << effIndex); + effectMask &= ~(1 << effect->EffectIndex); break; default: break; @@ -2187,9 +2218,9 @@ void Spell::AddGOTarget(GameObject* go, uint32 effectMask) void Spell::AddItemTarget(Item* item, uint32 effectMask) { - for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) - if (!m_spellInfo->Effects[effIndex].IsEffect()) - effectMask &= ~(1 << effIndex); + for (SpellEffectInfo const* effect : GetEffects()) + if (!effect->IsEffect()) + effectMask &= ~(1 << effect->EffectIndex); // no effects left if (!effectMask) @@ -2234,10 +2265,10 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) { uint8 farMask = 0; // create far target mask - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (m_spellInfo->Effects[i].IsFarUnitTargetEffect()) - if ((1 << i) & mask) - farMask |= (1 << i); + for (SpellEffectInfo const* effect : GetEffects()) + if (effect->IsFarUnitTargetEffect()) + if ((1 << effect->EffectIndex) & mask) + farMask |= (1 << effect->EffectIndex); if (!farMask) return; @@ -2248,9 +2279,9 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) // do far effects on the unit // can't use default call because of threading, do stuff as fast as possible - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (farMask & (1 << i)) - HandleEffects(unit, NULL, NULL, i, SPELL_EFFECT_HANDLE_HIT_TARGET); + for(SpellEffectInfo const* effect : GetEffects()) + if (farMask & (1 << effect->EffectIndex)) + HandleEffects(unit, NULL, NULL, effect->EffectIndex, SPELL_EFFECT_HANDLE_HIT_TARGET); return; } @@ -2433,7 +2464,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) } } - if (missInfo != SPELL_MISS_EVADE && !m_caster->IsFriendlyTo(unit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL))) + if (missInfo != SPELL_MISS_EVADE && !m_caster->IsFriendlyTo(unit) && (!m_spellInfo->IsPositive() || HasEffect(SPELL_EFFECT_DISPEL))) { m_caster->CombatStart(unit, !(m_spellInfo->AttributesEx3 & SPELL_ATTR3_NO_INITIAL_AGGRO)); @@ -2474,10 +2505,10 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA // disable effects to which unit is immune SpellMissInfo returnVal = SPELL_MISS_IMMUNE; - for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber) - if (effectMask & (1 << effectNumber)) - if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber)) - effectMask &= ~(1 << effectNumber); + for (SpellEffectInfo const* effect : GetEffects()) + if (effectMask & (1 << effect->EffectIndex)) + if (unit->IsImmunedToSpellEffect(m_spellInfo, effect->EffectIndex)) + effectMask &= ~(1 << effect->EffectIndex); if (!effectMask) return returnVal; @@ -2535,9 +2566,9 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA } uint8 aura_effmask = 0; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect()) - aura_effmask |= 1 << i; + for (SpellEffectInfo const* effect : GetEffects()) + if (effectMask & (1 << effect->EffectIndex) && effect->IsUnitOwnedAuraEffect()) + aura_effmask |= 1 << effect->EffectIndex; // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add m_diminishGroup = GetDiminishingReturnsGroupForSpell(m_spellInfo, m_triggeredByAuraSpell != nullptr); @@ -2557,18 +2588,21 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA // Select rank for aura with level requirements only in specific cases // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target SpellInfo const* aurSpellInfo = m_spellInfo; - int32 basePoints[3]; + int32 basePoints[MAX_SPELL_EFFECTS]; if (scaleAura) { aurSpellInfo = m_spellInfo->GetAuraRankForLevel(unitTarget->getLevel()); ASSERT(aurSpellInfo); - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (SpellEffectInfo const* effect : aurSpellInfo->GetEffectsForDifficulty(0)) { - basePoints[i] = aurSpellInfo->Effects[i].BasePoints; - if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect) + basePoints[effect->EffectIndex] = effect->BasePoints; + if (SpellEffectInfo const* myEffect = GetEffect(effect->EffectIndex)) { - aurSpellInfo = m_spellInfo; - break; + if (myEffect->Effect != effect->Effect) + { + aurSpellInfo = m_spellInfo; + break; + } } } } @@ -2599,8 +2633,8 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA { m_spellAura->Remove(); bool found = false; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA) + for (SpellEffectInfo const* effect : GetEffects()) + if (effectMask & (1 << effect->EffectIndex) && effect->Effect != SPELL_EFFECT_APPLY_AURA) found = true; if (!found) return SPELL_MISS_IMMUNE; @@ -2624,8 +2658,8 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA { int32 origDuration = duration; duration = 0; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (AuraEffect const* eff = m_spellAura->GetEffect(i)) + for (SpellEffectInfo const* effect : GetEffects()) + if (AuraEffect const* eff = m_spellAura->GetEffect(effect->EffectIndex)) if (int32 period = eff->GetPeriod()) // period is hastened by UNIT_MOD_CAST_SPEED duration = std::max(std::max(origDuration / period, 1) * period, duration); @@ -2646,9 +2680,9 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA } } - for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber) - if (effectMask & (1 << effectNumber)) - HandleEffects(unit, NULL, NULL, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET); + for (SpellEffectInfo const* effect : GetEffects()) + if (effectMask & (1 << effect->EffectIndex)) + HandleEffects(unit, NULL, NULL, effect->EffectIndex, SPELL_EFFECT_HANDLE_HIT_TARGET); return SPELL_MISS_NONE; } @@ -2742,9 +2776,9 @@ void Spell::DoAllEffectOnTarget(GOTargetInfo* target) PrepareScriptHitHandlers(); CallScriptBeforeHitHandlers(); - for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber) - if (effectMask & (1 << effectNumber)) - HandleEffects(NULL, NULL, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET); + for (SpellEffectInfo const* effect : GetEffects()) + if (effectMask & (1 << effect->EffectIndex)) + HandleEffects(NULL, NULL, go, effect->EffectIndex, SPELL_EFFECT_HANDLE_HIT_TARGET); CallScriptOnHitHandlers(); CallScriptAfterHitHandlers(); @@ -2759,9 +2793,9 @@ void Spell::DoAllEffectOnTarget(ItemTargetInfo* target) PrepareScriptHitHandlers(); CallScriptBeforeHitHandlers(); - for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber) - if (effectMask & (1 << effectNumber)) - HandleEffects(NULL, target->item, NULL, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET); + for (SpellEffectInfo const* effect : GetEffects()) + if (effectMask & (1 << effect->EffectIndex)) + HandleEffects(NULL, target->item, NULL, effect->EffectIndex, SPELL_EFFECT_HANDLE_HIT_TARGET); CallScriptOnHitHandlers(); @@ -2776,9 +2810,9 @@ bool Spell::UpdateChanneledTargetList() uint8 channelTargetEffectMask = m_channelTargetEffectMask; uint8 channelAuraMask = 0; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA) - channelAuraMask |= 1<<i; + for (SpellEffectInfo const* effect : GetEffects()) + if (effect->Effect == SPELL_EFFECT_APPLY_AURA) + channelAuraMask |= 1 << effect->EffectIndex; channelAuraMask &= channelTargetEffectMask; @@ -2843,15 +2877,15 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered // Fill aura scaling information if (m_caster->IsControlledByPlayer() && !m_spellInfo->IsPassive() && m_spellInfo->SpellLevel && !m_spellInfo->IsChanneled() && !(_triggeredCastFlags & TRIGGERED_IGNORE_AURA_SCALING)) { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (SpellEffectInfo const* effect : GetEffects()) { - if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA) + if (effect->Effect == SPELL_EFFECT_APPLY_AURA) { // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive - if (m_spellInfo->IsPositiveEffect(i)) + if (m_spellInfo->IsPositiveEffect(effect->EffectIndex)) { - m_auraScaleMask |= (1 << i); - if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints) + m_auraScaleMask |= (1 << effect->EffectIndex); + if (m_spellValue->EffectBasePoints[effect->EffectIndex] != effect->BasePoints) { m_auraScaleMask = 0; break; @@ -2966,8 +3000,8 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered if (!(_triggeredCastFlags & TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS) && m_spellInfo->IsBreakingStealth()) { m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CAST); - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (m_spellInfo->Effects[i].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT) + for (SpellEffectInfo const* effect : GetEffects()) + if (effect->GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT) { m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_SPELL_ATTACK); break; @@ -3296,10 +3330,6 @@ void Spell::handle_immediate() // Remove used for cast item if need (it can be already NULL after TakeReagents call TakeCastItem(); - // handle ammo consumption for thrown weapons - if (m_spellInfo->IsRangedWeaponSpell() && m_spellInfo->IsChanneled()) - TakeAmmo(); - if (m_spellState != SPELL_STATE_CASTING) finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell) } @@ -3391,14 +3421,14 @@ void Spell::_handle_immediate_phase() PrepareScriptHitHandlers(); // handle effects with SPELL_EFFECT_HANDLE_HIT mode - for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) + for (SpellEffectInfo const* effect : GetEffects()) { // don't do anything for empty effect - if (!m_spellInfo->Effects[j].IsEffect()) + if (!effect->IsEffect()) continue; // call effect handlers to handle destination hit - HandleEffects(NULL, NULL, NULL, j, SPELL_EFFECT_HANDLE_HIT); + HandleEffects(NULL, NULL, NULL, effect->EffectIndex, SPELL_EFFECT_HANDLE_HIT); } // process items @@ -3436,7 +3466,7 @@ void Spell::_handle_finish_phase() HandleHolyPower(m_caster->m_movedPlayer); } - if (m_caster->m_extraAttacks && m_spellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) + if (m_caster->m_extraAttacks && HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) { if (Unit* victim = ObjectAccessor::FindUnit(m_targets.GetOrigUnitTargetGUID())) m_caster->HandleProcExtraAttackFor(victim); @@ -3494,9 +3524,10 @@ void Spell::update(uint32 difftime) // check if the player caster has moved before the spell finished // with the exception of spells affected with SPELL_AURA_CAST_WHILE_WALKING effect + SpellEffectInfo const* effect = GetEffect(EFFECT_0); if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) && m_caster->isMoving() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT) && - (m_spellInfo->Effects[0].Effect != SPELL_EFFECT_STUCK || !m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR)) && + ((effect && effect->Effect != SPELL_EFFECT_STUCK) || !m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR)) && !m_caster->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo)) { // don't cancel for melee, autorepeat, triggered and instant spells @@ -3724,9 +3755,9 @@ void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cas case SPELL_FAILED_TOO_MANY_OF_ITEM: { uint32 item = 0; - for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++) - if (spellInfo->Effects[eff].ItemType) - item = spellInfo->Effects[eff].ItemType; + for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(caster->GetMap()->GetDifficulty())) + if (effect->ItemType) + item = effect->ItemType; ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item); if (proto && proto->ItemLimitCategory) data << uint32(proto->ItemLimitCategory); @@ -3897,7 +3928,7 @@ void Spell::SendSpellGo() castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list } - if (m_spellInfo->HasEffect(SPELL_EFFECT_ACTIVATE_RUNE)) + if (HasEffect(SPELL_EFFECT_ACTIVATE_RUNE)) castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list if (m_targets.HasTraj()) @@ -4052,9 +4083,9 @@ void Spell::SendLogExecute() data << uint32(m_spellInfo->Id); uint8 effCount = 0; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (SpellEffectInfo const* effect : GetEffects()) { - if (m_effectExecuteData[i]) + if (m_effectExecuteData[effect->EffectIndex]) ++effCount; } @@ -4062,17 +4093,17 @@ void Spell::SendLogExecute() return; data << uint32(effCount); - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (SpellEffectInfo const* effect : GetEffects()) { - if (!m_effectExecuteData[i]) + if (!m_effectExecuteData[effect->EffectIndex]) continue; - data << uint32(m_spellInfo->Effects[i].Effect); // spell effect + data << uint32(effect->Effect); // spell effect - data.append(*m_effectExecuteData[i]); + data.append(*m_effectExecuteData[effect->EffectIndex]); - delete m_effectExecuteData[i]; - m_effectExecuteData[i] = NULL; + delete m_effectExecuteData[effect->EffectIndex]; + m_effectExecuteData[effect->EffectIndex] = NULL; } m_caster->SendMessageToSet(&data, true); } @@ -4407,36 +4438,6 @@ void Spell::TakePower() m_caster->ModifyPower(powerType, -irand(0, m_powerCost/4)); } -void Spell::TakeAmmo() -{ - if (m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER) - { - Item* pItem = m_caster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK); - - // wands don't have ammo - if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND) - return; - - if ((pItem->GetTemplate()->InventoryType == INVTYPE_THROWN || - pItem->GetTemplate()->InventoryType == INVTYPE_RANGED || - pItem->GetTemplate()->InventoryType == INVTYPE_RANGEDRIGHT) - && roll_chance_f(sWorld->getRate(RATE_DURABILITY_LOSS_DAMAGE))) - { - if (pItem->GetMaxStackCount() == 1) - { - // decrease durability for non-stackable throw weapon - m_caster->ToPlayer()->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_RANGED); - } - else - { - // decrease items amount for stackable throw weapon - uint32 count = 1; - m_caster->ToPlayer()->DestroyItemCount(pItem, count, true); - } - } - } -} - SpellCastResult Spell::CheckRuneCost(uint32 runeCostID) { if (m_spellInfo->PowerType != POWER_RUNES || !runeCostID) @@ -4693,9 +4694,15 @@ void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOT gameObjTarget = pGOTarget; destTarget = &m_destTargets[i]._position; - uint8 eff = m_spellInfo->Effects[i].Effect; + SpellEffectInfo const* effect = GetEffect(i); + if (!effect) + { + TC_LOG_ERROR("spells", "Spell: %u HandleEffects at EffectIndex: %u missing effect", m_spellInfo->Id, i); + return; + } + uint8 eff = effect->Effect; - TC_LOG_DEBUG("spells", "Spell: %u Effect : %u", m_spellInfo->Id, eff); + TC_LOG_DEBUG("spells", "Spell: %u Effect: %u", m_spellInfo->Id, eff); damage = CalculateDamage(i, unitTarget); @@ -4816,9 +4823,9 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_CASTER_AURASTATE; // Note: spell 62473 requres casterAuraSpell = triggering spell - if (m_spellInfo->CasterAuraSpell && !m_caster->HasAura(sSpellMgr->GetSpellIdForDifficulty(m_spellInfo->CasterAuraSpell, m_caster))) + if (m_spellInfo->CasterAuraSpell && !m_caster->HasAura(m_spellInfo->CasterAuraSpell)) return SPELL_FAILED_CASTER_AURASTATE; - if (m_spellInfo->ExcludeCasterAuraSpell && m_caster->HasAura(sSpellMgr->GetSpellIdForDifficulty(m_spellInfo->ExcludeCasterAuraSpell, m_caster))) + if (m_spellInfo->ExcludeCasterAuraSpell && m_caster->HasAura(m_spellInfo->ExcludeCasterAuraSpell)) return SPELL_FAILED_CASTER_AURASTATE; if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat()) @@ -4831,7 +4838,8 @@ SpellCastResult Spell::CheckCast(bool strict) if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->isMoving() && !m_caster->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo)) { // skip stuck spell to allow use it in falling case and apply spell limitations at movement - if ((!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR) || m_spellInfo->Effects[0].Effect != SPELL_EFFECT_STUCK) && + SpellEffectInfo const* effect = GetEffect(EFFECT_0); + if ((!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR) || (effect && effect->Effect != SPELL_EFFECT_STUCK)) && (IsAutoRepeat() || (m_spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) != 0)) return SPELL_FAILED_MOVING; } @@ -4916,9 +4924,9 @@ SpellCastResult Spell::CheckCast(bool strict) } // check pet presence - for (int j = 0; j < MAX_SPELL_EFFECTS; ++j) + for (SpellEffectInfo const* effect : GetEffects()) { - if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET) + if (effect->TargetA.GetTarget() == TARGET_UNIT_PET) { if (!m_caster->GetGuardianPet()) { @@ -5009,10 +5017,10 @@ SpellCastResult Spell::CheckCast(bool strict) if (castResult != SPELL_CAST_OK) return castResult; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (SpellEffectInfo const* effect : GetEffects()) { // for effects of spells that have only one target - switch (m_spellInfo->Effects[i].Effect) + switch (effect->Effect) { case SPELL_EFFECT_DUMMY: { @@ -5039,7 +5047,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (m_caster->GetTypeId() != TYPEID_PLAYER) return SPELL_FAILED_BAD_TARGETS; - if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET) + if (effect->TargetA.GetTarget() != TARGET_UNIT_PET) break; Pet* pet = m_caster->ToPlayer()->GetPet(); @@ -5047,7 +5055,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (!pet) return SPELL_FAILED_NO_PET; - SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell); + SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(effect->TriggerSpell); if (!learn_spellproto) return SPELL_FAILED_NOT_KNOWN; @@ -5078,7 +5086,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (!pet || pet->GetOwner() != m_caster) return SPELL_FAILED_BAD_TARGETS; - SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell); + SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(effect->TriggerSpell); if (!learn_spellproto) return SPELL_FAILED_NOT_KNOWN; @@ -5090,7 +5098,7 @@ SpellCastResult Spell::CheckCast(bool strict) } case SPELL_EFFECT_APPLY_GLYPH: { - uint32 glyphId = m_spellInfo->Effects[i].MiscValue; + uint32 glyphId = effect->MiscValue; if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId)) if (m_caster->HasAura(gp->SpellID)) return SPELL_FAILED_UNIQUE_GLYPH; @@ -5127,7 +5135,7 @@ SpellCastResult Spell::CheckCast(bool strict) // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects) if (m_caster->GetTypeId() == TYPEID_PLAYER) if (Unit* target = m_targets.GetUnitTarget()) - if (target != m_caster && target->getPowerType() != Powers(m_spellInfo->Effects[i].MiscValue)) + if (target != m_caster && target->getPowerType() != Powers(effect->MiscValue)) return SPELL_FAILED_BAD_TARGETS; break; } @@ -5200,13 +5208,13 @@ SpellCastResult Spell::CheckCast(bool strict) } case SPELL_EFFECT_OPEN_LOCK: { - if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET && - m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET) + if (effect->TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET && + effect->TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET) break; if (m_caster->GetTypeId() != TYPEID_PLAYER // only players can open locks, gather etc. // we need a go target in case of TARGET_GAMEOBJECT_TARGET - || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget())) + || (effect->TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget())) return SPELL_FAILED_BAD_TARGETS; Item* pTempItem = NULL; @@ -5219,7 +5227,7 @@ SpellCastResult Spell::CheckCast(bool strict) pTempItem = m_caster->ToPlayer()->GetItemByGuid(m_targets.GetItemTargetGUID()); // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET - if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET && + if (effect->TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET && !m_targets.GetGOTarget() && (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked())) return SPELL_FAILED_BAD_TARGETS; @@ -5246,7 +5254,7 @@ SpellCastResult Spell::CheckCast(bool strict) int32 skillValue = 0; // check lock compatibility - SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue); + SpellCastResult res = CanOpenLock(effect->EffectIndex, lockId, skillId, reqSkillValue, skillValue); if (res != SPELL_CAST_OK) return res; @@ -5274,7 +5282,7 @@ SpellCastResult Spell::CheckCast(bool strict) // This is generic summon effect case SPELL_EFFECT_SUMMON: { - SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB); + SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(effect->MiscValueB); if (!SummonProperties) break; switch (SummonProperties->Category) @@ -5408,9 +5416,9 @@ SpellCastResult Spell::CheckCast(bool strict) } } - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (SpellEffectInfo const* effect : GetEffects()) { - switch (m_spellInfo->Effects[i].ApplyAuraName) + switch (effect->ApplyAuraName) { case SPELL_AURA_MOD_POSSESS_PET: { @@ -5432,8 +5440,8 @@ SpellCastResult Spell::CheckCast(bool strict) if (!m_caster->GetCharmerGUID().IsEmpty()) return SPELL_FAILED_CHARMED; - if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_CHARM - || m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS) + if (effect->ApplyAuraName == SPELL_AURA_MOD_CHARM + || effect->ApplyAuraName == SPELL_AURA_MOD_POSSESS) { if (!m_caster->GetPetGUID().IsEmpty()) return SPELL_FAILED_ALREADY_HAVE_SUMMON; @@ -5456,7 +5464,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (target->GetOwner() && target->GetOwner()->GetTypeId() == TYPEID_PLAYER) return SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED; - int32 damage = CalculateDamage(i, target); + int32 damage = CalculateDamage(effect->EffectIndex, target); if (damage && int32(target->getLevel()) > damage) return SPELL_FAILED_HIGHLEVEL; } @@ -5508,7 +5516,7 @@ SpellCastResult Spell::CheckCast(bool strict) } case SPELL_AURA_PERIODIC_MANA_LEECH: { - if (m_spellInfo->Effects[i].IsTargetingArea()) + if (effect->IsTargetingArea()) break; if (!m_targets.GetUnitTarget()) @@ -5608,14 +5616,14 @@ SpellCastResult Spell::CheckCasterAuras() const // We use bitmasks so the loop is done only once and not on every aura check below. if (m_spellInfo->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY) { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (SpellEffectInfo const* effect : GetEffects()) { - if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY) - school_immune |= uint32(m_spellInfo->Effects[i].MiscValue); - else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY) - mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue); - else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY) - dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue)); + if (effect->ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY) + school_immune |= uint32(effect->MiscValue); + else if (effect->ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY) + mechanic_immune |= 1 << uint32(effect->MiscValue); + else if (effect->ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY) + dispel_immune |= SpellInfo::GetDispelMask(DispelType(effect->MiscValue)); } // immune movement impairment and loss of control if (m_spellInfo->Id == 42292 || m_spellInfo->Id == 59752 || m_spellInfo->Id == 19574) @@ -5684,9 +5692,9 @@ SpellCastResult Spell::CheckCasterAuras() const //Make a second check for spell failed so the right SPELL_FAILED message is returned. //That is needed when your casting is prevented by multiple states and you are only immune to some of them. - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (SpellEffectInfo const* effect : GetEffects()) { - if (AuraEffect* part = aura->GetEffect(i)) + if (AuraEffect* part = aura->GetEffect(effect->EffectIndex)) { switch (part->GetAuraType()) { @@ -5758,25 +5766,25 @@ bool Spell::CanAutoCast(Unit* target) { ObjectGuid targetguid = target->GetGUID(); - for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) + for (SpellEffectInfo const* effect : GetEffects()) { - if (m_spellInfo->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA) + if (effect->Effect == SPELL_EFFECT_APPLY_AURA) { if (m_spellInfo->StackAmount <= 1) { - if (target->HasAuraEffect(m_spellInfo->Id, j)) + if (target->HasAuraEffect(m_spellInfo->Id, effect->EffectIndex)) return false; } else { - if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j)) + if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, effect->EffectIndex)) if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount) return false; } } - else if (m_spellInfo->Effects[j].IsAreaAuraEffect()) + else if (effect->IsAreaAuraEffect()) { - if (target->HasAuraEffect(m_spellInfo->Id, j)) + if (target->HasAuraEffect(m_spellInfo->Id, effect->EffectIndex)) return false; } } @@ -5921,13 +5929,13 @@ SpellCastResult Spell::CheckItems() { // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example SpellCastResult failReason = SPELL_CAST_OK; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (SpellEffectInfo const* effect : GetEffects()) { // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster - if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET) + if (effect->TargetA.GetTarget() == TARGET_UNIT_PET) continue; - if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL) + if (effect->Effect == SPELL_EFFECT_HEAL) { if (m_targets.GetUnitTarget()->IsFullHealth()) { @@ -5942,15 +5950,15 @@ SpellCastResult Spell::CheckItems() } // Mana Potion, Rage Potion, Thistle Tea(Rogue), ... - if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE) + if (effect->Effect == SPELL_EFFECT_ENERGIZE) { - if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS)) + if (effect->MiscValue < 0 || effect->MiscValue >= int8(MAX_POWERS)) { failReason = SPELL_FAILED_ALREADY_AT_FULL_POWER; continue; } - Powers power = Powers(m_spellInfo->Effects[i].MiscValue); + Powers power = Powers(effect->MiscValue); if (m_targets.GetUnitTarget()->GetPower(power) == m_targets.GetUnitTarget()->GetMaxPower(power)) { failReason = SPELL_FAILED_ALREADY_AT_FULL_POWER; @@ -6048,34 +6056,34 @@ SpellCastResult Spell::CheckItems() } // special checks for spell effects - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (SpellEffectInfo const* effect : GetEffects()) { - switch (m_spellInfo->Effects[i].Effect) + switch (effect->Effect) { case SPELL_EFFECT_CREATE_ITEM: case SPELL_EFFECT_CREATE_ITEM_2: { - if (!IsTriggered() && m_spellInfo->Effects[i].ItemType) + if (!IsTriggered() && effect->ItemType) { ItemPosCountVec dest; - InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1); + InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, effect->ItemType, 1); if (msg != EQUIP_ERR_OK) { - ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType); + ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(effect->ItemType); /// @todo Needs review if (pProto && !(pProto->ItemLimitCategory)) { - player->SendEquipError(msg, NULL, NULL, m_spellInfo->Effects[i].ItemType); + player->SendEquipError(msg, NULL, NULL, effect->ItemType); return SPELL_FAILED_DONT_REPORT; } else { if (!(m_spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (m_spellInfo->SpellFamilyFlags[0] & 0x40000000))) return SPELL_FAILED_TOO_MANY_OF_ITEM; - else if (!(player->HasItemCount(m_spellInfo->Effects[i].ItemType))) + else if (!(player->HasItemCount(effect->ItemType))) return SPELL_FAILED_TOO_MANY_OF_ITEM; - else - player->CastSpell(m_caster, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere + else if (SpellEffectInfo const* efi = GetEffect(EFFECT_1)) + player->CastSpell(m_caster, efi->CalcValue(), false); // move this to anywhere return SPELL_FAILED_DONT_REPORT; } } @@ -6083,7 +6091,7 @@ SpellCastResult Spell::CheckItems() break; } case SPELL_EFFECT_ENCHANT_ITEM: - if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget() + if (effect->ItemType && m_targets.GetItemTarget() && (m_targets.GetItemTarget()->IsVellum())) { // cannot enchant vellum for other player @@ -6093,10 +6101,10 @@ SpellCastResult Spell::CheckItems() if (m_CastItem && m_CastItem->GetTemplate()->Flags[0] & ITEM_PROTO_FLAG_TRIGGERED_CAST) return SPELL_FAILED_TOTEM_CATEGORY; ItemPosCountVec dest; - InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1); + InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, effect->ItemType, 1); if (msg != EQUIP_ERR_OK) { - player->SendEquipError(msg, NULL, NULL, m_spellInfo->Effects[i].ItemType); + player->SendEquipError(msg, NULL, NULL, effect->ItemType); return SPELL_FAILED_DONT_REPORT; } } @@ -6123,7 +6131,7 @@ SpellCastResult Spell::CheckItems() } } - SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue); + SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(effect->MiscValue); // do not allow adding usable enchantments to items that have use effect already if (enchantEntry) { @@ -6168,7 +6176,7 @@ SpellCastResult Spell::CheckItems() // Not allow enchant in trade slot for some enchant type if (item->GetOwner() != m_caster) { - uint32 enchant_id = m_spellInfo->Effects[i].MiscValue; + uint32 enchant_id = effect->MiscValue; SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); if (!pEnchant) return SPELL_FAILED_ERROR; @@ -6285,7 +6293,7 @@ SpellCastResult Spell::CheckItems() } case SPELL_EFFECT_CREATE_MANA_GEM: { - uint32 item_id = m_spellInfo->Effects[i].ItemType; + uint32 item_id = effect->ItemType; ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id); if (!pProto) @@ -6457,9 +6465,9 @@ bool Spell::UpdatePointers() WorldObject* transport = NULL; // update effect destinations (in case of moved transport dest target) - for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) + for (SpellEffectInfo const* effect : GetEffects()) { - SpellDestination& dest = m_destTargets[effIndex]; + SpellDestination& dest = m_destTargets[effect->EffectIndex]; if (!dest._transportGUID) continue; @@ -6490,7 +6498,11 @@ CurrentSpellTypes Spell::GetCurrentContainer() const bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* losPosition) const { - switch (m_spellInfo->Effects[eff].ApplyAuraName) + SpellEffectInfo const* effect = GetEffect(eff); + if (!effect) + return false; + + switch (effect->ApplyAuraName) { case SPELL_AURA_MOD_POSSESS: case SPELL_AURA_MOD_CHARM: @@ -6520,7 +6532,7 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* lo /// @todo shit below shouldn't be here, but it's temporary //Check targets for LOS visibility (except spells without range limitations) - switch (m_spellInfo->Effects[eff].Effect) + switch (effect->Effect) { case SPELL_EFFECT_RESURRECT_NEW: // player far away, maybe his corpse near? @@ -6731,21 +6743,19 @@ bool Spell::IsValidDeadOrAliveTarget(Unit const* target) const void Spell::HandleLaunchPhase() { // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (SpellEffectInfo const* effect : GetEffects()) { // don't do anything for empty effect - if (!m_spellInfo->Effects[i].IsEffect()) + if (!effect->IsEffect()) continue; - HandleEffects(NULL, NULL, NULL, i, SPELL_EFFECT_HANDLE_LAUNCH); + HandleEffects(NULL, NULL, NULL, effect->EffectIndex, SPELL_EFFECT_HANDLE_LAUNCH); } float multiplier[MAX_SPELL_EFFECTS]; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (m_applyMultiplierMask & (1 << i)) - multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this); - - bool usesAmmo = (m_spellInfo->AttributesCu & SPELL_ATTR0_CU_DIRECT_DAMAGE) != 0; + for (SpellEffectInfo const* effect : GetEffects()) + if (m_applyMultiplierMask & (1 << effect->EffectIndex)) + multiplier[effect->EffectIndex] = effect->CalcDamageMultiplier(m_originalCaster, this); for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) { @@ -6755,31 +6765,6 @@ void Spell::HandleLaunchPhase() if (!mask) continue; - // do not consume ammo anymore for Hunter's volley spell - if (IsTriggered() && m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellInfo->IsTargetingArea()) - usesAmmo = false; - - if (usesAmmo) - { - bool ammoTaken = false; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++) - { - if (!(mask & 1<<i)) - continue; - switch (m_spellInfo->Effects[i].Effect) - { - case SPELL_EFFECT_SCHOOL_DAMAGE: - case SPELL_EFFECT_WEAPON_DAMAGE: - case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: - case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: - case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: - ammoTaken=true; - TakeAmmo(); - } - if (ammoTaken) - break; - } - } DoAllEffectOnLaunchTarget(target, multiplier); } } @@ -6796,18 +6781,18 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier) if (!unit) return; - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (SpellEffectInfo const* effect : GetEffects()) { - if (targetInfo.effectMask & (1<<i)) + if (targetInfo.effectMask & (1<<effect->EffectIndex)) { m_damage = 0; m_healing = 0; - HandleEffects(unit, NULL, NULL, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET); + HandleEffects(unit, NULL, NULL, effect->EffectIndex, SPELL_EFFECT_HANDLE_LAUNCH_TARGET); if (m_damage > 0) { - if (m_spellInfo->Effects[i].IsTargetingArea() || m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA)) + if (effect->IsTargetingArea() || effect->IsAreaAuraEffect() || effect->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA)) { m_damage = int32(float(m_damage) * unit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask)); if (m_caster->GetTypeId() != TYPEID_PLAYER) @@ -6822,10 +6807,10 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier) } } - if (m_applyMultiplierMask & (1 << i)) + if (m_applyMultiplierMask & (1 << effect->EffectIndex)) { - m_damage = int32(m_damage * m_damageMultipliers[i]); - m_damageMultipliers[i] *= multiplier[i]; + m_damage = int32(m_damage * m_damageMultipliers[effect->EffectIndex]); + m_damageMultipliers[effect->EffectIndex] *= multiplier[effect->EffectIndex]; } targetInfo.damage += m_damage; } @@ -6845,6 +6830,10 @@ SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& sk if (!lockInfo) return SPELL_FAILED_BAD_TARGETS; + SpellEffectInfo const* effect = GetEffect(effIndex); + if (!effect) + return SPELL_FAILED_BAD_TARGETS; // no idea about correct error + bool reqKey = false; // some locks not have reqs for (int j = 0; j < MAX_LOCK_CASE; ++j) @@ -6863,7 +6852,7 @@ SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& sk reqKey = true; // wrong locktype, skip - if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j]) + if (uint32(effect->MiscValue) != lockInfo->Index[j]) continue; skillId = SkillByLockType(LockType(lockInfo->Index[j])); @@ -6878,8 +6867,8 @@ SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& sk // skill bonus provided by casting spell (mostly item spells) // add the effect base points modifier from the spell cast (cheat lock / skeleton key etc.) - if (m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET) - skillValue += m_spellInfo->Effects[effIndex].CalcValue(); + if (effect->TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || effect->TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET) + skillValue += effect->CalcValue(); if (skillValue < reqSkillValue) return SPELL_FAILED_LOW_CASTLEVEL; @@ -6898,17 +6887,15 @@ SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& sk void Spell::SetSpellValue(SpellValueMod mod, int32 value) { + if (mod < SPELLVALUE_BASE_POINT_END) + { + if (SpellEffectInfo const* effect = GetEffect(mod)) + m_spellValue->EffectBasePoints[mod] = effect->CalcBaseValue(value); + return; + } + switch (mod) { - case SPELLVALUE_BASE_POINT0: - m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value); - break; - case SPELLVALUE_BASE_POINT1: - m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value); - break; - case SPELLVALUE_BASE_POINT2: - m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value); - break; case SPELLVALUE_RADIUS_MOD: m_spellValue->RadiusMod = (float)value / 10000; break; @@ -6931,7 +6918,7 @@ void Spell::FinishTargetProcessing() SendLogExecute(); } -void Spell::InitEffectExecuteData(uint8 effIndex) +void Spell::InitEffectExecuteData(uint32 effIndex) { ASSERT(effIndex < MAX_SPELL_EFFECTS); if (!m_effectExecuteData[effIndex]) @@ -7193,9 +7180,9 @@ bool Spell::CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* triggeredByA { bool only_on_caster = (triggeredByAura && (triggeredByAura->AttributesEx4 & SPELL_ATTR4_PROC_ONLY_ON_CASTER)); // If triggeredByAura has SPELL_ATTR4_PROC_ONLY_ON_CASTER then it can only proc on a cast spell with TARGET_UNIT_CASTER - for (uint8 i = 0;i < MAX_SPELL_EFFECTS; ++i) + for (SpellEffectInfo const* effect : GetEffects()) { - if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER))) + if ((effMask & (1 << effect->EffectIndex)) && (!only_on_caster || (effect->TargetA.GetTarget() == TARGET_UNIT_CASTER))) return true; } return false; @@ -7236,19 +7223,23 @@ void Spell::PrepareTriggersExecutedOnHit() continue; SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo(); uint32 auraSpellIdx = (*i)->GetEffIndex(); - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell)) + // todo 6.x + if (SpellEffectInfo const* auraEffect = auraSpellInfo->GetEffect(m_caster->GetMap()->GetDifficulty(), auraSpellIdx)) { - // calculate the chance using spell base amount, because aura amount is not updated on combo-points change - // this possibly needs fixing - int32 auraBaseAmount = (*i)->GetBaseAmount(); - // proc chance is stored in effect amount - int32 chance = m_caster->CalculateSpellDamage(NULL, auraSpellInfo, auraSpellIdx, &auraBaseAmount); - // build trigger and add to the list - HitTriggerSpell spellTriggerInfo; - spellTriggerInfo.triggeredSpell = spellInfo; - spellTriggerInfo.triggeredByAura = auraSpellInfo; - spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount(); - m_hitTriggerSpells.push_back(spellTriggerInfo); + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraEffect->TriggerSpell)) + { + // calculate the chance using spell base amount, because aura amount is not updated on combo-points change + // this possibly needs fixing + int32 auraBaseAmount = (*i)->GetBaseAmount(); + // proc chance is stored in effect amount + int32 chance = m_caster->CalculateSpellDamage(NULL, auraSpellInfo, auraSpellIdx, &auraBaseAmount); + // build trigger and add to the list + HitTriggerSpell spellTriggerInfo; + spellTriggerInfo.triggeredSpell = spellInfo; + spellTriggerInfo.triggeredByAura = auraSpellInfo; + spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount(); + m_hitTriggerSpells.push_back(spellTriggerInfo); + } } } } @@ -7321,6 +7312,16 @@ void Spell::CancelGlobalCooldown() m_caster->ToPlayer()->GetGlobalCooldownMgr().CancelGlobalCooldown(m_spellInfo); } +bool Spell::HasEffect(SpellEffectName effect) const +{ + for (SpellEffectInfo const* eff : GetEffects()) + { + if (eff->IsEffect(effect)) + return true; + } + return false; +} + namespace Trinity { diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index dc07449c41f..ee31326808f 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -192,7 +192,7 @@ class SpellCastTargets struct SpellValue { explicit SpellValue(SpellInfo const* proto); - int32 EffectBasePoints[MAX_SPELL_EFFECTS]; + std::vector<int32> EffectBasePoints; uint32 MaxAffectedTargets; float RadiusMod; uint8 AuraStackAmount; @@ -377,7 +377,7 @@ class Spell void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask); void SelectImplicitTrajTargets(SpellEffIndex effIndex); - void SelectEffectTypeImplicitTargets(uint8 effIndex); + void SelectEffectTypeImplicitTargets(uint32 effIndex); uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList* condList); template<class SEARCHER> void SearchTargets(SEARCHER& searcher, uint32 containerMask, Unit* referer, Position const* pos, float radius); @@ -394,7 +394,6 @@ class Spell void cast(bool skipCheck = false); void finish(bool ok = true); void TakePower(); - void TakeAmmo(); void TakeRunePower(bool didHit); void TakeReagents(); @@ -503,6 +502,18 @@ class Spell void CleanupTargetList(); void SetSpellValue(SpellValueMod mod, int32 value); + + SpellEffectInfoVector GetEffects() const { return difficultyEffects; } + SpellEffectInfo const* GetEffect(uint32 index) const + { + if (index >= difficultyEffects.size()) + return nullptr; + + return difficultyEffects[index]; + } + + bool HasEffect(SpellEffectName effect) const; + protected: bool HasGlobalCooldown() const; void TriggerGlobalCooldown(); @@ -591,7 +602,7 @@ class Spell uint64 timeDelay; SpellMissInfo missCondition:8; SpellMissInfo reflectResult:8; - uint8 effectMask:8; + uint32 effectMask:32; bool processed:1; bool alive:1; bool crit:1; @@ -599,13 +610,13 @@ class Spell int32 damage; }; std::list<TargetInfo> m_UniqueTargetInfo; - uint8 m_channelTargetEffectMask; // Mask req. alive targets + uint32 m_channelTargetEffectMask; // Mask req. alive targets struct GOTargetInfo { ObjectGuid targetGUID; uint64 timeDelay; - uint8 effectMask:8; + uint32 effectMask:32; bool processed:1; }; std::list<GOTargetInfo> m_UniqueGOTargetInfo; @@ -613,7 +624,7 @@ class Spell struct ItemTargetInfo { Item *item; - uint8 effectMask; + uint32 effectMask; }; std::list<ItemTargetInfo> m_UniqueItemInfo; @@ -638,7 +649,7 @@ class Spell void FinishTargetProcessing(); // spell execution log - void InitEffectExecuteData(uint8 effIndex); + void InitEffectExecuteData(uint32 effIndex); void CheckEffectExecuteData(); // Scripting system @@ -689,7 +700,7 @@ class Spell SpellInfo const* m_triggeredByAuraSpell; bool m_skipCheck; - uint8 m_auraScaleMask; + uint32 m_auraScaleMask; PathGenerator m_preGeneratedPath; ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]; @@ -704,6 +715,8 @@ class Spell Spell(Spell const& right) = delete; Spell& operator=(Spell const& right) = delete; + + SpellEffectInfoVector difficultyEffects; }; namespace Trinity diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 9c12abbe6e2..c1e588c7edf 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -359,7 +359,7 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) { // Consumption case 28865: - damage = (((InstanceMap*)m_caster->GetMap())->GetDifficulty() == REGULAR_DIFFICULTY ? 2750 : 4250); + damage = (((InstanceMap*)m_caster->GetMap())->GetDifficulty() == DIFFICULTY_NONE ? 2750 : 4250); break; // percent from health with min case 25599: // Thundercrash diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index cc88cc41e5a..3c4cf37b4e3 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -344,7 +344,7 @@ SpellEffectInfo::SpellEffectInfo(SpellEntry const* /*spellEntry*/, SpellInfo con SpellScalingEntry const* scaling = spellInfo->GetSpellScaling(); _spellInfo = spellInfo; - _effIndex = _effect ? _effect->EffectIndex : effIndex; + EffectIndex = _effect ? _effect->EffectIndex : effIndex; Effect = _effect ? _effect->Effect : 0; ApplyAuraName = _effect ? _effect->EffectAura : 0; ApplyAuraPeriod = _effect ? _effect->EffectAuraPeriod : 0; @@ -368,9 +368,9 @@ SpellEffectInfo::SpellEffectInfo(SpellEntry const* /*spellEntry*/, SpellInfo con SpellClassMask = _effect ? _effect->EffectSpellClassMask : flag128(); ImplicitTargetConditions = NULL; // TODO: 6.x these values are no longer in dbc - ScalingMultiplier = /*scaling ? scaling->Multiplier[_effIndex] :*/ 0.0f; - DeltaScalingMultiplier = /*scaling ? scaling->RandomMultiplier[_effIndex] :*/ 0.0f; - ComboScalingMultiplier = /*scaling ? scaling->OtherMultiplier[_effIndex] :*/ 0.0f; + ScalingMultiplier = /*scaling ? scaling->Multiplier[EffectIndex] :*/ 0.0f; + DeltaScalingMultiplier = /*scaling ? scaling->RandomMultiplier[EffectIndex] :*/ 0.0f; + ComboScalingMultiplier = /*scaling ? scaling->OtherMultiplier[EffectIndex] :*/ 0.0f; } bool SpellEffectInfo::IsEffect() const @@ -378,7 +378,7 @@ bool SpellEffectInfo::IsEffect() const return Effect != 0; } -bool SpellEffectInfo::IsEffect(SpellEffects effectName) const +bool SpellEffectInfo::IsEffect(SpellEffectName effectName) const { return Effect == uint32(effectName); } @@ -441,7 +441,7 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const if (caster) { int32 level = caster->getLevel(); - if (target && _spellInfo->IsPositiveEffect(_effIndex) && (Effect == SPELL_EFFECT_APPLY_AURA)) + if (target && _spellInfo->IsPositiveEffect(EffectIndex) && (Effect == SPELL_EFFECT_APPLY_AURA)) level = target->getLevel(); if (GtSpellScalingEntry const* gtScaling = sGtSpellScalingStore.LookupEntry((_spellInfo->ScalingClass != -1 ? _spellInfo->ScalingClass - 1 : MAX_CLASSES - 1) * 100 + level - 1)) @@ -508,7 +508,7 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const if (uint8 comboPoints = caster->m_movedPlayer->GetComboPoints()) value += comboDamage * comboPoints; - value = caster->ApplyEffectModifiers(_spellInfo, _effIndex, value); + value = caster->ApplyEffectModifiers(_spellInfo, EffectIndex, value); // amount multiplication based on caster's level /* REVIEW - MERGE <<<<<<< HEAD @@ -862,10 +862,12 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] = {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 182 SPELL_EFFECT_182 }; -SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntry const** effects) +SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectInfoMap effects) { Id = spellEntry->ID; + Effects = effects; + SpellName = spellEntry->Name_lang; //Rank = spellEntry->Rank; RuneCostID = spellEntry->RuneCostID; @@ -916,10 +918,6 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntry const** effe SpellIconID = _misc ? _misc->SpellIconID : 0; ActiveIconID = _misc ? _misc->ActiveIconID : 0; - // SpellDifficultyEntry - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - Effects[i] = SpellEffectInfo(spellEntry, this, i, effects[i]); - // SpellScalingEntry SpellScalingEntry const* _scaling = GetSpellScaling(); CastTimeMin = _scaling ? _scaling->CastTimeMin : 0; @@ -1040,27 +1038,35 @@ uint32 SpellInfo::GetCategory() const return CategoryEntry ? CategoryEntry->ID : 0; } -bool SpellInfo::HasEffect(SpellEffects effect) const +bool SpellInfo::HasEffect(uint32 difficulty, SpellEffectName effect) const { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (Effects[i].IsEffect(effect)) + SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty); + for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr) + { + if ((*itr)->IsEffect(effect)) return true; + } return false; } -bool SpellInfo::HasAura(AuraType aura) const +bool SpellInfo::HasAura(uint32 difficulty, AuraType aura) const { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (Effects[i].IsAura(aura)) + SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty); + for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr) + { + if ((*itr)->IsAura(aura)) return true; - return false; + } } -bool SpellInfo::HasAreaAuraEffect() const +bool SpellInfo::HasAreaAuraEffect(uint32 difficulty) const { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (Effects[i].IsAreaAuraEffect()) + SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty); + for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr) + { + if ((*itr)->IsAreaAuraEffect()) return true; + } return false; } @@ -1085,13 +1091,14 @@ bool SpellInfo::IsQuestTame() const return Effects[0].Effect == SPELL_EFFECT_THREAT && Effects[1].Effect == SPELL_EFFECT_APPLY_AURA && Effects[1].ApplyAuraName == SPELL_AURA_DUMMY; } -bool SpellInfo::IsProfessionOrRiding() const +bool SpellInfo::IsProfessionOrRiding(uint32 difficulty) const { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty); + for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr) { - if (Effects[i].Effect == SPELL_EFFECT_SKILL) + if ((*itr)->Effect == SPELL_EFFECT_SKILL) { - uint32 skill = Effects[i].MiscValue; + uint32 skill = (*itr)->MiscValue; if (IsProfessionOrRidingSkill(skill)) return true; @@ -1100,13 +1107,14 @@ bool SpellInfo::IsProfessionOrRiding() const return false; } -bool SpellInfo::IsProfession() const +bool SpellInfo::IsProfession(uint32 difficulty) const { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty); + for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr) { - if (Effects[i].Effect == SPELL_EFFECT_SKILL) + if ((*itr)->Effect == SPELL_EFFECT_SKILL) { - uint32 skill = Effects[i].MiscValue; + uint32 skill = (*itr)->MiscValue; if (IsProfessionSkill(skill)) return true; @@ -1115,13 +1123,14 @@ bool SpellInfo::IsProfession() const return false; } -bool SpellInfo::IsPrimaryProfession() const +bool SpellInfo::IsPrimaryProfession(uint32 difficulty) const { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty); + for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr) { - if (Effects[i].Effect == SPELL_EFFECT_SKILL) + if ((*itr)->Effect == SPELL_EFFECT_SKILL) { - uint32 skill = Effects[i].MiscValue; + uint32 skill = (*itr)->MiscValue; if (IsPrimaryProfessionSkill(skill)) return true; @@ -1130,9 +1139,9 @@ bool SpellInfo::IsPrimaryProfession() const return false; } -bool SpellInfo::IsPrimaryProfessionFirstRank() const +bool SpellInfo::IsPrimaryProfessionFirstRank(uint32 difficulty) const { - return IsPrimaryProfession() && GetRank() == 1; + return IsPrimaryProfession(difficulty) && GetRank() == 1; } bool SpellInfo::IsAbilityLearnedWithProfession() const @@ -1163,20 +1172,26 @@ bool SpellInfo::IsAbilityOfSkillType(uint32 skillType) const return false; } -bool SpellInfo::IsAffectingArea() const +bool SpellInfo::IsAffectingArea(uint32 difficulty) const { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (Effects[i].IsEffect() && (Effects[i].IsTargetingArea() || Effects[i].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || Effects[i].IsAreaAuraEffect())) + SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty); + for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr) + { + if ((*itr)->IsEffect() && ((*itr)->IsTargetingArea() || (*itr)->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || (*itr)->IsAreaAuraEffect())) return true; + } return false; } // checks if spell targets are selected from area, doesn't include spell effects in check (like area wide auras for example) -bool SpellInfo::IsTargetingArea() const +bool SpellInfo::IsTargetingArea(uint32 difficulty) const { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (Effects[i].IsEffect() && Effects[i].IsTargetingArea()) + SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty); + for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr) + { + if ((*itr)->IsEffect() && (*itr)->IsTargetingArea()) return true; + } return false; } @@ -2931,16 +2946,46 @@ SpellCooldownsEntry const* SpellInfo::GetSpellCooldowns() const void SpellInfo::_UnloadImplicitTargetConditionLists() { // find the same instances of ConditionList and delete them. - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + for (uint32 d = 0; d < DIFFICULTY_MAX; ++d) { - ConditionList* cur = Effects[i].ImplicitTargetConditions; - if (!cur) - continue; - for (uint8 j = i; j < MAX_SPELL_EFFECTS; ++j) + for (uint32 i = 0; i < Effects.size(); ++i) { - if (Effects[j].ImplicitTargetConditions == cur) - Effects[j].ImplicitTargetConditions = NULL; + if (SpellEffectInfo const* effect = GetEffect(d, i)) + { + ConditionList* cur = effect->ImplicitTargetConditions; + if (!cur) + continue; + for (uint8 j = i; j < Effects.size(); ++j) + { + if (SpellEffectInfo const* eff = GetEffect(d, j)) + { + if (eff->ImplicitTargetConditions == cur) + const_cast<SpellEffectInfo*>(eff)->ImplicitTargetConditions = NULL; + } + } + delete cur; + } } - delete cur; } } + +SpellEffectInfoVector SpellInfo::GetEffectsForDifficulty(uint32 difficulty) const +{ + // downscale difficulty if original was not found + for (; difficulty >= DIFFICULTY_NONE; --difficulty) + { + SpellEffectInfoMap::const_iterator itr = Effects.find(difficulty); + if (itr != Effects.end()) + return itr->second; + } + return SpellEffectInfoVector(); +} + +SpellEffectInfo const* SpellInfo::GetEffect(uint32 difficulty, uint32 index) const +{ + SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty); + if (index >= effects.size()) + return nullptr; + + return effects[index]; +}
\ No newline at end of file diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 1fad30dd23b..36c8523dbf2 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -230,8 +230,8 @@ private: class SpellEffectInfo { SpellInfo const* _spellInfo; - uint8 _effIndex; public: + uint32 EffectIndex; uint32 Effect; uint32 ApplyAuraName; uint32 ApplyAuraPeriod; @@ -259,14 +259,14 @@ public: float DeltaScalingMultiplier; float ComboScalingMultiplier; - SpellEffectInfo() : _spellInfo(NULL), _effIndex(0), Effect(0), ApplyAuraName(0), ApplyAuraPeriod(0), DieSides(0), + SpellEffectInfo() : _spellInfo(NULL), EffectIndex(0), Effect(0), ApplyAuraName(0), ApplyAuraPeriod(0), DieSides(0), RealPointsPerLevel(0), BasePoints(0), PointsPerResource(0), Amplitude(0), ChainAmplitude(0), BonusCoefficient(0), MiscValue(0), MiscValueB(0), Mechanic(MECHANIC_NONE), RadiusEntry(NULL), ChainTargets(0), ItemType(0), TriggerSpell(0), ImplicitTargetConditions(NULL) {} SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex, SpellEffectEntry const* effect); bool IsEffect() const; - bool IsEffect(SpellEffects effectName) const; + bool IsEffect(SpellEffectName effectName) const; bool IsAura() const; bool IsAura(AuraType aura) const; bool IsTargetingArea() const; @@ -299,6 +299,9 @@ private: static StaticData _data[TOTAL_SPELL_EFFECTS]; }; +typedef std::vector<SpellEffectInfo const*> SpellEffectInfoVector; +typedef std::unordered_map<uint32, SpellEffectInfoVector> SpellEffectInfoMap; + class SpellInfo { public: @@ -403,7 +406,6 @@ public: int32 ScalingClass; float CoefBase; int32 CoefLevelBase; - SpellEffectInfo Effects[MAX_SPELL_EFFECTS]; uint32 ExplicitTargetMask; SpellChainNode const* ChainEntry; @@ -425,26 +427,26 @@ public: SpellTotemsEntry const* GetSpellTotems() const; SpellMiscEntry const* GetSpellMisc() const; - SpellInfo(SpellEntry const* spellEntry, SpellEffectEntry const** effects); + SpellInfo(SpellEntry const* spellEntry, SpellEffectInfoMap effects); ~SpellInfo(); uint32 GetCategory() const; - bool HasEffect(SpellEffects effect) const; - bool HasAura(AuraType aura) const; - bool HasAreaAuraEffect() const; + bool HasEffect(uint32 difficulty, SpellEffectName effect) const; + bool HasAura(uint32 difficulty, AuraType aura) const; + bool HasAreaAuraEffect(uint32 difficulty) const; bool IsExplicitDiscovery() const; bool IsLootCrafting() const; bool IsQuestTame() const; - bool IsProfessionOrRiding() const; - bool IsProfession() const; - bool IsPrimaryProfession() const; - bool IsPrimaryProfessionFirstRank() const; + bool IsProfessionOrRiding(uint32 difficulty = DIFFICULTY_NONE) const; + bool IsProfession(uint32 difficulty = DIFFICULTY_NONE) const; + bool IsPrimaryProfession(uint32 difficulty = DIFFICULTY_NONE) const; + bool IsPrimaryProfessionFirstRank(uint32 difficulty = DIFFICULTY_NONE) const; bool IsAbilityLearnedWithProfession() const; bool IsAbilityOfSkillType(uint32 skillType) const; - bool IsAffectingArea() const; - bool IsTargetingArea() const; + bool IsAffectingArea(uint32 difficulty) const; + bool IsTargetingArea(uint32 difficulty) const; bool NeedsExplicitUnitTarget() const; bool NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) const; @@ -529,6 +531,11 @@ public: // unloading helpers void _UnloadImplicitTargetConditionLists(); + + SpellEffectInfoVector GetEffectsForDifficulty(uint32 difficulty) const; + SpellEffectInfo const* GetEffect(uint32 difficulty, uint32 index) const; + + SpellEffectInfoMap Effects; }; #endif // _SPELLINFO_H diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 3b7ab7abe30..e0f43097abd 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -453,81 +453,6 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg return true; } -uint32 SpellMgr::GetSpellDifficultyId(uint32 spellId) const -{ - SpellDifficultySearcherMap::const_iterator i = mSpellDifficultySearcherMap.find(spellId); - return i == mSpellDifficultySearcherMap.end() ? 0 : i->second; -} - -void SpellMgr::SetSpellDifficultyId(uint32 spellId, uint32 id) -{ - if (uint32 i = GetSpellDifficultyId(spellId)) - TC_LOG_ERROR("spells", "SpellMgr::SetSpellDifficultyId: Spell %u has already spellDifficultyId %u. Will override with spellDifficultyId %u.", spellId, i, id); - mSpellDifficultySearcherMap[spellId] = id; -} - -// TODO: 6.x adapt to new spell diff system -uint32 SpellMgr::GetSpellIdForDifficulty(uint32 spellId, Unit const* caster) const -{ - /*if (!GetSpellInfo(spellId)) - return spellId; - - if (!caster || !caster->GetMap() || !caster->GetMap()->IsDungeon()) - return spellId; - - uint32 mode = uint32(caster->GetMap()->GetSpawnMode()); - if (mode >= MAX_DIFFICULTY) - { - TC_LOG_ERROR("spells", "SpellMgr::GetSpellIdForDifficulty: Incorrect Difficulty for spell %u.", spellId); - return spellId; //return source spell - } - - uint32 difficultyId = GetSpellDifficultyId(spellId); - if (!difficultyId) - return spellId; //return source spell, it has only REGULAR_DIFFICULTY - - SpellDifficultyEntry const* difficultyEntry = sSpellDifficultyStore.LookupEntry(difficultyId); - if (!difficultyEntry) - { - TC_LOG_ERROR("spells", "SpellMgr::GetSpellIdForDifficulty: SpellDifficultyEntry not found for spell %u. This should never happen.", spellId); - return spellId; //return source spell - } - - if (difficultyEntry->SpellID[mode] <= 0 && mode > DUNGEON_DIFFICULTY_HEROIC) - { - TC_LOG_DEBUG("spells", "SpellMgr::GetSpellIdForDifficulty: spell %u mode %u spell is NULL, using mode %u", spellId, mode, mode - 2); - mode -= 2; - } - - if (difficultyEntry->SpellID[mode] <= 0) - { - TC_LOG_ERROR("sql.sql", "SpellMgr::GetSpellIdForDifficulty: spell %u mode %u spell is 0. Check spelldifficulty_dbc!", spellId, mode); - return spellId; - } - - TC_LOG_DEBUG("spells", "SpellMgr::GetSpellIdForDifficulty: spellid for spell %u in mode %u is %d", spellId, mode, difficultyEntry->SpellID[mode]); - return uint32(difficultyEntry->SpellID[mode]); - */ - return 0; -} - -SpellInfo const* SpellMgr::GetSpellForDifficultyFromSpell(SpellInfo const* spell, Unit const* caster) const -{ - if (!spell) - return NULL; - - uint32 newSpellId = GetSpellIdForDifficulty(spell->Id, caster); - SpellInfo const* newSpell = GetSpellInfo(newSpellId); - if (!newSpell) - { - TC_LOG_DEBUG("spells", "SpellMgr::GetSpellForDifficultyFromSpell: spell %u not found. Check spelldifficulty_dbc!", newSpellId); - return spell; - } - - TC_LOG_DEBUG("spells", "SpellMgr::GetSpellForDifficultyFromSpell: Spell id for instance mode is %u (original %u)", newSpell->Id, spell->Id); - return newSpell; -} - SpellChainNode const* SpellMgr::GetSpellChainNode(uint32 spell_id) const { SpellChainMap::const_iterator itr = mSpellChains.find(spell_id); @@ -2791,18 +2716,7 @@ void SpellMgr::LoadSpellAreas() TC_LOG_INFO("server.loading", ">> Loaded %u spell area requirements in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } -// Temporary structure to hold spell effect entries for faster loading -struct SpellEffectArray -{ - SpellEffectArray() - { - effects[0] = NULL; - effects[1] = NULL; - effects[2] = NULL; - } - - SpellEffectEntry const* effects[MAX_SPELL_EFFECTS]; -}; +typedef std::vector<SpellEffectEntry const*> SpellEffectVector; void SpellMgr::LoadSpellInfoStore() { @@ -2811,7 +2725,7 @@ void SpellMgr::LoadSpellInfoStore() UnloadSpellInfoStore(); mSpellInfoMap.resize(sSpellStore.GetNumRows(), NULL); - std::map<uint32, SpellEffectArray> effectsBySpell; + std::map<uint32, SpellEffectInfoMap> effectsBySpell; for (uint32 i = 0; i < sSpellEffectStore.GetNumRows(); ++i) { @@ -2819,17 +2733,17 @@ void SpellMgr::LoadSpellInfoStore() if (!effect) continue; - // TODO: 6.x implement dynamic spell effect storage and remove MAX_SPELL_EFFECTS - // This is a temporary fix to avoid crash when loading spells if (effect->EffectIndex >= MAX_SPELL_EFFECTS) + { + TC_LOG_ERROR("server.loading", "Spell %u has invalid EffectIndex %u, max is %u, skipped", i, effect->EffectIndex, uint32(MAX_SPELL_EFFECTS)); continue; - - effectsBySpell[effect->SpellID].effects[effect->EffectIndex] = effect; + } + effectsBySpell[effect->SpellID][effect->DifficultyID][effect->EffectIndex] = effect; } for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i) if (SpellEntry const* spellEntry = sSpellStore.LookupEntry(i)) - mSpellInfoMap[i] = new SpellInfo(spellEntry, effectsBySpell[i].effects); + mSpellInfoMap[i] = new SpellInfo(spellEntry, effectsBySpell[i]); TC_LOG_INFO("server.loading", ">> Loaded SpellInfo store in %u ms", GetMSTimeDiffToNow(oldMSTime)); } diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 053935a53cb..5be0cfda84c 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -617,12 +617,6 @@ class SpellMgr // Spell correctness for client using static bool IsSpellValid(SpellInfo const* spellInfo, Player* player = NULL, bool msg = true); - // Spell difficulty - uint32 GetSpellDifficultyId(uint32 spellId) const; - void SetSpellDifficultyId(uint32 spellId, uint32 id); - uint32 GetSpellIdForDifficulty(uint32 spellId, Unit const* caster) const; - SpellInfo const* GetSpellForDifficultyFromSpell(SpellInfo const* spell, Unit const* caster) const; - // Spell Ranks table SpellChainNode const* GetSpellChainNode(uint32 spell_id) const; uint32 GetFirstSpellInChain(uint32 spell_id) const; diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp index 189cc842d9b..919f8b43ce3 100644 --- a/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp +++ b/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp @@ -106,7 +106,7 @@ public: //THIS GOB IS A TRAP - What shall i do? =( //Cast it spell? Copyed Heigan method floorEruption->SendCustomAnim(floorEruption->GetGoAnimProgress()); - floorEruption->CastSpell(NULL, Difficulty(instance->GetSpawnMode()) == RAID_DIFFICULTY_10MAN_NORMAL ? 17731 : 69294); //pFloorEruption->GetGOInfo()->trap.spellId + floorEruption->CastSpell(NULL, Difficulty(instance->GetSpawnMode()) == DIFFICULTY_10_N ? 17731 : 69294); //pFloorEruption->GetGOInfo()->trap.spellId //Get all immediatly nearby floors std::list<GameObject*> nearFloorList; diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp index c826b8fc9ef..f1d029e53e2 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp @@ -151,7 +151,7 @@ class boss_baltharus_the_warborn : public CreatureScript void DamageTaken(Unit* /*attacker*/, uint32& damage) override { - if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + if (GetDifficulty() == DIFFICULTY_10_N) { if (me->HealthBelowPctDamaged(50, damage) && _cloneCount == 1) DoAction(ACTION_CLONE); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp index 2b541e4b972..b79e093a3e0 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp @@ -384,7 +384,7 @@ class boss_toc_champion_controller : public CreatureScript vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_WARRIOR : NPC_ALLIANCE_WARRIOR); uint8 healersSubtracted = 2; - if (_instance->instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL || _instance->instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC) + if (_instance->instance->GetSpawnMode() == DIFFICULTY_25_N || _instance->instance->GetSpawnMode() == DIFFICULTY_25_HC) healersSubtracted = 1; for (uint8 i = 0; i < healersSubtracted; ++i) { @@ -421,7 +421,7 @@ class boss_toc_champion_controller : public CreatureScript vHealersEntries.erase(vHealersEntries.begin() + pos); } - if (_instance->instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_NORMAL || _instance->instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC) + if (_instance->instance->GetSpawnMode() == DIFFICULTY_10_N || _instance->instance->GetSpawnMode() == DIFFICULTY_10_HC) for (uint8 i = 0; i < 4; ++i) vOtherEntries.erase(vOtherEntries.begin() + urand(0, vOtherEntries.size() - 1)); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp index cb7e58cfe16..91da9ebd9be 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp @@ -274,7 +274,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript { EventStage = 6000; uint32 tributeChest = 0; - if (instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC) + if (instance->GetSpawnMode() == DIFFICULTY_10_HC) { if (TrialCounter >= 50) tributeChest = GO_TRIBUTE_CHEST_10H_99; @@ -291,7 +291,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript } } } - else if (instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC) + else if (instance->GetSpawnMode() == DIFFICULTY_25_HC) { if (TrialCounter >= 50) tributeChest = GO_TRIBUTE_CHEST_25H_99; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index 3e78865c924..834b0aeb5e1 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -288,7 +288,7 @@ class boss_lady_deathwhisper : public CreatureScript events.ScheduleEvent(EVENT_P1_SUMMON_WAVE, 5000, 0, PHASE_ONE); events.ScheduleEvent(EVENT_P1_SHADOW_BOLT, urand(5500, 6000), 0, PHASE_ONE); events.ScheduleEvent(EVENT_P1_EMPOWER_CULTIST, urand(20000, 30000), 0, PHASE_ONE); - if (GetDifficulty() != RAID_DIFFICULTY_10MAN_NORMAL) + if (GetDifficulty() != DIFFICULTY_10_N) events.ScheduleEvent(EVENT_DOMINATE_MIND_H, 27000); Talk(SAY_AGGRO); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 8f5ca0b4322..64e9864c666 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -395,14 +395,14 @@ class boss_professor_putricide : public CreatureScript { SpellInfo const* spell = sSpellMgr->GetSpellInfo(SPELL_CREATE_CONCOCTION); DoCast(me, SPELL_CREATE_CONCOCTION); - events.ScheduleEvent(EVENT_PHASE_TRANSITION, sSpellMgr->GetSpellForDifficultyFromSpell(spell, me)->CalcCastTime() + 100); + events.ScheduleEvent(EVENT_PHASE_TRANSITION, spell->CalcCastTime() + 100); break; } case PHASE_COMBAT_3: { SpellInfo const* spell = sSpellMgr->GetSpellInfo(SPELL_GUZZLE_POTIONS); DoCast(me, SPELL_GUZZLE_POTIONS); - events.ScheduleEvent(EVENT_PHASE_TRANSITION, sSpellMgr->GetSpellForDifficultyFromSpell(spell, me)->CalcCastTime() + 100); + events.ScheduleEvent(EVENT_PHASE_TRANSITION, spell->CalcCastTime() + 100); break; } default: @@ -1260,7 +1260,6 @@ class spell_putricide_mutated_plague : public SpellScriptLoader uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; SpellInfo const* spell = sSpellMgr->GetSpellInfo(triggerSpell); - spell = sSpellMgr->GetSpellForDifficultyFromSpell(spell, caster); int32 damage = spell->Effects[EFFECT_0].CalcValue(caster); float multiplier = 2.0f; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp index 35402771494..f6ef74d721e 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp @@ -80,7 +80,7 @@ public: Initialize(); - if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + if (GetDifficulty() == DIFFICULTY_25_N) { Position pos; @@ -121,7 +121,7 @@ public: events.ScheduleEvent(EVENT_LOCUST, 90000); events.ScheduleEvent(EVENT_BERSERK, 600000); - if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + if (GetDifficulty() == DIFFICULTY_10_N) events.ScheduleEvent(EVENT_SPAWN_GUARDIAN_NORMAL, urand(15000, 20000)); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp index dcb004cc3a0..568df379f15 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp @@ -192,7 +192,7 @@ class npc_faerlina_add : public CreatureScript void Reset() override { - if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) { + if (GetDifficulty() == DIFFICULTY_10_N) { me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_BIND, true); me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM, true); } @@ -200,7 +200,7 @@ class npc_faerlina_add : public CreatureScript void JustDied(Unit* /*killer*/) override { - if (_instance && GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + if (_instance && GetDifficulty() == DIFFICULTY_10_N) if (Creature* faerlina = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FAERLINA))) DoCast(faerlina, SPELL_WIDOWS_EMBRACE); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp index 39381f38d67..a70d354b966 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp @@ -259,7 +259,7 @@ class boss_gothik : public CreatureScript void DoGothikSummon(uint32 entry) { - if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + if (GetDifficulty() == DIFFICULTY_25_N) { switch (entry) { @@ -421,9 +421,9 @@ class boss_gothik : public CreatureScript case EVENT_SUMMON: if (waves[waveCount].entry) { - if ((waves[waveCount].mode == 2) && (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)) + if ((waves[waveCount].mode == 2) && (GetDifficulty() == DIFFICULTY_25_N)) DoGothikSummon(waves[waveCount].entry); - else if ((waves[waveCount].mode == 0) && (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)) + else if ((waves[waveCount].mode == 0) && (GetDifficulty() == DIFFICULTY_10_N)) DoGothikSummon(waves[waveCount].entry); else if (waves[waveCount].mode == 1) DoGothikSummon(waves[waveCount].entry); @@ -443,9 +443,9 @@ class boss_gothik : public CreatureScript if (waves[waveCount].mode == 1) events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time); - else if ((waves[waveCount].mode == 2) && (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)) + else if ((waves[waveCount].mode == 2) && (GetDifficulty() == DIFFICULTY_25_N)) events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time); - else if ((waves[waveCount].mode == 0) && (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)) + else if ((waves[waveCount].mode == 0) && (GetDifficulty() == DIFFICULTY_10_N)) events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time); else events.ScheduleEvent(EVENT_SUMMON, 0); diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp index 87466b6bf41..102d1f0fb5b 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp @@ -415,7 +415,7 @@ public: events.ScheduleEvent(EVENT_DETONATE, urand(30000, 40000)); events.ScheduleEvent(EVENT_FISSURE, urand(10000, 30000)); events.ScheduleEvent(EVENT_BLAST, urand(60000, 120000)); - if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + if (GetDifficulty() == DIFFICULTY_25_N) events.ScheduleEvent(EVENT_CHAIN, urand(30000, 60000)); Phase = 2; break; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp index 0e07ff027f6..be4c8583377 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp @@ -106,7 +106,7 @@ public: events.ScheduleEvent(EVENT_BALCONY, 110000); events.ScheduleEvent(EVENT_CURSE, 10000 + rand32() % 15000); events.ScheduleEvent(EVENT_WARRIOR, 30000); - if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + if (GetDifficulty() == DIFFICULTY_25_N) events.ScheduleEvent(EVENT_BLINK, urand(20000, 40000)); } } diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp index b66bc07f2c8..bada44b20a0 100644 --- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp +++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp @@ -387,11 +387,11 @@ class instance_naxxramas : public InstanceMapScript switch (criteria_id) { case 7600: // Criteria for achievement 2176: And They Would All Go Down Together 15sec of each other 10-man - if (Difficulty(instance->GetSpawnMode()) == RAID_DIFFICULTY_10MAN_NORMAL && (maxHorsemenDiedTime - minHorsemenDiedTime) < 15) + if (Difficulty(instance->GetSpawnMode()) == DIFFICULTY_10_N && (maxHorsemenDiedTime - minHorsemenDiedTime) < 15) return true; return false; case 7601: // Criteria for achievement 2177: And They Would All Go Down Together 15sec of each other 25-man - if (Difficulty(instance->GetSpawnMode()) == RAID_DIFFICULTY_25MAN_NORMAL && (maxHorsemenDiedTime - minHorsemenDiedTime) < 15) + if (Difficulty(instance->GetSpawnMode()) == DIFFICULTY_25_N && (maxHorsemenDiedTime - minHorsemenDiedTime) < 15) return true; return false; // Difficulty checks are done on DB. diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 813e51ad23c..f1a4152d0e3 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -406,7 +406,7 @@ public: { _summonDeaths = value; - if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + if (GetDifficulty() == DIFFICULTY_10_N) { if (_summonDeaths == MAX_SUMMONS_PHASE_TWO_10MAN) { @@ -414,7 +414,7 @@ public: DoAction(ACTION_HANDLE_P_THREE_INTRO); } } - else if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + else if (GetDifficulty() == DIFFICULTY_25_N) { if (_summonDeaths == MAX_SUMMONS_PHASE_TWO_25MAN) { @@ -862,7 +862,7 @@ public: if (_arcaneReinforcements) { - for (uint8 rangeDisks = 0; rangeDisks < (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL ? 4 : 5); rangeDisks++) + for (uint8 rangeDisks = 0; rangeDisks < (GetDifficulty() == DIFFICULTY_10_N ? 4 : 5); rangeDisks++) { Creature* casterDiskSummon = me->SummonCreature(NPC_HOVER_DISK_CASTER, RangeHoverDisksSpawnPositions[rangeDisks]); @@ -878,7 +878,7 @@ public: _arcaneReinforcements = false; - if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + if (GetDifficulty() == DIFFICULTY_25_N) events.ScheduleEvent(EVENT_DELAYED_REINFORCEMENTS, 1*IN_MILLISECONDS, 0, PHASE_TWO); } break; @@ -958,7 +958,7 @@ public: SetPhase(PHASE_THREE, true); break; case EVENT_SURGE_OF_POWER_P_THREE: - if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + if (GetDifficulty() == DIFFICULTY_10_N) { if (Unit* tempSurgeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, false, SPELL_RIDE_RED_DRAGON_BUDDY)) { @@ -975,7 +975,7 @@ public: } } } - else if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + else if (GetDifficulty() == DIFFICULTY_25_N) { memset(_surgeTargetGUID, 0, sizeof(_surgeTargetGUID)); DoCastAOE(SPELL_SURGE_OF_POWER_WARNING_SELECTOR_25, true); @@ -1007,10 +1007,10 @@ public: Talk(SAY_DEATH); if (Creature* alexstraszaGiftBoxBunny = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GIFT_BOX_BUNNY_GUID))) { - if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + if (GetDifficulty() == DIFFICULTY_10_N) alexstraszaGiftBoxBunny->SummonGameObject(GO_HEART_OF_MAGIC_10, HeartOfMagicSpawnPos.GetPositionX(), HeartOfMagicSpawnPos.GetPositionY(), HeartOfMagicSpawnPos.GetPositionZ(), HeartOfMagicSpawnPos.GetOrientation(), 0.0f, 0.0f, 0.0f, 1.0f, 0); - else if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + else if (GetDifficulty() == DIFFICULTY_25_N) alexstraszaGiftBoxBunny->SummonGameObject(GO_HEART_OF_MAGIC_25, HeartOfMagicSpawnPos.GetPositionX(), HeartOfMagicSpawnPos.GetPositionY(), HeartOfMagicSpawnPos.GetPositionZ(), HeartOfMagicSpawnPos.GetOrientation(), 0.0f, 0.0f, 0.0f, 1.0f, 0); } @@ -1786,10 +1786,10 @@ class spell_malygos_arcane_storm : public SpellScriptLoader { // Resize list only to objects that are vehicles. IsCreatureVehicleCheck check(true); - Trinity::Containers::RandomResizeList(targets, check, (malygos->GetMap()->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL ? 4 : 10)); + Trinity::Containers::RandomResizeList(targets, check, (malygos->GetMap()->GetDifficulty() == DIFFICULTY_10_N ? 4 : 10)); } else - Trinity::Containers::RandomResizeList(targets, (malygos->GetMap()->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL ? 4 : 10)); + Trinity::Containers::RandomResizeList(targets, (malygos->GetMap()->GetDifficulty() == DIFFICULTY_10_N ? 4 : 10)); } void HandleVisual(SpellEffIndex /*effIndex*/) @@ -2475,9 +2475,9 @@ class spell_alexstrasza_gift_beam_visual : public SpellScriptLoader { if (Creature* target = GetTarget()->ToCreature()) { - if (target->GetMap()->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + if (target->GetMap()->GetDifficulty() == DIFFICULTY_10_N) _alexstraszaGift = target->SummonGameObject(GO_ALEXSTRASZA_S_GIFT_10, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0); - else if (target->GetMap()->GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + else if (target->GetMap()->GetDifficulty() == DIFFICULTY_25_N) _alexstraszaGift = target->SummonGameObject(GO_ALEXSTRASZA_S_GIFT_25, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0); } } diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp index 90decfbf46e..b689df3c977 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp @@ -92,14 +92,14 @@ public: platformGUID = go->GetGUID(); break; case GO_FOCUSING_IRIS_10: - if (instance->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + if (instance->GetDifficulty() == DIFFICULTY_10_N) { irisGUID = go->GetGUID(); focusingIrisPosition = go->GetPosition(); } break; case GO_FOCUSING_IRIS_25: - if (instance->GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + if (instance->GetDifficulty() == DIFFICULTY_25_N) { irisGUID = go->GetGUID(); focusingIrisPosition = go->GetPosition(); @@ -110,11 +110,11 @@ public: exitPortalPosition = go->GetPosition(); break; case GO_HEART_OF_MAGIC_10: - if (instance->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + if (instance->GetDifficulty() == DIFFICULTY_10_N) heartOfMagicGUID = go->GetGUID(); break; case GO_HEART_OF_MAGIC_25: - if (instance->GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + if (instance->GetDifficulty() == DIFFICULTY_25_N) heartOfMagicGUID = go->GetGUID(); break; } @@ -240,7 +240,7 @@ public: PowerSparksHandling(); break; case DATA_RESPAWN_IRIS: - SpawnGameObject(instance->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL ? GO_FOCUSING_IRIS_10 : GO_FOCUSING_IRIS_25, focusingIrisPosition); + SpawnGameObject(instance->GetDifficulty() == DIFFICULTY_10_N ? GO_FOCUSING_IRIS_10 : GO_FOCUSING_IRIS_25, focusingIrisPosition); break; } } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp index 419052baddc..56a1fe96497 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp @@ -454,10 +454,10 @@ class spell_ulduar_cancel_stone_grip : public SpellScriptLoader switch (target->GetMap()->GetDifficulty()) { - case RAID_DIFFICULTY_10MAN_NORMAL: + case DIFFICULTY_10_N: target->RemoveAura(GetSpellInfo()->Effects[EFFECT_0].CalcValue()); break; - case RAID_DIFFICULTY_25MAN_NORMAL: + case DIFFICULTY_25_N: target->RemoveAura(GetSpellInfo()->Effects[EFFECT_1].CalcValue()); break; default: @@ -534,7 +534,7 @@ class spell_ulduar_stone_grip_absorb : public SpellScriptLoader if (!GetOwner()->ToCreature()) return; - uint32 rubbleStalkerEntry = (GetOwner()->GetMap()->GetDifficulty() == DUNGEON_DIFFICULTY_NORMAL ? 33809 : 33942); + uint32 rubbleStalkerEntry = (GetOwner()->GetMap()->GetDifficulty() == DIFFICULTY_NORMAL ? 33809 : 33942); Creature* rubbleStalker = GetOwner()->FindNearestCreature(rubbleStalkerEntry, 200.0f, true); if (rubbleStalker) rubbleStalker->CastSpell(rubbleStalker, SPELL_STONE_GRIP_CANCEL, true); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp index cad6b045120..b029e26fbf1 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp @@ -237,7 +237,7 @@ class boss_razorscale_controller : public CreatureScript { case ACTION_HARPOON_BUILD: events.ScheduleEvent(EVENT_BUILD_HARPOON_1, 50000); - if (me->GetMap()->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL) + if (me->GetMap()->GetSpawnMode() == DIFFICULTY_25_N) events.ScheduleEvent(EVENT_BUILD_HARPOON_3, 90000); break; case ACTION_PLACE_BROKEN_HARPOON: |