diff --git a/sql/434/01_characters.sql b/sql/434/01_characters.sql new file mode 100644 index 000000000..0e4398249 --- /dev/null +++ b/sql/434/01_characters.sql @@ -0,0 +1,10 @@ +alter table `characters`.`characters` + add column `power8` int(10) UNSIGNED DEFAULT '0' NOT NULL after `power7`, + add column `power9` int(10) UNSIGNED DEFAULT '0' NOT NULL after `power8`, + add column `power10` int(10) UNSIGNED DEFAULT '0' NOT NULL after `power9`, + drop column `ammoId`; + +alter table `characters`.`character_stats` + add column `maxpower8` int(10) UNSIGNED DEFAULT '0' NOT NULL after `maxpower7`, + add column `maxpower9` int(10) UNSIGNED DEFAULT '0' NOT NULL after `maxpower8`, + add column `maxpower10` int(10) UNSIGNED DEFAULT '0' NOT NULL after `maxpower9`; diff --git a/sql/characters.sql b/sql/characters.sql index 1eb474198..91ae531fa 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -251,11 +251,13 @@ CREATE TABLE `characters` ( `power5` int(10) UNSIGNED NOT NULL default '0', `power6` int(10) UNSIGNED NOT NULL default '0', `power7` int(10) UNSIGNED NOT NULL default '0', + `power8` int(10) UNSIGNED NOT NULL default '0', + `power9` int(10) UNSIGNED NOT NULL default '0', + `power10` int(10) UNSIGNED NOT NULL default '0', `specCount` tinyint(3) UNSIGNED NOT NULL default '1', `activeSpec` tinyint(3) UNSIGNED NOT NULL default '0', `exploredZones` longtext, `equipmentCache` longtext, - `ammoId` int(10) UNSIGNED NOT NULL default '0', `knownTitles` longtext, `actionBars` tinyint(3) UNSIGNED NOT NULL default '0', `deleteInfos_Account` int(11) UNSIGNED default NULL, @@ -901,6 +903,9 @@ CREATE TABLE `character_stats` ( `maxpower5` int(10) UNSIGNED NOT NULL default '0', `maxpower6` int(10) UNSIGNED NOT NULL default '0', `maxpower7` int(10) UNSIGNED NOT NULL default '0', + `maxpower8` int(10) UNSIGNED NOT NULL default '0', + `maxpower9` int(10) UNSIGNED NOT NULL default '0', + `maxpower10` int(10) UNSIGNED NOT NULL default '0', `strength` int(10) UNSIGNED NOT NULL default '0', `agility` int(10) UNSIGNED NOT NULL default '0', `stamina` int(10) UNSIGNED NOT NULL default '0', diff --git a/sql/updates/11436_01_characters_character_queststatus.sql b/sql/updates/11436_01_characters_character_queststatus.sql index 2c07f03f3..b93fa42d8 100644 --- a/sql/updates/11436_01_characters_character_queststatus.sql +++ b/sql/updates/11436_01_characters_character_queststatus.sql @@ -3,4 +3,3 @@ ALTER TABLE character_db_version CHANGE COLUMN required_11391_01_characters_auct ALTER TABLE character_queststatus ADD COLUMN itemcount5 int(11) unsigned NOT NULL default '0' AFTER itemcount4, ADD COLUMN itemcount6 int(11) unsigned NOT NULL default '0' AFTER itemcount5; - diff --git a/sql/updates/11597_01_mangos_spell_proc_event.sql b/sql/updates/11597_01_mangos_spell_proc_event.sql index 5ccf9dbee..f4b692291 100644 --- a/sql/updates/11597_01_mangos_spell_proc_event.sql +++ b/sql/updates/11597_01_mangos_spell_proc_event.sql @@ -3,4 +3,3 @@ ALTER TABLE db_version CHANGE COLUMN required_11595_09_mangos_spell_elixir requi DELETE FROM `spell_proc_event` WHERE entry IN (17767); INSERT INTO `spell_proc_event` VALUE (17767, 0x00, 5, 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00080000, 0x00040000, 0.000000, 0.000000, 0); - diff --git a/sql/updates/11598_01_mangos_spell_proc_event.sql b/sql/updates/11598_01_mangos_spell_proc_event.sql index c0ef4ca82..81f0b9793 100644 --- a/sql/updates/11598_01_mangos_spell_proc_event.sql +++ b/sql/updates/11598_01_mangos_spell_proc_event.sql @@ -3,4 +3,3 @@ ALTER TABLE db_version CHANGE COLUMN required_11597_01_mangos_spell_proc_event r DELETE FROM `spell_proc_event` WHERE entry IN (64914); INSERT INTO `spell_proc_event` VALUE (64914, 0x00, 8, 0x00000000, 0x00000000, 0x00000000, 0x00080000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); - diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index cb2cecf80..339e66050 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -172,7 +172,8 @@ bool AchievementCriteriaRequirement::IsValid(AchievementCriteriaEntry const* cri criteria->ID, criteria->requiredType, (requirementType == ACHIEVEMENT_CRITERIA_REQUIRE_S_AURA ? "ACHIEVEMENT_CRITERIA_REQUIRE_S_AURA" : "ACHIEVEMENT_CRITERIA_REQUIRE_T_AURA"), requirementType, aura.effect_idx); return false; } - if (!spellEntry->EffectApplyAuraName[aura.effect_idx]) + SpellEffectEntry const* spellEffect = spellEntry->GetSpellEffect(SpellEffectIndex(aura.effect_idx)); + if (spellEffect && !spellEffect->EffectApplyAuraName) { sLog.outErrorDb("Table `achievement_criteria_requirement` (Entry: %u Type: %u) for requirement %s (%u) have non-aura spell effect (ID: %u Effect: %u), ignore.", criteria->ID, criteria->requiredType, (requirementType == ACHIEVEMENT_CRITERIA_REQUIRE_S_AURA ? "ACHIEVEMENT_CRITERIA_REQUIRE_S_AURA" : "ACHIEVEMENT_CRITERIA_REQUIRE_T_AURA"), requirementType, aura.spell_id, aura.effect_idx); diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index f5da834b6..1a455d126 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -70,10 +70,10 @@ bool LoginQueryHolder::Initialize() // NOTE: all fields in `characters` must be read to prevent lost character data at next save in case wrong DB structure. // !!! NOTE: including unused `zone`,`online` res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags," - "position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost," - "resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty," - "arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk," - "health, power1, power2, power3, power4, power5, power6, power7, specCount, activeSpec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars FROM characters WHERE guid = '%u'", m_guid.GetCounter()); + "position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost," + "resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty," + "arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk," + "health, power1, power2, power3, power4, power5, power6, power7, power8, power9, power10, specCount, activeSpec, exploredZones, equipmentCache, knownTitles, actionBars FROM characters WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT groupId FROM group_member WHERE memberGuid ='%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,item_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,periodictime0,periodictime1,periodictime2,maxduration,remaintime,effIndexMask FROM character_aura WHERE guid = '%u'", m_guid.GetCounter()); diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 4b199645d..0e41ffe7d 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -1965,7 +1965,7 @@ bool ChatHandler::isValidChatMessage(const char* message) } else if (linkedItem) { - char* const* suffix = itemSuffix ? itemSuffix->nameSuffix : (itemProperty ? itemProperty->nameSuffix : NULL); + DBCString suffix = itemSuffix?itemSuffix->nameSuffix:(itemProperty?itemProperty->nameSuffix:NULL); std::string expectedName = std::string(linkedItem->Name1); if (suffix) diff --git a/src/game/Corpse.cpp b/src/game/Corpse.cpp index a09087e95..ed87495f8 100644 --- a/src/game/Corpse.cpp +++ b/src/game/Corpse.cpp @@ -224,7 +224,7 @@ bool Corpse::LoadFromDB(uint32 lowguid, Field* fields) SetUInt32Value(CORPSE_FIELD_BYTES_1, ((0x00) | (race << 8) | (gender << 16) | (skin << 24))); SetUInt32Value(CORPSE_FIELD_BYTES_2, ((face) | (hairstyle << 8) | (haircolor << 16) | (facialhair << 24))); - SetUInt32Value(CORPSE_FIELD_GUILD, guildId); + //SetUInt32Value(CORPSE_FIELD_GUILD, guildId); uint32 flags = CORPSE_FLAG_UNK2; if (playerFlags & PLAYER_FLAGS_HIDE_HELM) diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 5a6b52524..0b4f2adfc 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1587,7 +1587,7 @@ bool Creature::IsImmuneToSpell(SpellEntry const* spellInfo) if (!spellInfo) return false; - if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1))) + if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->GetMechanic() - 1))) return true; return Unit::IsImmuneToSpell(spellInfo); @@ -1595,20 +1595,22 @@ bool Creature::IsImmuneToSpell(SpellEntry const* spellInfo) bool Creature::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index) const { - if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->EffectMechanic[index] - 1))) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(index); + + if (spellEffect && GetCreatureInfo()->MechanicImmuneMask & (1 << (spellEffect->EffectMechanic - 1))) return true; // Taunt immunity special flag check if (GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NOT_TAUNTABLE) { // Taunt aura apply check - if (spellInfo->Effect[index] == SPELL_EFFECT_APPLY_AURA) + if (spellEffect && spellEffect->Effect == SPELL_EFFECT_APPLY_AURA) { - if (spellInfo->EffectApplyAuraName[index] == SPELL_AURA_MOD_TAUNT) + if (spellEffect && spellEffect->EffectApplyAuraName == SPELL_AURA_MOD_TAUNT) return true; } // Spell effect taunt check - else if (spellInfo->Effect[index] == SPELL_EFFECT_ATTACK_ME) + else if (spellEffect && spellEffect->Effect == SPELL_EFFECT_ATTACK_ME) return true; } @@ -1634,20 +1636,25 @@ SpellEntry const* Creature::ReachWithSpellAttack(Unit* pVictim) bool bcontinue = true; for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if ((spellInfo->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE) || - (spellInfo->Effect[j] == SPELL_EFFECT_INSTAKILL) || - (spellInfo->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) || - (spellInfo->Effect[j] == SPELL_EFFECT_HEALTH_LEECH) - ) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(j)); + if(!spellEffect) + continue; + if( (spellEffect->Effect == SPELL_EFFECT_SCHOOL_DAMAGE ) || + (spellEffect->Effect == SPELL_EFFECT_INSTAKILL) || + (spellEffect->Effect == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) || + (spellEffect->Effect == SPELL_EFFECT_HEALTH_LEECH ) + ) { bcontinue = false; break; } } - if (bcontinue) continue; - - if (spellInfo->manaCost > GetPower(POWER_MANA)) + if (bcontinue) continue; + + if(spellInfo->GetManaCost() > GetPower(POWER_MANA)) + continue; + SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex); float range = GetSpellMaxRange(srange); float minrange = GetSpellMinRange(srange); @@ -1658,12 +1665,16 @@ SpellEntry const* Creature::ReachWithSpellAttack(Unit* pVictim) // continue; if (dist > range || dist < minrange) continue; - if (spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)) + + + if(spellInfo->GetPreventionType() == SPELL_PREVENTION_TYPE_SILENCE && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)) continue; - if (spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)) + if(spellInfo->GetPreventionType() == SPELL_PREVENTION_TYPE_PACIFY && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)) continue; + return spellInfo; } + return NULL; } @@ -1686,7 +1697,8 @@ SpellEntry const* Creature::ReachWithSpellCure(Unit* pVictim) bool bcontinue = true; for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if ((spellInfo->Effect[j] == SPELL_EFFECT_HEAL)) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(j)); + if( spellEffect && (spellEffect->Effect == SPELL_EFFECT_HEAL) ) { bcontinue = false; break; @@ -1695,8 +1707,9 @@ SpellEntry const* Creature::ReachWithSpellCure(Unit* pVictim) if (bcontinue) continue; - if (spellInfo->manaCost > GetPower(POWER_MANA)) + if(spellInfo->GetManaCost() > GetPower(POWER_MANA)) continue; + SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex); float range = GetSpellMaxRange(srange); float minrange = GetSpellMinRange(srange); @@ -1707,12 +1720,15 @@ SpellEntry const* Creature::ReachWithSpellCure(Unit* pVictim) // continue; if (dist > range || dist < minrange) continue; - if (spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)) + + if(spellInfo->GetPreventionType() == SPELL_PREVENTION_TYPE_SILENCE && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)) continue; - if (spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)) + if(spellInfo->GetPreventionType() == SPELL_PREVENTION_TYPE_PACIFY && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)) continue; + return spellInfo; } + return NULL; } @@ -2147,8 +2163,8 @@ void Creature::AddCreatureSpellCooldown(uint32 spellid) if (cooldown) _AddCreatureSpellCooldown(spellid, time(NULL) + cooldown / IN_MILLISECONDS); - if (spellInfo->Category) - _AddCreatureCategoryCooldown(spellInfo->Category, time(NULL)); + if(uint32 category = spellInfo->GetCategory()) + _AddCreatureCategoryCooldown(category, time(NULL)); } bool Creature::HasCategoryCooldown(uint32 spell_id) const @@ -2157,8 +2173,8 @@ bool Creature::HasCategoryCooldown(uint32 spell_id) const if (!spellInfo) return false; - CreatureSpellCooldowns::const_iterator itr = m_CreatureCategoryCooldowns.find(spellInfo->Category); - return (itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->CategoryRecoveryTime / IN_MILLISECONDS)) > time(NULL)); + CreatureSpellCooldowns::const_iterator itr = m_CreatureCategoryCooldowns.find(spellInfo->GetCategory()); + return (itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->GetCategoryRecoveryTime() / IN_MILLISECONDS)) > time(NULL)); } bool Creature::HasSpellCooldown(uint32 spell_id) const diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 76ba919f8..dc75638f9 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -40,10 +40,10 @@ CanCastResult CreatureAI::CanCastSpell(Unit* pTarget, const SpellEntry* pSpell, if (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL)) return CAST_FAIL_STATE; - if (pSpell->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)) + if (pSpell->GetPreventionType() == SPELL_PREVENTION_TYPE_SILENCE && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)) return CAST_FAIL_STATE; - if (pSpell->PreventionType == SPELL_PREVENTION_TYPE_PACIFY && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)) + if (pSpell->GetPreventionType() == SPELL_PREVENTION_TYPE_PACIFY && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)) return CAST_FAIL_STATE; // Check for power (also done by Spell::CheckCast()) diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h index 08d4e7e5d..224086a20 100644 --- a/src/game/DBCEnums.h +++ b/src/game/DBCEnums.h @@ -22,7 +22,7 @@ // Client expected level limitation, like as used in DBC item max levels for "until max player level" // use as default max player level, must be fit max level for used client // also see MAX_LEVEL and STRONG_MAX_LEVEL define -#define DEFAULT_MAX_LEVEL 80 +#define DEFAULT_MAX_LEVEL 85 // client supported max level for player/pets/etc. Avoid overflow or client stability affected. // also see GT_MAX_LEVEL define @@ -68,7 +68,13 @@ enum AchievementFlags ACHIEVEMENT_FLAG_BAR = 0x00000080, // ACHIEVEMENT_FLAG_HAS_PROGRESS_BAR Show as progress bar (value / max vale) depend from other flag (by def use last criteria value) ACHIEVEMENT_FLAG_REALM_FIRST_REACH = 0x00000100, // ACHIEVEMENT_FLAG_SERVER_FIRST ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, // - + ACHIEVEMENT_FLAG_UNK3 = 0x00000400, // ACHIEVEMENT_FLAG_HIDE_NAME_IN_TIE + ACHIEVEMENT_FLAG_REALM_FIRST_GUILD = 0x00000800, // first guild on realm done something + ACHIEVEMENT_FLAG_UNK4 = 0x00001000, // as guild group? + ACHIEVEMENT_FLAG_UNK5 = 0x00002000, // as guild group? + ACHIEVEMENT_FLAG_GUILD = 0x00004000, // + ACHIEVEMENT_FLAG_SHOW_GUILD_MEMBERS = 0x00008000, // + ACHIEVEMENT_FLAG_SHOW_CRITERIA_MEMBERS = 0x00010000, // }; enum AchievementCriteriaCondition @@ -106,9 +112,9 @@ enum AchievementCriteriaTypes ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11, ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13, ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND = 15, - ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP = 16, - ACHIEVEMENT_CRITERIA_TYPE_DEATH = 17, + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND= 15, + ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP= 16, + ACHIEVEMENT_CRITERIA_TYPE_DEATH= 17, ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON = 18, ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19, ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20, @@ -117,7 +123,7 @@ enum AchievementCriteriaTypes ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26, ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28, - ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL = 29, + ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL= 29, ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE = 30, ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31, ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32, @@ -132,18 +138,18 @@ enum AchievementCriteriaTypes ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING = 39, ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41, - ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM = 42, + ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM= 42, ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43, - ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK = 44, - ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT = 45, - ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION = 46, - ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION = 47, + ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK= 44, + ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT= 45, + ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION= 46, + ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION= 47, // noted: rewarded as soon as the player payed, not at taking place at the seat - ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP = 48, + ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP= 48, ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49, // TODO: itemlevel is mentioned in text but not present in dbc ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT = 50, - ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT = 51, + ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT= 51, ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52, ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53, ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54, @@ -160,20 +166,20 @@ enum AchievementCriteriaTypes ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL = 66, ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67, ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68, - ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2 = 69, - ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL = 70, + ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2= 69, + ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL= 70, ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72, // TODO: title id is not mentioned in dbc ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN = 74, - ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS = 75, + ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS= 75, ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76, ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL = 77, // TODO: creature type (demon, undead etc.) is not stored in dbc ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE = 78, - ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS = 80, - ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION = 82, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID = 83, - ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS = 84, + ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS= 80, + ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION= 82, + ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID= 83, + ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS= 84, ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD = 85, ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED = 86, ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION = 87, @@ -200,7 +206,7 @@ enum AchievementCriteriaTypes ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109, // TODO: target entry is missing ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110, - ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE = 112, + ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE= 112, ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113, ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS = 114, ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS = 115, @@ -209,10 +215,47 @@ enum AchievementCriteriaTypes // 121 unused // 122 unused // 123 unused - // 0..123 => 124 criteria types total + // 124 Spend X gold on guildmember repairs. + // 125 Reach guild level X + // 126 Craft X items + // 127 Catch X fish from fishing pools. + // 128 Purchase the X guild bank tab. + // 129 Earn X guild achievement points. + // 130 Win X rated battlegrounds. + // 131 unused + // 132 Earn a battleground rating of X. + // 133 Create and purchase a guild crest. + // 134 Complete quests + // 135 Honorable kills + // 0..135 => 136 criteria types total }; -#define ACHIEVEMENT_CRITERIA_TYPE_TOTAL 124 +#define ACHIEVEMENT_CRITERIA_TYPE_TOTAL 136 + +enum AchievementCriteriaMoreReqType +{ + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_ITEM_LEVEL = 3, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_CREATURE_ID = 4, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_SPELL = 8, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_SPELL_ON_TARGET = 10, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_ITEM_QUALITY_EQUIPPED = 14, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_ITEM_QUALITY_LOOTED = 15, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_AREA_ID = 17, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_AREA_ID2 = 18, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_RAID_DIFFICULTY = 20, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_ARENA_TYPE = 24, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_PLAYER_CLASS = 26, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_PLAYER_RACE = 27, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_PLAYER_CLASS2 = 28, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_CREATURE_TYPE = 30, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_MAP_ID = 32, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_TIMED_QUEST = 35, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_PLAYER_TITLE = 38, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_PLAYER_LEVEL = 39, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_PLAYER_LEVEL2 = 40, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_AREA_ID3 = 41, + ACHIEVEMENT_CRITERIA_MORE_REQ_TYPE_GUILD_REP = 62, +}; enum AreaFlags { @@ -253,7 +296,7 @@ enum Difficulty DUNGEON_DIFFICULTY_NORMAL = 0, DUNGEON_DIFFICULTY_HEROIC = 1, - // DUNGEON_DIFFICULTY_EPIC = 2, // not used, but exists + //DUNGEON_DIFFICULTY_EPIC = 2, // not used, but exists RAID_DIFFICULTY_10MAN_NORMAL = 0, RAID_DIFFICULTY_25MAN_NORMAL = 1, @@ -296,7 +339,7 @@ enum FactionMasks FACTION_MASK_ALLIANCE = 2, // player or creature from alliance team FACTION_MASK_HORDE = 4, // player or creature from horde team FACTION_MASK_MONSTER = 8 // aggressive creature from monster team - // if none flags set then non-aggressive creature + // if none flags set then non-aggressive creature }; enum MapTypes // Lua_IsInInstance @@ -334,8 +377,8 @@ enum ItemEnchantmentType enum ItemLimitCategoryMode { - ITEM_LIMIT_CATEGORY_MODE_HAVE = 0, // limit applied to amount items in inventory/bank - ITEM_LIMIT_CATEGORY_MODE_EQUIP = 1, // limit applied to amount equipped items (including used gems) + ITEM_LIMIT_CATEGORY_MODE_HAVE = 0, // limit applied to amount items in inventory/bank + ITEM_LIMIT_CATEGORY_MODE_EQUIP = 1, // limit applied to amount equipped items (including used gems) }; // some used in code cases @@ -355,55 +398,52 @@ enum TotemCategoryType TOTEM_CATEGORY_TYPE_SPANNER = 24 }; -// SummonProperties.dbc, col 0 == Id (m_id) -// SummonProperties.dbc, col 1 == Group (m_control) +// SummonProperties.dbc, col 1 enum SummonPropGroup { - SUMMON_PROP_GROUP_WILD = 0, - SUMMON_PROP_GROUP_FRIENDLY = 1, - SUMMON_PROP_GROUP_PETS = 2, - SUMMON_PROP_GROUP_CONTROLLABLE = 3, - SUMMON_PROP_GROUP_VEHICLE = 4 + SUMMON_PROP_GROUP_WILD = 0, + SUMMON_PROP_GROUP_FRIENDLY = 1, + SUMMON_PROP_GROUP_PETS = 2, + SUMMON_PROP_GROUP_CONTROLLABLE = 3, + SUMMON_PROP_GROUP_VEHICLE = 4 }; -// SummonProperties.dbc, col 2 == FactionId (m_faction) -// SummonProperties.dbc, col 3 == Title (m_title) +// SummonProperties.dbc, col 3 enum UnitNameSummonTitle { - UNITNAME_SUMMON_TITLE_NONE = 0, // no default title, different summons, 1330 spells in 3.0.3 - UNITNAME_SUMMON_TITLE_PET = 1, // 's Pet, generic summons, 49 spells in 3.0.3 - UNITNAME_SUMMON_TITLE_GUARDIAN = 2, // 's Guardian, summon guardian, 393 spells in 3.0.3 - UNITNAME_SUMMON_TITLE_MINION = 3, // 's Minion, summon army, 5 spells in 3.0.3 - UNITNAME_SUMMON_TITLE_TOTEM = 4, // 's Totem, summon totem, 169 spells in 3.0.3 - UNITNAME_SUMMON_TITLE_COMPANION = 5, // 's Companion, critter/minipet, 195 spells in 3.0.3 - UNITNAME_SUMMON_TITLE_RUNEBLADE = 6, // 's Runeblade, summon DRW/Ghoul, 2 spells in 3.0.3" - UNITNAME_SUMMON_TITLE_CONSTRUCT = 7, // 's Construct, summon bot/bomb, 4 spells in 3.0.3 - UNITNAME_SUMMON_TITLE_OPPONENT = 8, // 's Opponent, something todo with DK prequest line, 2 spells in 3.0.3 - UNITNAME_SUMMON_TITLE_VEHICLE = 9, // 's Vehicle, summon different vehicles, 14 spells in 3.0.3 - UNITNAME_SUMMON_TITLE_MOUNT = 10, // 's Mount, summon drake (vehicle), 3 spells - UNITNAME_SUMMON_TITLE_LIGHTWELL = 11, // 's Lightwell, summon lightwell, 6 spells in 3.0.3 - UNITNAME_SUMMON_TITLE_BUTLER = 12 // 's Butler, summon repair bot, 1 spells in 3.2.2a + UNITNAME_SUMMON_TITLE_NONE = 0, // no default title, different summons, 1330 spells in 3.0.3 + UNITNAME_SUMMON_TITLE_PET = 1, // 's Pet, generic summons, 49 spells in 3.0.3 + UNITNAME_SUMMON_TITLE_GUARDIAN = 2, // 's Guardian, summon guardian, 393 spells in 3.0.3 + UNITNAME_SUMMON_TITLE_MINION = 3, // 's Minion, summon army, 5 spells in 3.0.3 + UNITNAME_SUMMON_TITLE_TOTEM = 4, // 's Totem, summon totem, 169 spells in 3.0.3 + UNITNAME_SUMMON_TITLE_COMPANION = 5, // 's Companion, critter/minipet, 195 spells in 3.0.3 + UNITNAME_SUMMON_TITLE_RUNEBLADE = 6, // 's Runeblade, summon DRW/Ghoul, 2 spells in 3.0.3" + UNITNAME_SUMMON_TITLE_CONSTRUCT = 7, // 's Construct, summon bot/bomb, 4 spells in 3.0.3 + UNITNAME_SUMMON_TITLE_OPPONENT = 8, // 's Opponent, something todo with DK prequest line, 2 spells in 3.0.3 + UNITNAME_SUMMON_TITLE_VEHICLE = 9, // 's Vehicle, summon different vehicles, 14 spells in 3.0.3 + UNITNAME_SUMMON_TITLE_MOUNT = 10, // 's Mount, summon drake (vehicle), 3 spells + UNITNAME_SUMMON_TITLE_LIGHTWELL = 11, // 's Lightwell, summon lightwell, 6 spells in 3.0.3 + UNITNAME_SUMMON_TITLE_BUTLER = 12 // 's Butler, summon repair bot, 1 spells in 3.2.2a }; -// SummonProperties.dbc, col 4 == Slot (m_slot) -// SummonProperties.dbc, col 5 == Flags (m_flags) +// SummonProperties.dbc, col 5 enum SummonPropFlags { - SUMMON_PROP_FLAG_NONE = 0x0000, // 1342 spells in 3.0.3 - SUMMON_PROP_FLAG_UNK1 = 0x0001, // 75 spells in 3.0.3, something unfriendly - SUMMON_PROP_FLAG_UNK2 = 0x0002, // 616 spells in 3.0.3, something friendly - SUMMON_PROP_FLAG_UNK3 = 0x0004, // 22 spells in 3.0.3, no idea... - SUMMON_PROP_FLAG_UNK4 = 0x0008, // 49 spells in 3.0.3, some mounts - SUMMON_PROP_FLAG_UNK5 = 0x0010, // 25 spells in 3.0.3, quest related? - SUMMON_PROP_FLAG_CANT_BE_DISMISSED = 0x0020, // 0 spells in 3.0.3, unused - SUMMON_PROP_FLAG_UNK7 = 0x0040, // 12 spells in 3.0.3, no idea - SUMMON_PROP_FLAG_UNK8 = 0x0080, // 4 spells in 3.0.3, no idea - SUMMON_PROP_FLAG_UNK9 = 0x0100, // 51 spells in 3.0.3, no idea, many quest related - SUMMON_PROP_FLAG_UNK10 = 0x0200, // 51 spells in 3.0.3, something defensive - SUMMON_PROP_FLAG_UNK11 = 0x0400, // 3 spells, requires something near? - SUMMON_PROP_FLAG_UNK12 = 0x0800, // 30 spells in 3.0.3, no idea - SUMMON_PROP_FLAG_UNK13 = 0x1000, // 8 spells in 3.0.3, siege vehicle - SUMMON_PROP_FLAG_UNK14 = 0x2000, // 2 spells in 3.0.3, escort? + SUMMON_PROP_FLAG_NONE = 0x0000, // 1342 spells in 3.0.3 + SUMMON_PROP_FLAG_UNK1 = 0x0001, // 75 spells in 3.0.3, something unfriendly + SUMMON_PROP_FLAG_UNK2 = 0x0002, // 616 spells in 3.0.3, something friendly + SUMMON_PROP_FLAG_UNK3 = 0x0004, // 22 spells in 3.0.3, no idea... + SUMMON_PROP_FLAG_UNK4 = 0x0008, // 49 spells in 3.0.3, some mounts + SUMMON_PROP_FLAG_UNK5 = 0x0010, // 25 spells in 3.0.3, quest related? + SUMMON_PROP_FLAG_CANT_BE_DISMISSED = 0x0020, // 0 spells in 3.0.3, unused + SUMMON_PROP_FLAG_UNK7 = 0x0040, // 12 spells in 3.0.3, no idea + SUMMON_PROP_FLAG_UNK8 = 0x0080, // 4 spells in 3.0.3, no idea + SUMMON_PROP_FLAG_UNK9 = 0x0100, // 51 spells in 3.0.3, no idea, many quest related + SUMMON_PROP_FLAG_UNK10 = 0x0200, // 51 spells in 3.0.3, something defensive + SUMMON_PROP_FLAG_UNK11 = 0x0400, // 3 spells, requires something near? + SUMMON_PROP_FLAG_UNK12 = 0x0800, // 30 spells in 3.0.3, no idea + SUMMON_PROP_FLAG_UNK13 = 0x1000, // 8 spells in 3.0.3, siege vehicle + SUMMON_PROP_FLAG_UNK14 = 0x2000, // 2 spells in 3.0.3, escort? }; // SpellEntry::Targets diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp index 79d29c995..4f578b45a 100644 --- a/src/game/DBCStores.cpp +++ b/src/game/DBCStores.cpp @@ -27,8 +27,8 @@ #include -typedef std::map AreaFlagByAreaID; -typedef std::map AreaFlagByMapID; +typedef std::map AreaFlagByAreaID; +typedef std::map AreaFlagByMapID; struct WMOAreaTableTripple { @@ -38,7 +38,7 @@ struct WMOAreaTableTripple bool operator <(const WMOAreaTableTripple& b) const { - return memcmp(this, &b, sizeof(WMOAreaTableTripple)) < 0; + return memcmp(this, &b, sizeof(WMOAreaTableTripple))<0; } // ordered by entropy; that way memcmp will have a minimal medium runtime @@ -47,7 +47,7 @@ struct WMOAreaTableTripple int32 adtId; }; -typedef std::map WMOAreaInfoByTripple; +typedef std::map WMOAreaInfoByTripple; DBCStorage sAreaStore(AreaTableEntryfmt); DBCStorage sAreaGroupStore(AreaGroupEntryfmt); @@ -59,6 +59,7 @@ static WMOAreaInfoByTripple sWMOAreaInfoByTripple; DBCStorage sAchievementStore(Achievementfmt); DBCStorage sAchievementCriteriaStore(AchievementCriteriafmt); DBCStorage sAreaTriggerStore(AreaTriggerEntryfmt); +DBCStorage sArmorLocationStore(ArmorLocationfmt); DBCStorage sAuctionHouseStore(AuctionHouseEntryfmt); DBCStorage sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt); DBCStorage sBattlemasterListStore(BattlemasterListEntryfmt); @@ -67,6 +68,7 @@ DBCStorage sCharStartOutfitStore(CharStartOutfitEntryfmt) DBCStorage sCharTitlesStore(CharTitlesEntryfmt); DBCStorage sChatChannelsStore(ChatChannelsEntryfmt); DBCStorage sChrClassesStore(ChrClassesEntryfmt); +DBCStorage sChrPowerTypesStore(ChrClassesXPowerTypesfmt); DBCStorage sChrRacesStore(ChrRacesEntryfmt); DBCStorage sCinematicSequencesStore(CinematicSequencesEntryfmt); DBCStorage sCreatureDisplayInfoStore(CreatureDisplayInfofmt); @@ -74,7 +76,7 @@ DBCStorage sCreatureDisplayInfoExtraStore(Creatu DBCStorage sCreatureFamilyStore(CreatureFamilyfmt); DBCStorage sCreatureSpellDataStore(CreatureSpellDatafmt); DBCStorage sCreatureTypeStore(CreatureTypefmt); -DBCStorage sCurrencyTypesStore(CurrencyTypesfmt); +//DBCStorage sCurrencyTypesStore(CurrencyTypesfmt); DBCStorage sDungeonEncounterStore(DungeonEncounterfmt); DBCStorage sDurabilityQualityStore(DurabilityQualityfmt); @@ -83,7 +85,7 @@ DBCStorage sDurabilityCostsStore(DurabilityCostsfmt); DBCStorage sEmotesStore(EmotesEntryfmt); DBCStorage sEmotesTextStore(EmotesTextEntryfmt); -typedef std::map FactionTeamMap; +typedef std::map FactionTeamMap; static FactionTeamMap sFactionTeamMap; DBCStorage sFactionStore(FactionEntryfmt); DBCStorage sFactionTemplateStore(FactionTemplateEntryfmt); @@ -100,19 +102,28 @@ DBCStorage sGtChanceToMeleeCritStore(GtChanceToMe DBCStorage sGtChanceToSpellCritBaseStore(GtChanceToSpellCritBasefmt); DBCStorage sGtChanceToSpellCritStore(GtChanceToSpellCritfmt); DBCStorage sGtOCTClassCombatRatingScalarStore(GtOCTClassCombatRatingScalarfmt); -DBCStorage sGtOCTRegenHPStore(GtOCTRegenHPfmt); -// DBCStorage sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently -DBCStorage sGtRegenHPPerSptStore(GtRegenHPPerSptfmt); +//DBCStorage sGtOCTRegenHPStore(GtOCTRegenHPfmt); +//DBCStorage sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently +//DBCStorage sGtRegenHPPerSptStore(GtRegenHPPerSptfmt); DBCStorage sGtRegenMPPerSptStore(GtRegenMPPerSptfmt); DBCStorage sHolidaysStore(Holidaysfmt); -DBCStorage sItemStore(Itemfmt); +DBCStorage sItemArmorQualityStore(ItemArmorQualityfmt); +DBCStorage sItemArmorShieldStore(ItemArmorShieldfmt); +DBCStorage sItemArmorTotalStore(ItemArmorTotalfmt); DBCStorage sItemBagFamilyStore(ItemBagFamilyfmt); DBCStorage sItemClassStore(ItemClassfmt); -// DBCStorage sItemCondExtCostsStore(ItemCondExtCostsEntryfmt); -// DBCStorage sItemDisplayInfoStore(ItemDisplayTemplateEntryfmt); -- not used currently -DBCStorage sItemExtendedCostStore(ItemExtendedCostEntryfmt); +//DBCStorage sItemCondExtCostsStore(ItemCondExtCostsEntryfmt); +DBCStorage sItemDamageAmmoStore(ItemDamagefmt); +DBCStorage sItemDamageOneHandStore(ItemDamagefmt); +DBCStorage sItemDamageOneHandCasterStore(ItemDamagefmt); +DBCStorage sItemDamageRangedStore(ItemDamagefmt); +DBCStorage sItemDamageThrownStore(ItemDamagefmt); +DBCStorage sItemDamageTwoHandStore(ItemDamagefmt); +DBCStorage sItemDamageTwoHandCasterStore(ItemDamagefmt); +DBCStorage sItemDamageWandStore(ItemDamagefmt); +//DBCStorage sItemDisplayInfoStore(ItemDisplayTemplateEntryfmt); -- not used currently DBCStorage sItemLimitCategoryStore(ItemLimitCategoryEntryfmt); DBCStorage sItemRandomPropertiesStore(ItemRandomPropertiesfmt); DBCStorage sItemRandomSuffixStore(ItemRandomSuffixfmt); @@ -134,6 +145,7 @@ DBCStorage sQuestFactionRewardStore(QuestFactionReward DBCStorage sQuestSortStore(QuestSortEntryfmt); DBCStorage sQuestXPLevelStore(QuestXPLevelfmt); +DBCStorage sPhaseStore(Phasefmt); DBCStorage sPvPDifficultyStore(PvPDifficultyfmt); DBCStorage sRandomPropertiesPointsStore(RandomPropertiesPointsfmt); @@ -152,6 +164,25 @@ DBCStorage sSpellStore(SpellEntryfmt); SpellCategoryStore sSpellCategoryStore; PetFamilySpellsStore sPetFamilySpellsStore; +DBCStorage sSpellAuraOptionsStore(SpellAuraOptionsEntryfmt); +DBCStorage sSpellAuraRestrictionsStore(SpellAuraRestrictionsEntryfmt); +DBCStorage sSpellCastingRequirementsStore(SpellCastingRequirementsEntryfmt); +DBCStorage sSpellCategoriesStore(SpellCategoriesEntryfmt); +DBCStorage sSpellClassOptionsStore(SpellClassOptionsEntryfmt); +DBCStorage sSpellCooldownsStore(SpellCooldownsEntryfmt); +DBCStorage sSpellEffectStore(SpellEffectEntryfmt); +DBCStorage sSpellEquippedItemsStore(SpellEquippedItemsEntryfmt); +DBCStorage sSpellInterruptsStore(SpellInterruptsEntryfmt); +DBCStorage sSpellLevelsStore(SpellLevelsEntryfmt); +DBCStorage sSpellPowerStore(SpellPowerEntryfmt); +DBCStorage sSpellReagentsStore(SpellReagentsEntryfmt); +DBCStorage sSpellScalingStore(SpellScalingEntryfmt); +DBCStorage sSpellShapeshiftStore(SpellShapeshiftEntryfmt); +DBCStorage sSpellTargetRestrictionsStore(SpellTargetRestrictionsEntryfmt); +DBCStorage sSpellTotemsStore(SpellTotemsEntryfmt); + +SpellEffectMap sSpellEffectMap; + DBCStorage sSpellCastTimesStore(SpellCastTimefmt); DBCStorage sSpellDifficultyStore(SpellDifficultyfmt); DBCStorage sSpellDurationStore(SpellDurationfmt); @@ -160,7 +191,7 @@ DBCStorage sSpellRadiusStore(SpellRadiusfmt); DBCStorage sSpellRangeStore(SpellRangefmt); DBCStorage sSpellRuneCostStore(SpellRuneCostfmt); DBCStorage sSpellShapeshiftFormStore(SpellShapeshiftFormfmt); -DBCStorage sStableSlotPricesStore(StableSlotPricesfmt); +//DBCStorage sStableSlotPricesStore(StableSlotPricesfmt); DBCStorage sSummonPropertiesStore(SummonPropertiesfmt); DBCStorage sTalentStore(TalentEntryfmt); TalentSpellPosMap sTalentSpellPosMap; @@ -181,7 +212,6 @@ DBCStorage sTaxiPathStore(TaxiPathEntryfmt); TaxiPathNodesByPath sTaxiPathNodesByPath; static DBCStorage sTaxiPathNodeStore(TaxiPathNodeEntryfmt); -DBCStorage sTeamContributionPoints(TeamContributionPointsfmt); DBCStorage sTotemCategoryStore(TotemCategoryEntryfmt); DBCStorage sVehicleStore(VehicleEntryfmt); DBCStorage sVehicleSeatStore(VehicleSeatEntryfmt); @@ -195,8 +225,8 @@ typedef std::list StoreProblemList; bool IsAcceptableClientBuild(uint32 build) { int accepted_versions[] = EXPECTED_MANGOSD_CLIENT_BUILD; - for (int i = 0; accepted_versions[i]; ++i) - if (int(build) == accepted_versions[i]) + for(int i = 0; accepted_versions[i]; ++i) + if(int(build) == accepted_versions[i]) return true; return false; @@ -206,7 +236,7 @@ std::string AcceptableClientBuildsListStr() { std::ostringstream data; int accepted_versions[] = EXPECTED_MANGOSD_CLIENT_BUILD; - for (int i = 0; accepted_versions[i]; ++i) + for(int i = 0; accepted_versions[i]; ++i) data << accepted_versions[i] << " "; return data.str(); } @@ -215,10 +245,10 @@ static bool ReadDBCBuildFileText(const std::string& dbc_path, char const* locale { std::string filename = dbc_path + "component.wow-" + localeName + ".txt"; - if (FILE* file = fopen(filename.c_str(), "rb")) + if(FILE* file = fopen(filename.c_str(),"rb")) { char buf[100]; - fread(buf, 1, 100 - 1, file); + fread(buf,1,100-1,file); fclose(file); text = &buf[0]; @@ -228,15 +258,15 @@ static bool ReadDBCBuildFileText(const std::string& dbc_path, char const* locale return false; } -static uint32 ReadDBCBuild(const std::string& dbc_path, LocaleNameStr const* localeNameStr = NULL) +static uint32 ReadDBCBuild(const std::string& dbc_path, LocaleNameStr const*&localeNameStr) { std::string text; if (!localeNameStr) { - for (LocaleNameStr const* itr = &fullLocaleNameList[0]; itr->name; ++itr) + for(LocaleNameStr const* itr = &fullLocaleNameList[0]; itr->name; ++itr) { - if (ReadDBCBuildFileText(dbc_path, itr->name, text)) + if (ReadDBCBuildFileText(dbc_path,itr->name,text)) { localeNameStr = itr; break; @@ -244,18 +274,18 @@ static uint32 ReadDBCBuild(const std::string& dbc_path, LocaleNameStr const* loc } } else - ReadDBCBuildFileText(dbc_path, localeNameStr->name, text); + ReadDBCBuildFileText(dbc_path,localeNameStr->name,text); if (text.empty()) return 0; size_t pos = text.find("version=\""); size_t pos1 = pos + strlen("version=\""); - size_t pos2 = text.find("\"", pos1); + size_t pos2 = text.find("\"",pos1); if (pos == text.npos || pos2 == text.npos || pos1 >= pos2) return 0; - std::string build_str = text.substr(pos1, pos2 - pos1); + std::string build_str = text.substr(pos1,pos2-pos1); int build = atoi(build_str.c_str()); if (build <= 0) @@ -264,9 +294,9 @@ static uint32 ReadDBCBuild(const std::string& dbc_path, LocaleNameStr const* loc return build; } -static bool LoadDBC_assert_print(uint32 fsize, uint32 rsize, const std::string& filename) +static bool LoadDBC_assert_print(uint32 fsize,uint32 rsize, const std::string& filename) { - sLog.outError("Size of '%s' setted by format string (%u) not equal size of C++ structure (%u).", filename.c_str(), fsize, rsize); + sLog.outError("Size of '%s' setted by format string (%u) not equal size of C++ structure (%u).",filename.c_str(),fsize,rsize); // ASSERT must fail after function call return false; @@ -274,10 +304,11 @@ static bool LoadDBC_assert_print(uint32 fsize, uint32 rsize, const std::string& struct LocalData { - LocalData(uint32 build) - : main_build(build), availableDbcLocales(0xFFFFFFFF), checkedDbcLocaleBuilds(0) {} + LocalData(uint32 build, LocaleConstant loc) + : main_build(build), defaultLocale(loc), availableDbcLocales(0xFFFFFFFF),checkedDbcLocaleBuilds(0) {} uint32 main_build; + LocaleConstant defaultLocale; // bitmasks for index of fullLocaleNameList uint32 availableDbcLocales; @@ -288,13 +319,13 @@ template inline void LoadDBC(LocalData& localeData, BarGoLink& bar, StoreProblemList& errlist, DBCStorage& storage, const std::string& dbc_path, const std::string& filename) { // compatibility format and C++ structure sizes - MANGOS_ASSERT(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDBC_assert_print(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()), sizeof(T), filename)); + MANGOS_ASSERT(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDBC_assert_print(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()),sizeof(T),filename)); std::string dbc_filename = dbc_path + filename; - if (storage.Load(dbc_filename.c_str())) + if(storage.Load(dbc_filename.c_str(),localeData.defaultLocale)) { bar.step(); - for (uint8 i = 0; fullLocaleNameList[i].name; ++i) + for(uint8 i = 0; fullLocaleNameList[i].name; ++i) { if (!(localeData.availableDbcLocales & (1 << i))) continue; @@ -305,20 +336,20 @@ inline void LoadDBC(LocalData& localeData, BarGoLink& bar, StoreProblemList& err if (!(localeData.checkedDbcLocaleBuilds & (1 << i))) { - localeData.checkedDbcLocaleBuilds |= (1 << i); // mark as checked for speedup next checks + localeData.checkedDbcLocaleBuilds |= (1<name + "/" + filename; char buf[200]; - snprintf(buf, 200, " (exist, but DBC locale subdir %s have DBCs for build %u instead expected build %u, it and other DBC from subdir skipped)", localStr->name, build_loc, localeData.main_build); + snprintf(buf,200," (exist, but DBC locale subdir %s have DBCs for build %u instead expected build %u, it and other DBC from subdir skipped)",localStr->name,build_loc,localeData.main_build); errlist.push_back(dbc_filename_loc + buf); } @@ -327,15 +358,15 @@ inline void LoadDBC(LocalData& localeData, BarGoLink& bar, StoreProblemList& err } std::string dbc_filename_loc = dbc_path + localStr->name + "/" + filename; - if (!storage.LoadStringsFrom(dbc_filename_loc.c_str())) - localeData.availableDbcLocales &= ~(1 << i);// mark as not available for speedup next checks + if(!storage.LoadStringsFrom(dbc_filename_loc.c_str(),localStr->locale)) + localeData.availableDbcLocales &= ~(1<locale); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAreaStore, dbcPath, "AreaTable.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaStore, dbcPath,"AreaTable.dbc"); // must be after sAreaStore loading for (uint32 i = 0; i < sAreaStore.GetNumRows(); ++i) // areaflag numbered from 0 @@ -380,141 +412,168 @@ void LoadDBCStores(const std::string& dataPath) if (AreaTableEntry const* area = sAreaStore.LookupEntry(i)) { // fill AreaId->DBC records - sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID), area->exploreFlag)); + sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID),area->exploreFlag)); // fill MapId->DBC records ( skip sub zones and continents ) - if (area->zone == 0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 && area->mapid != 571) - sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid, area->exploreFlag)); + if(area->zone==0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 && area->mapid != 571 ) + sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid,area->exploreFlag)); } } - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAchievementStore, dbcPath, "Achievement.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAchievementCriteriaStore, dbcPath, "Achievement_Criteria.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAreaTriggerStore, dbcPath, "AreaTrigger.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAreaGroupStore, dbcPath, "AreaGroup.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAuctionHouseStore, dbcPath, "AuctionHouse.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sBankBagSlotPricesStore, dbcPath, "BankBagSlotPrices.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sBattlemasterListStore, dbcPath, "BattlemasterList.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sBarberShopStyleStore, dbcPath, "BarberShopStyle.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCharStartOutfitStore, dbcPath, "CharStartOutfit.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCharTitlesStore, dbcPath, "CharTitles.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sChatChannelsStore, dbcPath, "ChatChannels.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sChrClassesStore, dbcPath, "ChrClasses.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureDisplayInfoExtraStore, dbcPath, "CreatureDisplayInfoExtra.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureTypeStore, dbcPath, "CreatureType.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCurrencyTypesStore, dbcPath, "CurrencyTypes.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDungeonEncounterStore, dbcPath, "DungeonEncounter.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDurabilityCostsStore, dbcPath, "DurabilityCosts.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDurabilityQualityStore, dbcPath, "DurabilityQuality.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sEmotesStore, dbcPath, "Emotes.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sEmotesTextStore, dbcPath, "EmotesText.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sFactionStore, dbcPath, "Faction.dbc"); - for (uint32 i = 0; i < sFactionStore.GetNumRows(); ++i) + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementStore, dbcPath,"Achievement.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementCriteriaStore, dbcPath,"Achievement_Criteria.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaGroupStore, dbcPath,"AreaGroup.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAuctionHouseStore, dbcPath,"AuctionHouse.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBankBagSlotPricesStore, dbcPath,"BankBagSlotPrices.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrPowerTypesStore, dbcPath, "ChrClassesXPowerTypes.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrRacesStore, dbcPath,"ChrRaces.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCinematicSequencesStore, dbcPath,"CinematicSequences.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoStore, dbcPath,"CreatureDisplayInfo.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoExtraStore,dbcPath,"CreatureDisplayInfoExtra.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureTypeStore, dbcPath,"CreatureType.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDungeonEncounterStore, dbcPath,"DungeonEncounter.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityCostsStore, dbcPath,"DurabilityCosts.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityQualityStore, dbcPath,"DurabilityQuality.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesStore, dbcPath,"Emotes.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesTextStore, dbcPath,"EmotesText.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionStore, dbcPath,"Faction.dbc"); + for (uint32 i=0;iteam) { - SimpleFactionsList& flist = sFactionTeamMap[faction->team]; + SimpleFactionsList &flist = sFactionTeamMap[faction->team]; flist.push_back(i); } } - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sFactionTemplateStore, dbcPath, "FactionTemplate.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGameObjectDisplayInfoStore, dbcPath, "GameObjectDisplayInfo.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGemPropertiesStore, dbcPath, "GemProperties.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGlyphPropertiesStore, dbcPath, "GlyphProperties.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGlyphSlotStore, dbcPath, "GlyphSlot.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionTemplateStore, dbcPath,"FactionTemplate.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGameObjectDisplayInfoStore,dbcPath,"GameObjectDisplayInfo.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGemPropertiesStore, dbcPath,"GemProperties.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphPropertiesStore, dbcPath,"GlyphProperties.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphSlotStore, dbcPath,"GlyphSlot.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtBarberShopCostBaseStore, dbcPath, "gtBarberShopCostBase.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtCombatRatingsStore, dbcPath, "gtCombatRatings.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtBarberShopCostBaseStore,dbcPath,"gtBarberShopCostBase.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtCombatRatingsStore, dbcPath,"gtCombatRatings.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtChanceToMeleeCritBaseStore, dbcPath, "gtChanceToMeleeCritBase.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtChanceToMeleeCritStore, dbcPath, "gtChanceToMeleeCrit.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritBaseStore, dbcPath,"gtChanceToMeleeCritBase.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritStore, dbcPath,"gtChanceToMeleeCrit.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtChanceToSpellCritBaseStore, dbcPath, "gtChanceToSpellCritBase.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtChanceToSpellCritStore, dbcPath, "gtChanceToSpellCrit.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritBaseStore, dbcPath,"gtChanceToSpellCritBase.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritStore, dbcPath,"gtChanceToSpellCrit.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtOCTClassCombatRatingScalarStore, dbcPath, "gtOCTClassCombatRatingScalar.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtOCTRegenHPStore, dbcPath, "gtOCTRegenHP.dbc"); - // LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenMPStore, dbcPath,"gtOCTRegenMP.dbc"); -- not used currently - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtRegenHPPerSptStore, dbcPath, "gtRegenHPPerSpt.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGtRegenMPPerSptStore, dbcPath, "gtRegenMPPerSpt.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sHolidaysStore, dbcPath, "Holidays.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemStore, dbcPath, "Item.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemBagFamilyStore, dbcPath, "ItemBagFamily.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemClassStore, dbcPath, "ItemClass.dbc"); - // LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); -- not used currently - // LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemExtendedCostStore, dbcPath, "ItemExtendedCost.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemLimitCategoryStore, dbcPath, "ItemLimitCategory.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemRandomPropertiesStore, dbcPath, "ItemRandomProperties.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemRandomSuffixStore, dbcPath, "ItemRandomSuffix.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sLockStore, dbcPath, "Lock.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sMailTemplateStore, dbcPath, "MailTemplate.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sMapStore, dbcPath, "Map.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTClassCombatRatingScalarStore,dbcPath,"gtOCTClassCombatRatingScalar.dbc"); + //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenHPStore, dbcPath,"gtOCTRegenHP.dbc"); + //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenMPStore, dbcPath,"gtOCTRegenMP.dbc"); -- not used currently + //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenHPPerSptStore, dbcPath,"gtRegenHPPerSpt.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenMPPerSptStore, dbcPath,"gtRegenMPPerSpt.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sHolidaysStore, dbcPath,"Holidays.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemBagFamilyStore, dbcPath,"ItemBagFamily.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemClassStore, dbcPath,"ItemClass.dbc"); + //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); -- not used currently + //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemLimitCategoryStore, dbcPath,"ItemLimitCategory.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomPropertiesStore,dbcPath,"ItemRandomProperties.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomSuffixStore, dbcPath,"ItemRandomSuffix.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemSetStore, dbcPath,"ItemSet.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sMapDifficultyStore, dbcPath, "MapDifficulty.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapDifficultyStore, dbcPath,"MapDifficulty.dbc"); // fill data - for (uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i) - if (MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i)) - sMapDifficultyMap[MAKE_PAIR32(entry->MapId, entry->Difficulty)] = MapDifficulty(entry->resetTime, entry->maxPlayers); + for(uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i) + if(MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i)) + sMapDifficultyMap[MAKE_PAIR32(entry->MapId,entry->Difficulty)] = MapDifficulty(entry->resetTime,entry->maxPlayers); sMapDifficultyStore.Clear(); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sMovieStore, dbcPath, "Movie.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sOverrideSpellDataStore, dbcPath, "OverrideSpellData.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sQuestFactionRewardStore, dbcPath, "QuestFactionReward.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sQuestSortStore, dbcPath, "QuestSort.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sQuestXPLevelStore, dbcPath, "QuestXP.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sPvPDifficultyStore, dbcPath, "PvpDifficulty.dbc"); - for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMovieStore, dbcPath,"Movie.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sOverrideSpellDataStore, dbcPath,"OverrideSpellData.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestFactionRewardStore, dbcPath,"QuestFactionReward.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestXPLevelStore, dbcPath,"QuestXP.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sPhaseStore, dbcPath,"Phase.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sPvPDifficultyStore, dbcPath,"PvpDifficulty.dbc"); + for(uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i)) if (entry->bracketId > MAX_BATTLEGROUND_BRACKETS) MANGOS_ASSERT(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sRandomPropertiesPointsStore, dbcPath, "RandPropPoints.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sScalingStatDistributionStore, dbcPath, "ScalingStatDistribution.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sScalingStatValuesStore, dbcPath, "ScalingStatValues.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillLineStore, dbcPath, "SkillLine.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillLineAbilityStore, dbcPath, "SkillLineAbility.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillRaceClassInfoStore, dbcPath, "SkillRaceClassInfo.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc"); - for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatDistributionStore, dbcPath,"ScalingStatDistribution.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatValuesStore, dbcPath,"ScalingStatValues.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineStore, dbcPath,"SkillLine.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineAbilityStore, dbcPath,"SkillLineAbility.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillRaceClassInfoStore, dbcPath,"SkillRaceClassInfo.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSoundEntriesStore, dbcPath,"SoundEntries.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellStore, dbcPath,"Spell.dbc"); + for(uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) { - SpellEntry const* spell = sSpellStore.LookupEntry(i); - if (spell && spell->Category) - sSpellCategoryStore[spell->Category].insert(i); + if(SpellEntry const * spell = sSpellStore.LookupEntry(i)) + { + if(SpellCategoriesEntry const* category = spell->GetSpellCategories()) + if(uint32 cat = category->Category) + sSpellCategoryStore[cat].insert(i); - // DBC not support uint64 fields but SpellEntry have SpellFamilyFlags mapped at 2 uint32 fields - // uint32 field already converted to bigendian if need, but must be swapped for correct uint64 bigendian view -#if MANGOS_ENDIAN == MANGOS_BIGENDIAN - std::swap(*((uint32*)(&spell->SpellFamilyFlags)), *(((uint32*)(&spell->SpellFamilyFlags)) + 1)); -#endif + // DBC not support uint64 fields but SpellEntry have SpellFamilyFlags mapped at 2 uint32 fields + // uint32 field already converted to bigendian if need, but must be swapped for correct uint64 bigendian view + #if MANGOS_ENDIAN == MANGOS_BIGENDIAN + std::swap(*((uint32*)(&spell->SpellFamilyFlags)),*(((uint32*)(&spell->SpellFamilyFlags))+1)); + #endif + } } + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellAuraOptionsStore, dbcPath,"SpellAuraOptions.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellAuraRestrictionsStore, dbcPath,"SpellAuraRestrictions.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCastingRequirementsStore, dbcPath,"SpellCastingRequirements.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCategoriesStore, dbcPath,"SpellCategories.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellClassOptionsStore, dbcPath,"SpellClassOptions.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCooldownsStore, dbcPath,"SpellCooldowns.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellEffectStore, dbcPath,"SpellEffect.dbc"); + + for(uint32 i = 1; i < sSpellEffectStore.GetNumRows(); ++i) + { + if(SpellEffectEntry const *spellEffect = sSpellEffectStore.LookupEntry(i)) + sSpellEffectMap[spellEffect->EffectSpellId].effects[spellEffect->EffectIndex] = spellEffect; + } + + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellEquippedItemsStore, dbcPath,"SpellEquippedItems.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellInterruptsStore, dbcPath,"SpellInterrupts.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellLevelsStore, dbcPath,"SpellLevels.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellPowerStore, dbcPath,"SpellPower.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellReagentsStore, dbcPath,"SpellReagents.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellScalingStore, dbcPath,"SpellScaling.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftStore, dbcPath,"SpellShapeshift.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellTargetRestrictionsStore, dbcPath,"SpellTargetRestrictions.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellTotemsStore, dbcPath,"SpellTotems.dbc"); + for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) { - SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(j); + SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); - if (!skillLine) + if(!skillLine) continue; SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); + if (spellInfo && (spellInfo->Attributes & (SPELL_ATTR_UNK4 | SPELL_ATTR_PASSIVE | SPELL_ATTR_UNK7 | SPELL_ATTR_UNK8)) == (SPELL_ATTR_UNK4 | SPELL_ATTR_PASSIVE | SPELL_ATTR_UNK7 | SPELL_ATTR_UNK8)) { for (unsigned int i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i) { CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i); - if (!cFamily) + if(!cFamily) continue; - if (skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) + if(skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) continue; sPetFamilySpellsStore[i].insert(spellInfo->Id); @@ -522,120 +581,121 @@ void LoadDBCStores(const std::string& dataPath) } } - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellCastTimesStore, dbcPath, "SpellCastTimes.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellDurationStore, dbcPath, "SpellDuration.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellDifficultyStore, dbcPath, "SpellDifficulty.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellFocusObjectStore, dbcPath, "SpellFocusObject.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellItemEnchantmentStore, dbcPath, "SpellItemEnchantment.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellItemEnchantmentConditionStore, dbcPath, "SpellItemEnchantmentCondition.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellRadiusStore, dbcPath, "SpellRadius.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellRangeStore, dbcPath, "SpellRange.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellRuneCostStore, dbcPath, "SpellRuneCost.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellShapeshiftFormStore, dbcPath, "SpellShapeshiftForm.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sStableSlotPricesStore, dbcPath, "StableSlotPrices.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSummonPropertiesStore, dbcPath, "SummonProperties.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTalentStore, dbcPath, "Talent.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCastTimesStore, dbcPath,"SpellCastTimes.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDurationStore, dbcPath,"SpellDuration.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDifficultyStore, dbcPath,"SpellDifficulty.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellFocusObjectStore, dbcPath,"SpellFocusObject.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentStore,dbcPath,"SpellItemEnchantment.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentConditionStore,dbcPath,"SpellItemEnchantmentCondition.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRadiusStore, dbcPath,"SpellRadius.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRangeStore, dbcPath,"SpellRange.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRuneCostStore, dbcPath,"SpellRuneCost.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftFormStore, dbcPath,"SpellShapeshiftForm.dbc"); + //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc"); // create talent spells set for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i) { - TalentEntry const* talentInfo = sTalentStore.LookupEntry(i); + TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; - for (int j = 0; j < MAX_TALENT_RANK; ++j) - if (talentInfo->RankID[j]) - sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i, j); + for (int j = 0; j < MAX_TALENT_RANK; j++) + if(talentInfo->RankID[j]) + sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i,j); } - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTalentTabStore, dbcPath, "TalentTab.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentTabStore, dbcPath,"TalentTab.dbc"); // prepare fast data access to bit pos of talent ranks for use at inspecting { // now have all max ranks (and then bit amount used for store talent ranks in inspect) - for (uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId) + for(uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId) { - TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentTabId); - if (!talentTabInfo) + TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentTabId ); + if(!talentTabInfo) continue; // prevent memory corruption; otherwise cls will become 12 below - if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE) == 0) + if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE)==0) continue; // store class talent tab pages uint32 cls = 1; - for (uint32 m = 1; !(m & talentTabInfo->ClassMask) && cls < MAX_CLASSES; m <<= 1, ++cls) {} + for(uint32 m=1;!(m & talentTabInfo->ClassMask) && cls < MAX_CLASSES;m <<=1, ++cls) {} - sTalentTabPages[cls][talentTabInfo->tabpage] = talentTabId; + sTalentTabPages[cls][talentTabInfo->tabpage]=talentTabId; } } - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTaxiNodesStore, dbcPath, "TaxiNodes.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiNodesStore, dbcPath,"TaxiNodes.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTaxiPathStore, dbcPath, "TaxiPath.dbc"); - for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) - if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) - sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID, entry->price); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathStore, dbcPath,"TaxiPath.dbc"); + for(uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) + if(TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) + sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID,entry->price); uint32 pathCount = sTaxiPathStore.GetNumRows(); //## TaxiPathNode.dbc ## Loaded only for initialization different structures - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTaxiPathNodeStore, dbcPath, "TaxiPathNode.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathNodeStore, dbcPath,"TaxiPathNode.dbc"); // Calculate path nodes count std::vector pathLength; pathLength.resize(pathCount); // 0 and some other indexes not used - for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) - if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) + for(uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) + if(TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) { if (pathLength[entry->path] < entry->index + 1) pathLength[entry->path] = entry->index + 1; } // Set path length sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used - for (uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) + for(uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) sTaxiPathNodesByPath[i].resize(pathLength[i]); // fill data (pointers to sTaxiPathNodeStore elements - for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) - if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) + for(uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) + if(TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) sTaxiPathNodesByPath[entry->path].set(entry->index, entry); // Initialize global taxinodes mask // include existing nodes that have at least single not spell base (scripted) path { std::set spellPaths; - for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) - if (SpellEntry const* sInfo = sSpellStore.LookupEntry(i)) - for (int j = 0; j < MAX_EFFECT_INDEX; ++j) - if (sInfo->Effect[j] == 123 /*SPELL_EFFECT_SEND_TAXI*/) - spellPaths.insert(sInfo->EffectMiscValue[j]); + for(uint32 i = 1; i < sSpellStore.GetNumRows (); ++i) + if(SpellEntry const* sInfo = sSpellStore.LookupEntry (i)) + for(int j=0; j < MAX_EFFECT_INDEX; ++j) + if(SpellEffectEntry const* effect = sInfo->GetSpellEffect(SpellEffectIndex(j))) + if(effect->Effect==123 /*SPELL_EFFECT_SEND_TAXI*/) + spellPaths.insert(effect->EffectMiscValue); - memset(sTaxiNodesMask, 0, sizeof(sTaxiNodesMask)); - memset(sOldContinentsNodesMask, 0, sizeof(sTaxiNodesMask)); - for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) + memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask)); + memset(sOldContinentsNodesMask,0,sizeof(sTaxiNodesMask)); + for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) { TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i); - if (!node) + if(!node) continue; TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(i); - if (src_i != sTaxiPathSetBySource.end() && !src_i->second.empty()) + if(src_i!=sTaxiPathSetBySource.end() && !src_i->second.empty()) { bool ok = false; - for (TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin(); dest_i != src_i->second.end(); ++dest_i) + for(TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin();dest_i != src_i->second.end(); ++dest_i) { // not spell path - if (spellPaths.find(dest_i->second.ID) == spellPaths.end()) + if(spellPaths.find(dest_i->second.ID)==spellPaths.end()) { ok = true; break; } } - if (!ok) + if(!ok) continue; } // valid taxi network node uint8 field = (uint8)((i - 1) / 32); - uint32 submask = 1 << ((i - 1) % 32); + uint32 submask = 1<<((i-1)%32); sTaxiNodesMask[field] |= submask; // old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info) @@ -644,89 +704,95 @@ void LoadDBCStores(const std::string& dataPath) } } - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTeamContributionPoints, dbcPath, "TeamContributionPoints.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTotemCategoryStore, dbcPath, "TotemCategory.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sVehicleStore, dbcPath, "Vehicle.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sVehicleSeatStore, dbcPath, "VehicleSeat.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sWorldMapAreaStore, dbcPath, "WorldMapArea.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sWMOAreaTableStore, dbcPath, "WMOAreaTable.dbc"); - for (uint32 i = 0; i < sWMOAreaTableStore.GetNumRows(); ++i) + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleStore, dbcPath,"Vehicle.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleSeatStore, dbcPath,"VehicleSeat.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapAreaStore, dbcPath,"WorldMapArea.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWMOAreaTableStore, dbcPath,"WMOAreaTable.dbc"); + for(uint32 i = 0; i < sWMOAreaTableStore.GetNumRows(); ++i) { - if (WMOAreaTableEntry const* entry = sWMOAreaTableStore.LookupEntry(i)) + if(WMOAreaTableEntry const* entry = sWMOAreaTableStore.LookupEntry(i)) { sWMOAreaInfoByTripple.insert(WMOAreaInfoByTripple::value_type(WMOAreaTableTripple(entry->rootId, entry->adtId, entry->groupId), entry)); } } - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sWorldMapOverlayStore, dbcPath, "WorldMapOverlay.dbc"); - LoadDBC(availableDbcLocales, bar, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapOverlayStore, dbcPath,"WorldMapOverlay.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldSafeLocsStore, dbcPath,"WorldSafeLocs.dbc"); // error checks - if (bad_dbc_files.size() >= DBCFilesCount) + if (bad_dbc_files.size() >= DBCFilesCount ) { - sLog.outError("\nIncorrect DataDir value in mangosd.conf or ALL required *.dbc files (%d) not found by path: %sdbc", DBCFilesCount, dataPath.c_str()); + sLog.outError("\nIncorrect DataDir value in mangosd.conf or ALL required *.dbc files (%d) not found by path: %sdbc",DBCFilesCount,dataPath.c_str()); Log::WaitBeforeContinueIfNeed(); exit(1); } - else if (!bad_dbc_files.empty()) + else if (!bad_dbc_files.empty() ) { std::string str; - for (std::list::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) + for(std::list::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) str += *i + "\n"; - sLog.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s", (uint32)bad_dbc_files.size(), DBCFilesCount, str.c_str()); + sLog.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s",(uint32)bad_dbc_files.size(),DBCFilesCount,str.c_str()); Log::WaitBeforeContinueIfNeed(); exit(1); } // Check loaded DBC files proper version - if (!sAreaStore.LookupEntry(3617) || // last area (areaflag) added in 3.3.5a - !sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.5a - !sGemPropertiesStore.LookupEntry(1629) || // last gem property added in 3.3.5a - !sItemStore.LookupEntry(56806) || // last client known item added in 3.3.5a - !sItemExtendedCostStore.LookupEntry(2997) || // last item extended cost added in 3.3.5a - !sMapStore.LookupEntry(724) || // last map added in 3.3.5a - !sSpellStore.LookupEntry(80864)) // last added spell in 3.3.5a + if (!sAreaStore.LookupEntry(4713) || // last area (areaflag) added in 4.3.0a + !sCharTitlesStore.LookupEntry(287) || // last char title added in 4.3.0a + !sGemPropertiesStore.LookupEntry(2250) || // last gem property added in 4.3.0a + !sMapStore.LookupEntry(980) || // last map added in 4.3.0a + !sSpellStore.LookupEntry(110966) ) // last added spell in 4.3.0a { - sLog.outError("\nYou have mixed version DBC files. Please re-extract DBC files for one from client build: %s", AcceptableClientBuildsListStr().c_str()); + sLog.outError("\nYou have mixed version DBC files. Please re-extract DBC files for one from client build: %s",AcceptableClientBuildsListStr().c_str()); Log::WaitBeforeContinueIfNeed(); exit(1); } sLog.outString(); - sLog.outString(">> Initialized %d data stores", DBCFilesCount); + sLog.outString( ">> Initialized %d data stores", DBCFilesCount ); } SimpleFactionsList const* GetFactionTeamList(uint32 faction) { FactionTeamMap::const_iterator itr = sFactionTeamMap.find(faction); - if (itr == sFactionTeamMap.end()) + if(itr==sFactionTeamMap.end()) return NULL; return &itr->second; } char const* GetPetName(uint32 petfamily, uint32 dbclang) { - if (!petfamily) + if(!petfamily) return NULL; - CreatureFamilyEntry const* pet_family = sCreatureFamilyStore.LookupEntry(petfamily); - if (!pet_family) + CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(petfamily); + if(!pet_family) return NULL; - return pet_family->Name[dbclang] ? pet_family->Name[dbclang] : NULL; + return pet_family->Name[dbclang]?pet_family->Name[dbclang]:NULL; } TalentSpellPos const* GetTalentSpellPos(uint32 spellId) { TalentSpellPosMap::const_iterator itr = sTalentSpellPosMap.find(spellId); - if (itr == sTalentSpellPosMap.end()) + if(itr==sTalentSpellPosMap.end()) return NULL; return &itr->second; } +SpellEffectEntry const* GetSpellEffectEntry(uint32 spellId, SpellEffectIndex effect) +{ + SpellEffectMap::const_iterator itr = sSpellEffectMap.find(spellId); + if(itr == sSpellEffectMap.end()) + return NULL; + + return itr->second.effects[effect]; +} + uint32 GetTalentSpellCost(TalentSpellPos const* pos) { if (pos) - return pos->rank + 1; + return pos->rank+1; return 0; } @@ -739,7 +805,7 @@ uint32 GetTalentSpellCost(uint32 spellId) int32 GetAreaFlagByAreaID(uint32 area_id) { AreaFlagByAreaID::iterator i = sAreaFlagByAreaID.find(area_id); - if (i == sAreaFlagByAreaID.end()) + if(i == sAreaFlagByAreaID.end()) return -1; return i->second; @@ -747,28 +813,28 @@ int32 GetAreaFlagByAreaID(uint32 area_id) WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid) { - WMOAreaInfoByTripple::iterator i = sWMOAreaInfoByTripple.find(WMOAreaTableTripple(rootid, adtid, groupid)); - if (i == sWMOAreaInfoByTripple.end()) - return NULL; - return i->second; + WMOAreaInfoByTripple::iterator i = sWMOAreaInfoByTripple.find(WMOAreaTableTripple(rootid, adtid, groupid)); + if(i == sWMOAreaInfoByTripple.end()) + return NULL; + return i->second; } AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id) { int32 areaflag = GetAreaFlagByAreaID(area_id); - if (areaflag < 0) + if(areaflag < 0) return NULL; - return sAreaStore.LookupEntry(areaflag); + return sAreaStore.LookupEntry(areaflag ); } -AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag, uint32 map_id) +AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag,uint32 map_id) { - if (area_flag) + if(area_flag) return sAreaStore.LookupEntry(area_flag); - if (MapEntry const* mapEntry = sMapStore.LookupEntry(map_id)) + if(MapEntry const* mapEntry = sMapStore.LookupEntry(map_id)) return GetAreaEntryByAreaID(mapEntry->linked_zone); return NULL; @@ -777,7 +843,7 @@ AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag, uint32 map_ uint32 GetAreaFlagByMapId(uint32 mapid) { AreaFlagByMapID::iterator i = sAreaFlagByMapID.find(mapid); - if (i == sAreaFlagByMapID.end()) + if(i == sAreaFlagByMapID.end()) return 0; else return i->second; @@ -785,10 +851,10 @@ uint32 GetAreaFlagByMapId(uint32 mapid) uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId) { - if (mapid != 530 && mapid != 571) // speed for most cases + if(mapid != 530 && mapid != 571) // speed for most cases return mapid; - if (WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId)) + if(WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId)) return wma->virtual_map_id >= 0 ? wma->virtual_map_id : wma->map_id; return mapid; @@ -796,15 +862,15 @@ uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId) ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId) { - mapid = GetVirtualMapForMapAndZone(mapid, zoneId); - if (mapid < 2) + mapid = GetVirtualMapForMapAndZone(mapid,zoneId); + if(mapid < 2) return CONTENT_1_60; MapEntry const* mapEntry = sMapStore.LookupEntry(mapid); - if (!mapEntry) + if(!mapEntry) return CONTENT_1_60; - switch (mapEntry->Expansion()) + switch(mapEntry->Expansion()) { default: return CONTENT_1_60; case 1: return CONTENT_61_70; @@ -815,10 +881,10 @@ ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId) ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id) { // not sorted, numbering index from 0 - for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i) + for(uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i) { ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(i); - if (ch && ch->ChannelID == channel_id) + if(ch && ch->ChannelID == channel_id) return ch; } return NULL; @@ -826,25 +892,25 @@ ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id) bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId) { - if (requiredTotemCategoryId == 0) + if(requiredTotemCategoryId==0) return true; - if (itemTotemCategoryId == 0) + if(itemTotemCategoryId==0) return false; TotemCategoryEntry const* itemEntry = sTotemCategoryStore.LookupEntry(itemTotemCategoryId); - if (!itemEntry) + if(!itemEntry) return false; TotemCategoryEntry const* reqEntry = sTotemCategoryStore.LookupEntry(requiredTotemCategoryId); - if (!reqEntry) + if(!reqEntry) return false; - if (itemEntry->categoryType != reqEntry->categoryType) + if(itemEntry->categoryType!=reqEntry->categoryType) return false; - return (itemEntry->categoryMask & reqEntry->categoryMask) == reqEntry->categoryMask; + return (itemEntry->categoryMask & reqEntry->categoryMask)==reqEntry->categoryMask; } -bool Zone2MapCoordinates(float& x, float& y, uint32 zone) +bool Zone2MapCoordinates(float& x,float& y,uint32 zone) { WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone); @@ -852,14 +918,14 @@ bool Zone2MapCoordinates(float& x, float& y, uint32 zone) if (!maEntry || maEntry->x2 == maEntry->x1 || maEntry->y2 == maEntry->y1) return false; - std::swap(x, y); // at client map coords swapped - x = x * ((maEntry->x2 - maEntry->x1) / 100) + maEntry->x1; - y = y * ((maEntry->y2 - maEntry->y1) / 100) + maEntry->y1; // client y coord from top to down + std::swap(x,y); // at client map coords swapped + x = x*((maEntry->x2-maEntry->x1)/100)+maEntry->x1; + y = y*((maEntry->y2-maEntry->y1)/100)+maEntry->y1; // client y coord from top to down return true; } -bool Map2ZoneCoordinates(float& x, float& y, uint32 zone) +bool Map2ZoneCoordinates(float& x,float& y,uint32 zone) { WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone); @@ -867,23 +933,23 @@ bool Map2ZoneCoordinates(float& x, float& y, uint32 zone) if (!maEntry || maEntry->x2 == maEntry->x1 || maEntry->y2 == maEntry->y1) return false; - x = (x - maEntry->x1) / ((maEntry->x2 - maEntry->x1) / 100); - y = (y - maEntry->y1) / ((maEntry->y2 - maEntry->y1) / 100); // client y coord from top to down - std::swap(x, y); // client have map coords swapped + x = (x-maEntry->x1)/((maEntry->x2-maEntry->x1)/100); + y = (y-maEntry->y1)/((maEntry->y2-maEntry->y1)/100); // client y coord from top to down + std::swap(x,y); // client have map coords swapped return true; } MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty) { - MapDifficultyMap::const_iterator itr = sMapDifficultyMap.find(MAKE_PAIR32(mapId, difficulty)); + MapDifficultyMap::const_iterator itr = sMapDifficultyMap.find(MAKE_PAIR32(mapId,difficulty)); return itr != sMapDifficultyMap.end() ? &itr->second : NULL; } -PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level) +PvPDifficultyEntry const* GetBattlegroundBracketByLevel( uint32 mapid, uint32 level ) { PvPDifficultyEntry const* maxEntry = NULL; // used for level > max listed level case - for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) + for(uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) { if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i)) { @@ -906,7 +972,7 @@ PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 lev PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattleGroundBracketId id) { - for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) + for(uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i)) if (entry->mapId == mapid && entry->GetBracketId() == id) return entry; @@ -927,8 +993,8 @@ bool IsPointInAreaTriggerZone(AreaTriggerEntry const* atEntry, uint32 mapid, flo if (atEntry->radius > 0) { // if we have radius check it - float dist2 = (x - atEntry->x) * (x - atEntry->x) + (y - atEntry->y) * (y - atEntry->y) + (z - atEntry->z) * (z - atEntry->z); - if (dist2 > (atEntry->radius + delta) * (atEntry->radius + delta)) + float dist2 = (x-atEntry->x)*(x-atEntry->x) + (y-atEntry->y)*(y-atEntry->y) + (z-atEntry->z)*(z-atEntry->z); + if(dist2 > (atEntry->radius + delta)*(atEntry->radius + delta)) return false; } else @@ -939,23 +1005,23 @@ bool IsPointInAreaTriggerZone(AreaTriggerEntry const* atEntry, uint32 mapid, flo // is-in-cube check and we have to calculate only one point instead of 4 // 2PI = 360, keep in mind that ingame orientation is counter-clockwise - double rotation = 2 * M_PI - atEntry->box_orientation; + double rotation = 2*M_PI-atEntry->box_orientation; double sinVal = sin(rotation); double cosVal = cos(rotation); float playerBoxDistX = x - atEntry->x; float playerBoxDistY = y - atEntry->y; - float rotPlayerX = float(atEntry->x + playerBoxDistX * cosVal - playerBoxDistY * sinVal); - float rotPlayerY = float(atEntry->y + playerBoxDistY * cosVal + playerBoxDistX * sinVal); + float rotPlayerX = float(atEntry->x + playerBoxDistX * cosVal - playerBoxDistY*sinVal); + float rotPlayerY = float(atEntry->y + playerBoxDistY * cosVal + playerBoxDistX*sinVal); // box edges are parallel to coordiante axis, so we can treat every dimension independently :D float dz = z - atEntry->z; float dx = rotPlayerX - atEntry->x; float dy = rotPlayerY - atEntry->y; - if ((fabs(dx) > atEntry->box_x / 2 + delta) || - (fabs(dy) > atEntry->box_y / 2 + delta) || - (fabs(dz) > atEntry->box_z / 2 + delta)) + if( (fabs(dx) > atEntry->box_x/2 + delta) || + (fabs(dy) > atEntry->box_y/2 + delta) || + (fabs(dz) > atEntry->box_z/2 + delta) ) { return false; } @@ -978,7 +1044,6 @@ MANGOS_DLL_SPEC DBCStorage const* GetSoundEntriesStore() MANGOS_DLL_SPEC DBCStorage const* GetSpellStore() { return &sSpellStore; } MANGOS_DLL_SPEC DBCStorage const* GetSpellRangeStore() { return &sSpellRangeStore; } MANGOS_DLL_SPEC DBCStorage const* GetFactionStore() { return &sFactionStore; } -MANGOS_DLL_SPEC DBCStorage const* GetItemDisplayStore() { return &sItemStore; } MANGOS_DLL_SPEC DBCStorage const* GetCreatureDisplayStore() { return &sCreatureDisplayInfoStore; } MANGOS_DLL_SPEC DBCStorage const* GetEmotesStore() { return &sEmotesStore; } MANGOS_DLL_SPEC DBCStorage const* GetEmotesTextStore() { return &sEmotesTextStore; } diff --git a/src/game/DBCStores.h b/src/game/DBCStores.h index 3e1871f8f..8d8da6497 100644 --- a/src/game/DBCStores.h +++ b/src/game/DBCStores.h @@ -35,6 +35,7 @@ char const* GetPetName(uint32 petfamily, uint32 dbclang); uint32 GetTalentSpellCost(uint32 spellId); uint32 GetTalentSpellCost(TalentSpellPos const* pos); TalentSpellPos const* GetTalentSpellPos(uint32 spellId); +SpellEffectEntry const* GetSpellEffectEntry(uint32 spellId, SpellEffectIndex effect); int32 GetAreaFlagByAreaID(uint32 area_id); // -1 if not found uint32 GetAreaFlagByMapId(uint32 mapid); @@ -42,7 +43,7 @@ uint32 GetAreaFlagByMapId(uint32 mapid); WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid); MANGOS_DLL_SPEC AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id); -MANGOS_DLL_SPEC AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag, uint32 map_id); +MANGOS_DLL_SPEC AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag,uint32 map_id); uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId); @@ -58,10 +59,10 @@ ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id); bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId); -bool Zone2MapCoordinates(float& x, float& y, uint32 zone); -bool Map2ZoneCoordinates(float& x, float& y, uint32 zone); +bool Zone2MapCoordinates(float& x,float& y,uint32 zone); +bool Map2ZoneCoordinates(float& x,float& y,uint32 zone); -typedef std::map < uint32/*pair32(map,diff)*/, MapDifficulty > MapDifficultyMap; +typedef std::map MapDifficultyMap; MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty); // natural order for difficulties up-down iteration @@ -100,14 +101,16 @@ extern DBCStorage sAchievementCriteriaStore; extern DBCStorage sAreaStore;// recommend access using functions extern DBCStorage sAreaGroupStore; extern DBCStorage sAreaTriggerStore; +extern DBCStorage sArmorLocationStore; extern DBCStorage sAuctionHouseStore; extern DBCStorage sBankBagSlotPricesStore; extern DBCStorage sBarberShopStyleStore; extern DBCStorage sBattlemasterListStore; -// extern DBCStorage sChatChannelsStore; -- accessed using function, no usable index +//extern DBCStorage sChatChannelsStore; -- accessed using function, no usable index extern DBCStorage sCharStartOutfitStore; extern DBCStorage sCharTitlesStore; extern DBCStorage sChrClassesStore; +extern DBCStorage sChrPowerTypesStore; extern DBCStorage sChrRacesStore; extern DBCStorage sCinematicSequencesStore; extern DBCStorage sCreatureDisplayInfoStore; @@ -115,7 +118,7 @@ extern DBCStorage sCreatureDisplayInfoExtraStore; extern DBCStorage sCreatureFamilyStore; extern DBCStorage sCreatureSpellDataStore; extern DBCStorage sCreatureTypeStore; -extern DBCStorage sCurrencyTypesStore; +//extern DBCStorage sCurrencyTypesStore; extern DBCStorage sDungeonEncounterStore; extern DBCStorage sDurabilityCostsStore; extern DBCStorage sDurabilityQualityStore; @@ -135,16 +138,26 @@ extern DBCStorage sGtChanceToMeleeCritStore; extern DBCStorage sGtChanceToSpellCritBaseStore; extern DBCStorage sGtChanceToSpellCritStore; extern DBCStorage sGtOCTClassCombatRatingScalarStore; -extern DBCStorage sGtOCTRegenHPStore; -// extern DBCStorage sGtOCTRegenMPStore; -- not used currently -extern DBCStorage sGtRegenHPPerSptStore; +//extern DBCStorage sGtOCTRegenHPStore; +//extern DBCStorage sGtOCTRegenMPStore; -- not used currently +//extern DBCStorage sGtRegenHPPerSptStore; extern DBCStorage sGtRegenMPPerSptStore; extern DBCStorage sHolidaysStore; -extern DBCStorage sItemStore; +extern DBCStorage sItemArmorQualityStore; +extern DBCStorage sItemArmorShieldStore; +extern DBCStorage sItemArmorTotalStore; extern DBCStorage sItemBagFamilyStore; extern DBCStorage sItemClassStore; -// extern DBCStorage sItemDisplayInfoStore; -- not used currently -extern DBCStorage sItemExtendedCostStore; +extern DBCStorage sItemDamageAmmoStore; +extern DBCStorage sItemDamageOneHandStore; +extern DBCStorage sItemDamageOneHandCasterStore; +extern DBCStorage sItemDamageRangedStore; +extern DBCStorage sItemDamageThrownStore; +extern DBCStorage sItemDamageTwoHandStore; +extern DBCStorage sItemDamageTwoHandCasterStore; +extern DBCStorage sItemDamageWandStore; +//extern DBCStorage sItemExtendedCostStore; +//extern DBCStorage sItemDisplayInfoStore; -- not used currently extern DBCStorage sItemLimitCategoryStore; extern DBCStorage sItemRandomPropertiesStore; extern DBCStorage sItemRandomSuffixStore; @@ -152,14 +165,15 @@ extern DBCStorage sItemSetStore; extern DBCStorage sLockStore; extern DBCStorage sMailTemplateStore; extern DBCStorage sMapStore; -// extern DBCStorage sMapDifficultyStore; -- use GetMapDifficultyData insteed +//extern DBCStorage sMapDifficultyStore; -- use GetMapDifficultyData insteed extern MapDifficultyMap sMapDifficultyMap; extern DBCStorage sMovieStore; extern DBCStorage sOverrideSpellDataStore; extern DBCStorage sQuestFactionRewardStore; extern DBCStorage sQuestSortStore; extern DBCStorage sQuestXPLevelStore; -// extern DBCStorage sPvPDifficultyStore; -- use GetBattlegroundSlotByLevel for access +extern DBCStorage sPhaseStore; +//extern DBCStorage sPvPDifficultyStore; -- use GetBattlegroundSlotByLevel for access extern DBCStorage sRandomPropertiesPointsStore; extern DBCStorage sScalingStatDistributionStore; extern DBCStorage sScalingStatValuesStore; @@ -180,7 +194,23 @@ extern DBCStorage sSpellRangeStore; extern DBCStorage sSpellRuneCostStore; extern DBCStorage sSpellShapeshiftFormStore; extern DBCStorage sSpellStore; -extern DBCStorage sStableSlotPricesStore; +extern DBCStorage sSpellAuraOptionsStore; +extern DBCStorage sSpellAuraRestrictionsStore; +extern DBCStorage sSpellCastingRequirementsStore; +extern DBCStorage sSpellCategoriesStore; +extern DBCStorage sSpellClassOptionsStore; +extern DBCStorage sSpellCooldownsStore; +extern DBCStorage sSpellEffectStore; +extern DBCStorage sSpellEquippedItemsStore; +extern DBCStorage sSpellInterruptsStore; +extern DBCStorage sSpellLevelsStore; +extern DBCStorage sSpellPowerStore; +extern DBCStorage sSpellReagentsStore; +extern DBCStorage sSpellScalingStore; +extern DBCStorage sSpellShapeshiftStore; +extern DBCStorage sSpellTargetRestrictionsStore; +extern DBCStorage sSpellTotemsStore; +//extern DBCStorage sStableSlotPricesStore; extern DBCStorage sSummonPropertiesStore; extern DBCStorage sTalentStore; extern DBCStorage sTalentTabStore; @@ -190,12 +220,11 @@ extern TaxiMask sTaxiNodesMask; extern TaxiMask sOldContinentsNodesMask; extern TaxiPathSetBySource sTaxiPathSetBySource; extern TaxiPathNodesByPath sTaxiPathNodesByPath; -extern DBCStorage sTeamContributionPoints; extern DBCStorage sTotemCategoryStore; extern DBCStorage sVehicleStore; extern DBCStorage sVehicleSeatStore; extern DBCStorage sWMOAreaTableStore; -// extern DBCStorage sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates +//extern DBCStorage sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates extern DBCStorage sWorldMapOverlayStore; extern DBCStorage sWorldSafeLocsStore; @@ -206,9 +235,7 @@ MANGOS_DLL_SPEC DBCStorage const* GetSoundEntriesSt MANGOS_DLL_SPEC DBCStorage const* GetSpellStore(); MANGOS_DLL_SPEC DBCStorage const* GetSpellRangeStore(); MANGOS_DLL_SPEC DBCStorage const* GetFactionStore(); -MANGOS_DLL_SPEC DBCStorage const* GetItemDisplayStore(); MANGOS_DLL_SPEC DBCStorage const* GetCreatureDisplayStore(); MANGOS_DLL_SPEC DBCStorage const* GetEmotesStore(); MANGOS_DLL_SPEC DBCStorage const* GetEmotesTextStore(); - #endif diff --git a/src/game/DBCStructure.cpp b/src/game/DBCStructure.cpp new file mode 100644 index 000000000..535583c8a --- /dev/null +++ b/src/game/DBCStructure.cpp @@ -0,0 +1,353 @@ +/* + * Copyright (C) 2005-2010 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Common.h" +#include "DBCStructure.h" +#include "DBCStores.h" +#include "SharedDefines.h" + +int32 SpellEntry::CalculateSimpleValue(SpellEffectIndex eff) const +{ + if(SpellEffectEntry const* effectEntry = GetSpellEffectEntry(Id, eff)) + return effectEntry->CalculateSimpleValue(); + return 0; +} + +ClassFamilyMask const& SpellEntry::GetEffectSpellClassMask(SpellEffectIndex eff) const +{ + if (SpellEffectEntry const* effectEntry = GetSpellEffectEntry(Id, eff)) + return effectEntry->EffectSpellClassMask; + + static ClassFamilyMask const emptyCFM; + + return emptyCFM; +} + +SpellAuraOptionsEntry const* SpellEntry::GetSpellAuraOptions() const +{ + return SpellAuraOptionsId ? sSpellAuraOptionsStore.LookupEntry(SpellAuraOptionsId) : NULL; +} + +SpellAuraRestrictionsEntry const* SpellEntry::GetSpellAuraRestrictions() const +{ + return SpellAuraRestrictionsId ? sSpellAuraRestrictionsStore.LookupEntry(SpellAuraRestrictionsId) : NULL; +} + +SpellCastingRequirementsEntry const* SpellEntry::GetSpellCastingRequirements() const +{ + return SpellCastingRequirementsId ? sSpellCastingRequirementsStore.LookupEntry(SpellCastingRequirementsId) : NULL; +} + +SpellCategoriesEntry const* SpellEntry::GetSpellCategories() const +{ + return SpellCategoriesId ? sSpellCategoriesStore.LookupEntry(SpellCategoriesId) : NULL; +} + +SpellClassOptionsEntry const* SpellEntry::GetSpellClassOptions() const +{ + return SpellClassOptionsId ? sSpellClassOptionsStore.LookupEntry(SpellClassOptionsId) : NULL; +} + +SpellCooldownsEntry const* SpellEntry::GetSpellCooldowns() const +{ + return SpellCooldownsId ? sSpellCooldownsStore.LookupEntry(SpellCooldownsId) : NULL; +} + +SpellEffectEntry const* SpellEntry::GetSpellEffect(SpellEffectIndex eff) const +{ + return GetSpellEffectEntry(Id, eff); +} + +SpellEquippedItemsEntry const* SpellEntry::GetSpellEquippedItems() const +{ + return SpellEquippedItemsId ? sSpellEquippedItemsStore.LookupEntry(SpellEquippedItemsId) : NULL; +} + +SpellInterruptsEntry const* SpellEntry::GetSpellInterrupts() const +{ + return SpellInterruptsId ? sSpellInterruptsStore.LookupEntry(SpellInterruptsId) : NULL; +} + +SpellLevelsEntry const* SpellEntry::GetSpellLevels() const +{ + return SpellLevelsId ? sSpellLevelsStore.LookupEntry(SpellLevelsId) : NULL; +} + +SpellPowerEntry const* SpellEntry::GetSpellPower() const +{ + return SpellPowerId ? sSpellPowerStore.LookupEntry(SpellPowerId) : NULL; +} + +SpellReagentsEntry const* SpellEntry::GetSpellReagents() const +{ + return SpellReagentsId ? sSpellReagentsStore.LookupEntry(SpellReagentsId) : NULL; +} + +SpellScalingEntry const* SpellEntry::GetSpellScaling() const +{ + return SpellScalingId ? sSpellScalingStore.LookupEntry(SpellScalingId) : NULL; +} + +SpellShapeshiftEntry const* SpellEntry::GetSpellShapeshift() const +{ + return SpellShapeshiftId ? sSpellShapeshiftStore.LookupEntry(SpellShapeshiftId) : NULL; +} + +SpellTargetRestrictionsEntry const* SpellEntry::GetSpellTargetRestrictions() const +{ + return SpellTargetRestrictionsId ? sSpellTargetRestrictionsStore.LookupEntry(SpellTargetRestrictionsId) : NULL; +} + +SpellTotemsEntry const* SpellEntry::GetSpellTotems() const +{ + return SpellTotemsId ? sSpellTotemsStore.LookupEntry(SpellTotemsId) : NULL; +} + +uint32 SpellEntry::GetManaCost() const +{ + SpellPowerEntry const* power = GetSpellPower(); + return power ? power->manaCost : 0; +} + +uint32 SpellEntry::GetPreventionType() const +{ + SpellCategoriesEntry const* cat = GetSpellCategories(); + return cat ? cat->PreventionType : 0; +} + +uint32 SpellEntry::GetCategory() const +{ + SpellCategoriesEntry const* cat = GetSpellCategories(); + return cat ? cat->Category : 0; +} + +uint32 SpellEntry::GetStartRecoveryTime() const +{ + SpellCooldownsEntry const* cd = GetSpellCooldowns(); + return cd ? cd->StartRecoveryTime : 0; +} + +uint32 SpellEntry::GetMechanic() const +{ + SpellCategoriesEntry const* cat = GetSpellCategories(); + return cat ? cat->Mechanic : 0; +} + +uint32 SpellEntry::GetRecoveryTime() const +{ + SpellCooldownsEntry const* cd = GetSpellCooldowns(); + return cd ? cd->RecoveryTime : 0; +} + +uint32 SpellEntry::GetCategoryRecoveryTime() const +{ + SpellCooldownsEntry const* cd = GetSpellCooldowns(); + return cd ? cd->CategoryRecoveryTime : 0; +} + +uint32 SpellEntry::GetStartRecoveryCategory() const +{ + SpellCategoriesEntry const* cat = GetSpellCategories(); + return cat ? cat->StartRecoveryCategory : 0; +} + +uint32 SpellEntry::GetSpellLevel() const +{ + SpellLevelsEntry const* levels = GetSpellLevels(); + return levels ? levels->spellLevel : 0; +} + +int32 SpellEntry::GetEquippedItemClass() const +{ + SpellEquippedItemsEntry const* items = GetSpellEquippedItems(); + return items ? items->EquippedItemClass : -1; +} + +SpellFamily SpellEntry::GetSpellFamilyName() const +{ + SpellClassOptionsEntry const* classOpt = GetSpellClassOptions(); + return classOpt ? SpellFamily(classOpt->SpellFamilyName) : SPELLFAMILY_GENERIC; +} + +uint32 SpellEntry::GetDmgClass() const +{ + SpellCategoriesEntry const* cat = GetSpellCategories(); + return cat ? cat->DmgClass : 0; +} + +uint32 SpellEntry::GetDispel() const +{ + SpellCategoriesEntry const* cat = GetSpellCategories(); + return cat ? cat->Dispel : 0; +} + +uint32 SpellEntry::GetMaxAffectedTargets() const +{ + SpellTargetRestrictionsEntry const* target = GetSpellTargetRestrictions(); + return target ? target->MaxAffectedTargets : 0; +} + +uint32 SpellEntry::GetStackAmount() const +{ + SpellAuraOptionsEntry const* aura = GetSpellAuraOptions(); + return aura ? aura->StackAmount : 0; +} + +uint32 SpellEntry::GetManaCostPercentage() const +{ + SpellPowerEntry const* power = GetSpellPower(); + return power ? power->ManaCostPercentage : 0; +} + +uint32 SpellEntry::GetProcCharges() const +{ + SpellAuraOptionsEntry const* aura = GetSpellAuraOptions(); + return aura ? aura->procCharges : 0; +} + +uint32 SpellEntry::GetProcChance() const +{ + SpellAuraOptionsEntry const* aura = GetSpellAuraOptions(); + return aura ? aura->procChance : 0; +} + +uint32 SpellEntry::GetMaxLevel() const +{ + SpellLevelsEntry const* levels = GetSpellLevels(); + return levels ? levels->maxLevel : 0; +} + +uint32 SpellEntry::GetTargetAuraState() const +{ + SpellAuraRestrictionsEntry const* aura = GetSpellAuraRestrictions(); + return aura ? aura->TargetAuraState : 0; +} + +uint32 SpellEntry::GetManaPerSecond() const +{ + SpellPowerEntry const* power = GetSpellPower(); + return power ? power->manaPerSecond : 0; +} + +uint32 SpellEntry::GetRequiresSpellFocus() const +{ + SpellCastingRequirementsEntry const* castReq = GetSpellCastingRequirements(); + return castReq ? castReq->RequiresSpellFocus : 0; +} + +uint32 SpellEntry::GetSpellEffectIdByIndex(SpellEffectIndex index) const +{ + SpellEffectEntry const* effect = GetSpellEffect(index); + return effect ? effect->Effect : SPELL_EFFECT_NONE; +} + +uint32 SpellEntry::GetAuraInterruptFlags() const +{ + SpellInterruptsEntry const* interrupt = GetSpellInterrupts(); + return interrupt ? interrupt->AuraInterruptFlags : 0; +} + +uint32 SpellEntry::GetEffectImplicitTargetAByIndex(SpellEffectIndex index) const +{ + SpellEffectEntry const* effect = GetSpellEffect(index); + return effect ? effect->EffectImplicitTargetA : TARGET_NONE; +} + +int32 SpellEntry::GetAreaGroupId() const +{ + SpellCastingRequirementsEntry const* castReq = GetSpellCastingRequirements(); + return castReq ? castReq->AreaGroupId : -1; +} + +uint32 SpellEntry::GetFacingCasterFlags() const +{ + SpellCastingRequirementsEntry const* castReq = GetSpellCastingRequirements(); + return castReq ? castReq->FacingCasterFlags : -1; +} + +uint32 SpellEntry::GetBaseLevel() const +{ + SpellLevelsEntry const* levels = GetSpellLevels(); + return levels ? levels->baseLevel : 0; +} + +uint32 SpellEntry::GetInterruptFlags() const +{ + SpellInterruptsEntry const* interrupt = GetSpellInterrupts(); + return interrupt ? interrupt->InterruptFlags : 0; +} + +uint32 SpellEntry::GetTargetCreatureType() const +{ + SpellTargetRestrictionsEntry const* target = GetSpellTargetRestrictions(); + return target ? target->TargetCreatureType : 0; +} + +int32 SpellEntry::GetEffectMiscValue(SpellEffectIndex index) const +{ + SpellEffectEntry const* effect = GetSpellEffect(index); + return effect ? effect->EffectMiscValue : 0; +} + +uint32 SpellEntry::GetStances() const +{ + SpellShapeshiftEntry const* ss = GetSpellShapeshift(); + return ss ? ss->Stances : 0; +} + +uint32 SpellEntry::GetStancesNot() const +{ + SpellShapeshiftEntry const* ss = GetSpellShapeshift(); + return ss ? ss->StancesNot : 0; +} + +uint32 SpellEntry::GetProcFlags() const +{ + SpellAuraOptionsEntry const* aura = GetSpellAuraOptions(); + return aura ? aura->procFlags : 0; +} + +uint32 SpellEntry::GetChannelInterruptFlags() const +{ + SpellInterruptsEntry const* interrupt = GetSpellInterrupts(); + return interrupt ? interrupt->ChannelInterruptFlags : 0; +} + +uint32 SpellEntry::GetManaCostPerLevel() const +{ + SpellPowerEntry const* power = GetSpellPower(); + return power ? power->manaCostPerlevel : 0; +} + +uint32 SpellEntry::GetCasterAuraState() const +{ + SpellAuraRestrictionsEntry const* aura = GetSpellAuraRestrictions(); + return aura ? aura->CasterAuraState : 0; +} + +uint32 SpellEntry::GetTargets() const +{ + SpellTargetRestrictionsEntry const* target = GetSpellTargetRestrictions(); + return target ? target->Targets : 0; +} + +uint32 SpellEntry::GetEffectApplyAuraNameByIndex(SpellEffectIndex index) const +{ + SpellEffectEntry const* effect = GetSpellEffect(index); + return effect ? effect->EffectApplyAuraName : 0; +} diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index 23debe16a..e1faaa3ef 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -38,34 +38,32 @@ #pragma pack(push,1) #endif +typedef char const* const* DBCString; //char* DBCStrings[MAX_LOCALE]; + struct AchievementEntry { uint32 ID; // 0 m_ID uint32 factionFlag; // 1 m_faction -1=all, 0=horde, 1=alliance uint32 mapID; // 2 m_instance_id -1=none - // uint32 parentAchievement; // 3 m_supercedes its Achievement parent (can`t start while parent uncomplete, use its Criteria if don`t have own, use its progress on begin) - char* name[16]; // 4-19 m_title_lang - // uint32 name_flags; // 20 string flags - // char *description[16]; // 21-36 m_description_lang - // uint32 desc_flags; // 37 string flags - uint32 categoryId; // 38 m_category - uint32 points; // 39 m_points - // uint32 OrderInCategory; // 40 m_ui_order - uint32 flags; // 41 m_flags - // uint32 icon; // 42 m_iconID - // char *titleReward[16]; // 43-58 m_reward_lang - // uint32 titleReward_flags; // 59 string flags - uint32 count; // 60 m_minimum_criteria - need this count of completed criterias (own or referenced achievement criterias) - uint32 refAchievement; // 61 m_shares_criteria - referenced achievement (counting of all completed criterias) + //uint32 parentAchievement; // 3 m_supercedes its Achievement parent (can`t start while parent uncomplete, use its Criteria if don`t have own, use its progress on begin) + DBCString name; // 4 m_title_lang + //char *description; // 5 m_description_lang + uint32 categoryId; // 6 m_category + uint32 points; // 7 m_points + //uint32 OrderInCategory; // 8 m_ui_order + uint32 flags; // 9 m_flags + //uint32 icon; // 10 m_iconID + //char *titleReward; // 11 m_reward_lang + uint32 count; // 12 m_minimum_criteria - need this count of completed criterias (own or referenced achievement criterias) + uint32 refAchievement; // 13 m_shares_criteria - referenced achievement (counting of all completed criterias) }; struct AchievementCategoryEntry { uint32 ID; // 0 m_ID uint32 parentCategory; // 1 m_parent -1 for main category - // char *name[16]; // 2-17 m_name_lang - // uint32 name_flags; // 18 string flags - // uint32 sortOrder; // 19 m_ui_order + //char *name; // 2 m_name_lang + //uint32 sortOrder; // 3 m_ui_order }; struct AchievementCriteriaEntry @@ -490,13 +488,19 @@ struct AchievementCriteriaEntry uint32 additionalRequirement2_value; // 8 m_fail_asset } raw; }; - char* name[16]; // 9-24 m_description_lang - // uint32 name_flags; // 25 - uint32 completionFlag; // 26 m_flags - // uint32 timedCriteriaStartType; // 27 m_timer_start_event Only appears with timed achievements, seems to be the type of starting a timed Achievement, only type 1 and some of type 6 need manual starting: 1: ByEventId(?) (serverside IDs), 2: ByQuestId, 5: ByCastSpellId(?), 6: BySpellIdTarget(some of these are unknown spells, some not, some maybe spells), 7: ByKillNpcId, 9: ByUseItemId - uint32 timedCriteriaMiscId; // 28 m_timer_asset_id Alway appears with timed events, used internally to start the achievement, store - uint32 timeLimit; // 29 m_timer_time - uint32 showOrder; // 30 m_ui_order also used in achievement shift-links as index in state bitmask + DBCString name; // 9 m_description_lang + uint32 completionFlag; // 10 m_flags + uint32 timedCriteriaStartType; // 11 m_timer_start_event Only appears with timed achievements, seems to be the type of starting a timed Achievement, only type 1 and some of type 6 need manual starting + // 1: ByEventId(?) (serverside IDs), 2: ByQuestId, 5: ByCastSpellId(?) + // 6: BySpellIdTarget(some of these are unknown spells, some not, some maybe spells) + // 7: ByKillNpcId, 9: ByUseItemId + uint32 timedCriteriaMiscId; // 12 m_timer_asset_id Alway appears with timed events, used internally to start the achievement, store + uint32 timeLimit; // 13 m_timer_time time limit in seconds + uint32 showOrder; // 14 m_ui_order also used in achievement shift-links as index in state bitmask + //uint32 unk1; // 15 only one value, still unknown + //uint32 unk2; // 16 all zeros + //uint32 moreRequirement[3]; // 17-19 + //uint32 moreRequirementValue[3]; // 20-22 // helpers bool IsExplicitlyStartedTimedCriteria() const @@ -516,19 +520,23 @@ struct AreaTableEntry uint32 zone; // 2 m_ParentAreaID uint32 exploreFlag; // 3 m_AreaBit uint32 flags; // 4 m_flags - // 5 m_SoundProviderPref - // 6 m_SoundProviderPrefUnderwater - // 7 m_AmbienceID - // 8 m_ZoneMusic - // 9 m_IntroSound + // 5 m_SoundProviderPref + // 6 m_SoundProviderPrefUnderwater + // 7 m_AmbienceID + // 8 m_ZoneMusic + // 9 m_IntroSound int32 area_level; // 10 m_ExplorationLevel - char* area_name[16]; // 11-26 m_AreaName_lang - // 27 string flags - uint32 team; // 28 m_factionGroupMask - // 29-32 m_liquidTypeID[4] - // 33 m_minElevation - // 34 m_ambient_multiplier - // 35 m_lightid + DBCString area_name; // 11 m_AreaName_lang + uint32 team; // 12 m_factionGroupMask + // 13-16 m_liquidTypeID[4] + // 17 m_minElevation + // 18 m_ambient_multiplier + // 19 m_lightid + //uint32 unk20; // 20 4.0.0 + //uint32 unk21; // 21 4.0.0 + //uint32 unk22; // 22 4.0.0 + //uint32 unk23; // 23 4.0.0 + //uint32 unk24; // 24 4.0.1, may be worldStateId }; struct AreaGroupEntry @@ -545,11 +553,20 @@ struct AreaTriggerEntry float x; // 2 m_x float y; // 3 m_y float z; // 4 m_z - float radius; // 5 m_radius - float box_x; // 6 m_box_length - float box_y; // 7 m_box_width - float box_z; // 8 m_box_heigh - float box_orientation; // 9 m_box_yaw + //uint32 // 5 + //uint32 // 6 + //uint32 // 7 + float radius; // 8 m_radius + float box_x; // 9 m_box_length + float box_y; // 10 m_box_width + float box_z; // 11 m_box_heigh + float box_orientation; // 12 m_box_yaw +}; + +struct ArmorLocationEntry +{ + uint32 InventoryType; // 0 + float Value[5]; // 1-5 multiplier for armor types (cloth...plate, no armor?) }; struct AuctionHouseEntry @@ -558,8 +575,7 @@ struct AuctionHouseEntry uint32 faction; // 1 m_factionID uint32 depositPercent; // 2 m_depositRate uint32 cutPercent; // 3 m_consignmentRate - // char* name[16]; // 4-19 m_name_lang - // 20 string flags + //char* name; // 4 m_name_lang }; struct BankBagSlotPricesEntry @@ -572,14 +588,12 @@ struct BarberShopStyleEntry { uint32 Id; // 0 m_ID uint32 type; // 1 m_type - // char* name[16]; // 2-17 m_DisplayName_lang - // uint32 name_flags; // 18 string flags - // uint32 unk_name[16]; // 19-34 m_Description_lang - // uint32 unk_flags; // 35 string flags - // float CostMultiplier; // 36 m_Cost_Modifier - uint32 race; // 37 m_race - uint32 gender; // 38 m_sex - uint32 hair_id; // 39 m_data (real ID to hair/facial hair) + //char* name; // 2 m_DisplayName_lang + //uint32 unk_name; // 3 m_Description_lang + //float CostMultiplier; // 4 m_Cost_Modifier + uint32 race; // 5 m_race + uint32 gender; // 6 m_sex + uint32 hair_id; // 7 m_data (real ID to hair/facial hair) }; struct BattlemasterListEntry @@ -587,13 +601,16 @@ struct BattlemasterListEntry uint32 id; // 0 m_ID int32 mapid[8]; // 1-8 m_mapID[8] uint32 type; // 9 m_instanceType - // uint32 canJoinAsGroup; // 10 m_groupsAllowed - char* name[16]; // 11-26 m_name_lang - // uint32 nameFlags // 27 string flags - uint32 maxGroupSize; // 28 m_maxGroupSize - uint32 HolidayWorldStateId; // 29 m_holidayWorldState - uint32 minLevel; // 30 m_minlevel (sync with PvPDifficulty.dbc content) - uint32 maxLevel; // 31 m_maxlevel (sync with PvPDifficulty.dbc content) + //uint32 canJoinAsGroup; // 10 m_groupsAllowed + DBCString name; // 11 m_name_lang + uint32 maxGroupSize; // 12 m_maxGroupSize + uint32 HolidayWorldStateId; // 13 m_holidayWorldState + uint32 minLevel; // 14, m_minlevel (sync with PvPDifficulty.dbc content) + uint32 maxLevel; // 15, m_maxlevel (sync with PvPDifficulty.dbc content) + uint32 maxGroupSizeRated; // 16 4.0.1 + uint32 minPlayers; // 17 - 4.0.6.13596 + uint32 maxPlayers; // 18 4.0.1 + uint32 rated; // 19 4.0.3, value 2 for Rated Battlegrounds }; /*struct Cfg_CategoriesEntry @@ -602,8 +619,7 @@ struct BattlemasterListEntry uint32 Unk1; // m_localeMask uint32 Unk2; // m_charsetMask uint32 IsTournamentRealm; // m_flags - char *categoryName[16]; // m_name_lang - uint32 categoryNameFlags; + char *categoryName; // m_name_lang }*/ /*struct Cfg_ConfigsEntry @@ -618,82 +634,87 @@ struct BattlemasterListEntry struct CharStartOutfitEntry { - // uint32 Id; // 0 m_ID + //uint32 Id; // 0 m_ID uint32 RaceClassGender; // 1 m_raceID m_classID m_sexID m_outfitID (UNIT_FIELD_BYTES_0 & 0x00FFFFFF) comparable (0 byte = race, 1 byte = class, 2 byte = gender) int32 ItemId[MAX_OUTFIT_ITEMS]; // 2-25 m_ItemID - // int32 ItemDisplayId[MAX_OUTFIT_ITEMS]; // 26-29 m_DisplayItemID not required at server side - // int32 ItemInventorySlot[MAX_OUTFIT_ITEMS]; // 50-73 m_InventoryType not required at server side - // uint32 Unknown1; // 74 unique values (index-like with gaps ordered in other way as ids) - // uint32 Unknown2; // 75 - // uint32 Unknown3; // 76 + //int32 ItemDisplayId[MAX_OUTFIT_ITEMS]; // 26-29 m_DisplayItemID not required at server side + //int32 ItemInventorySlot[MAX_OUTFIT_ITEMS]; // 50-73 m_InventoryType not required at server side + //uint32 Unknown1; // 74 unique values (index-like with gaps ordered in other way as ids) + //uint32 Unknown2; // 75 + //uint32 Unknown3; // 76 + //uint32 Unknown4; // 77 + //uint32 Unknown5; // 78 }; struct CharTitlesEntry { uint32 ID; // 0, m_ID - // uint32 unk1; // 1 m_Condition_ID - char* name[16]; // 2-17 m_name_lang - // 18 string flags - // char* name2[16]; // 19-34 m_name1_lang - // 35 string flags - uint32 bit_index; // 36 m_mask_ID used in PLAYER_CHOSEN_TITLE and 1< CreatureDisplayInfoExtraEntry::DisplayExtraId float scale; // 4 m_creatureModelScale - // 5 m_creatureModelAlpha - // 6-8 m_textureVariation[3] - // 9 m_portraitTextureName - // 10 m_sizeClass - // 11 m_bloodID - // 12 m_NPCSoundID - // 13 m_particleColorID - // 14 m_creatureGeosetData - // 15 m_objectEffectPackageID + // 5 m_creatureModelAlpha + // 6-8 m_textureVariation[3] + // 9 m_portraitTextureName + // 10 m_sizeClass + // 11 m_bloodID + // 12 m_NPCSoundID + // 13 m_particleColorID + // 14 m_creatureGeosetData + // 15 m_objectEffectPackageID + // 16 all 0 }; struct CreatureDisplayInfoExtraEntry { uint32 DisplayExtraId; // 0 m_ID CreatureDisplayInfoEntry::m_extendedDisplayInfoID uint32 Race; // 1 m_DisplayRaceID - // uint32 Gender; // 2 m_DisplaySexID - // uint32 SkinColor; // 3 m_SkinID - // uint32 FaceType; // 4 m_FaceID - // uint32 HairType; // 5 m_HairStyleID - // uint32 HairStyle; // 6 m_HairColorID - // uint32 BeardStyle; // 7 m_FacialHairID - // uint32 Equipment[11]; // 8-18 m_NPCItemDisplay equipped static items EQUIPMENT_SLOT_HEAD..EQUIPMENT_SLOT_HANDS, client show its by self - // uint32 CanEquip; // 19 m_flags 0..1 Can equip additional things when used for players - // char* // 20 m_BakeName CreatureDisplayExtra-*.blp + //uint32 Gender; // 2 m_DisplaySexID + //uint32 SkinColor; // 3 m_SkinID + //uint32 FaceType; // 4 m_FaceID + //uint32 HairType; // 5 m_HairStyleID + //uint32 HairStyle; // 6 m_HairColorID + //uint32 BeardStyle; // 7 m_FacialHairID + //uint32 Equipment[11]; // 8-18 m_NPCItemDisplay equipped static items EQUIPMENT_SLOT_HEAD..EQUIPMENT_SLOT_HANDS, client show its by self + //uint32 CanEquip; // 19 m_flags 0..1 Can equip additional things when used for players + //char* // 20 m_BakeName CreatureDisplayExtra-*.blp }; struct CreatureFamilyEntry @@ -757,10 +779,9 @@ struct CreatureFamilyEntry uint32 skillLine[2]; // 5-6 m_skillLine uint32 petFoodMask; // 7 m_petFoodMask int32 petTalentType; // 8 m_petTalentType - // 9 m_categoryEnumID - char* Name[16]; // 10-25 m_name_lang - // 26 string flags - // 27 m_iconFile + // 9 m_categoryEnumID + DBCString Name; // 10 m_name_lang + // 11 m_iconFile }; #define MAX_CREATURE_SPELL_DATA_SLOT 4 @@ -769,34 +790,37 @@ struct CreatureSpellDataEntry { uint32 ID; // 0 m_ID uint32 spellId[MAX_CREATURE_SPELL_DATA_SLOT]; // 1-4 m_spells[4] - // uint32 availability[MAX_CREATURE_SPELL_DATA_SLOT];// 4-7 m_availability[4] + //uint32 availability[MAX_CREATURE_SPELL_DATA_SLOT]; // 4-7 m_availability[4] }; struct CreatureTypeEntry { uint32 ID; // 0 m_ID - // char* Name[16]; // 1-16 m_name_lang - // 17 string flags - // uint32 no_expirience; // 18 m_flags + //char* Name; // 1 m_name_lang + //uint32 no_expirience; // 2 m_flags no exp? critters, non-combat pets, gas cloud. }; -/* not used -struct CurrencyCategoryEntry +/*struct CurrencyCategoryEntry { uint32 ID; // 0 m_ID uint32 Unk1; // 1 m_flags 0 for known categories and 3 for unknown one (3.0.9) - char* Name[16]; // 2-17 m_name_lang - // // 18 string flags -}; -*/ + char* Name; // 2 m_name_lang +};*/ -struct CurrencyTypesEntry +/*struct CurrencyTypesEntry { - // uint32 ID; // 0 m_ID - uint32 ItemId; // 1 m_itemID used as real index - // uint32 Category; // 2 m_categoryID may be category - uint32 BitIndex; // 3 m_bitIndex bit index in PLAYER_FIELD_KNOWN_CURRENCIES (1 << (index-1)) -}; + //uint32 ID; // 0 m_ID + //uint32 Category; // 1 m_categoryID + //char *name; // 2 + //char *iconName; // 3 + //uint32 // 4 + //uint32 // 5 + //uint32 // 6 + //uint32 // 7 + //uint32 // 8 + //uint32 // 9 + //char* description; // 10 +};*/ struct DungeonEncounterEntry { @@ -805,9 +829,9 @@ struct DungeonEncounterEntry uint32 Difficulty; // 2 m_difficulty uint32 encounterData; // 3 m_orderIndex uint32 encounterIndex; // 4 m_Bit - char* encounterName[16]; // 5-20 m_name_lang - // uint32 nameLangFlags; // 21 m_name_lang_flags - // uint32 spellIconID; // 22 m_spellIconID + DBCString encounterName; // 5 - encounter name + //uint32 nameLangFlags; // 6 m_name_lang_flags + //uint32 spellIconID; // 7 m_spellIconID }; struct DurabilityCostsEntry @@ -825,20 +849,21 @@ struct DurabilityQualityEntry struct EmotesEntry { uint32 Id; // 0 m_ID - // char* Name; // 1 m_EmoteSlashCommand - // uint32 AnimationId; // 2 m_AnimID + //char* Name; // 1 m_EmoteSlashCommand + //uint32 AnimationId; // 2 m_AnimID uint32 Flags; // 3 m_EmoteFlags uint32 EmoteType; // 4 m_EmoteSpecProc (determine how emote are shown) uint32 UnitStandState; // 5 m_EmoteSpecProcParam - // uint32 SoundId; // 6 m_EventSoundID + //uint32 SoundId; // 6 m_EventSoundID + //uint32 unk; // 7 - 4.2.0 }; struct EmotesTextEntry { uint32 Id; // m_ID - // m_name + // m_name uint32 textid; // m_emoteID - // m_emoteText + // m_emoteText }; struct FactionEntry @@ -853,11 +878,10 @@ struct FactionEntry float spilloverRateIn; // 19 m_parentFactionMod[2] Faction gains incoming rep * spilloverRateIn float spilloverRateOut; // 20 Faction outputs rep * spilloverRateOut as spillover reputation uint32 spilloverMaxRankIn; // 21 m_parentFactionCap[2] The highest rank the faction will profit from incoming spillover - // uint32 spilloverRank_unk; // 22 It does not seem to be the max standing at which a faction outputs spillover ...so no idea - char* name[16]; // 23-38 m_name_lang - // 39 string flags - // char* description[16]; // 40-55 m_description_lang - // 56 string flags + //uint32 spilloverRank_unk; // 22 It does not seem to be the max standing at which a faction outputs spillover ...so no idea + DBCString name; // 23 m_name_lang + //char* description; // 24 m_description_lang + //uint32 // 25 // helpers @@ -866,7 +890,7 @@ struct FactionEntry for (int i = 0; i < 4; ++i) { if ((BaseRepRaceMask[i] == 0 || (BaseRepRaceMask[i] & raceMask)) && - (BaseRepClassMask[i] == 0 || (BaseRepClassMask[i] & classMask))) + (BaseRepClassMask[i] == 0 || (BaseRepClassMask[i] & classMask))) return i; } @@ -889,12 +913,12 @@ struct FactionTemplateEntry // helpers bool IsFriendlyTo(FactionTemplateEntry const& entry) const { - if (entry.faction) + if(entry.faction) { - for (int i = 0; i < 4; ++i) + for(int i = 0; i < 4; ++i) if (enemyFaction[i] == entry.faction) return false; - for (int i = 0; i < 4; ++i) + for(int i = 0; i < 4; ++i) if (friendFaction[i] == entry.faction) return true; } @@ -902,49 +926,52 @@ struct FactionTemplateEntry } bool IsHostileTo(FactionTemplateEntry const& entry) const { - if (entry.faction) + if(entry.faction) { - for (int i = 0; i < 4; ++i) + for(int i = 0; i < 4; ++i) if (enemyFaction[i] == entry.faction) return true; - for (int i = 0; i < 4; ++i) + for(int i = 0; i < 4; ++i) if (friendFaction[i] == entry.faction) return false; } return (hostileMask & entry.ourMask) != 0; } - bool IsHostileToPlayers() const { return (hostileMask & FACTION_MASK_PLAYER) != 0; } + bool IsHostileToPlayers() const { return (hostileMask & FACTION_MASK_PLAYER) !=0; } bool IsNeutralToAll() const { - for (int i = 0; i < 4; ++i) + for(int i = 0; i < 4; ++i) if (enemyFaction[i] != 0) return false; return hostileMask == 0 && friendlyMask == 0; } - bool IsContestedGuardFaction() const { return (factionFlags & FACTION_TEMPLATE_FLAG_CONTESTED_GUARD) != 0; } + bool IsContestedGuardFaction() const { return (factionFlags & FACTION_TEMPLATE_FLAG_CONTESTED_GUARD)!=0; } }; struct GameObjectDisplayInfoEntry { uint32 Displayid; // 0 m_ID - // char* filename; // 1 m_modelName - // 2-11 m_Sound - float unknown12; // 12 m_geoBoxMinX (use first value as interact dist, mostly in hacks way) - // 13 m_geoBoxMinY - // 14 m_geoBoxMinZ - // 15 m_geoBoxMaxX - // 16 m_geoBoxMaxY - // 17 m_geoBoxMaxZ - // 18 m_objectEffectPackageID + //DBCString filename; // 1 + //uint32 unk1[10]; // 2-11 + float minX; // 1 + float minY; // 13 + float minZ; // 14 + float maxX; // 15 + float maxY; // 16 + float maxZ; // 17 + //uint32 transport; // 18 + //uint32 unk; // 19 + //uint32 unk1; // 20 }; struct GemPropertiesEntry { - uint32 ID; // m_id - uint32 spellitemenchantement; // m_enchant_id - // m_maxcount_inv - // m_maxcount_item - uint32 color; // m_type + uint32 ID; // 0 m_id + uint32 spellitemenchantement; // 1 m_enchant_id + // 2 m_maxcount_inv + // 3 m_maxcount_item + uint32 color; // 4 m_type + //uint32 // 5 }; struct GlyphPropertiesEntry @@ -969,31 +996,37 @@ struct GlyphSlotEntry struct GtBarberShopCostBaseEntry { + //uint32 level; float cost; }; struct GtCombatRatingsEntry { + //uint32 level; float ratio; }; struct GtChanceToMeleeCritBaseEntry { + //uint32 level; float base; }; struct GtChanceToMeleeCritEntry { + //uint32 level; float ratio; }; struct GtChanceToSpellCritBaseEntry { + //uint32 level; float base; }; struct GtChanceToSpellCritEntry { + //uint32 level; float ratio; }; @@ -1002,162 +1035,160 @@ struct GtOCTClassCombatRatingScalarEntry float ratio; }; -struct GtOCTRegenHPEntry +/*struct GtOCTRegenHPEntry { + //uint32 level; float ratio; -}; +};*/ -// struct GtOCTRegenMPEntry +//struct GtOCTRegenMPEntry //{ // float ratio; //}; -struct GtRegenHPPerSptEntry +/*struct GtRegenHPPerSptEntry { + //uint32 level; float ratio; -}; +};*/ struct GtRegenMPPerSptEntry { + //uint32 level; float ratio; }; /*struct HolidayDescriptionsEntry { - uint32 ID; // 0 m_ID this is NOT holiday id - // char* name[16] // 1-16 m_name_lang - // 17 string flags + uint32 ID; // 0, m_ID this is NOT holiday id + //char* name; // 1 m_name_lang };*/ -/* no used -struct HolidayNamesEntry +/*struct HolidayNamesEntry { - uint32 ID; // 0 m_ID this is NOT holiday id - // char* name[16] // 1-16 m_name_lang - // 17 string flags -}; -*/ + uint32 ID; // 0, m_ID this is NOT holiday id + //char* name; // 1 m_name_lang +};*/ struct HolidaysEntry { uint32 ID; // 0 m_ID - // uint32 duration[10]; // 1-10 m_duration - // uint32 date[26]; // 11-36 m_date (dates in unix time starting at January, 1, 2000) - // uint32 region; // 37 m_region (wow region) - // uint32 looping; // 38 m_looping - // uint32 calendarFlags[10]; // 39-48 m_calendarFlags - // uint32 holidayNameId; // 49 m_holidayNameID (HolidayNames.dbc) - // uint32 holidayDescriptionId; // 50 m_holidayDescriptionID (HolidayDescriptions.dbc) - // char *textureFilename; // 51 m_textureFilename - // uint32 priority; // 52 m_priority - // uint32 calendarFilterType; // 53 m_calendarFilterType (-1,0,1 or 2) - // uint32 flags; // 54 m_flags + //uint32 duration[10]; // 1-10 m_duration + //uint32 date[26]; // 11-36 m_date (dates in unix time starting at January, 1, 2000) + //uint32 region; // 37 m_region (wow region) + //uint32 looping; // 38 m_looping + //uint32 calendarFlags[10]; // 39-48 m_calendarFlags + //uint32 holidayNameId; // 49 m_holidayNameID (HolidayNames.dbc) + //uint32 holidayDescriptionId; // 50 m_holidayDescriptionID (HolidayDescriptions.dbc) + //char *textureFilename; // 51 m_textureFilename + //uint32 priority; // 52 m_priority + //uint32 calendarFilterType; // 53 m_calendarFilterType (-1,0,1 or 2) + //uint32 flags; // 54 m_flags }; -struct ItemEntry +struct ItemArmorQualityEntry { - uint32 ID; // 0 m_ID - uint32 Class; // 1 m_classID - uint32 SubClass; // 2 m_subclassID (some items have strange subclasses) - int32 Unk0; // 3 m_sound_override_subclassid - int32 Material; // 4 m_material - uint32 DisplayId; // 5 m_displayInfoID - uint32 InventoryType; // 6 m_inventoryType - uint32 Sheath; // 7 m_sheatheType + uint32 Id; // 0 item level + float Value[7]; // 1-7 multiplier for item quality + uint32 Id2; // 8 item level +}; + +struct ItemArmorShieldEntry +{ + uint32 Id; // 0 item level + uint32 Id2; // 1 item level + float Value[7]; // 2-8 multiplier for item quality +}; + +struct ItemArmorTotalEntry +{ + uint32 Id; // 0 item level + uint32 Id2; // 1 item level + float Value[4]; // 2-5 multiplier for armor types (cloth...plate) }; struct ItemBagFamilyEntry { uint32 ID; // 0 m_ID - // char* name[16] // 1-16 m_name_lang - // // 17 name flags + //char* name; // 1 m_name_lang }; struct ItemClassEntry { uint32 ID; // 0 m_ID - // uint32 unk1; // 1 - // uint32 unk2; // 2 only weapon have 1 in field, other 0 - char* name[16]; // 3-19 m_name_lang - // // 20 name flags + uint32 Class; // 1 + //uint32 unk2; // 2 looks like second class + //uint32 unk3; // 3 1 for weapons + //float Multiplier // 4 + DBCString name; // 5 m_name_lang }; struct ItemDisplayInfoEntry { uint32 ID; // 0 m_ID - // 1 m_modelName[2] - // 2 m_modelTexture[2] - // 3 m_inventoryIcon - // 4 m_geosetGroup[3] - // 5 m_flags - // 6 m_spellVisualID - // 7 m_groupSoundIndex - // 8 m_helmetGeosetVis[2] - // 9 m_texture[2] - // 10 m_itemVisual[8] - // 11 m_particleColorID + // 1 m_modelName[2] + // 2 m_modelTexture[2] + // 3 m_inventoryIcon + // 4 m_geosetGroup[3] + // 5 m_flags + // 6 m_spellVisualID + // 7 m_groupSoundIndex + // 8 m_helmetGeosetVis[2] + // 9 m_texture[2] + // 10 m_itemVisual[8] + // 11 m_particleColorID }; -// struct ItemCondExtCostsEntry -//{ -// uint32 ID; -// uint32 condExtendedCost; // ItemPrototype::CondExtendedCost -// uint32 itemextendedcostentry; // ItemPrototype::ExtendedCost -// uint32 arenaseason; // arena season number(1-4) -//}; - -#define MAX_EXTENDED_COST_ITEMS 5 - -struct ItemExtendedCostEntry +// common struct for: +// ItemDamageAmmo.dbc +// ItemDamageOneHand.dbc +// ItemDamageOneHandCaster.dbc +// ItemDamageRanged.dbc +// ItemDamageThrown.dbc +// ItemDamageTwoHand.dbc +// ItemDamageTwoHandCaster.dbc +// ItemDamageWand.dbc +struct ItemDamageEntry { - uint32 ID; // 0 m_ID - uint32 reqhonorpoints; // 1 m_honorPoints - uint32 reqarenapoints; // 2 m_arenaPoints - uint32 reqarenaslot; // 4 m_arenaBracket - uint32 reqitem[MAX_EXTENDED_COST_ITEMS]; // 5-8 m_itemID - uint32 reqitemcount[MAX_EXTENDED_COST_ITEMS]; // 9-13 m_itemCount - uint32 reqpersonalarenarating; // 14 m_requiredArenaRating - // 15 m_itemPurchaseGroup + uint32 Id; // 0 item level + float Value[7]; // 1-7 multiplier for item quality + uint32 Id2; // 8 item level }; struct ItemLimitCategoryEntry { uint32 ID; // 0 Id m_ID - // char* name[16] // 1-16 m_name_lang - // 17 string flags - uint32 maxCount; // 18 m_quantity max allowed equipped as item or in gem slot - uint32 mode; // 19 m_flags 0 = have, 1 = equip (enum ItemLimitCategoryMode) + //char* name; // 1 m_name_lang + uint32 maxCount; // 2, m_quantity max allowed equipped as item or in gem slot + uint32 mode; // 3, m_flags 0 = have, 1 = equip (enum ItemLimitCategoryMode) }; struct ItemRandomPropertiesEntry { uint32 ID; // 0 m_ID - // char* internalName // 1 m_Name + //char* internalName // 1 m_Name uint32 enchant_id[5]; // 2-6 m_Enchantment - char* nameSuffix[16]; // 7-22 m_name_lang - // 23 string flags + DBCString nameSuffix; // 7 m_name_lang }; struct ItemRandomSuffixEntry { uint32 ID; // 0 m_ID - char* nameSuffix[16]; // 1-16 m_name_lang - // 17 string flags - // 18 m_internalName - uint32 enchant_id[5]; // 19-21 m_enchantment - uint32 prefix[5]; // 22-24 m_allocationPct + DBCString nameSuffix; // 1 m_name_lang + // 2 m_internalName + uint32 enchant_id[5]; // 3-7 m_enchantment + uint32 prefix[5]; // 8-12 m_allocationPct }; struct ItemSetEntry { - // uint32 id // 0 m_ID - char* name[16]; // 1-16 m_name_lang - // 17 string flags - // uint32 itemId[17]; // 18-34 m_itemID - uint32 spells[8]; // 35-42 m_setSpellID - uint32 items_to_triggerspell[8]; // 43-50 m_setThreshold - uint32 required_skill_id; // 51 m_requiredSkill - uint32 required_skill_value; // 52 m_requiredSkillRank + //uint32 id // 0 m_ID + DBCString name; // 1 m_name_lang + //uint32 itemId[17]; // 2-18 m_itemID + uint32 spells[8]; // 19-26 m_setSpellID + uint32 items_to_triggerspell[8]; // 27-34 m_setThreshold + uint32 required_skill_id; // 35 m_requiredSkill + uint32 required_skill_value; // 36 m_requiredSkillRank }; /*struct LfgDungeonsEntry @@ -1210,40 +1241,38 @@ struct LockEntry uint32 Type[MAX_LOCK_CASE]; // 1-8 m_Type uint32 Index[MAX_LOCK_CASE]; // 9-16 m_Index uint32 Skill[MAX_LOCK_CASE]; // 17-24 m_Skill - // uint32 Action[MAX_LOCK_CASE]; // 25-32 m_Action + //uint32 Action[MAX_LOCK_CASE]; // 25-32 m_Action }; struct MailTemplateEntry { uint32 ID; // 0 m_ID - // char* subject[16]; // 1-16 m_subject_lang - // 17 string flags - char* content[16]; // 18-33 m_body_lang + //char* subject; // 1 m_subject_lang + DBCString content; // 2 m_body_lang }; struct MapEntry { uint32 MapID; // 0 m_ID - // char* internalname; // 1 m_Directory + //char* internalname; // 1 m_Directory uint32 map_type; // 2 m_InstanceType - // uint32 mapFlags; // 3 m_Flags (0x100 - CAN_CHANGE_PLAYER_DIFFICULTY) - // uint32 isPvP; // 4 m_PVP 0 or 1 for battlegrounds (not arenas) - char* name[16]; // 5-20 m_MapName_lang - // 21 string flags - uint32 linked_zone; // 22 m_areaTableID - // char* hordeIntro[16]; // 23-38 m_MapDescription0_lang - // 39 string flags - // char* allianceIntro[16]; // 40-55 m_MapDescription1_lang - // 56 string flags - uint32 multimap_id; // 57 m_LoadingScreenID (LoadingScreens.dbc) - // float BattlefieldMapIconScale; // 58 m_minimapIconScale - int32 ghost_entrance_map; // 59 m_corpseMapID map_id of entrance map in ghost mode (continent always and in most cases = normal entrance) - float ghost_entrance_x; // 60 m_corpseX entrance x coordinate in ghost mode (in most cases = normal entrance) - float ghost_entrance_y; // 61 m_corpseY entrance y coordinate in ghost mode (in most cases = normal entrance) - // uint32 timeOfDayOverride; // 62 m_timeOfDayOverride - uint32 addon; // 63 m_expansionID - // 64 m_raidOffset - // uint32 maxPlayers; // 65 m_maxPlayers + //uint32 mapFlags; // 3 m_Flags (0x100 - CAN_CHANGE_PLAYER_DIFFICULTY) + //uint32 unk4; // 4 4.0.1 + //uint32 isPvP; // 5 m_PVP 0 or 1 for battlegrounds (not arenas) + DBCString name; // 6 m_MapName_lang + uint32 linked_zone; // 7 m_areaTableID + //char* hordeIntro; // 8 m_MapDescription0_lang + //char* allianceIntro; // 9 m_MapDescription1_lang + uint32 multimap_id; // 10 m_LoadingScreenID (LoadingScreens.dbc) + //float BattlefieldMapIconScale; // 11 m_minimapIconScale + int32 ghost_entrance_map; // 12 m_corpseMapID map_id of entrance map in ghost mode (continent always and in most cases = normal entrance) + float ghost_entrance_x; // 13 m_corpseX entrance x coordinate in ghost mode (in most cases = normal entrance) + float ghost_entrance_y; // 14 m_corpseY entrance y coordinate in ghost mode (in most cases = normal entrance) + //uint32 timeOfDayOverride; // 15 m_timeOfDayOverride + uint32 addon; // 16 m_expansionID + //uint32 unkTime; // 17 m_raidOffset + //uint32 maxPlayers; // 18 m_maxPlayers + uint32 NextPhaseMap; // 19 - MapId for next phase. // Helpers uint32 Expansion() const { return addon; } @@ -1259,10 +1288,10 @@ struct MapEntry bool IsMountAllowed() const { return !IsDungeon() || - MapID == 209 || MapID == 269 || MapID == 309 || // TanarisInstance, CavernsOfTime, Zul'gurub - MapID == 509 || MapID == 534 || MapID == 560 || // AhnQiraj, HyjalPast, HillsbradPast - MapID == 568 || MapID == 580 || MapID == 595 || // ZulAman, Sunwell Plateau, Culling of Stratholme - MapID == 603 || MapID == 615 || MapID == 616;// Ulduar, The Obsidian Sanctum, The Eye Of Eternity + MapID==209 || MapID==269 || MapID==309 || // TanarisInstance, CavernsOfTime, Zul'gurub + MapID==509 || MapID==534 || MapID==560 || // AhnQiraj, HyjalPast, HillsbradPast + MapID==568 || MapID==580 || MapID==595 || // ZulAman, Sunwell Plateau, Culling of Stratholme + MapID==603 || MapID==615 || MapID==616; // Ulduar, The Obsidian Sanctum, The Eye Of Eternity } bool IsContinent() const @@ -1273,21 +1302,30 @@ struct MapEntry struct MapDifficultyEntry { - // uint32 Id; // 0 m_ID + //uint32 Id; // 0 m_ID uint32 MapId; // 1 m_mapID uint32 Difficulty; // 2 m_difficulty (for arenas: arena slot) - // char* areaTriggerText[16]; // 3-18 m_message_lang (text showed when transfer to map failed) - // uint32 textFlags; // 19 + //char* areaTriggerText; // 3 m_message_lang (text showed when transfer to map failed) + uint32 resetTime; // 4, m_raidDuration in secs, 0 if no fixed reset time + uint32 maxPlayers; // 5, m_maxPlayers some heroic versions have 0 when expected same amount as in normal version + //char* difficultyString; // 6 m_difficultystring +}; + +// Additional 335 fields to MapDifficulty +/* + //char* areaTriggerText[16]; // 3-18 m_message_lang (text showed when transfer to map failed) + //uint32 textFlags; // 19 uint32 resetTime; // 20 m_raidDuration in secs, 0 if no fixed reset time uint32 maxPlayers; // 21 m_maxPlayers some heroic versions have 0 when expected same amount as in normal version - // char* difficultyString; // 22 m_difficultystring -}; + //char* difficultyString; // 22 +*/ struct MovieEntry { uint32 Id; // 0 m_ID - // char* filename; // 1 m_filename - // uint32 unk2; // 2 m_volume + //char* filename; // 1 m_filename + //uint32 unk1; // 2 m_volume + //uint32 unk2; // 3 4.0.0 }; #define MAX_OVERRIDE_SPELLS 10 @@ -1296,12 +1334,20 @@ struct OverrideSpellDataEntry { uint32 Id; // 0 m_ID uint32 Spells[MAX_OVERRIDE_SPELLS]; // 1-10 m_spells - // uint32 unk2; // 11 m_flags + //uint32 unk2; // 11 m_flags + //uint32 unk3; // 12 possibly flag +}; + +struct PhaseEntry +{ + uint32 Id; // 0 + uint32 PhaseShift; // 1 + uint32 Flags; // 2 - 0x0, 0x4, 0x8 }; struct PvPDifficultyEntry { - // uint32 id; // 0 m_ID + //uint32 id; // 0 m_ID uint32 mapId; // 1 m_mapID uint32 bracketId; // 2 m_rangeIndex uint32 minLevel; // 3 m_minLevel @@ -1321,8 +1367,7 @@ struct QuestFactionRewardEntry struct QuestSortEntry { uint32 id; // 0 m_ID - // char* name[16]; // 1-16 m_SortName_lang - // 17 string flags + //char* name; // 1 m_SortName_lang }; struct QuestXPLevel @@ -1333,7 +1378,7 @@ struct QuestXPLevel struct RandomPropertiesPointsEntry { - // uint32 Id; // 0 m_ID + //uint32 Id; // 0 m_ID uint32 itemLevel; // 1 m_ItemLevel uint32 EpicPropertiesPoints[5]; // 2-6 m_Epic uint32 RarePropertiesPoints[5]; // 7-11 m_Superior @@ -1345,59 +1390,59 @@ struct ScalingStatDistributionEntry uint32 Id; // 0 m_ID int32 StatMod[10]; // 1-10 m_statID uint32 Modifier[10]; // 11-20 m_bonus - uint32 MaxLevel; // 21 m_maxlevel + //uint32 unk1; // 21 + uint32 MaxLevel; // 22 m_maxlevel }; struct ScalingStatValuesEntry { uint32 Id; // 0 m_ID uint32 Level; // 1 m_charlevel - uint32 ssdMultiplier[4]; // 2-5 Multiplier for ScalingStatDistribution - uint32 armorMod[4]; // 6-9 Armor for level - uint32 dpsMod[6]; // 10-15 DPS mod for level - uint32 spellBonus; // 16 spell power for level - uint32 ssdMultiplier2; // 17 there's data from 3.1 dbc ssdMultiplier[3] - uint32 ssdMultiplier3; // 18 3.3 - // uint32 unk2; // 19 unk, probably also Armor for level (flag 0x80000?) - uint32 armorMod2[4]; // 20-23 Armor for level + uint32 dpsMod[6]; // 2-7 DPS mod for level + uint32 spellBonus; // 8 spell power for level + uint32 ssdMultiplier[5]; // 9-13 Multiplier for ScalingStatDistribution + uint32 armorMod[4]; // 14-17 Armor for level + uint32 armorMod2[4]; // 18-21 Armor for level + //uint32 trash[24]; // 22-45 + //uint32 unk2; // 46 unk, probably also Armor for level (flag 0x80000?) - /*struct ScalingStatValuesEntry - { - m_ID - m_charlevel - m_shoulderBudget - m_trinketBudget - m_weaponBudget1H - m_rangedBudget - m_clothShoulderArmor - m_leatherShoulderArmor - m_mailShoulderArmor - m_plateShoulderArmor - m_weaponDPS1H - m_weaponDPS2H - m_spellcasterDPS1H - m_spellcasterDPS2H - m_rangedDPS - m_wandDPS - m_spellPower - m_primaryBudget - m_tertiaryBudget - m_clothCloakArmor - m_clothChestArmor - m_leatherChestArmor - m_mailChestArmor - m_plateChestArmor - };*/ +/*struct ScalingStatValuesEntry +{ + m_ID + m_charlevel + m_shoulderBudget + m_trinketBudget + m_weaponBudget1H + m_rangedBudget + m_clothShoulderArmor + m_leatherShoulderArmor + m_mailShoulderArmor + m_plateShoulderArmor + m_weaponDPS1H + m_weaponDPS2H + m_spellcasterDPS1H + m_spellcasterDPS2H + m_rangedDPS + m_wandDPS + m_spellPower + m_primaryBudget + m_tertiaryBudget + m_clothCloakArmor + m_clothChestArmor + m_leatherChestArmor + m_mailChestArmor + m_plateChestArmor +};*/ uint32 getssdMultiplier(uint32 mask) const { if (mask & 0x4001F) { - if (mask & 0x00000001) return ssdMultiplier[0]; - if (mask & 0x00000002) return ssdMultiplier[1]; - if (mask & 0x00000004) return ssdMultiplier[2]; - if (mask & 0x00000008) return ssdMultiplier2; - if (mask & 0x00000010) return ssdMultiplier[3]; - if (mask & 0x00040000) return ssdMultiplier3; + if(mask & 0x00000001) return ssdMultiplier[1]; + if(mask & 0x00000002) return ssdMultiplier[2]; // 0 and 1 were duplicated + if(mask & 0x00000004) return ssdMultiplier[3]; + if(mask & 0x00000008) return ssdMultiplier[0]; + if(mask & 0x00000010) return ssdMultiplier[4]; + if(mask & 0x00040000) return ssdMultiplier[2]; // 4.0.0 } return 0; } @@ -1406,15 +1451,15 @@ struct ScalingStatValuesEntry { if (mask & 0x00F001E0) { - if (mask & 0x00000020) return armorMod[0]; - if (mask & 0x00000040) return armorMod[1]; - if (mask & 0x00000080) return armorMod[2]; - if (mask & 0x00000100) return armorMod[3]; + if(mask & 0x00000020) return armorMod[0]; + if(mask & 0x00000040) return armorMod[1]; + if(mask & 0x00000080) return armorMod[2]; + if(mask & 0x00000100) return armorMod[3]; - if (mask & 0x00100000) return armorMod2[0]; // cloth - if (mask & 0x00200000) return armorMod2[1]; // leather - if (mask & 0x00400000) return armorMod2[2]; // mail - if (mask & 0x00800000) return armorMod2[3]; // plate + if(mask & 0x00100000) return armorMod2[0]; // cloth + if(mask & 0x00200000) return armorMod2[1]; // leather + if(mask & 0x00400000) return armorMod2[2]; // mail + if(mask & 0x00800000) return armorMod2[3]; // plate } return 0; } @@ -1423,12 +1468,12 @@ struct ScalingStatValuesEntry { if (mask & 0x7E00) { - if (mask & 0x00000200) return dpsMod[0]; - if (mask & 0x00000400) return dpsMod[1]; - if (mask & 0x00000800) return dpsMod[2]; - if (mask & 0x00001000) return dpsMod[3]; - if (mask & 0x00002000) return dpsMod[4]; - if (mask & 0x00004000) return dpsMod[5]; // not used? + if(mask & 0x00000200) return dpsMod[0]; + if(mask & 0x00000400) return dpsMod[1]; + if(mask & 0x00000800) return dpsMod[2]; + if(mask & 0x00001000) return dpsMod[3]; + if(mask & 0x00002000) return dpsMod[4]; + if(mask & 0x00004000) return dpsMod[5]; // not used? } return 0; } @@ -1448,24 +1493,23 @@ struct ScalingStatValuesEntry } }; -/*struct SkillLineCategoryEntry -{ - uint32 id; // 0 m_ID - char* name[16]; // 1-17 m_name_lang - // 18 string flags - uint32 displayOrder; // 19 m_sortIndex +/*struct SkillLineCategoryEntry{ + uint32 id; // 0 m_ID + char* name; // 1 m_name_lang + uint32 displayOrder; // 2 m_sortIndex };*/ struct SkillRaceClassInfoEntry { - // uint32 id; // 0 m_ID + //uint32 id; // 0 m_ID uint32 skillId; // 1 m_skillID uint32 raceMask; // 2 m_raceMask uint32 classMask; // 3 m_classMask uint32 flags; // 4 m_flags uint32 reqLevel; // 5 m_minLevel - // uint32 skillTierId; // 6 m_skillTierID - // uint32 skillCostID; // 7 m_skillCostIndex + //uint32 skillTierId; // 6 m_skillTierID + //uint32 skillCostID; // 7 m_skillCostIndex + //uint32 Unk; // 8 }; /*struct SkillTiersEntry{ @@ -1478,15 +1522,11 @@ struct SkillLineEntry { uint32 id; // 0 m_ID int32 categoryId; // 1 m_categoryID - // uint32 skillCostID; // 2 m_skillCostsID - char* name[16]; // 3-18 m_displayName_lang - // 19 string flags - // char* description[16]; // 20-35 m_description_lang - // 36 string flags - uint32 spellIcon; // 37 m_spellIconID - // char* alternateVerb[16]; // 38-53 m_alternateVerb_lang - // 54 string flags - uint32 canLink; // 55 m_canLink (prof. with recipes) + DBCString name; // 2 m_displayName_lang + //DBCString description; // 3 m_description_lang + uint32 spellIcon; // 4 m_spellIconID + //DBCString alternateVerb; // 5 m_alternateVerb_lang + uint32 canLink; // 6 m_canLink (prof. with recipes) }; struct SkillLineAbilityEntry @@ -1496,30 +1536,36 @@ struct SkillLineAbilityEntry uint32 spellId; // 2 m_spell uint32 racemask; // 3 m_raceMask uint32 classmask; // 4 m_classMask - // uint32 racemaskNot; // 5 m_excludeRace - // uint32 classmaskNot; // 6 m_excludeClass + //uint32 racemaskNot; // 5 m_excludeRace + //uint32 classmaskNot; // 6 m_excludeClass uint32 req_skill_value; // 7 m_minSkillLineRank uint32 forward_spellid; // 8 m_supercededBySpell uint32 learnOnGetSkill; // 9 m_acquireMethod uint32 max_value; // 10 m_trivialSkillLineRankHigh uint32 min_value; // 11 m_trivialSkillLineRankLow - // uint32 characterPoints[2]; // 12-13 m_characterPoints[2] + //uint32 // 12 + //uint32 // 13 4.0.0 }; struct SoundEntriesEntry { uint32 Id; // 0 m_ID - // uint32 Type; // 1 m_soundType - // char* InternalName; // 2 m_name - // char* FileName[10]; // 3-12 m_File[10] - // uint32 Unk13[10]; // 13-22 m_Freq[10] - // char* Path; // 23 m_DirectoryBase - // 24 m_volumeFloat - // 25 m_flags - // 26 m_minDistance - // 27 m_distanceCutoff - // 28 m_EAXDef - // 29 m_soundEntriesAdvancedID + //uint32 Type; // 1 m_soundType + //char* InternalName; // 2 m_name + //char* FileName[10]; // 3-12 m_File[10] + //uint32 Unk13[10]; // 13-22 m_Freq[10] + //char* Path; // 23 m_DirectoryBase + // 24 m_volumeFloat + // 25 m_flags + // 26 m_minDistance + // 27 m_distanceCutoff + // 28 m_EAXDef + // 29 m_soundEntriesAdvancedID, new in 3.1 + //unk // 30 4.0.0 + //unk // 31 4.0.0 + //unk // 32 4.0.0 + //unk // 33 4.0.0 + //unk // 34 4.3.0 }; struct ClassFamilyMask @@ -1531,7 +1577,7 @@ struct ClassFamilyMask explicit ClassFamilyMask(uint64 familyFlags, uint32 familyFlags2 = 0) : Flags(familyFlags), Flags2(familyFlags2) {} bool Empty() const { return Flags == 0 && Flags2 == 0; } - bool operator!() const { return Empty(); } + bool operator! () const { return Empty(); } operator void const* () const { return Empty() ? NULL : this; }// for allow normal use in if(mask) bool IsFitToFamilyMask(uint64 familyFlags, uint32 familyFlags2 = 0) const @@ -1544,7 +1590,7 @@ struct ClassFamilyMask return (Flags & mask.Flags) || (Flags2 & mask.Flags2); } - uint64 operator& (uint64 mask) const // possible will removed at finish convertion code use IsFitToFamilyMask + uint64 operator& (uint64 mask) const // possible will removed at finish convertion code use IsFitToFamilyMask { return Flags & mask; } @@ -1561,153 +1607,375 @@ struct ClassFamilyMask #define MAX_SPELL_TOTEMS 2 #define MAX_SPELL_TOTEM_CATEGORIES 2 +// SpellAuraOptions.dbc +struct SpellAuraOptionsEntry +{ + //uint32 Id; // 0 m_ID + uint32 StackAmount; // 51 m_cumulativeAura + uint32 procChance; // 38 m_procChance + uint32 procCharges; // 39 m_procCharges + uint32 procFlags; // 37 m_procTypeMask +}; + +// SpellAuraRestrictions.dbc +struct SpellAuraRestrictionsEntry +{ + //uint32 Id; // 0 m_ID + uint32 CasterAuraState; // 21 m_casterAuraState + uint32 TargetAuraState; // 22 m_targetAuraState + uint32 CasterAuraStateNot; // 23 m_excludeCasterAuraState + uint32 TargetAuraStateNot; // 24 m_excludeTargetAuraState + uint32 casterAuraSpell; // 25 m_casterAuraSpell + uint32 targetAuraSpell; // 26 m_targetAuraSpell + uint32 excludeCasterAuraSpell; // 27 m_excludeCasterAuraSpell + uint32 excludeTargetAuraSpell; // 28 m_excludeTargetAuraSpell +}; + +// SpellCastingRequirements.dbc +struct SpellCastingRequirementsEntry +{ + //uint32 Id; // 0 m_ID + uint32 FacingCasterFlags; // 20 m_facingCasterFlags + //uint32 MinFactionId; // 159 m_minFactionID not used + //uint32 MinReputation; // 160 m_minReputation not used + int32 AreaGroupId; // 164 m_requiredAreaGroupId + //uint32 RequiredAuraVision; // 161 m_requiredAuraVision not used + uint32 RequiresSpellFocus; // 19 m_requiresSpellFocus +}; + +// SpellCategories.dbc +struct SpellCategoriesEntry +{ + //uint32 Id; // 0 m_ID + uint32 Category; // 1 m_category + uint32 DmgClass; // 153 m_defenseType + uint32 Dispel; // 2 m_dispelType + uint32 Mechanic; // 3 m_mechanic + uint32 PreventionType; // 154 m_preventionType + uint32 StartRecoveryCategory; // 145 m_startRecoveryCategory +}; + +// SpellClassOptions.dbc +struct SpellClassOptionsEntry +{ + //uint32 Id; // 0 m_ID + //uint32 modalNextSpell; // 50 m_modalNextSpell not used + ClassFamilyMask SpellFamilyFlags; // 149-151 m_spellClassMask NOTE: size is 12 bytes!!! + uint32 SpellFamilyName; // 148 m_spellClassSet + //char* Description; // 6 4.0.0 + + // helpers + + bool IsFitToFamilyMask(uint64 familyFlags, uint32 familyFlags2 = 0) const + { + return SpellFamilyFlags.IsFitToFamilyMask(familyFlags, familyFlags2); + } + + bool IsFitToFamily(SpellFamily family, uint64 familyFlags, uint32 familyFlags2 = 0) const + { + return SpellFamily(SpellFamilyName) == family && IsFitToFamilyMask(familyFlags, familyFlags2); + } + + bool IsFitToFamilyMask(ClassFamilyMask const& mask) const + { + return SpellFamilyFlags.IsFitToFamilyMask(mask); + } + + bool IsFitToFamily(SpellFamily family, ClassFamilyMask const& mask) const + { + return SpellFamily(SpellFamilyName) == family && IsFitToFamilyMask(mask); + } + + private: + // catch wrong uses + template + bool IsFitToFamilyMask(SpellFamily family, T t) const; +}; + +// SpellCooldowns.dbc +struct SpellCooldownsEntry +{ + //uint32 Id; // 0 m_ID + uint32 CategoryRecoveryTime; // 31 m_categoryRecoveryTime + uint32 RecoveryTime; // 30 m_recoveryTime + uint32 StartRecoveryTime; // 146 m_startRecoveryTime +}; + +// SpellEffect.dbc +struct SpellEffectEntry +{ + //uint32 Id; // 0 m_ID + uint32 Effect; // 73-75 m_effect + float EffectMultipleValue; // 106-108 m_effectAmplitude + uint32 EffectApplyAuraName; // 100-102 m_effectAura + uint32 EffectAmplitude; // 103-105 m_effectAuraPeriod + int32 EffectBasePoints; // 82-84 m_effectBasePoints (don't must be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints) + //float unk_320_4; // 169-171 3.2.0 + float DmgMultiplier; // 156-158 m_effectChainAmplitude + uint32 EffectChainTarget; // 109-111 m_effectChainTargets + int32 EffectDieSides; // 76-78 m_effectDieSides + uint32 EffectItemType; // 112-114 m_effectItemType + uint32 EffectMechanic; // 85-87 m_effectMechanic + int32 EffectMiscValue; // 115-117 m_effectMiscValue + int32 EffectMiscValueB; // 118-120 m_effectMiscValueB + float EffectPointsPerComboPoint; // 124-126 m_effectPointsPerCombo + uint32 EffectRadiusIndex; // 94-96 m_effectRadiusIndex - spellradius.dbc + //uint32 EffectRadiusMaxIndex; // 97-99 4.0.0 + float EffectRealPointsPerLevel; // 79-81 m_effectRealPointsPerLevel + ClassFamilyMask EffectSpellClassMask; // 127-129 m_effectSpellClassMask + uint32 EffectTriggerSpell; // 121-123 m_effectTriggerSpell + uint32 EffectImplicitTargetA; // 88-90 m_implicitTargetA + uint32 EffectImplicitTargetB; // 91-93 m_implicitTargetB + uint32 EffectSpellId; // new 4.0.0 + uint32 EffectIndex; // new 4.0.0 + //uint32 unk; // 24 - 4.2.0 + + // helpers + + int32 CalculateSimpleValue() const { return EffectBasePoints; } +}; + +// SpellEquippedItems.dbc +struct SpellEquippedItemsEntry +{ + //uint32 Id; // 0 m_ID + int32 EquippedItemClass; // 70 m_equippedItemClass (value) + int32 EquippedItemInventoryTypeMask; // 72 m_equippedItemInvTypes (mask) + int32 EquippedItemSubClassMask; // 71 m_equippedItemSubclass (mask) +}; + +// SpellInterrupts.dbc +struct SpellInterruptsEntry +{ + //uint32 Id; // 0 m_ID + uint32 AuraInterruptFlags; // 33 m_auraInterruptFlags + //uint32 // 34 4.0.0 + uint32 ChannelInterruptFlags; // 35 m_channelInterruptFlags + //uint32 // 36 4.0.0 + uint32 InterruptFlags; // 32 m_interruptFlags +}; + +// SpellLevels.dbc +struct SpellLevelsEntry +{ + //uint32 Id; // 0 m_ID + uint32 baseLevel; // 41 m_baseLevel + uint32 maxLevel; // 40 m_maxLevel + uint32 spellLevel; // 42 m_spellLevel +}; + +// SpellPower.dbc +struct SpellPowerEntry +{ + //uint32 Id; // 0 - m_ID + uint32 manaCost; // 1 - m_manaCost + uint32 manaCostPerlevel; // 2 - m_manaCostPerLevel + uint32 ManaCostPercentage; // 3 - m_manaCostPct + uint32 manaPerSecond; // 4 - m_manaPerSecond + //uint32 PowerDisplayId; // 5 - m_powerDisplayID - id from PowerDisplay.dbc, new in 3.1 + //uint32 unk1; // 6 - 4.0.0 + //unk // 7 - 4.3.0 +}; + +// SpellReagents.dbc +struct SpellReagentsEntry +{ + //uint32 Id; // 0 m_ID + int32 Reagent[MAX_SPELL_REAGENTS]; // 54-61 m_reagent + uint32 ReagentCount[MAX_SPELL_REAGENTS]; // 62-69 m_reagentCount +}; + +// SpellScaling.dbc +struct SpellScalingEntry +{ + //uint32 Id; // 0 m_ID + uint32 castTimeMin; // 1 + uint32 castTimeMax; // 2 + uint32 castScalingMaxLevel; // 3 + uint32 playerClass; // 4 (index * 100) + charLevel => gtSpellScaling.dbc + float coeff1[3]; // 5-7 + float coeff2[3]; // 8-10 + float coeff3[3]; // 11-13 + float unkMult; // 14 some coefficient, mostly 1.0f + uint32 unkLevel; // 15 some level +}; + +// SpellShapeshift.dbc +struct SpellShapeshiftEntry +{ + //uint32 Id; // 0 m_ID + uint32 Stances; // 13 m_shapeshiftMask + // uint32 unk_320_2; // 14 3.2.0 + uint32 StancesNot; // 15 m_shapeshiftExclude + // uint32 unk_320_3; // 16 3.2.0 + // uint32 StanceBarOrder; // 155 m_stanceBarOrder not used +}; + +// SpellTargetRestrictions.dbc +struct SpellTargetRestrictionsEntry +{ + //uint32 Id; // 0 m_ID + float MaxTargetRadius; // 1 - m_maxTargetRadius + uint32 MaxAffectedTargets; // 1 - m_maxTargets + uint32 MaxTargetLevel; // 2 - m_maxTargetLevel + uint32 TargetCreatureType; // 3 - m_targetCreatureType + uint32 Targets; // 4 - m_targets +}; + +// SpellTotems.dbc +struct SpellTotemsEntry +{ + //uint32 Id; // 0 m_ID + uint32 TotemCategory[MAX_SPELL_TOTEM_CATEGORIES]; // 162-163 m_requiredTotemCategoryID + uint32 Totem[MAX_SPELL_TOTEMS]; // 52-53 m_totem +}; + +// Spell.dbc struct SpellEntry { - uint32 Id; // 0 m_ID - uint32 Category; // 1 m_category - uint32 Dispel; // 2 m_dispelType - uint32 Mechanic; // 3 m_mechanic - uint32 Attributes; // 4 m_attributes - uint32 AttributesEx; // 5 m_attributesEx - uint32 AttributesEx2; // 6 m_attributesExB - uint32 AttributesEx3; // 7 m_attributesExC - uint32 AttributesEx4; // 8 m_attributesExD - uint32 AttributesEx5; // 9 m_attributesExE - uint32 AttributesEx6; // 10 m_attributesExF - uint32 AttributesEx7; // 11 m_attributesExG (0x20 - totems, 0x4 - paladin auras, etc...) - uint32 Stances; // 12 m_shapeshiftMask - // uint32 unk_320_1; // 13 3.2.0 - uint32 StancesNot; // 14 m_shapeshiftExclude - // uint32 unk_320_2; // 15 3.2.0 - uint32 Targets; // 16 m_targets - uint32 TargetCreatureType; // 17 m_targetCreatureType - uint32 RequiresSpellFocus; // 18 m_requiresSpellFocus - uint32 FacingCasterFlags; // 19 m_facingCasterFlags - uint32 CasterAuraState; // 20 m_casterAuraState - uint32 TargetAuraState; // 21 m_targetAuraState - uint32 CasterAuraStateNot; // 22 m_excludeCasterAuraState - uint32 TargetAuraStateNot; // 23 m_excludeTargetAuraState - uint32 casterAuraSpell; // 24 m_casterAuraSpell - uint32 targetAuraSpell; // 25 m_targetAuraSpell - uint32 excludeCasterAuraSpell; // 26 m_excludeCasterAuraSpell - uint32 excludeTargetAuraSpell; // 27 m_excludeTargetAuraSpell - uint32 CastingTimeIndex; // 28 m_castingTimeIndex - uint32 RecoveryTime; // 29 m_recoveryTime - uint32 CategoryRecoveryTime; // 30 m_categoryRecoveryTime - uint32 InterruptFlags; // 31 m_interruptFlags - uint32 AuraInterruptFlags; // 32 m_auraInterruptFlags - uint32 ChannelInterruptFlags; // 33 m_channelInterruptFlags - uint32 procFlags; // 34 m_procTypeMask - uint32 procChance; // 35 m_procChance - uint32 procCharges; // 36 m_procCharges - uint32 maxLevel; // 37 m_maxLevel - uint32 baseLevel; // 38 m_baseLevel - uint32 spellLevel; // 39 m_spellLevel - uint32 DurationIndex; // 40 m_durationIndex - uint32 powerType; // 41 m_powerType - uint32 manaCost; // 42 m_manaCost - uint32 manaCostPerlevel; // 43 m_manaCostPerLevel - uint32 manaPerSecond; // 44 m_manaPerSecond - uint32 manaPerSecondPerLevel; // 45 m_manaPerSecondPerLevel - uint32 rangeIndex; // 46 m_rangeIndex - float speed; // 47 m_speed - // uint32 modalNextSpell; // 48 m_modalNextSpell not used - uint32 StackAmount; // 49 m_cumulativeAura - uint32 Totem[MAX_SPELL_TOTEMS]; // 50-51 m_totem - int32 Reagent[MAX_SPELL_REAGENTS]; // 52-59 m_reagent - uint32 ReagentCount[MAX_SPELL_REAGENTS]; // 60-67 m_reagentCount - int32 EquippedItemClass; // 68 m_equippedItemClass (value) - int32 EquippedItemSubClassMask; // 69 m_equippedItemSubclass (mask) - int32 EquippedItemInventoryTypeMask; // 70 m_equippedItemInvTypes (mask) - uint32 Effect[MAX_EFFECT_INDEX]; // 71-73 m_effect - int32 EffectDieSides[MAX_EFFECT_INDEX]; // 74-76 m_effectDieSides - float EffectRealPointsPerLevel[MAX_EFFECT_INDEX]; // 77-79 m_effectRealPointsPerLevel - int32 EffectBasePoints[MAX_EFFECT_INDEX]; // 80-82 m_effectBasePoints (don't must be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints) - uint32 EffectMechanic[MAX_EFFECT_INDEX]; // 83-85 m_effectMechanic - uint32 EffectImplicitTargetA[MAX_EFFECT_INDEX]; // 86-88 m_implicitTargetA - uint32 EffectImplicitTargetB[MAX_EFFECT_INDEX]; // 89-91 m_implicitTargetB - uint32 EffectRadiusIndex[MAX_EFFECT_INDEX]; // 92-94 m_effectRadiusIndex - spellradius.dbc - uint32 EffectApplyAuraName[MAX_EFFECT_INDEX]; // 95-97 m_effectAura - uint32 EffectAmplitude[MAX_EFFECT_INDEX]; // 98-100 m_effectAuraPeriod - float EffectMultipleValue[MAX_EFFECT_INDEX]; // 101-103 m_effectAmplitude - uint32 EffectChainTarget[MAX_EFFECT_INDEX]; // 104-106 m_effectChainTargets - uint32 EffectItemType[MAX_EFFECT_INDEX]; // 107-109 m_effectItemType - int32 EffectMiscValue[MAX_EFFECT_INDEX]; // 110-112 m_effectMiscValue - int32 EffectMiscValueB[MAX_EFFECT_INDEX]; // 113-115 m_effectMiscValueB - uint32 EffectTriggerSpell[MAX_EFFECT_INDEX]; // 116-118 m_effectTriggerSpell - float EffectPointsPerComboPoint[MAX_EFFECT_INDEX]; // 119-121 m_effectPointsPerCombo - ClassFamilyMask EffectSpellClassMask[MAX_EFFECT_INDEX]; // 122-130 m_effectSpellClassMaskA/B/C, effect 0/1/2 - uint32 SpellVisual[2]; // 131-132 m_spellVisualID - uint32 SpellIconID; // 133 m_spellIconID - uint32 activeIconID; // 134 m_activeIconID - // uint32 spellPriority; // 135 m_spellPriority not used - char* SpellName[16]; // 136-151 m_name_lang - // uint32 SpellNameFlag; // 152 m_name_flag not used - char* Rank[16]; // 153-168 m_nameSubtext_lang - // uint32 RankFlags; // 169 m_nameSubtext_flag not used - // char* Description[16]; // 170-185 m_description_lang not used - // uint32 DescriptionFlags; // 186 m_description_flag not used - // char* ToolTip[16]; // 187-202 m_auraDescription_lang not used - // uint32 ToolTipFlags; // 203 m_auraDescription_flag not used - uint32 ManaCostPercentage; // 204 m_manaCostPct - uint32 StartRecoveryCategory; // 205 m_startRecoveryCategory - uint32 StartRecoveryTime; // 206 m_startRecoveryTime - uint32 MaxTargetLevel; // 207 m_maxTargetLevel - uint32 SpellFamilyName; // 208 m_spellClassSet - ClassFamilyMask SpellFamilyFlags; // 209-211 m_spellClassMask NOTE: size is 12 bytes!!! - uint32 MaxAffectedTargets; // 212 m_maxTargets - uint32 DmgClass; // 213 m_defenseType - uint32 PreventionType; // 214 m_preventionType - // uint32 StanceBarOrder; // 215 m_stanceBarOrder not used - float DmgMultiplier[MAX_EFFECT_INDEX]; // 216-218 m_effectChainAmplitude - // uint32 MinFactionId; // 219 m_minFactionID not used - // uint32 MinReputation; // 220 m_minReputation not used - // uint32 RequiredAuraVision; // 221 m_requiredAuraVision not used - uint32 TotemCategory[MAX_SPELL_TOTEM_CATEGORIES];// 222-223 m_requiredTotemCategoryID - int32 AreaGroupId; // 224 m_requiredAreasId - uint32 SchoolMask; // 225 m_schoolMask - uint32 runeCostID; // 226 m_runeCostID - // uint32 spellMissileID; // 227 m_spellMissileID - // uint32 PowerDisplayId; // 228 m_powerDisplayID (PowerDisplay.dbc) - // float effectBonusCoefficient[3]; // 229-231 m_effectBonusCoefficient - // uint32 spellDescriptionVariableID; // 232 m_descriptionVariablesID - uint32 SpellDifficultyId; // 233 m_difficulty (SpellDifficulty.dbc) + uint32 Id; // 0 m_ID + uint32 Attributes; // 1 m_attribute + uint32 AttributesEx; // 2 m_attributesEx + uint32 AttributesEx2; // 3 m_attributesExB + uint32 AttributesEx3; // 4 m_attributesExC + uint32 AttributesEx4; // 5 m_attributesExD + uint32 AttributesEx5; // 6 m_attributesExE + uint32 AttributesEx6; // 7 m_attributesExF + uint32 AttributesEx7; // 8 m_attributesExG (0x20 - totems, 0x4 - paladin auras, etc...) + uint32 AttributesEx8; // 9 m_attributesExH + // uint32 unk_400_1; // 10 4.0.0 + // uint32 unk_420; // 11 4.0.0 + uint32 CastingTimeIndex; // 12 m_castingTimeIndex + uint32 DurationIndex; // 13 m_durationIndex + uint32 powerType; // 14 m_powerType + uint32 rangeIndex; // 15 m_rangeIndex + float speed; // 16 m_speed + uint32 SpellVisual[2]; // 17-18 m_spellVisualID + uint32 SpellIconID; // 19 m_spellIconID + uint32 activeIconID; // 20 m_activeIconID + DBCString SpellName; // 21 m_name_lang + DBCString Rank; // 22 m_nameSubtext_lang + //DBCString Description; // 23 m_description_lang not used + //DBCString ToolTip; // 24 m_auraDescription_lang not used + uint32 SchoolMask; // 25 m_schoolMask + uint32 runeCostID; // 26 m_runeCostID + //uint32 spellMissileID; // 27 m_spellMissileID not used + //uint32 spellDescriptionVariableID; // 28 m_spellDescriptionVariableID, 3.2.0 + uint32 SpellDifficultyId; // 29 m_spellDifficultyID - id from SpellDifficulty.dbc + //float unk_f1; // 30 + uint32 SpellScalingId; // 31 SpellScaling.dbc + uint32 SpellAuraOptionsId; // 32 SpellAuraOptions.dbc + uint32 SpellAuraRestrictionsId; // 33 SpellAuraRestrictions.dbc + uint32 SpellCastingRequirementsId; // 34 SpellCastingRequirements.dbc + uint32 SpellCategoriesId; // 35 SpellCategories.dbc + uint32 SpellClassOptionsId; // 36 SpellClassOptions.dbc + uint32 SpellCooldownsId; // 37 SpellCooldowns.dbc + //uint32 unkIndex7; // 38 all zeros... + uint32 SpellEquippedItemsId; // 39 SpellEquippedItems.dbc + uint32 SpellInterruptsId; // 40 SpellInterrupts.dbc + uint32 SpellLevelsId; // 41 SpellLevels.dbc + uint32 SpellPowerId; // 42 SpellPower.dbc + uint32 SpellReagentsId; // 43 SpellReagents.dbc + uint32 SpellShapeshiftId; // 44 SpellShapeshift.dbc + uint32 SpellTargetRestrictionsId; // 45 SpellTargetRestrictions.dbc + uint32 SpellTotemsId; // 46 SpellTotems.dbc + //uint32 ResearchProject; // 47 ResearchProject.dbc - // helpers - int32 CalculateSimpleValue(SpellEffectIndex eff) const { return EffectBasePoints[eff] + int32(1); } - ClassFamilyMask const& GetEffectSpellClassMask(SpellEffectIndex effect) const - { - return EffectSpellClassMask[effect]; - } + // helpers + int32 CalculateSimpleValue(SpellEffectIndex eff) const; + ClassFamilyMask const& GetEffectSpellClassMask(SpellEffectIndex eff) const; - bool IsFitToFamilyMask(uint64 familyFlags, uint32 familyFlags2 = 0) const - { - return SpellFamilyFlags.IsFitToFamilyMask(familyFlags, familyFlags2); - } + // struct access functions + SpellAuraOptionsEntry const* GetSpellAuraOptions() const; + SpellAuraRestrictionsEntry const* GetSpellAuraRestrictions() const; + SpellCastingRequirementsEntry const* GetSpellCastingRequirements() const; + SpellCategoriesEntry const* GetSpellCategories() const; + SpellClassOptionsEntry const* GetSpellClassOptions() const; + SpellCooldownsEntry const* GetSpellCooldowns() const; + SpellEffectEntry const* GetSpellEffect(SpellEffectIndex eff) const; + SpellEquippedItemsEntry const* GetSpellEquippedItems() const; + SpellInterruptsEntry const* GetSpellInterrupts() const; + SpellLevelsEntry const* GetSpellLevels() const; + SpellPowerEntry const* GetSpellPower() const; + SpellReagentsEntry const* GetSpellReagents() const; + SpellScalingEntry const* GetSpellScaling() const; + SpellShapeshiftEntry const* GetSpellShapeshift() const; + SpellTargetRestrictionsEntry const* GetSpellTargetRestrictions() const; + SpellTotemsEntry const* GetSpellTotems() const; - bool IsFitToFamily(SpellFamily family, uint64 familyFlags, uint32 familyFlags2 = 0) const - { - return SpellFamily(SpellFamilyName) == family && IsFitToFamilyMask(familyFlags, familyFlags2); - } + // single fields + uint32 GetManaCost() const; + uint32 GetPreventionType() const; + uint32 GetCategory() const; + uint32 GetStartRecoveryTime() const; + uint32 GetMechanic() const; + uint32 GetRecoveryTime() const; + uint32 GetCategoryRecoveryTime() const; + uint32 GetStartRecoveryCategory() const; + uint32 GetSpellLevel() const; + int32 GetEquippedItemClass() const; + SpellFamily GetSpellFamilyName() const; + uint32 GetDmgClass() const; + uint32 GetDispel() const; + uint32 GetMaxAffectedTargets() const; + uint32 GetStackAmount() const; + uint32 GetManaCostPercentage() const; + uint32 GetProcCharges() const; + uint32 GetProcChance() const; + uint32 GetMaxLevel() const; + uint32 GetTargetAuraState() const; + uint32 GetManaPerSecond() const; + uint32 GetRequiresSpellFocus() const; + uint32 GetSpellEffectIdByIndex(SpellEffectIndex index) const; + uint32 GetAuraInterruptFlags() const; + uint32 GetEffectImplicitTargetAByIndex(SpellEffectIndex index) const; + int32 GetAreaGroupId() const; + uint32 GetFacingCasterFlags() const; + uint32 GetBaseLevel() const; + uint32 GetInterruptFlags() const; + uint32 GetTargetCreatureType() const; + int32 GetEffectMiscValue(SpellEffectIndex index) const; + uint32 GetStances() const; + uint32 GetStancesNot() const; + uint32 GetProcFlags() const; + uint32 GetChannelInterruptFlags() const; + uint32 GetManaCostPerLevel() const; + uint32 GetCasterAuraState() const; + uint32 GetTargets() const; + uint32 GetEffectApplyAuraNameByIndex(SpellEffectIndex index) const; - bool IsFitToFamilyMask(ClassFamilyMask const& mask) const - { - return SpellFamilyFlags.IsFitToFamilyMask(mask); - } + bool IsFitToFamilyMask(uint64 familyFlags, uint32 familyFlags2 = 0) const + { + SpellClassOptionsEntry const* classOpt = GetSpellClassOptions(); + return classOpt && classOpt->IsFitToFamilyMask(familyFlags, familyFlags2); + } - bool IsFitToFamily(SpellFamily family, ClassFamilyMask const& mask) const - { - return SpellFamily(SpellFamilyName) == family && IsFitToFamilyMask(mask); - } + bool IsFitToFamily(SpellFamily family, uint64 familyFlags, uint32 familyFlags2 = 0) const + { + SpellClassOptionsEntry const* classOpt = GetSpellClassOptions(); + return classOpt && classOpt->IsFitToFamily(family, familyFlags, familyFlags2); + } - inline bool HasAttribute(SpellAttributes attribute) const { return Attributes & attribute; } - inline bool HasAttribute(SpellAttributesEx attribute) const { return AttributesEx & attribute; } - inline bool HasAttribute(SpellAttributesEx2 attribute) const { return AttributesEx2 & attribute; } - inline bool HasAttribute(SpellAttributesEx3 attribute) const { return AttributesEx3 & attribute; } - inline bool HasAttribute(SpellAttributesEx4 attribute) const { return AttributesEx4 & attribute; } - inline bool HasAttribute(SpellAttributesEx5 attribute) const { return AttributesEx5 & attribute; } - inline bool HasAttribute(SpellAttributesEx6 attribute) const { return AttributesEx6 & attribute; } - inline bool HasAttribute(SpellAttributesEx7 attribute) const { return AttributesEx7 & attribute; } + bool IsFitToFamilyMask(ClassFamilyMask const& mask) const + { + SpellClassOptionsEntry const* classOpt = GetSpellClassOptions(); + return classOpt && classOpt->IsFitToFamilyMask(mask); + } + + bool IsFitToFamily(SpellFamily family, ClassFamilyMask const& mask) const + { + SpellClassOptionsEntry const* classOpt = GetSpellClassOptions(); + return classOpt && classOpt->IsFitToFamily(family, mask); + } + + inline bool HasAttribute(SpellAttributes attribute) const { return Attributes & attribute; } + inline bool HasAttribute(SpellAttributesEx attribute) const { return AttributesEx & attribute; } + inline bool HasAttribute(SpellAttributesEx2 attribute) const { return AttributesEx2 & attribute; } + inline bool HasAttribute(SpellAttributesEx3 attribute) const { return AttributesEx3 & attribute; } + inline bool HasAttribute(SpellAttributesEx4 attribute) const { return AttributesEx4 & attribute; } + inline bool HasAttribute(SpellAttributesEx5 attribute) const { return AttributesEx5 & attribute; } + inline bool HasAttribute(SpellAttributesEx6 attribute) const { return AttributesEx6 & attribute; } + inline bool HasAttribute(SpellAttributesEx7 attribute) const { return AttributesEx7 & attribute; } private: // prevent creating custom entries (copy data from original in fact) @@ -1718,32 +1986,26 @@ struct SpellEntry bool IsFitToFamilyMask(SpellFamily family, T t) const; }; -// A few fields which are required for automated convertion -// NOTE that these fields are count by _skipping_ the fields that are unused! -#define LOADED_SPELLDBC_FIELD_POS_EQUIPPED_ITEM_CLASS 65 // Must be converted to -1 -#define LOADED_SPELLDBC_FIELD_POS_SPELLNAME_0 132 // Links to "MaNGOS server-side spell" - struct SpellCastTimesEntry { uint32 ID; // 0 m_ID int32 CastTime; // 1 m_base - // float CastTimePerLevel; // 2 m_perLevel - // int32 MinCastTime; // 3 m_minimum + //float CastTimePerLevel; // 2 m_perLevel + //int32 MinCastTime; // 3 m_minimum }; struct SpellFocusObjectEntry { uint32 ID; // 0 m_ID - // char* Name[16]; // 1-15 m_name_lang - // 16 string flags + //char* Name; // 1 m_name_lang }; struct SpellRadiusEntry { - uint32 ID; // m_ID - float Radius; // m_radius - // m_radiusPerLevel - // float RadiusMax; // m_radiusMax + uint32 ID; // 0 m_ID + float Radius; // 1 m_radius + // 2 m_radiusPerLevel + //float RadiusMax; // 3 m_radiusMax }; struct SpellRangeEntry @@ -1753,11 +2015,9 @@ struct SpellRangeEntry float minRangeFriendly; // 2 float maxRange; // 3 m_rangeMax[2] float maxRangeFriendly; // 4 - // uint32 Flags; // 5 m_flags - // char* Name[16]; // 6-21 m_displayName_lang - // uint32 NameFlags; // 22 string flags - // char* ShortName[16]; // 23-38 m_displayNameShort_lang - // uint32 NameFlags; // 39 string flags + //uint32 Flags; // 5 m_flags + //char* Name; // 6-21 m_displayName_lang + //char* ShortName; // 23-38 m_displayNameShort_lang }; struct SpellRuneCostEntry @@ -1773,18 +2033,19 @@ struct SpellRuneCostEntry struct SpellShapeshiftFormEntry { uint32 ID; // 0 m_ID - // uint32 buttonPosition; // 1 m_bonusActionBar - // char* Name[16]; // 2-17 m_name_lang - // uint32 NameFlags; // 18 string flags - uint32 flags1; // 19 m_flags - int32 creatureType; // 20 m_creatureType <=0 humanoid, other normal creature types - // uint32 unk1; // 21 m_attackIconID - uint32 attackSpeed; // 22 m_combatRoundTime - uint32 modelID_A; // 23 m_creatureDisplayID[4] - uint32 modelID_H; // 24 - // uint32 unk3; // 25 - // uint32 unk4; // 26 - uint32 spellId[8]; // 27-34 m_presetSpellID[8] + //uint32 buttonPosition; // 1 m_bonusActionBar + //char* Name; // 2 m_name_lang + uint32 flags1; // 3 m_flags + int32 creatureType; // 4 m_creatureType <=0 humanoid, other normal creature types + //uint32 unk1; // 5 m_attackIconID + uint32 attackSpeed; // 6 m_combatRoundTime + uint32 modelID_A; // 7 m_creatureDisplayID[4] + uint32 modelID_H; // 8 + //uint32 unk3; // 9 unused always 0 + //uint32 unk4; // 10 unused always 0 + uint32 spellId[8]; // 11-18 m_presetSpellID[8] + //uint32 unk5; // 19 unused, !=0 for flight forms + //uint32 unk6; // 20 }; struct SpellDifficultyEntry @@ -1802,37 +2063,31 @@ struct SpellDurationEntry struct SpellItemEnchantmentEntry { uint32 ID; // 0 m_ID - // uint32 charges; // 1 m_charges + //uint32 charges; // 1 m_charges uint32 type[3]; // 2-4 m_effect[3] uint32 amount[3]; // 5-7 m_effectPointsMin[3] - // uint32 amount2[3] // 8-10 m_effectPointsMax[3] + //uint32 amount2[3] // 8-10 m_effectPointsMax[3] uint32 spellid[3]; // 11-13 m_effectArg[3] - char* description[16]; // 14-29 m_name_lang[16] - // uint32 descriptionFlags; // 30 string flags - uint32 aura_id; // 31 m_itemVisual - uint32 slot; // 32 m_flags - uint32 GemID; // 33 m_src_itemID - uint32 EnchantmentCondition; // 34 m_condition_id - // uint32 requiredSkill; // 35 m_requiredSkillID - // uint32 requiredSkillValue; // 36 m_requiredSkillRank - // 37 m_minLevel + DBCString description; // 14 m_name_lang + uint32 aura_id; // 15 m_itemVisual + uint32 slot; // 16 m_flags + uint32 GemID; // 17 m_src_itemID + uint32 EnchantmentCondition; // 18 m_condition_id + //uint32 requiredSkill; // 19 m_requiredSkillID + //uint32 requiredSkillValue; // 20 m_requiredSkillRank + // 21 new in 3.1 + // 22 new in 3.1 }; struct SpellItemEnchantmentConditionEntry { uint32 ID; // 0 m_ID uint8 Color[5]; // 1-5 m_lt_operandType[5] - // uint32 LT_Operand[5]; // 6-10 m_lt_operand[5] + //uint32 LT_Operand[5]; // 6-10 m_lt_operand[5] uint8 Comparator[5]; // 11-15 m_operator[5] uint8 CompareColor[5]; // 15-20 m_rt_operandType[5] uint32 Value[5]; // 21-25 m_rt_operand[5] - // uint8 Logic[5] // 25-30 m_logic[5] -}; - -struct StableSlotPricesEntry -{ - uint32 Slot; // m_ID - uint32 Price; // m_cost + //uint8 Logic[5] // 25-30 m_logic[5] }; struct SummonPropertiesEntry @@ -1842,12 +2097,12 @@ struct SummonPropertiesEntry uint32 FactionId; // 2 m_faction uint32 Title; // 3 m_title (enum UnitNameSummonTitle) uint32 Slot; // 4 m_slot if title = UNITNAME_SUMMON_TITLE_TOTEM, its actual slot (0-6). - // if title = UNITNAME_SUMMON_TITLE_COMPANION, slot=6 -> defensive guardian, in other cases criter/minipet - // Slot may have other uses, selection of pet type in some cases? + // if title = UNITNAME_SUMMON_TITLE_COMPANION, slot=6 -> defensive guardian, in other cases criter/minipet + // Slot may have other uses, selection of pet type in some cases? uint32 Flags; // 5 m_flags (enum SummonPropFlags) }; -#define MAX_TALENT_RANK 5 +#define MAX_TALENT_RANK 3 #define MAX_PET_TALENT_RANK 3 // use in calculations, expected <= MAX_TALENT_RANK struct TalentEntry @@ -1856,28 +2111,26 @@ struct TalentEntry uint32 TalentTab; // 1 m_tabID (TalentTab.dbc) uint32 Row; // 2 m_tierID uint32 Col; // 3 m_columnIndex - uint32 RankID[MAX_TALENT_RANK]; // 4-8 m_spellRank - // 9-12 part of prev field - uint32 DependsOn; // 13 m_prereqTalent (Talent.dbc) - // 14-15 part of prev field - uint32 DependsOnRank; // 16 m_prereqRank - // 17-18 part of prev field - // uint32 needAddInSpellBook; // 19 m_flags also need disable higest ranks on reset talent tree - // uint32 unk2; // 20 m_requiredSpellID - // uint64 allowForPet; // 21 m_categoryMask its a 64 bit mask for pet 1< SpellCategorySet; -typedef std::map SpellCategoryStore; +typedef std::map SpellCategoryStore; typedef std::set PetFamilySpellsSet; -typedef std::map PetFamilySpellsStore; +typedef std::map PetFamilySpellsStore; // Structures not used for casting to loaded DBC data and not required then packing struct MapDifficulty @@ -2123,18 +2379,31 @@ struct TalentSpellPos uint8 rank; }; -typedef std::map TalentSpellPosMap; +typedef std::map TalentSpellPosMap; + +struct SpellEffect +{ + SpellEffect() + { + effects[0] = NULL; + effects[1] = NULL; + effects[2] = NULL; + } + SpellEffectEntry const* effects[3]; +}; + +typedef std::map SpellEffectMap; struct TaxiPathBySourceAndDestination { - TaxiPathBySourceAndDestination() : ID(0), price(0) {} - TaxiPathBySourceAndDestination(uint32 _id, uint32 _price) : ID(_id), price(_price) {} + TaxiPathBySourceAndDestination() : ID(0),price(0) {} + TaxiPathBySourceAndDestination(uint32 _id,uint32 _price) : ID(_id),price(_price) {} uint32 ID; uint32 price; }; -typedef std::map TaxiPathSetForSource; -typedef std::map TaxiPathSetBySource; +typedef std::map TaxiPathSetForSource; +typedef std::map TaxiPathSetBySource; struct TaxiPathNodePtr { @@ -2146,7 +2415,7 @@ struct TaxiPathNodePtr operator TaxiPathNodeEntry const& () const { return *i_ptr; } }; -typedef Path TaxiPathNodeList; +typedef Path TaxiPathNodeList; typedef std::vector TaxiPathNodesByPath; #define TaxiMaskSize 14 diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h index 4df1292a0..727d74b75 100644 --- a/src/game/DBCfmt.h +++ b/src/game/DBCfmt.h @@ -19,103 +19,123 @@ #ifndef MANGOS_DBCSFRM_H #define MANGOS_DBCSFRM_H -const char Achievementfmt[] = "niixssssssssssssssssxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxii"; -const char AchievementCriteriafmt[] = "niiiiiiiissssssssssssssssxixiii"; -const char AreaTableEntryfmt[] = "iiinixxxxxissssssssssssssssxixxxxxxx"; -const char AreaGroupEntryfmt[] = "niiiiiii"; -const char AreaTriggerEntryfmt[] = "niffffffff"; -const char AuctionHouseEntryfmt[] = "niiixxxxxxxxxxxxxxxxx"; -const char BankBagSlotPricesEntryfmt[] = "ni"; -const char BarberShopStyleEntryfmt[] = "nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii"; -const char BattlemasterListEntryfmt[] = "niiiiiiiiixssssssssssssssssxiiii"; -const char CharStartOutfitEntryfmt[] = "diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; -const char CharTitlesEntryfmt[] = "nxssssssssssssssssxxxxxxxxxxxxxxxxxxi"; -const char ChatChannelsEntryfmt[] = "iixssssssssssssssssxxxxxxxxxxxxxxxxxx"; -// ChatChannelsEntryfmt, index not used (more compact store) -const char ChrClassesEntryfmt[] = "nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii"; -const char ChrRacesEntryfmt[] = "nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; -const char CinematicSequencesEntryfmt[] = "nxxxxxxxxx"; -const char CreatureDisplayInfofmt[] = "nxxifxxxxxxxxxxx"; -const char CreatureDisplayInfoExtrafmt[] = "nixxxxxxxxxxxxxxxxxxx"; -const char CreatureFamilyfmt[] = "nfifiiiiixssssssssssssssssxx"; -const char CreatureSpellDatafmt[] = "niiiixxxx"; -const char CreatureTypefmt[] = "nxxxxxxxxxxxxxxxxxx"; -const char CurrencyTypesfmt[] = "xnxi"; -const char DungeonEncounterfmt[] = "niiiissssssssssssssssxx"; -const char DurabilityCostsfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiiiiiii"; -const char DurabilityQualityfmt[] = "nf"; -const char EmotesEntryfmt[] = "nxxiiix"; -const char EmotesTextEntryfmt[] = "nxixxxxxxxxxxxxxxxx"; -const char FactionEntryfmt[] = "niiiiiiiiiiiiiiiiiiffixssssssssssssssssxxxxxxxxxxxxxxxxxx"; -const char FactionTemplateEntryfmt[] = "niiiiiiiiiiiii"; -const char GameObjectDisplayInfofmt[] = "nxxxxxxxxxxxfxxxxxx"; -const char GemPropertiesEntryfmt[] = "nixxi"; -const char GlyphPropertiesfmt[] = "niii"; -const char GlyphSlotfmt[] = "nii"; -const char GtBarberShopCostBasefmt[] = "f"; -const char GtCombatRatingsfmt[] = "f"; -const char GtChanceToMeleeCritBasefmt[] = "f"; -const char GtChanceToMeleeCritfmt[] = "f"; -const char GtChanceToSpellCritBasefmt[] = "f"; -const char GtChanceToSpellCritfmt[] = "f"; -const char GtOCTClassCombatRatingScalarfmt[] = "df"; -const char GtOCTRegenHPfmt[] = "f"; -// const char GtOCTRegenMPfmt[]="f"; -const char GtRegenHPPerSptfmt[] = "f"; -const char GtRegenMPPerSptfmt[] = "f"; -const char Holidaysfmt[] = "nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; -const char Itemfmt[] = "niiiiiii"; -const char ItemBagFamilyfmt[] = "nxxxxxxxxxxxxxxxxx"; -const char ItemClassfmt[] = "nxxssssssssssssssssx"; -// const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx"; -// const char ItemCondExtCostsEntryfmt[]="xiii"; -const char ItemExtendedCostEntryfmt[] = "niiiiiiiiiiiiiix"; -const char ItemLimitCategoryEntryfmt[] = "nxxxxxxxxxxxxxxxxxii"; -const char ItemRandomPropertiesfmt[] = "nxiiiiissssssssssssssssx"; -const char ItemRandomSuffixfmt[] = "nssssssssssssssssxxiiiiiiiiii"; -const char ItemSetEntryfmt[] = "dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii"; -const char LockEntryfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx"; -const char MailTemplateEntryfmt[] = "nxxxxxxxxxxxxxxxxxssssssssssssssssx"; -const char MapEntryfmt[] = "nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxixx"; -const char MapDifficultyEntryfmt[] = "diixxxxxxxxxxxxxxxxxiix"; -const char MovieEntryfmt[] = "nxx"; -const char OverrideSpellDatafmt[] = "niiiiiiiiiix"; -const char QuestFactionRewardfmt[] = "niiiiiiiiii"; -const char QuestSortEntryfmt[] = "nxxxxxxxxxxxxxxxxx"; -const char QuestXPLevelfmt[] = "niiiiiiiiii"; -const char PvPDifficultyfmt[] = "diiiii"; -const char RandomPropertiesPointsfmt[] = "niiiiiiiiiiiiiii"; -const char ScalingStatDistributionfmt[] = "niiiiiiiiiiiiiiiiiiiii"; -const char ScalingStatValuesfmt[] = "iniiiiiiiiiiiiiiiiixiiii"; -const char SkillLinefmt[] = "nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxi"; -const char SkillLineAbilityfmt[] = "niiiixxiiiiixx"; -const char SkillRaceClassInfofmt[] = "diiiiixx"; -const char SoundEntriesfmt[] = "nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; -const char SpellCastTimefmt[] = "nixx"; -const char SpellDurationfmt[] = "niii"; -const char SpellDifficultyfmt[] = "niiii"; -const char SpellEntryfmt[] = "niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxxxxxi"; -const char SpellFocusObjectfmt[] = "nxxxxxxxxxxxxxxxxx"; -const char SpellItemEnchantmentfmt[] = "nxiiiiiixxxiiissssssssssssssssxiiiixxx"; -const char SpellItemEnchantmentConditionfmt[] = "nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX"; -const char SpellRadiusfmt[] = "nfxx"; -const char SpellRangefmt[] = "nffffxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; -const char SpellRuneCostfmt[] = "niiii"; -const char SpellShapeshiftFormfmt[] = "nxxxxxxxxxxxxxxxxxxiixiiixxiiiiiiii"; -const char StableSlotPricesfmt[] = "ni"; +const char Achievementfmt[]="niixsxiixixxii"; +const char AchievementCriteriafmt[]="niiiiiiiixsiiiiixxxxxxx"; +const char AreaTableEntryfmt[]="iiinixxxxxisixxxxxxxxxxxxx"; +const char AreaGroupEntryfmt[]="niiiiiii"; +const char AreaTriggerEntryfmt[]="nifffxxxfffff"; +const char ArmorLocationfmt[]="nfffff"; +const char AuctionHouseEntryfmt[]="niiix"; +const char BankBagSlotPricesEntryfmt[]="ni"; +const char BarberShopStyleEntryfmt[]="nixxxiii"; +const char BattlemasterListEntryfmt[]="niiiiiiiiixsiiiiiiii"; +const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +const char CharTitlesEntryfmt[]="nxsxix"; +const char ChatChannelsEntryfmt[]="iixsx"; + // ChatChannelsEntryfmt, index not used (more compact store) +const char ChrClassesEntryfmt[]="nixsxxxixiixxx"; +const char ChrRacesEntryfmt[]="nxixiixixxxxixsxxxxxixxx"; +const char ChrClassesXPowerTypesfmt[]="nii"; +const char CinematicSequencesEntryfmt[]="nxxxxxxxxx"; +const char CreatureDisplayInfofmt[]="nxxifxxxxxxxxxxxx"; +const char CreatureDisplayInfoExtrafmt[]="nixxxxxxxxxxxxxxxxxxx"; +const char CreatureFamilyfmt[]="nfifiiiiixsx"; +const char CreatureSpellDatafmt[]="niiiixxxx"; +const char CreatureTypefmt[]="nxx"; +const char DungeonEncounterfmt[]="niiiisxx"; +const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii"; +const char DurabilityQualityfmt[]="nf"; +const char EmotesEntryfmt[]="nxxiiixx"; +const char EmotesTextEntryfmt[]="nxixxxxxxxxxxxxxxxx"; +const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiiffixsxx"; +const char FactionTemplateEntryfmt[]="niiiiiiiiiiiii"; +const char GameObjectDisplayInfofmt[]="nxxxxxxxxxxxffffffxxx"; +const char GemPropertiesEntryfmt[]="nixxix"; +const char GlyphPropertiesfmt[]="niii"; +const char GlyphSlotfmt[]="nii"; +const char GtBarberShopCostBasefmt[]="xf"; +const char GtCombatRatingsfmt[]="xf"; +const char GtChanceToMeleeCritBasefmt[]="xf"; +const char GtChanceToMeleeCritfmt[]="xf"; +const char GtChanceToSpellCritBasefmt[]="xf"; +const char GtOCTClassCombatRatingScalarfmt[]="df"; +const char GtChanceToSpellCritfmt[]="xf"; +const char GtOCTRegenHPfmt[]="xf"; +//const char GtOCTRegenMPfmt[]="f"; +const char GtRegenHPPerSptfmt[]="xf"; +const char GtRegenMPPerSptfmt[]="xf"; +const char Holidaysfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +const char ItemClassfmt[]="nixxxs"; +const char ItemArmorQualityfmt[]="nfffffffi"; +const char ItemArmorShieldfmt[]="nifffffff"; +const char ItemArmorTotalfmt[]="niffff"; +const char ItemBagFamilyfmt[]="nx"; +//const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx"; +//const char ItemCondExtCostsEntryfmt[]="xiii"; +//const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiiix"; +const char ItemDamagefmt[]="nfffffffi"; +const char ItemLimitCategoryEntryfmt[]="nxii"; +const char ItemRandomPropertiesfmt[]="nxiiiiis"; +const char ItemRandomSuffixfmt[]="nsxiiiiiiiiii"; +const char ItemSetEntryfmt[]="dsxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii"; +const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx"; +const char MailTemplateEntryfmt[]="nxs"; +const char MapEntryfmt[]="nxixxxsixxixiffxixxi"; +const char MapDifficultyEntryfmt[]="diixiix"; +const char MovieEntryfmt[]="nxxx"; +const char OverrideSpellDatafmt[]="niiiiiiiiiixx"; +const char QuestFactionRewardfmt[]="niiiiiiiiii"; +const char QuestSortEntryfmt[]="nx"; +const char QuestXPLevelfmt[]="niiiiiiiiii"; +const char Phasefmt[]="nii"; +const char PvPDifficultyfmt[]="diiiii"; +const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii"; +const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiixi"; +const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxx"; +const char SkillLinefmt[]="nisxixi"; +const char SkillLineAbilityfmt[]="niiiixxiiiiixx"; +const char SkillRaceClassInfofmt[]="diiiiixxx"; +const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +const char SpellCastTimefmt[]="nixx"; +const char SpellDurationfmt[]="niii"; +const char SpellDifficultyfmt[]="niiii"; +const char SpellEntryfmt[]="niiiiiiiiixxiiiifiiiissxxiixxixiiiiiiixiiiiiiiix"; +const char SpellAuraOptionsEntryfmt[]="diiii"; +const char SpellAuraRestrictionsEntryfmt[]="diiiiiiii"; +const char SpellCastingRequirementsEntryfmt[]="dixxixi"; +const char SpellCategoriesEntryfmt[]="diiiiii"; +const char SpellClassOptionsEntryfmt[]="dxiiiix"; +const char SpellCooldownsEntryfmt[]="diii"; +const char SpellEffectEntryfmt[]="difiiixfiiiiiifixfiiiiiiiix"; +const char SpellEquippedItemsEntryfmt[]="diii"; +const char SpellInterruptsEntryfmt[]="dixixi"; +const char SpellLevelsEntryfmt[]="diii"; +const char SpellPowerEntryfmt[]="diiiixxx"; +const char SpellReagentsEntryfmt[]="diiiiiiiiiiiiiiii"; +const char SpellScalingEntryfmt[]="diiiiffffffffffi"; +const char SpellShapeshiftEntryfmt[]="dixixx"; +const char SpellTargetRestrictionsEntryfmt[]="dfiiii"; +const char SpellTotemsEntryfmt[]="diiii"; +const char SpellFocusObjectfmt[]="nx"; +const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiisiiiixxxx"; +const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX"; +const char SpellRadiusfmt[]="nfxx"; +const char SpellRangefmt[]="nffffxxx"; +const char SpellRuneCostfmt[]="niiii"; +const char SpellShapeshiftFormfmt[]="nxxiixiiixxiiiiiiiixx"; +//const char StableSlotPricesfmt[] = "ni"; // removed const char SummonPropertiesfmt[] = "niiiii"; -const char TalentEntryfmt[] = "niiiiiiiixxxxixxixxxxxx"; -const char TalentTabEntryfmt[] = "nxxxxxxxxxxxxxxxxxxxiiix"; -const char TaxiNodesEntryfmt[] = "nifffssssssssssssssssxii"; -const char TaxiPathEntryfmt[] = "niii"; -const char TaxiPathNodeEntryfmt[] = "diiifffiiii"; -const char TeamContributionPointsfmt[] = "df"; -const char TotemCategoryEntryfmt[] = "nxxxxxxxxxxxxxxxxxii"; -const char VehicleEntryfmt[] = "niffffiiiiiiiifffffffffffffffssssfifixxx"; -const char VehicleSeatEntryfmt[] = "niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx"; -const char WMOAreaTableEntryfmt[] = "niiixxxxxiixxxxxxxxxxxxxxxxx"; -const char WorldMapAreaEntryfmt[] = "xinxffffixx"; -const char WorldMapOverlayEntryfmt[] = "nxiiiixxxxxxxxxxx"; -const char WorldSafeLocsEntryfmt[] = "nifffxxxxxxxxxxxxxxxxx"; +const char TalentEntryfmt[]="niiiiiiixxiiibbbbxx"; +const char TalentTabEntryfmt[]="nxxiiixxxxx"; +const char TaxiNodesEntryfmt[]="nifffsiixxx"; +const char TaxiPathEntryfmt[]="niii"; +const char TaxiPathNodeEntryfmt[]="diiifffiiii"; +const char TotemCategoryEntryfmt[]="nxii"; +const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifiixx"; +const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxxxxxxxxxx"; +const char WMOAreaTableEntryfmt[]="niiixxxxxiixxxx"; +const char WorldMapAreaEntryfmt[]="xinxffffixxxxx"; +const char WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxx"; +const char WorldSafeLocsEntryfmt[]="nifffx"; #endif diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp index 8280ec500..7fbd85f86 100644 --- a/src/game/DynamicObject.cpp +++ b/src/game/DynamicObject.cpp @@ -171,7 +171,10 @@ void DynamicObject::Delay(int32 delaytime) bool foundAura = false; for (int32 i = m_effIndex + 1; i < MAX_EFFECT_INDEX; ++i) { - if ((holder->GetSpellProto()->Effect[i] == SPELL_EFFECT_PERSISTENT_AREA_AURA || holder->GetSpellProto()->Effect[i] == SPELL_EFFECT_ADD_FARSIGHT) && holder->m_auras[i]) + SpellEffectEntry const* effect = holder->GetSpellProto()->GetSpellEffect(SpellEffectIndex(i)); + if(!effect) + continue; + if ((effect->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA || effect->Effect == SPELL_EFFECT_ADD_FARSIGHT) && holder->m_auras[i]) { foundAura = true; break; diff --git a/src/game/DynamicObject.h b/src/game/DynamicObject.h index 72d63ab69..3e389ca6e 100644 --- a/src/game/DynamicObject.h +++ b/src/game/DynamicObject.h @@ -28,6 +28,7 @@ enum DynamicObjectType DYNAMIC_OBJECT_PORTAL = 0x0, // unused DYNAMIC_OBJECT_AREA_SPELL = 0x1, DYNAMIC_OBJECT_FARSIGHT_FOCUS = 0x2, + DYNAMIC_OBJECT_RAID_MARKER = 0x3, }; struct SpellEntry; diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 8edefddb4..c0bf88588 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -1858,8 +1858,8 @@ float GameObject::GetObjectBoundingRadius() const // FIXME: // 1. This is clearly hack way because GameObjectDisplayInfoEntry have 6 floats related to GO sizes, but better that use DEFAULT_WORLD_OBJECT_SIZE // 2. In some cases this must be only interactive size, not GO size, current way can affect creature target point auto-selection in strange ways for big underground/virtual GOs - if (m_displayInfo) - return fabs(m_displayInfo->unknown12) * GetObjectScale(); + /*if (m_displayInfo) + return fabs(m_displayInfo->unknown12) * GetObjectScale();*/ return DEFAULT_WORLD_OBJECT_SIZE; } diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp index d5f982c0d..c32eec587 100644 --- a/src/game/GossipDef.cpp +++ b/src/game/GossipDef.cpp @@ -689,8 +689,19 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* pQuest) for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; ++iI) data << ObjectiveText[iI]; - GetMenuSession()->SendPacket(&data); + for(iI = 0; iI < 4; ++iI) // 4.0.0 currency reward id and count + { + data << uint32(0); + data << uint32(0); + } + for(iI = 0; iI < 4; ++iI) // 4.0.0 currency required id and count + { + data << uint32(0); + data << uint32(0); + } + + GetMenuSession()->SendPacket( &data ); DEBUG_LOG("WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u", pQuest->GetQuestId()); } diff --git a/src/game/Item.cpp b/src/game/Item.cpp index 8d7eda09b..96dbbcfc8 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -230,6 +230,132 @@ bool ItemCanGoIntoBag(ItemPrototype const* pProto, ItemPrototype const* pBagProt return false; } +uint32 ItemPrototype::GetArmor() const +{ + if (Quality >= ITEM_QUALITY_HEIRLOOM) // heirlooms have it's own dbc... + return 0; + + if (Class == ITEM_CLASS_ARMOR && SubClass == ITEM_SUBCLASS_ARMOR_SHIELD) + { + if (ItemArmorShieldEntry const* ias = sItemArmorShieldStore.LookupEntry(ItemLevel)) + { + return uint32(floor(ias->Value[Quality] + 0.5f)); + } + return 0; + } + + ItemArmorQualityEntry const* iaq = sItemArmorQualityStore.LookupEntry(ItemLevel); + ItemArmorTotalEntry const* iat = sItemArmorTotalStore.LookupEntry(ItemLevel); + + if (!iaq || !iat) + return 0; + + if (InventoryType != INVTYPE_HEAD && InventoryType != INVTYPE_CHEST && InventoryType != INVTYPE_SHOULDERS && + InventoryType != INVTYPE_LEGS && InventoryType != INVTYPE_FEET && InventoryType != INVTYPE_WRISTS && + InventoryType != INVTYPE_HANDS && InventoryType != INVTYPE_WAIST && InventoryType != INVTYPE_CLOAK && + InventoryType != INVTYPE_ROBE) + return 0; + + ArmorLocationEntry const* al = NULL; + + if (InventoryType == INVTYPE_ROBE) + al = sArmorLocationStore.LookupEntry(INVTYPE_CHEST); + else + al = sArmorLocationStore.LookupEntry(InventoryType); + + if (!al) + return 0; + + float iatMult, alMult; + + switch (SubClass) + { + case ITEM_SUBCLASS_ARMOR_CLOTH: + iatMult = iat->Value[0]; + alMult = al->Value[0]; + break; + case ITEM_SUBCLASS_ARMOR_LEATHER: + iatMult = iat->Value[1]; + alMult = al->Value[1]; + break; + case ITEM_SUBCLASS_ARMOR_MAIL: + iatMult = iat->Value[2]; + alMult = al->Value[2]; + break; + case ITEM_SUBCLASS_ARMOR_PLATE: + iatMult = iat->Value[3]; + alMult = al->Value[3]; + break; + default: + return 0; + } + + return uint32(floor(iaq->Value[Quality] * iatMult * alMult + 0.5f)); +} + +float ItemPrototype::getDPS() const +{ + float damage = 0.0f; + + if (Class == ITEM_CLASS_WEAPON) + { + if (Quality >= ITEM_QUALITY_HEIRLOOM) // heirlooms have it's own dbc... + return damage; + + ItemDamageEntry const* id = NULL; + + switch (InventoryType) + { + case INVTYPE_WEAPON: + case INVTYPE_WEAPONMAINHAND: + case INVTYPE_WEAPONOFFHAND: + if (Flags2 & ITEM_FLAG2_CASTER_WEAPON) // caster weapon flag + id = sItemDamageOneHandCasterStore.LookupEntry(ItemLevel); + else + id = sItemDamageOneHandStore.LookupEntry(ItemLevel); + break; + case INVTYPE_2HWEAPON: + if (Flags2 & ITEM_FLAG2_CASTER_WEAPON) // caster weapon flag + id = sItemDamageTwoHandCasterStore.LookupEntry(ItemLevel); + else + id = sItemDamageTwoHandStore.LookupEntry(ItemLevel); + break; + case INVTYPE_AMMO: + id = sItemDamageAmmoStore.LookupEntry(ItemLevel); + break; + case INVTYPE_RANGED: + case INVTYPE_THROWN: + case INVTYPE_RANGEDRIGHT: + switch (SubClass) + { + case ITEM_SUBCLASS_WEAPON_BOW: + case ITEM_SUBCLASS_WEAPON_GUN: + case ITEM_SUBCLASS_WEAPON_CROSSBOW: + id = sItemDamageRangedStore.LookupEntry(ItemLevel); + break; + case ITEM_SUBCLASS_WEAPON_THROWN: + id = sItemDamageThrownStore.LookupEntry(ItemLevel); + break; + case ITEM_SUBCLASS_WEAPON_WAND: + id = sItemDamageWandStore.LookupEntry(ItemLevel); + break; + default: + break; + } + break; + default: + break; + } + + if (!id) + return damage; + + return id->Value[Quality]; + } + + return damage; +} + Item::Item() { m_objectType |= TYPEMASK_ITEM; @@ -883,25 +1009,35 @@ bool Item::IsFitToSpellRequirements(SpellEntry const* spellInfo) const { ItemPrototype const* proto = GetProto(); + SpellEquippedItemsEntry const* equippedItems = spellInfo->GetSpellEquippedItems(); + if (!equippedItems) + return true; + // Enchant spells only use Effect[0] (patch 3.3.2) - if (proto->IsVellum() && spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_ENCHANT_ITEM) + if (proto->IsVellum()) { - // EffectItemType[0] is the associated scroll itemID, if a scroll can be made - if (spellInfo->EffectItemType[EFFECT_INDEX_0] == 0) - return false; - // Other checks do not apply to vellum enchants, so return final result - return ((proto->SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT && spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON) || - (proto->SubClass == ITEM_SUBCLASS_ARMOR_ENCHANTMENT && spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR)); + SpellEffectEntry const* spellEffect_0 = spellInfo->GetSpellEffect(EFFECT_INDEX_0); + + if (spellEffect_0 && spellEffect_0->Effect == SPELL_EFFECT_ENCHANT_ITEM) + { + // EffectItemType[0] is the associated scroll itemID, if a scroll can be made + if (spellEffect_0->EffectItemType == 0) + return false; + // Other checks do not apply to vellum enchants, so return final result + int32 eqItemClass = spellInfo->GetEquippedItemClass(); + return ((proto->SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT && eqItemClass == ITEM_CLASS_WEAPON) || + (proto->SubClass == ITEM_SUBCLASS_ARMOR_ENCHANTMENT && eqItemClass == ITEM_CLASS_ARMOR)); + } } - if (spellInfo->EquippedItemClass != -1) // -1 == any item class + if (equippedItems->EquippedItemClass != -1) // -1 == any item class { - if (spellInfo->EquippedItemClass != int32(proto->Class)) + if (equippedItems->EquippedItemClass != int32(proto->Class)) return false; // wrong item class - if (spellInfo->EquippedItemSubClassMask != 0) // 0 == any subclass + if (equippedItems->EquippedItemSubClassMask != 0) // 0 == any subclass { - if ((spellInfo->EquippedItemSubClassMask & (1 << proto->SubClass)) == 0) + if ((equippedItems->EquippedItemSubClassMask & (1 << proto->SubClass)) == 0) return false; // subclass not present in mask } } @@ -909,9 +1045,9 @@ bool Item::IsFitToSpellRequirements(SpellEntry const* spellInfo) const // Only check for item enchantments (TARGET_FLAG_ITEM), all other spells are either NPC spells // or spells where slot requirements are already handled with AttributesEx3 fields // and special code (Titan's Grip, Windfury Attack). Check clearly not applicable for Lava Lash. - if (spellInfo->EquippedItemInventoryTypeMask != 0 && (spellInfo->Targets & TARGET_FLAG_ITEM)) // 0 == any inventory type + if (equippedItems->EquippedItemInventoryTypeMask != 0 && (spellInfo->GetTargets() & TARGET_FLAG_ITEM)) // 0 == any inventory type { - if ((spellInfo->EquippedItemInventoryTypeMask & (1 << proto->InventoryType)) == 0) + if ((equippedItems->EquippedItemInventoryTypeMask & (1 << proto->InventoryType)) == 0) return false; // inventory type not present in mask } diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp index c8e169103..df6113497 100644 --- a/src/game/ItemHandler.cpp +++ b/src/game/ItemHandler.cpp @@ -331,27 +331,30 @@ void WorldSession::HandleItemQuerySingleOpcode(WorldPacket& recv_data) { data << pProto->ItemStat[i].ItemStatType; data << pProto->ItemStat[i].ItemStatValue; + data << uint32(0); // 4.0.0 + data << uint32(0); // 4.0.0 } data << pProto->ScalingStatDistribution; // scaling stats distribution data << pProto->ScalingStatValue; // some kind of flags used to determine stat values column - for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) - { - data << pProto->Damage[i].DamageMin; - data << pProto->Damage[i].DamageMax; - data << pProto->Damage[i].DamageType; - } + //for(int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) + //{ + // data << pProto->Damage[i].DamageMin; + // data << pProto->Damage[i].DamageMax; + // data << pProto->Damage[i].DamageType; + //} // resistances (7) - data << pProto->Armor; - data << pProto->HolyRes; - data << pProto->FireRes; - data << pProto->NatureRes; - data << pProto->FrostRes; - data << pProto->ShadowRes; - data << pProto->ArcaneRes; + //data << pProto->Armor; + //data << pProto->HolyRes; + //data << pProto->FireRes; + //data << pProto->NatureRes; + //data << pProto->FrostRes; + //data << pProto->ShadowRes; + //data << pProto->ArcaneRes; + data << uint32(0); // DamageType + //data << pProto->AmmoType; data << pProto->Delay; - data << pProto->AmmoType; data << pProto->RangedModRange; for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s) @@ -375,9 +378,9 @@ void WorldSession::HandleItemQuerySingleOpcode(WorldPacket& recv_data) } else { - data << uint32(spell->RecoveryTime); - data << uint32(spell->Category); - data << uint32(spell->CategoryRecoveryTime); + data << uint32(spell->GetRecoveryTime()); + data << uint32(spell->GetCategory()); + data << uint32(spell->GetCategoryRecoveryTime()); } } else @@ -420,7 +423,10 @@ void WorldSession::HandleItemQuerySingleOpcode(WorldPacket& recv_data) data << uint32(pProto->Duration); // added in 2.4.2.8209, duration (seconds) data << uint32(pProto->ItemLimitCategory); // WotLK, ItemLimitCategory data << uint32(pProto->HolidayId); // Holiday.dbc? - SendPacket(&data); + data << float(0); // damage/armor scaling factor + data << uint32(0); // 4.0.0 + data << uint32(0); // 4.0.0 + SendPacket( &data ); } else { @@ -1086,7 +1092,7 @@ void WorldSession::HandleItemNameQueryOpcode(WorldPacket& recv_data) else { // listed in dbc or not expected to exist unknown item - if (sItemStore.LookupEntry(itemid)) + if(true/*sItemStore.LookupEntry(itemid)*/) sLog.outErrorDb("WORLD: CMSG_ITEM_NAME_QUERY for item %u failed (item listed in Item.dbc but not exist in DB)", itemid); else sLog.outError("WORLD: CMSG_ITEM_NAME_QUERY for item %u failed (unknown item, not listed in Item.dbc)", itemid); diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h index ba6734708..89a06de17 100644 --- a/src/game/ItemPrototype.h +++ b/src/game/ItemPrototype.h @@ -66,10 +66,18 @@ enum ItemModType ITEM_MOD_SPELL_POWER = 45, ITEM_MOD_HEALTH_REGEN = 46, ITEM_MOD_SPELL_PENETRATION = 47, - ITEM_MOD_BLOCK_VALUE = 48 + ITEM_MOD_BLOCK_VALUE = 48, + ITEM_MOD_MASTERY_RATING = 49, + ITEM_MOD_EXTRA_ARMOR = 50, + ITEM_MOD_FIRE_RESISTANCE = 51, + ITEM_MOD_FROST_RESISTANCE = 52, + ITEM_MOD_HOLY_RESISTANCE = 53, + ITEM_MOD_SHADOW_RESISTANCE = 54, + ITEM_MOD_NATURE_RESISTANCE = 55, + ITEM_MOD_ARCANE_RESISTANCE = 56 }; -#define MAX_ITEM_MOD 49 +#define MAX_ITEM_MOD 57 enum ItemSpelltriggerType { @@ -567,16 +575,16 @@ struct ItemPrototype _ItemStat ItemStat[MAX_ITEM_PROTO_STATS]; uint32 ScalingStatDistribution; // id from ScalingStatDistribution.dbc uint32 ScalingStatValue; // mask for selecting column in ScalingStatValues.dbc - _Damage Damage[MAX_ITEM_PROTO_DAMAGES]; - uint32 Armor; - uint32 HolyRes; - uint32 FireRes; - uint32 NatureRes; - uint32 FrostRes; - uint32 ShadowRes; - uint32 ArcaneRes; + _Damage Damage[MAX_ITEM_PROTO_DAMAGES]; // TODO: remove it + uint32 Armor; // TODO: remove it + uint32 HolyRes; // TODO: remove it + uint32 FireRes; // TODO: remove it + uint32 NatureRes; // TODO: remove it + uint32 FrostRes; // TODO: remove it + uint32 ShadowRes; // TODO: remove it + uint32 ArcaneRes; // TODO: remove it uint32 Delay; - uint32 AmmoType; + uint32 AmmoType; // TODO: remove it float RangedModRange; _Spell Spells[MAX_ITEM_PROTO_SPELLS]; uint32 Bonding; @@ -634,16 +642,7 @@ struct ItemPrototype } uint32 GetMaxStackSize() const { return Stackable > 0 ? uint32(Stackable) : uint32(0x7FFFFFFF - 1); } - - float getDPS() const - { - if (Delay == 0) - return 0; - float temp = 0; - for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) - temp += Damage[i].DamageMin + Damage[i].DamageMax; - return temp * 500 / Delay; - } + float getDPS() const; int32 getFeralBonus(int32 extraDPS = 0) const { @@ -658,7 +657,11 @@ struct ItemPrototype return 0; } - bool IsPotion() const { return Class == ITEM_CLASS_CONSUMABLE && SubClass == ITEM_SUBCLASS_POTION; } + uint32 GetArmor() const; + float GetMinDamage() const { return floor(getDPS() * float(Delay) / 1000.0f * 0.7f + 0.5f); } + float GetMaxDamage() const { return floor(getDPS() * float(Delay) / 1000.0f * 1.3f + 0.5f); } + + bool IsPotion() const { return Class==ITEM_CLASS_CONSUMABLE && SubClass==ITEM_SUBCLASS_POTION; } bool IsConjuredConsumable() const { return Class == ITEM_CLASS_CONSUMABLE && (Flags & ITEM_FLAG_CONJURED); } bool IsVellum() const { diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index b252304e2..510254646 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -2345,7 +2345,7 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(char* /*args*/) continue; // skip server-side/triggered spells - if (spellInfo->spellLevel == 0) + if(spellInfo->GetSpellLevel()==0) continue; // skip wrong class/race skills @@ -2353,7 +2353,7 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(char* /*args*/) continue; // skip other spell families - if (spellInfo->SpellFamilyName != family) + if( spellInfo->GetSpellFamilyName() != family) continue; // skip spells with first rank learned as talent (and all talents then also) @@ -3293,7 +3293,8 @@ void ChatHandler::ShowSpellListHelper(Player* target, SpellEntry const* spellInf uint32 id = spellInfo->Id; bool known = target && target->HasSpell(id); - bool learn = (spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_LEARN_SPELL); + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(EFFECT_INDEX_0); + bool learn = (spellEffect && spellEffect->Effect == SPELL_EFFECT_LEARN_SPELL); uint32 talentCost = GetTalentSpellCost(id); @@ -3303,7 +3304,7 @@ void ChatHandler::ShowSpellListHelper(Player* target, SpellEntry const* spellInf // unit32 used to prevent interpreting uint8 as char at output // find rank of learned spell for learning spell, or talent rank - uint32 rank = talentCost ? talentCost : sSpellMgr.GetSpellRank(learn ? spellInfo->EffectTriggerSpell[EFFECT_INDEX_0] : id); + uint32 rank = talentCost ? talentCost : sSpellMgr.GetSpellRank(learn ? (spellEffect ? spellEffect->EffectTriggerSpell : 0) : id); // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format std::ostringstream ss; @@ -4001,9 +4002,14 @@ bool ChatHandler::HandleAuraCommand(char* args) for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - uint8 eff = spellInfo->Effect[i]; - if (eff >= TOTAL_SPELL_EFFECTS) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) continue; + + uint8 eff = spellEffect->Effect; + if (eff>=TOTAL_SPELL_EFFECTS) + continue; + if (IsAreaAuraEffect(eff) || eff == SPELL_EFFECT_APPLY_AURA || eff == SPELL_EFFECT_PERSISTENT_AREA_AURA) @@ -4949,8 +4955,8 @@ bool ChatHandler::HandleResetHonorCommand(char* args) target->SetHonorPoints(0); target->SetUInt32Value(PLAYER_FIELD_KILLS, 0); target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0); - target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); - target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0); + //target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); + //target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0); target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL); return true; diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 0fa5e54b3..12b9aa30f 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -416,4 +416,3 @@ BattleGroundMap* MapManager::CreateBattleGroundMap(uint32 id, uint32 InstanceId, return map; } - diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 91cc77071..124fbf96e 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -1167,10 +1167,10 @@ void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data) WorldPacket data(MSG_INSPECT_HONOR_STATS, 8 + 1 + 4 * 4); data << player->GetObjectGuid(); - data << uint8(player->GetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY)); + data << uint8(player->GetHonorPoints()); data << uint32(player->GetUInt32Value(PLAYER_FIELD_KILLS)); - data << uint32(player->GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION)); - data << uint32(player->GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION)); + //data << uint32(player->GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION)); + //data << uint32(player->GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION)); data << uint32(player->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS)); SendPacket(&data); } diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index be74d4ac1..456384ed1 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -755,21 +755,6 @@ void WorldSession::HandleBuyStableSlot(WorldPacket& recv_data) // remove fake death if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - - if (GetPlayer()->m_stableSlots < MAX_PET_STABLES) - { - StableSlotPricesEntry const* SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots + 1); - if (_player->GetMoney() >= SlotPrice->Price) - { - ++GetPlayer()->m_stableSlots; - _player->ModifyMoney(-int32(SlotPrice->Price)); - SendStableResult(STABLE_SUCCESS_BUY_SLOT); - } - else - SendStableResult(STABLE_ERR_MONEY); - } - else - SendStableResult(STABLE_ERR_STABLE); } void WorldSession::HandleStableRevivePet(WorldPacket& /* recv_data */) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index e9afa4762..2427a2bad 100755 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -91,7 +91,9 @@ LanguageDesc lang_description[LANGUAGES_COUNT] = { LANG_DRAENEI, 29932, SKILL_LANG_DRAENEI }, { LANG_ZOMBIE, 0, 0 }, { LANG_GNOMISH_BINARY, 0, 0 }, - { LANG_GOBLIN_BINARY, 0, 0 } + { LANG_GOBLIN_BINARY, 0, 0 }, + { LANG_WORGEN, 69270, SKILL_LANG_WORGEN }, + { LANG_GOBLIN, 69269, SKILL_LANG_GOBLIN } }; LanguageDesc const* GetLanguageDescByID(uint32 lang) @@ -842,30 +844,31 @@ void ObjectMgr::LoadEquipmentTemplates() for (uint8 j = 0; j < 3; ++j) { if (!eqInfo->equipentry[j]) - continue; + continue; - ItemEntry const* dbcitem = sItemStore.LookupEntry(eqInfo->equipentry[j]); - if (!dbcitem) - { - sLog.outErrorDb("Unknown item (entry=%u) in creature_equip_template.equipentry%u for entry = %u, forced to 0.", eqInfo->equipentry[j], j + 1, i); - const_cast(eqInfo)->equipentry[j] = 0; - continue; - } + //ItemEntry const *dbcitem = sItemStore.LookupEntry(eqInfo->equipentry[j]); - if (dbcitem->InventoryType != INVTYPE_WEAPON && - dbcitem->InventoryType != INVTYPE_SHIELD && - dbcitem->InventoryType != INVTYPE_RANGED && - dbcitem->InventoryType != INVTYPE_2HWEAPON && - dbcitem->InventoryType != INVTYPE_WEAPONMAINHAND && - dbcitem->InventoryType != INVTYPE_WEAPONOFFHAND && - dbcitem->InventoryType != INVTYPE_HOLDABLE && - dbcitem->InventoryType != INVTYPE_THROWN && - dbcitem->InventoryType != INVTYPE_RANGEDRIGHT && - dbcitem->InventoryType != INVTYPE_RELIC) - { - sLog.outErrorDb("Item (entry=%u) in creature_equip_template.equipentry%u for entry = %u is not equipable in a hand, forced to 0.", eqInfo->equipentry[j], j + 1, i); - const_cast(eqInfo)->equipentry[j] = 0; - } + //if (!dbcitem) + //{ + // sLog.outErrorDb("Unknown item (entry=%u) in creature_equip_template.equipentry%u for entry = %u, forced to 0.", eqInfo->equipentry[j], j+1, i); + // const_cast(eqInfo)->equipentry[j] = 0; + // continue; + //} + + //if (dbcitem->InventoryType != INVTYPE_WEAPON && + // dbcitem->InventoryType != INVTYPE_SHIELD && + // dbcitem->InventoryType != INVTYPE_RANGED && + // dbcitem->InventoryType != INVTYPE_2HWEAPON && + // dbcitem->InventoryType != INVTYPE_WEAPONMAINHAND && + // dbcitem->InventoryType != INVTYPE_WEAPONOFFHAND && + // dbcitem->InventoryType != INVTYPE_HOLDABLE && + // dbcitem->InventoryType != INVTYPE_THROWN && + // dbcitem->InventoryType != INVTYPE_RANGEDRIGHT && + // dbcitem->InventoryType != INVTYPE_RELIC) + //{ + // sLog.outErrorDb("Item (entry=%u) in creature_equip_template.equipentry%u for entry = %u is not equipable in a hand, forced to 0.", eqInfo->equipentry[j], j+1, i); + // const_cast(eqInfo)->equipentry[j] = 0; + //} } } @@ -1790,8 +1793,8 @@ void ObjectMgr::LoadItemPrototypes() for (uint32 i = 1; i < sItemStorage.MaxEntry; ++i) { ItemPrototype const* proto = sItemStorage.LookupEntry(i); - ItemEntry const* dbcitem = sItemStore.LookupEntry(i); - if (!proto) + //ItemEntry const *dbcitem = sItemStore.LookupEntry(i); + if(!proto) { /* to many errors, and possible not all items really used in game if (dbcitem) @@ -1800,13 +1803,13 @@ void ObjectMgr::LoadItemPrototypes() continue; } - if (dbcitem) + if(true/*dbcitem*/) { - if (proto->Class != dbcitem->Class) - { - sLog.outErrorDb("Item (Entry: %u) not correct class %u, must be %u (still using DB value).", i, proto->Class, dbcitem->Class); - // It safe let use Class from DB - } + //if(proto->Class != dbcitem->Class) + //{ + // sLog.outErrorDb("Item (Entry: %u) not correct class %u, must be %u (still using DB value).",i,proto->Class,dbcitem->Class); + // // It safe let use Class from DB + //} /* disabled: have some strange wrong cases for Subclass values. for enable also uncomment Subclass field in ItemEntry structure and in Itemfmt[] if(proto->SubClass != dbcitem->SubClass) @@ -1816,34 +1819,34 @@ void ObjectMgr::LoadItemPrototypes() } */ - if (proto->Unk0 != dbcitem->Unk0) - { - sLog.outErrorDb("Item (Entry: %u) not correct %i Unk0, must be %i (still using DB value).", i, proto->Unk0, dbcitem->Unk0); - // It safe let use Unk0 from DB - } + //if(proto->Unk0 != dbcitem->Unk0) + //{ + // sLog.outErrorDb("Item (Entry: %u) not correct %i Unk0, must be %i (still using DB value).",i,proto->Unk0,dbcitem->Unk0); + // // It safe let use Unk0 from DB + //} - if (proto->Material != dbcitem->Material) - { - sLog.outErrorDb("Item (Entry: %u) not correct %i material, must be %i (still using DB value).", i, proto->Material, dbcitem->Material); - // It safe let use Material from DB - } + //if(proto->Material != dbcitem->Material) + //{ + // sLog.outErrorDb("Item (Entry: %u) not correct %i material, must be %i (still using DB value).",i,proto->Material,dbcitem->Material); + // // It safe let use Material from DB + //} - if (proto->InventoryType != dbcitem->InventoryType) - { - sLog.outErrorDb("Item (Entry: %u) not correct %u inventory type, must be %u (still using DB value).", i, proto->InventoryType, dbcitem->InventoryType); - // It safe let use InventoryType from DB - } + //if(proto->InventoryType != dbcitem->InventoryType) + //{ + // sLog.outErrorDb("Item (Entry: %u) not correct %u inventory type, must be %u (still using DB value).",i,proto->InventoryType,dbcitem->InventoryType); + // // It safe let use InventoryType from DB + //} - if (proto->DisplayInfoID != dbcitem->DisplayId) - { - sLog.outErrorDb("Item (Entry: %u) not correct %u display id, must be %u (using it).", i, proto->DisplayInfoID, dbcitem->DisplayId); - const_cast(proto)->DisplayInfoID = dbcitem->DisplayId; - } - if (proto->Sheath != dbcitem->Sheath) - { - sLog.outErrorDb("Item (Entry: %u) not correct %u sheath, must be %u (using it).", i, proto->Sheath, dbcitem->Sheath); - const_cast(proto)->Sheath = dbcitem->Sheath; - } + //if(proto->DisplayInfoID != dbcitem->DisplayId) + //{ + // sLog.outErrorDb("Item (Entry: %u) not correct %u display id, must be %u (using it).",i,proto->DisplayInfoID,dbcitem->DisplayId); + // const_cast(proto)->DisplayInfoID = dbcitem->DisplayId; + //} + //if(proto->Sheath != dbcitem->Sheath) + //{ + // sLog.outErrorDb("Item (Entry: %u) not correct %u sheath, must be %u (using it).",i,proto->Sheath,dbcitem->Sheath); + // const_cast(proto)->Sheath = dbcitem->Sheath; + //} } else { @@ -2214,15 +2217,15 @@ void ObjectMgr::LoadItemPrototypes() continue; } - if (BAG_FAMILY_MASK_CURRENCY_TOKENS & mask) - { - CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(proto->ItemId); - if (!ctEntry) - { - sLog.outErrorDb("Item (Entry: %u) has currency bag family bit set in BagFamily but not listed in CurrencyTypes.dbc, remove bit", i); - const_cast(proto)->BagFamily &= ~mask; - } - } + //if(BAG_FAMILY_MASK_CURRENCY_TOKENS & mask) + //{ + // CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(proto->ItemId); + // if(!ctEntry) + // { + // sLog.outErrorDb("Item (Entry: %u) has currency bag family bit set in BagFamily but not listed in CurrencyTypes.dbc, remove bit",i); + // const_cast(proto)->BagFamily &= ~mask; + // } + //} } } @@ -2545,10 +2548,14 @@ void ObjectMgr::LoadItemRequiredTarget() for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if (pSpellInfo->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE || - pSpellInfo->EffectImplicitTargetB[j] == TARGET_CHAIN_DAMAGE || - pSpellInfo->EffectImplicitTargetA[j] == TARGET_DUELVSPLAYER || - pSpellInfo->EffectImplicitTargetB[j] == TARGET_DUELVSPLAYER) + SpellEffectEntry const* spellEffect = pSpellInfo->GetSpellEffect(SpellEffectIndex(j)); + if(!pSpellInfo) + continue; + + if (spellEffect->EffectImplicitTargetA == TARGET_CHAIN_DAMAGE || + spellEffect->EffectImplicitTargetB == TARGET_CHAIN_DAMAGE || + spellEffect->EffectImplicitTargetA == TARGET_DUELVSPLAYER || + spellEffect->EffectImplicitTargetB == TARGET_DUELVSPLAYER) { bIsItemSpellValid = true; break; @@ -4010,8 +4017,12 @@ void ObjectMgr::LoadQuests() bool found = false; for (int k = 0; k < MAX_EFFECT_INDEX; ++k) { - if ((spellInfo->Effect[k] == SPELL_EFFECT_QUEST_COMPLETE && uint32(spellInfo->EffectMiscValue[k]) == qinfo->QuestId) || - spellInfo->Effect[k] == SPELL_EFFECT_SEND_EVENT) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(k)); + if(!spellEffect) + continue; + + if ((spellEffect->Effect == SPELL_EFFECT_QUEST_COMPLETE && uint32(spellEffect->EffectMiscValue) == qinfo->QuestId) || + spellEffect->Effect == SPELL_EFFECT_SEND_EVENT) { found = true; break; @@ -4286,10 +4297,13 @@ void ObjectMgr::LoadQuests() for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if (spellInfo->Effect[j] != SPELL_EFFECT_QUEST_COMPLETE) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(j)); + if(!spellEffect) + continue; + if (spellEffect->Effect != SPELL_EFFECT_QUEST_COMPLETE) continue; - uint32 quest_id = spellInfo->EffectMiscValue[j]; + uint32 quest_id = spellEffect->EffectMiscValue; Quest const* quest = GetQuestTemplate(quest_id); @@ -6819,59 +6833,6 @@ void ObjectMgr::LoadNPCSpellClickSpells() sLog.outString(">> Loaded %u spellclick definitions", count); } -static char* SERVER_SIDE_SPELL = "MaNGOS server-side spell"; - -struct SQLSpellLoader : public SQLStorageLoaderBase -{ - template - void default_fill(uint32 field_pos, S src, D& dst) - { - if (field_pos == LOADED_SPELLDBC_FIELD_POS_EQUIPPED_ITEM_CLASS) - dst = D(-1); - else - dst = D(src); - } - - void default_fill_to_str(uint32 field_pos, char const* /*src*/, char*& dst) - { - if (field_pos == LOADED_SPELLDBC_FIELD_POS_SPELLNAME_0) - { - dst = SERVER_SIDE_SPELL; - } - else - { - dst = new char[1]; - *dst = 0; - } - } -}; - -void ObjectMgr::LoadSpellTemplate() -{ - SQLSpellLoader loader; - loader.Load(sSpellTemplate); - - sLog.outString(">> Loaded %u spell definitions", sSpellTemplate.RecordCount); - sLog.outString(); - - for (uint32 i = 1; i < sSpellTemplate.MaxEntry; ++i) - { - // check data correctness - SpellEntry const* spellEntry = sSpellTemplate.LookupEntry(i); - if (!spellEntry) - continue; - - // insert serverside spell data - if (sSpellStore.GetNumRows() <= i) - { - sLog.outErrorDb("Loading Spell Template for spell %u, index out of bounds (max = %u)", i, sSpellStore.GetNumRows()); - continue; - } - else - sSpellStore.InsertEntry(const_cast(spellEntry), i); - } -} - void ObjectMgr::LoadWeatherZoneChances() { uint32 count = 0; @@ -8490,15 +8451,23 @@ void ObjectMgr::LoadTrainers(char const* tableName, bool isTemplates) trainerSpell.learnedSpell = spell; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (spellinfo->Effect[i] == SPELL_EFFECT_LEARN_SPELL && - SpellMgr::IsProfessionOrRidingSpell(spellinfo->EffectTriggerSpell[i])) + SpellEffectEntry const* spellEffect = spellinfo->GetSpellEffect(SpellEffectIndex(i)); + if (!spellEffect) + continue; + + if (spellEffect->Effect == SPELL_EFFECT_LEARN_SPELL && + SpellMgr::IsProfessionOrRidingSpell(spellEffect->EffectTriggerSpell)) { // prof spells sometime only additions to main spell learn that have level data for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if (spellinfo->Effect[j] == SPELL_EFFECT_LEARN_SPELL) + SpellEffectEntry const* spellEff = spellinfo->GetSpellEffect(SpellEffectIndex(j)); + if (!spellEff) + continue; + + if (spellEff->Effect == SPELL_EFFECT_LEARN_SPELL) { - trainerSpell.learnedSpell = spellinfo->EffectTriggerSpell[j]; + trainerSpell.learnedSpell = spellEff->EffectTriggerSpell; break; } } @@ -8528,11 +8497,11 @@ void ObjectMgr::LoadTrainers(char const* tableName, bool isTemplates) { if (trainerSpell.reqLevel) { - if (trainerSpell.reqLevel == learnSpellinfo->spellLevel) + if (trainerSpell.reqLevel == learnSpellinfo->GetSpellLevel()) ERROR_DB_STRICT_LOG("Table `%s` (Entry: %u) has redundant reqlevel %u (=spell level) for spell %u", tableName, entry, trainerSpell.reqLevel, spell); } else - trainerSpell.reqLevel = learnSpellinfo->spellLevel; + trainerSpell.reqLevel = learnSpellinfo->GetSpellLevel(); } ++count; @@ -9106,7 +9075,7 @@ bool ObjectMgr::IsVendorItemValid(bool isTemplate, char const* tableName, uint32 return false; } - if (ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost)) + /*if (ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost)) { if (pl) ChatHandler(pl).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST, ExtendedCost); @@ -9114,7 +9083,7 @@ bool ObjectMgr::IsVendorItemValid(bool isTemplate, char const* tableName, uint32 sLog.outErrorDb("Table `%s` contain item (Entry: %u) with wrong ExtendedCost (%u) for %s %u, ignoring", tableName, item_id, ExtendedCost, idStr, vendor_entry); return false; - } + }*/ if (maxcount > 0 && incrtime == 0) { diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h index e36907df2..53530b0a7 100644 --- a/src/game/Opcodes.h +++ b/src/game/Opcodes.h @@ -1341,11 +1341,35 @@ enum Opcodes MSG_MOVE_SET_COLLISION_HGT = 0x518, CMSG_CLEAR_RANDOM_BG_WIN_TIME = 0x519, CMSG_CLEAR_HOLIDAY_BG_WIN_TIME = 0x51A, - CMSG_COMMENTATOR_SKIRMISH_QUEUE_COMMAND = 0x51B,// lua: CommentatorSetSkirmishMatchmakingMode/CommentatorRequestSkirmishQueueData/CommentatorRequestSkirmishMode/CommentatorStartSkirmishMatch - SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT1 = 0x51C,// event EVENT_COMMENTATOR_SKIRMISH_QUEUE_REQUEST, CGCommentator::QueueNode - SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT2 = 0x51D,// event EVENT_COMMENTATOR_SKIRMISH_QUEUE_REQUEST - SMSG_COMPRESSED_UNKNOWN_1310 = 0x51E,// some compressed packet - NUM_MSG_TYPES = 0x51F + CMSG_COMMENTATOR_SKIRMISH_QUEUE_COMMAND = 0x51B, // Lua_CommentatorSetSkirmishMatchmakingMode and Lua_CommentatorRequestSkirmishQueueData + SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT1 = 0x51C, // event EVENT_COMMENTATOR_SKIRMISH_QUEUE_REQUEST, CGCommentator::QueueNode + SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT2 = 0x51D, // event EVENT_COMMENTATOR_SKIRMISH_QUEUE_REQUEST + SMSG_COMPRESSED_UNKNOWN_1310 = 0x51E, // some compressed packet + SMSG_UNKNOWN_1311 = 0x51F, // related to transform + SMSG_UNKNOWN_1312 = 0x520, // related to transform + UMSG_UNKNOWN_1313 = 0x521, // not found + SMSG_UNKNOWN_1314 = 0x522, // sets unit+4336 to value from packet + SMSG_UNKNOWN_1315 = 0x523, // related to opcode 0x522 + SMSG_UNKNOWN_1316 = 0x524, // sets unit+4338 to value from packet + SMSG_UNKNOWN_1317 = 0x525, // sets unit+4340 to value from packet + UMSG_UNKNOWN_1318 = 0x526, // not found + UMSG_UNKNOWN_1319 = 0x527, // not found + CMSG_UNKNOWN_1320 = 0x528, // setcurrency console command? + UMSG_UNKNOWN_1321 = 0x529, // not found + UMSG_UNKNOWN_1322 = 0x52A, // not found + UMSG_UNKNOWN_1323 = 0x52B, // not found + UMSG_UNKNOWN_1324 = 0x52C, // not found + UMSG_UNKNOWN_1325 = 0x52D, // not found + UMSG_UNKNOWN_1326 = 0x52E, // not found + UMSG_UNKNOWN_1327 = 0x52F, // not found + UMSG_UNKNOWN_1328 = 0x530, // not found + SMSG_UNKNOWN_1329 = 0x531, // faction related + UMSG_UNKNOWN_1330 = 0x532, // not found + UMSG_UNKNOWN_1331 = 0x533, // not found + UMSG_UNKNOWN_1332 = 0x534, // not found + UMSG_UNKNOWN_1333 = 0x535, // not found + UMSG_UNKNOWN_1334 = 0x536, // not found + NUM_MSG_TYPES = 0x537 }; /// Player state diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 2c9595118..36ed58ae2 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -724,21 +724,22 @@ void Pet::Unsummon(PetSaveMode mode, Unit* owner /*= NULL*/) { // returning of reagents only for players, so best done here uint32 spellId = GetUInt32Value(UNIT_CREATED_BY_SPELL); - SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId); + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + SpellReagentsEntry const* spellReagents = spellInfo ? spellInfo->GetSpellReagents() : NULL; - if (spellInfo) + if (spellReagents) { for (uint32 i = 0; i < MAX_SPELL_REAGENTS; ++i) { - if (spellInfo->Reagent[i] > 0) + if (spellReagents->Reagent[i] > 0) { - ItemPosCountVec dest; // for succubus, voidwalker, felhunter and felguard credit soulshard when despawn reason other than death (out of range, logout) - uint8 msg = p_owner->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, spellInfo->Reagent[i], spellInfo->ReagentCount[i]); + ItemPosCountVec dest; //for succubus, voidwalker, felhunter and felguard credit soulshard when despawn reason other than death (out of range, logout) + uint8 msg = p_owner->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, spellReagents->Reagent[i], spellReagents->ReagentCount[i]); if (msg == EQUIP_ERR_OK) { - Item* item = p_owner->StoreNewItem(dest, spellInfo->Reagent[i], true); + Item* item = p_owner->StoreNewItem(dest, spellReagents->Reagent[i], true); if (p_owner->IsInWorld()) - p_owner->SendNewItem(item, spellInfo->ReagentCount[i], true, false); + p_owner->SendNewItem(item, spellReagents->ReagentCount[i], true, false); } } } @@ -1317,13 +1318,20 @@ void Pet::_LoadAuras(uint32 timediff) } // prevent wrong values of remaincharges - if (spellproto->procCharges == 0) + uint32 procCharges = spellproto->GetProcCharges(); + if (procCharges) + { + if (remaincharges <= 0 || remaincharges > procCharges) + remaincharges = procCharges; + } + else remaincharges = 0; - if (!spellproto->StackAmount) + uint32 defstackamount = spellproto->GetStackAmount(); + if (!defstackamount) stackcount = 1; - else if (spellproto->StackAmount < stackcount) - stackcount = spellproto->StackAmount; + else if (defstackamount < stackcount) + stackcount = defstackamount; else if (!stackcount) stackcount = 1; @@ -1379,9 +1387,13 @@ void Pet::_SaveAuras() for (int32 j = 0; j < MAX_EFFECT_INDEX; ++j) { SpellEntry const* spellInfo = holder->GetSpellProto(); - if (spellInfo->EffectApplyAuraName[j] == SPELL_AURA_MOD_STEALTH || - spellInfo->Effect[j] == SPELL_EFFECT_APPLY_AREA_AURA_OWNER || - spellInfo->Effect[j] == SPELL_EFFECT_APPLY_AREA_AURA_PET) + SpellEffectEntry const* effectEntry = spellInfo->GetSpellEffect(SpellEffectIndex(j)); + if(!effectEntry) + continue; + + if (effectEntry->EffectApplyAuraName == SPELL_AURA_MOD_STEALTH || + effectEntry->Effect == SPELL_EFFECT_APPLY_AREA_AURA_OWNER || + effectEntry->Effect == SPELL_EFFECT_APPLY_AREA_AURA_PET ) { save = false; break; @@ -1610,8 +1622,8 @@ void Pet::InitLevelupSpellsForLevel() continue; // will called first if level down - if (spellEntry->spellLevel > level) - unlearnSpell(spellEntry->Id, true); + if(spellEntry->GetSpellLevel() > level) + unlearnSpell(spellEntry->Id,true); // will called if level up else learnSpell(spellEntry->Id); diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp index 1420a8e4e..d18c7fa8f 100644 --- a/src/game/PetAI.cpp +++ b/src/game/PetAI.cpp @@ -220,7 +220,8 @@ void PetAI::UpdateAI(const uint32 diff) { // allow only spell without spell cost or with spell cost but not duration limit int32 duration = GetSpellDuration(spellInfo); - if ((spellInfo->manaCost || spellInfo->ManaCostPercentage || spellInfo->manaPerSecond) && duration > 0) + SpellPowerEntry const* spellPower = spellInfo->GetSpellPower(); + if (spellPower && (spellPower->manaCost || spellPower->ManaCostPercentage || spellPower->manaPerSecond) && duration > 0) continue; // allow only spell without cooldown > duration diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index bddc8b65e..93ec72bf0 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -186,7 +186,10 @@ void WorldSession::HandlePetAction(WorldPacket& recv_data) for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if (!spellEffect) + continue; + if (spellEffect->EffectImplicitTargetA == TARGET_ALL_ENEMY_IN_AREA || spellEffect->EffectImplicitTargetA == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellEffect->EffectImplicitTargetA == TARGET_ALL_ENEMY_IN_AREA_CHANNELED) return; } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 89f9e5e49..0dbf78141 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -274,6 +274,26 @@ std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi) ss << taxi.m_taximask[i] << " "; return ss; } + +SpellModifier::SpellModifier( SpellModOp _op, SpellModType _type, int32 _value, SpellEntry const* spellEntry, SpellEffectIndex eff, int16 _charges /*= 0*/ ) : op(_op), type(_type), charges(_charges), value(_value), spellId(spellEntry->Id), lastAffected(NULL) +{ + mask = spellEntry->GetEffectSpellClassMask(eff); +} + +SpellModifier::SpellModifier( SpellModOp _op, SpellModType _type, int32 _value, Aura const* aura, int16 _charges /*= 0*/ ) : op(_op), type(_type), charges(_charges), value(_value), spellId(aura->GetId()), lastAffected(NULL) +{ + mask = aura->GetAuraSpellClassMask(); +} + +bool SpellModifier::isAffectedOnSpell( SpellEntry const *spell ) const +{ + SpellEntry const *affect_spell = sSpellStore.LookupEntry(spellId); + // False if affect_spell == NULL or spellFamily not equal + if (!affect_spell || affect_spell->GetSpellFamilyName() != spell->GetSpellFamilyName()) + return false; + return spell->IsFitToFamilyMask(mask); +} + //== TradeData ================================================= TradeData* TradeData::GetTraderData() const @@ -425,6 +445,7 @@ Player::Player(WorldSession* session): Unit(), m_mover(this), m_camera(this), m_ memset(m_items, 0, sizeof(Item*)*PLAYER_SLOTS_COUNT); m_social = NULL; + m_guildId = 0; // group is initialized in the reference constructor SetGroupInvite(NULL); @@ -541,6 +562,8 @@ Player::Player(WorldSession* session): Unit(), m_mover(this), m_camera(this), m_ // Honor System m_lastHonorUpdateTime = time(NULL); + m_honorPoints = 0; + m_arenaPoints = 0; // Player summoning m_summon_expire = 0; @@ -677,18 +700,16 @@ bool Player::Create(uint32 guidlow, const std::string& name, uint8 race, uint8 c SetUInt16Value(PLAYER_BYTES_3, 0, gender); // only GENDER_MALE/GENDER_FEMALE (1 bit) allowed, drunk state = 0 SetByteValue(PLAYER_BYTES_3, 3, 0); // BattlefieldArenaFaction (0 or 1) - SetUInt32Value(PLAYER_GUILDID, 0); - SetUInt32Value(PLAYER_GUILDRANK, 0); - SetUInt32Value(PLAYER_GUILD_TIMESTAMP, 0); + SetInGuild( 0 ); + SetUInt32Value( PLAYER_GUILDRANK, 0 ); + SetUInt32Value( PLAYER_GUILD_TIMESTAMP, 0 ); for (int i = 0; i < KNOWN_TITLES_SIZE; ++i) SetUInt64Value(PLAYER__FIELD_KNOWN_TITLES + i, 0); // 0=disabled SetUInt32Value(PLAYER_CHOSEN_TITLE, 0); - SetUInt32Value(PLAYER_FIELD_KILLS, 0); - SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0); - SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); - SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0); + SetUInt32Value( PLAYER_FIELD_KILLS, 0 ); + SetUInt32Value( PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0 ); // set starting level uint32 start_level = getClass() != CLASS_DEATH_KNIGHT @@ -1995,6 +2016,9 @@ void Player::RegenerateAll(uint32 diff) if (getClass() == CLASS_DEATH_KNIGHT) Regenerate(POWER_RUNE, diff); + if (getClass() == CLASS_HUNTER) + Regenerate(POWER_FOCUS, diff); + m_regenTimer = REGEN_TIME_FULL; } @@ -2029,6 +2053,9 @@ void Player::Regenerate(Powers power, uint32 diff) float RageDecreaseRate = sWorld.getConfig(CONFIG_FLOAT_RATE_POWER_RAGE_LOSS); addvalue = 20 * RageDecreaseRate; // 2 rage by tick (= 2 seconds => 1 rage/sec) } break; + case POWER_FOCUS: + addvalue = 12; + break; case POWER_ENERGY: // Regenerate energy (rogue) { float EnergyRate = sWorld.getConfig(CONFIG_FLOAT_RATE_POWER_ENERGY); @@ -2059,7 +2086,6 @@ void Player::Regenerate(Powers power, uint32 diff) } } } break; - case POWER_FOCUS: case POWER_HAPPINESS: case POWER_HEALTH: break; @@ -2638,12 +2664,14 @@ void Player::InitStatsForLevel(bool reapplyMods) SetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, 0.0f); SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, 0.0f); - SetInt32Value(UNIT_FIELD_ATTACK_POWER, 0); - SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, 0); - SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, 0.0f); - SetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER, 0); - SetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS, 0); - SetFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER, 0.0f); + SetInt32Value(UNIT_FIELD_ATTACK_POWER, 0 ); + SetInt32Value(UNIT_FIELD_ATTACK_POWER_MOD_POS, 0 ); + SetInt32Value(UNIT_FIELD_ATTACK_POWER_MOD_NEG, 0 ); + SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER,0.0f); + SetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER, 0 ); + SetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS,0 ); + SetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG,0 ); + SetFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER,0.0f); // Base crit values (will be recalculated in UpdateAllStats() at loading and in _ApplyAllStatBonuses() at reset SetFloatValue(PLAYER_CRIT_PERCENTAGE, 0.0f); @@ -2688,7 +2716,7 @@ void Player::InitStatsForLevel(bool reapplyMods) // save new stats for (int i = POWER_MANA; i < MAX_POWERS; ++i) - SetMaxPower(Powers(i), GetCreatePowers(Powers(i))); + SetMaxPower(Powers(i), GetCreatePowers(Powers(i))); SetMaxHealth(classInfo.basehealth); // stamina bonus will applied later @@ -2774,7 +2802,7 @@ void Player::SendInitialSpells() data << uint32(itr->first); data << uint16(itr->second.itemid); // cast item id - data << uint16(sEntry->Category); // spell category + data << uint16(sEntry->GetCategory()); // spell category // send infinity cooldown in special format if (itr->second.end >= infTime) @@ -2786,7 +2814,7 @@ void Player::SendInitialSpells() time_t cooldown = itr->second.end > curTime ? (itr->second.end - curTime) * IN_MILLISECONDS : 0; - if (sEntry->Category) // may be wrong, but anyway better than nothing... + if(sEntry->GetCategory()) // may be wrong, but anyway better than nothing... { data << uint32(0); // cooldown data << uint32(cooldown); // category cooldown @@ -3260,10 +3288,12 @@ bool Player::IsNeedCastPassiveLikeSpellAtLearn(SpellEntry const* spellInfo) cons // note: form passives activated with shapeshift spells be implemented by HandleShapeshiftBoosts instead of spell_learn_spell // talent dependent passives activated at form apply have proper stance data - bool need_cast = !spellInfo->Stances || (!form && spellInfo->HasAttribute(SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT)); + SpellShapeshiftEntry const* shapeShift = spellInfo->GetSpellShapeshift(); + bool need_cast = (!shapeShift || !shapeShift->Stances || (!form && spellInfo->HasAttribute(SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT))); // Check CasterAuraStates - return need_cast && (!spellInfo->CasterAuraState || HasAuraState(AuraState(spellInfo->CasterAuraState))); + SpellAuraRestrictionsEntry const* auraRestrictions = spellInfo->GetSpellAuraRestrictions(); + return need_cast && (auraRestrictions && (!auraRestrictions->CasterAuraState || HasAuraState(AuraState(auraRestrictions->CasterAuraState)))); } void Player::learnSpell(uint32 spell_id, bool dependent) @@ -3553,9 +3583,9 @@ void Player::RemoveArenaSpellCooldowns() ++next; SpellEntry const* entry = sSpellStore.LookupEntry(itr->first); // check if spellentry is present and if the cooldown is less than 15 mins - if (entry && - entry->RecoveryTime <= 15 * MINUTE * IN_MILLISECONDS && - entry->CategoryRecoveryTime <= 15 * MINUTE * IN_MILLISECONDS) + if( entry && + entry->GetRecoveryTime() <= 15 * MINUTE * IN_MILLISECONDS && + entry->GetCategoryRecoveryTime() <= 15 * MINUTE * IN_MILLISECONDS ) { // remove & notify RemoveSpellCooldown(itr->first, true); @@ -3855,6 +3885,9 @@ void Player::InitVisibleBits() updateVisualBits.SetBit(UNIT_FIELD_POWER5); updateVisualBits.SetBit(UNIT_FIELD_POWER6); updateVisualBits.SetBit(UNIT_FIELD_POWER7); + updateVisualBits.SetBit(UNIT_FIELD_POWER8); + updateVisualBits.SetBit(UNIT_FIELD_POWER9); + updateVisualBits.SetBit(UNIT_FIELD_POWER10); updateVisualBits.SetBit(UNIT_FIELD_MAXHEALTH); updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER1); updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER2); @@ -3863,6 +3896,9 @@ void Player::InitVisibleBits() updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER5); updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER6); updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER7); + updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER8); + updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER9); + updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER10); updateVisualBits.SetBit(UNIT_FIELD_LEVEL); updateVisualBits.SetBit(UNIT_FIELD_FACTIONTEMPLATE); updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 0); @@ -3891,7 +3927,7 @@ void Player::InitVisibleBits() updateVisualBits.SetBit(PLAYER_DUEL_ARBITER + 0); updateVisualBits.SetBit(PLAYER_DUEL_ARBITER + 1); updateVisualBits.SetBit(PLAYER_FLAGS); - updateVisualBits.SetBit(PLAYER_GUILDID); + //updateVisualBits.SetBit(PLAYER_GUILDID); updateVisualBits.SetBit(PLAYER_GUILDRANK); updateVisualBits.SetBit(PLAYER_BYTES); updateVisualBits.SetBit(PLAYER_BYTES_2); @@ -4035,9 +4071,10 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell SpellEntry const* spell = sSpellStore.LookupEntry(trainer_spell->learnedSpell); // secondary prof. or not prof. spell - uint32 skill = spell->EffectMiscValue[1]; + SpellEffectEntry const* spellEffect = spell->GetSpellEffect(EFFECT_INDEX_1); + uint32 skill = spellEffect ? spellEffect->EffectMiscValue : 0; - if (spell->Effect[1] != SPELL_EFFECT_SKILL || !IsPrimaryProfessionSkill(skill)) + if(spellEffect && (spellEffect->Effect != SPELL_EFFECT_SKILL || !IsPrimaryProfessionSkill(skill))) return TRAINER_SPELL_GREEN; // check primary prof. limit @@ -4531,8 +4568,6 @@ Corpse* Player::CreateCorpse() corpse->SetUInt32Value(CORPSE_FIELD_DISPLAY_ID, GetNativeDisplayId()); - corpse->SetUInt32Value(CORPSE_FIELD_GUILD, GetGuildId()); - uint32 iDisplayID; uint32 iIventoryType; uint32 _cfi; @@ -5115,23 +5150,23 @@ float Player::GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const float Player::OCTRegenHPPerSpirit() { - uint32 level = getLevel(); - uint32 pclass = getClass(); + //uint32 level = getLevel(); + //uint32 pclass = getClass(); - if (level > GT_MAX_LEVEL) level = GT_MAX_LEVEL; + //if (level>GT_MAX_LEVEL) level = GT_MAX_LEVEL; - GtOCTRegenHPEntry const* baseRatio = sGtOCTRegenHPStore.LookupEntry((pclass - 1) * GT_MAX_LEVEL + level - 1); - GtRegenHPPerSptEntry const* moreRatio = sGtRegenHPPerSptStore.LookupEntry((pclass - 1) * GT_MAX_LEVEL + level - 1); - if (baseRatio == NULL || moreRatio == NULL) + //GtOCTRegenHPEntry const *baseRatio = sGtOCTRegenHPStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1); + //GtRegenHPPerSptEntry const *moreRatio = sGtRegenHPPerSptStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1); + //if (baseRatio==NULL || moreRatio==NULL) return 0.0f; // Formula from PaperDollFrame script - float spirit = GetStat(STAT_SPIRIT); - float baseSpirit = spirit; - if (baseSpirit > 50) baseSpirit = 50; - float moreSpirit = spirit - baseSpirit; - float regen = baseSpirit * baseRatio->ratio + moreSpirit * moreRatio->ratio; - return regen; + //float spirit = GetStat(STAT_SPIRIT); + //float baseSpirit = spirit; + //if (baseSpirit>50) baseSpirit = 50; + //float moreSpirit = spirit - baseSpirit; + //float regen = baseSpirit * baseRatio->ratio + moreSpirit * moreRatio->ratio; + //return regen; } float Player::OCTRegenMPPerSpirit() @@ -5352,7 +5387,7 @@ bool Player::UpdateCraftSkill(uint32 spellid) // Alchemy Discoveries here SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellid); - if (spellEntry && spellEntry->Mechanic == MECHANIC_DISCOVERY) + if (spellEntry && spellEntry->GetMechanic() == MECHANIC_DISCOVERY) { if (uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->skillId, spellid, this)) learnSpell(discoveredSpell, false); @@ -6394,16 +6429,14 @@ void Player::UpdateHonorFields() // update yesterday's contribution if (m_lastHonorUpdateTime >= yesterday) { - SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION)); + //SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION)); // this is the first update today, reset today's contribution - SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); - SetUInt32Value(PLAYER_FIELD_KILLS, MAKE_PAIR32(0, kills_today)); + SetUInt32Value(PLAYER_FIELD_KILLS, MAKE_PAIR32(0,kills_today)); } else { // no honor/kills yesterday or today, reset - SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0); SetUInt32Value(PLAYER_FIELD_KILLS, 0); } } @@ -6537,7 +6570,7 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, float honor) // add honor points ModifyHonorPoints(int32(honor)); - ApplyModUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, uint32(honor), true); + // FIXME 4x ApplyModUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, uint32(honor), true); return true; } @@ -6546,7 +6579,9 @@ void Player::SetHonorPoints(uint32 value) if (value > sWorld.getConfig(CONFIG_UINT32_MAX_HONOR_POINTS)) value = sWorld.getConfig(CONFIG_UINT32_MAX_HONOR_POINTS); - SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, value); + // FIXME 4x SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, value); + // must be recalculated to new honor points items and removed + m_honorPoints = value; } void Player::SetArenaPoints(uint32 value) @@ -6554,7 +6589,9 @@ void Player::SetArenaPoints(uint32 value) if (value > sWorld.getConfig(CONFIG_UINT32_MAX_ARENA_POINTS)) value = sWorld.getConfig(CONFIG_UINT32_MAX_ARENA_POINTS); - SetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY, value); + // FIXME 4x SetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY, value); + // must be recalculated to new honor points items and removed + m_arenaPoints = value; } void Player::ModifyHonorPoints(int32 value) @@ -7149,7 +7186,7 @@ void Player::_ApplyItemBonuses(ItemPrototype const* proto, uint8 slot, bool appl } // If set ScalingStatValue armor get it or use item armor - uint32 armor = proto->Armor; + uint32 armor = proto->GetArmor(); if (ssv) { if (uint32 ssvarmor = ssv->getArmorMod(proto->ScalingStatValue)) @@ -7210,8 +7247,8 @@ void Player::_ApplyItemBonuses(ItemPrototype const* proto, uint8 slot, bool appl attType = OFF_ATTACK; } - float minDamage = proto->Damage[0].DamageMin; - float maxDamage = proto->Damage[0].DamageMax; + float minDamage = proto->GetMinDamage(); + float maxDamage = proto->GetMaxDamage(); int32 extraDPS = 0; // If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage if (ssv) @@ -7285,7 +7322,7 @@ void Player::_ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackTy void Player::_ApplyWeaponDependentAuraCritMod(Item* item, WeaponAttackType attackType, Aura* aura, bool apply) { // generic not weapon specific case processes in aura code - if (aura->GetSpellProto()->EquippedItemClass == -1) + if(aura->GetSpellProto()->GetEquippedItemClass() == -1) return; BaseModGroup mod = BASEMOD_END; @@ -7311,7 +7348,7 @@ void Player::_ApplyWeaponDependentAuraDamageMod(Item* item, WeaponAttackType att return; // generic not weapon specific case processes in aura code - if (aura->GetSpellProto()->EquippedItemClass == -1) + if(aura->GetSpellProto()->GetEquippedItemClass() == -1) return; UnitMods unitMod = UNIT_MOD_END; @@ -7542,7 +7579,7 @@ void Player::_HandleDeadlyPoison(Unit* Target, WeaponAttackType attType, SpellEn break; } } - if (dPoison && dPoison->GetStackAmount() == spellInfo->StackAmount) + if (dPoison && dPoison->GetStackAmount() == spellInfo->GetStackAmount()) { Item* otherWeapon = GetWeaponForAttack(attType == BASE_ATTACK ? OFF_ATTACK : BASE_ATTACK); if (!otherWeapon) @@ -7562,9 +7599,9 @@ void Player::_HandleDeadlyPoison(Unit* Target, WeaponAttackType attType, SpellEn if (pSecondEnchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL) continue; - SpellEntry const* combatEntry = sSpellStore.LookupEntry(pSecondEnchant->spellid[s]); - if (combatEntry && combatEntry->Dispel == DISPEL_POISON) - CastSpell(Target, combatEntry, true, otherWeapon); + if (SpellEntry const* combatEntry = sSpellStore.LookupEntry(pSecondEnchant->spellid[s])) + if (combatEntry->GetDispel() == DISPEL_POISON) + CastSpell(Target, combatEntry, true, otherWeapon); } } } @@ -7605,7 +7642,7 @@ void Player::CastItemCombatSpell(Unit* Target, WeaponAttackType attType) if (m_extraAttacks && IsSpellHaveEffect(spellInfo, SPELL_EFFECT_ADD_EXTRA_ATTACKS)) return; - float chance = (float)spellInfo->procChance; + float chance = (float)spellInfo->GetProcChance(); if (spellData.SpellPPMRate) { @@ -7658,7 +7695,7 @@ void Player::CastItemCombatSpell(Unit* Target, WeaponAttackType attType) else { // Deadly Poison, unique effect needs to be handled before casting triggered spell - if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && spellInfo->SpellFamilyFlags & UI64LIT(0x10000)) + if (spellInfo->IsFitToFamily(SPELLFAMILY_ROGUE, UI64LIT(0x0000000000010000))) _HandleDeadlyPoison(Target, attType, spellInfo); CastSpell(Target, spellInfo->Id, true, item); @@ -7873,26 +7910,26 @@ void Player::_ApplyAllLevelScaleItemMods(bool apply) void Player::_ApplyAmmoBonuses() { - // check ammo - uint32 ammo_id = GetUInt32Value(PLAYER_AMMO_ID); - if (!ammo_id) - return; + //// check ammo + //uint32 ammo_id = GetUInt32Value(PLAYER_AMMO_ID); + //if(!ammo_id) + // return; - float currentAmmoDPS; + //float currentAmmoDPS; - ItemPrototype const* ammo_proto = ObjectMgr::GetItemPrototype(ammo_id); - if (!ammo_proto || ammo_proto->Class != ITEM_CLASS_PROJECTILE || !CheckAmmoCompatibility(ammo_proto)) - currentAmmoDPS = 0.0f; - else - currentAmmoDPS = ammo_proto->Damage[0].DamageMin; + //ItemPrototype const *ammo_proto = ObjectMgr::GetItemPrototype( ammo_id ); + //if( !ammo_proto || ammo_proto->Class!=ITEM_CLASS_PROJECTILE || !CheckAmmoCompatibility(ammo_proto)) + // currentAmmoDPS = 0.0f; + //else + // currentAmmoDPS = ammo_proto->Damage[0].DamageMin; - if (currentAmmoDPS == GetAmmoDPS()) - return; + //if(currentAmmoDPS == GetAmmoDPS()) + // return; - m_ammoDPS = currentAmmoDPS; + //m_ammoDPS = currentAmmoDPS; - if (CanModifyStats()) - UpdateDamagePhysical(RANGED_ATTACK); + //if(CanModifyStats()) + // UpdateDamagePhysical(RANGED_ATTACK); } bool Player::CheckAmmoCompatibility(const ItemPrototype* ammo_proto) const @@ -11049,37 +11086,37 @@ InventoryResult Player::CanUseAmmo(uint32 item) const void Player::SetAmmo(uint32 item) { - if (!item) - return; + //if(!item) + // return; - // already set - if (GetUInt32Value(PLAYER_AMMO_ID) == item) - return; + //// already set + //if( GetUInt32Value(PLAYER_AMMO_ID) == item ) + // return; - // check ammo - if (item) - { - InventoryResult msg = CanUseAmmo(item); - if (msg != EQUIP_ERR_OK) - { - SendEquipError(msg, NULL, NULL, item); - return; - } - } + //// check ammo + //if (item) + //{ + // InventoryResult msg = CanUseAmmo( item ); + // if (msg != EQUIP_ERR_OK) + // { + // SendEquipError(msg, NULL, NULL, item); + // return; + // } + //} - SetUInt32Value(PLAYER_AMMO_ID, item); + //SetUInt32Value(PLAYER_AMMO_ID, item); - _ApplyAmmoBonuses(); + //_ApplyAmmoBonuses(); } void Player::RemoveAmmo() { - SetUInt32Value(PLAYER_AMMO_ID, 0); + //SetUInt32Value(PLAYER_AMMO_ID, 0); - m_ammoDPS = 0.0f; + //m_ammoDPS = 0.0f; - if (CanModifyStats()) - UpdateDamagePhysical(RANGED_ATTACK); + //if (CanModifyStats()) + // UpdateDamagePhysical(RANGED_ATTACK); } // Return stored item (if stored to stack, it can diff. from pItem). And pItem ca be deleted in this case. @@ -11284,7 +11321,7 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update) sLog.outError("Weapon switch cooldown spell %u couldn't be found in Spell.dbc", cooldownSpell); else { - m_weaponChangeTimer = spellProto->StartRecoveryTime; + m_weaponChangeTimer = spellProto->GetStartRecoveryTime(); WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4); data << GetObjectGuid(); @@ -15487,9 +15524,9 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder) //"resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty," // 39 40 41 42 43 44 45 46 47 48 49 //"arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk," - // 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 - //"health, power1, power2, power3, power4, power5, power6, power7, specCount, activeSpec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid)); - QueryResult* result = holder->GetResult(PLAYER_LOGIN_QUERY_LOADFROM); + // 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 + //"health, power1, power2, power3, power4, power5, power6, power7, power8, power9, power10, specCount, activeSpec, exploredZones, equipmentCache, knownTitles, actionBars FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid)); + QueryResult *result = holder->GetResult(PLAYER_LOGIN_QUERY_LOADFROM); if (!result) { @@ -15538,8 +15575,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder) SetUInt32Value(UNIT_FIELD_LEVEL, fields[6].GetUInt8()); SetUInt32Value(PLAYER_XP, fields[7].GetUInt32()); - _LoadIntoDataField(fields[60].GetString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE); - _LoadIntoDataField(fields[63].GetString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE * 2); + _LoadIntoDataField(fields[63].GetString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE); + _LoadIntoDataField(fields[65].GetString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE*2); InitDisplayIds(); // model, scale and model data @@ -15564,12 +15601,10 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder) SetUInt32Value(PLAYER_FLAGS, fields[11].GetUInt32()); SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fields[48].GetInt32()); - SetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES, fields[47].GetUInt64()); - - SetUInt32Value(PLAYER_AMMO_ID, fields[62].GetUInt32()); + //SetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES, fields[47].GetUInt64()); // Action bars state - SetByteValue(PLAYER_FIELD_BYTES, 2, fields[64].GetUInt8()); + SetByteValue(PLAYER_FIELD_BYTES, 2, fields[66].GetUInt8()); // cleanup inventory related item value fields (its will be filled correctly in _LoadInventory) for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot) @@ -15632,8 +15667,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder) SetHonorPoints(fields[40].GetUInt32()); - SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, fields[41].GetUInt32()); - SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, fields[42].GetUInt32()); + //SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, fields[41].GetUInt32()); + //SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, fields[42].GetUInt32()); SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, fields[43].GetUInt32()); SetUInt16Value(PLAYER_FIELD_KILLS, 0, fields[44].GetUInt16()); SetUInt16Value(PLAYER_FIELD_KILLS, 1, fields[45].GetUInt16()); @@ -15904,8 +15939,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder) _LoadMailedItems(holder->GetResult(PLAYER_LOGIN_QUERY_LOADMAILEDITEMS)); UpdateNextMailTimeAndUnreads(); - m_specsCount = fields[58].GetUInt8(); - m_activeSpec = fields[59].GetUInt8(); + m_specsCount = fields[61].GetUInt8(); + m_activeSpec = fields[62].GetUInt8(); _LoadGlyphs(holder->GetResult(PLAYER_LOGIN_QUERY_LOADGLYPHS)); @@ -16015,7 +16050,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder) // restore remembered power/health values (but not more max values) uint32 savedhealth = fields[50].GetUInt32(); SetHealth(savedhealth > GetMaxHealth() ? GetMaxHealth() : savedhealth); - for (uint32 i = 0; i < MAX_POWERS; ++i) + + for(uint32 i = 0; i < MAX_POWERS; ++i) { uint32 savedpower = fields[51 + i].GetUInt32(); SetPower(Powers(i), savedpower > GetMaxPower(Powers(i)) ? GetMaxPower(Powers(i)) : savedpower); @@ -16200,13 +16236,19 @@ void Player::_LoadAuras(QueryResult* result, uint32 timediff) } // prevent wrong values of remaincharges - if (spellproto->procCharges == 0) + if (uint32 procCharges = spellproto->GetProcCharges()) + { + if (remaincharges <= 0 || remaincharges > procCharges) + remaincharges = procCharges; + } + else remaincharges = 0; - if (!spellproto->StackAmount) + uint32 defstackamount = spellproto->GetStackAmount(); + if (!defstackamount) stackcount = 1; - else if (spellproto->StackAmount < stackcount) - stackcount = spellproto->StackAmount; + else if (defstackamount < stackcount) + stackcount = defstackamount; else if (!stackcount) stackcount = 1; @@ -17329,21 +17371,21 @@ void Player::SaveToDB() stmt.PExecute(GetGUIDLow()); SqlStatement uberInsert = CharacterDatabase.CreateStatement(insChar, "INSERT INTO characters (guid,account,name,race,class,gender,level,xp,money,playerBytes,playerBytes2,playerFlags," - "map, dungeon_difficulty, position_x, position_y, position_z, orientation, " - "taximask, online, cinematic, " - "totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, " - "trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, " - "death_expire_time, taxi_path, arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, " - "todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, health, power1, power2, power3, " - "power4, power5, power6, power7, specCount, activeSpec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars) " - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " - "?, ?, ?, ?, ?, ?, " - "?, ?, ?, " - "?, ?, ?, ?, ?, ?, ?, " - "?, ?, ?, ?, ?, ?, ?, ?, ?, " - "?, ?, ?, ?, ?, ?, ?, " - "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " - "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "); + "map, dungeon_difficulty, position_x, position_y, position_z, orientation, " + "taximask, online, cinematic, " + "totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, " + "trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, " + "death_expire_time, taxi_path, arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, " + "todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, health, power1, power2, power3, " + "power4, power5, power6, power7, power8, power9, power10, specCount, activeSpec, exploredZones, equipmentCache, knownTitles, actionBars) VALUES (" + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " + "?, ?, ?, ?, ?, ?, " + "?, ?, ?, " + "?, ?, ?, ?, ?, ?, ?, " + "?, ?, ?, ?, ?, ?, ?, ?, ?, " + "?, ?, ?, ?, ?, ?, ?, " + "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " + "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "); uberInsert.addUInt32(GetGUIDLow()); uberInsert.addUInt32(GetSession()->GetAccountId()); @@ -17422,9 +17464,9 @@ void Player::SaveToDB() uberInsert.addUInt32(GetHonorPoints()); - uberInsert.addUInt32(GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION)); + uberInsert.addUInt32(0); // FIXME 4x GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION) - uberInsert.addUInt32(GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION)); + uberInsert.addUInt32(0); // FIXME 4x GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION) uberInsert.addUInt32(GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS)); @@ -17434,7 +17476,7 @@ void Player::SaveToDB() uberInsert.addUInt32(GetUInt32Value(PLAYER_CHOSEN_TITLE)); - uberInsert.addUInt64(GetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES)); + uberInsert.addUInt64(0); // FIXME 4x GetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES) // FIXME: at this moment send to DB as unsigned, including unit32(-1) uberInsert.addUInt32(GetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX)); @@ -17461,9 +17503,7 @@ void Player::SaveToDB() } uberInsert.addString(ss); - uberInsert.addUInt32(GetUInt32Value(PLAYER_AMMO_ID)); - - for (uint32 i = 0; i < KNOWN_TITLES_SIZE * 2; ++i) // string + for(uint32 i = 0; i < KNOWN_TITLES_SIZE*2; ++i ) //string { ss << GetUInt32Value(PLAYER__FIELD_KNOWN_TITLES + i) << " "; } @@ -18111,10 +18151,10 @@ void Player::_SaveStats() SqlStatement stmt = CharacterDatabase.CreateStatement(delStats, "DELETE FROM character_stats WHERE guid = ?"); stmt.PExecute(GetGUIDLow()); - stmt = CharacterDatabase.CreateStatement(insertStats, "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, maxpower6, maxpower7, " - "strength, agility, stamina, intellect, spirit, armor, resHoly, resFire, resNature, resFrost, resShadow, resArcane, " - "blockPct, dodgePct, parryPct, critPct, rangedCritPct, spellCritPct, attackPower, rangedAttackPower, spellPower) " - "VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + stmt = CharacterDatabase.CreateStatement(insertStats, "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, maxpower6, maxpower7, maxpower8, maxpower9, maxpower10" + "strength, agility, stamina, intellect, spirit, armor, resHoly, resFire, resNature, resFrost, resShadow, resArcane, " + "blockPct, dodgePct, parryPct, critPct, rangedCritPct, spellCritPct, attackPower, rangedAttackPower, spellPower) " + "VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); stmt.addUInt32(GetGUIDLow()); stmt.addUInt32(GetMaxHealth()); @@ -19245,7 +19285,7 @@ void Player::InitDisplayIds() } } -void Player::TakeExtendedCost(uint32 extendedCostId, uint32 count) +/*void Player::TakeExtendedCost(uint32 extendedCostId, uint32 count) { ItemExtendedCostEntry const* extendedCost = sItemExtendedCostStore.LookupEntry(extendedCostId); @@ -19259,7 +19299,7 @@ void Player::TakeExtendedCost(uint32 extendedCostId, uint32 count) if (extendedCost->reqitem[i]) DestroyItemCount(extendedCost->reqitem[i], extendedCost->reqitemcount[i] * count, true); } -} +}*/ // Return true is the bought item has a max count to force refresh of window by caller bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot) @@ -19344,7 +19384,7 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uin return false; } - if (uint32 extendedCostId = crItem->ExtendedCost) + /*if (uint32 extendedCostId = crItem->ExtendedCost) { ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(extendedCostId); if (!iece) @@ -19384,7 +19424,7 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uin SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK, NULL, NULL); return false; } - } + }*/ uint32 price = (crItem->ExtendedCost == 0 || pProto->Flags2 & ITEM_FLAG2_EXT_COST_REQUIRES_GOLD) ? pProto->BuyPrice * count : 0; @@ -19412,8 +19452,8 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uin ModifyMoney(-int32(price)); - if (crItem->ExtendedCost) - TakeExtendedCost(crItem->ExtendedCost, count); + /*if (crItem->ExtendedCost) + TakeExtendedCost(crItem->ExtendedCost, count);*/ pItem = StoreNewItem(dest, item, true); } @@ -19435,8 +19475,8 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uin ModifyMoney(-int32(price)); - if (crItem->ExtendedCost) - TakeExtendedCost(crItem->ExtendedCost, count); + /*if (crItem->ExtendedCost) + TakeExtendedCost(crItem->ExtendedCost, count);*/ pItem = EquipNewItem(dest, item, true); @@ -19572,9 +19612,9 @@ void Player::AddSpellAndCategoryCooldowns(SpellEntry const* spellInfo, uint32 it // if no cooldown found above then base at DBC data if (rec < 0 && catrec < 0) { - cat = spellInfo->Category; - rec = spellInfo->RecoveryTime; - catrec = spellInfo->CategoryRecoveryTime; + cat = spellInfo->GetCategory(); + rec = spellInfo->GetRecoveryTime(); + catrec = spellInfo->GetCategoryRecoveryTime(); } time_t curTime = time(NULL); @@ -20449,10 +20489,13 @@ void Player::learnQuestRewardedSpells(Quest const* quest) bool found = false; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (spellInfo->Effect[i] == SPELL_EFFECT_LEARN_SPELL && !HasSpell(spellInfo->EffectTriggerSpell[i])) + if(SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i))) { - found = true; - break; + if(spellEffect->Effect == SPELL_EFFECT_LEARN_SPELL && !HasSpell(spellEffect->EffectTriggerSpell)) + { + found = true; + break; + } } } @@ -20461,8 +20504,10 @@ void Player::learnQuestRewardedSpells(Quest const* quest) return; // prevent learn non first rank unknown profession and second specialization for same profession) - uint32 learned_0 = spellInfo->EffectTriggerSpell[EFFECT_INDEX_0]; - if (sSpellMgr.GetSpellRank(learned_0) > 1 && !HasSpell(learned_0)) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(EFFECT_INDEX_0); + uint32 learned_0 = spellEffect ? spellEffect->EffectTriggerSpell : 0; + + if( sSpellMgr.GetSpellRank(learned_0) > 1 && !HasSpell(learned_0) ) { // not have first rank learned (unlearned prof?) uint32 first_spell = sSpellMgr.GetFirstSpellInChain(learned_0); @@ -20474,7 +20519,9 @@ void Player::learnQuestRewardedSpells(Quest const* quest) return; // specialization - if (learnedInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_TRADE_SKILL && learnedInfo->Effect[EFFECT_INDEX_1] == 0) + SpellEffectEntry const* learnedSpellEffect0 = learnedInfo->GetSpellEffect(EFFECT_INDEX_0); + SpellEffectEntry const* learnedSpellEffect1 = learnedInfo->GetSpellEffect(EFFECT_INDEX_1); + if (learnedSpellEffect0 && learnedSpellEffect0->Effect == SPELL_EFFECT_TRADE_SKILL && learnedSpellEffect1 && learnedSpellEffect1->Effect == 0) { // search other specialization for same prof for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) @@ -20487,7 +20534,9 @@ void Player::learnQuestRewardedSpells(Quest const* quest) return; // compare only specializations - if (itrInfo->Effect[EFFECT_INDEX_0] != SPELL_EFFECT_TRADE_SKILL || itrInfo->Effect[EFFECT_INDEX_1] != 0) + SpellEffectEntry const* itrSpellEffect0 = learnedInfo->GetSpellEffect(EFFECT_INDEX_0); + SpellEffectEntry const* itrSpellEffect1 = learnedInfo->GetSpellEffect(EFFECT_INDEX_1); + if ((itrSpellEffect0 && itrSpellEffect0->Effect != SPELL_EFFECT_TRADE_SKILL) || (itrSpellEffect1 && itrSpellEffect1->Effect != 0)) continue; // compare same chain spells @@ -20889,12 +20938,13 @@ void Player::AutoUnequipOffhandIfNeed() bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item const* ignoreItem) { - if (spellInfo->EquippedItemClass < 0) + int32 itemClass = spellInfo->GetEquippedItemClass(); + if(itemClass < 0) return true; // scan other equipped items for same requirements (mostly 2 daggers/etc) // for optimize check 2 used cases only - switch (spellInfo->EquippedItemClass) + switch(itemClass) { case ITEM_CLASS_WEAPON: { @@ -20925,7 +20975,7 @@ bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item cons break; } default: - sLog.outError("HasItemFitToSpellReqirements: Not handled spell requirement for item class %u", spellInfo->EquippedItemClass); + sLog.outError("HasItemFitToSpellReqirements: Not handled spell requirement for item class %u", itemClass); break; } @@ -22147,7 +22197,7 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank) return; // Check if it requires another talent - if (talentInfo->DependsOn > 0) + /*if (talentInfo->DependsOn > 0) { if (TalentEntry const* depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn)) { @@ -22163,7 +22213,7 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank) if (!hasEnoughRank) return; } - } + }*/ // Find out how many points we have in this field uint32 spentPoints = 0; @@ -22261,7 +22311,7 @@ void Player::LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRa return; // Check if it requires another talent - if (talentInfo->DependsOn > 0) + /*if (talentInfo->DependsOn > 0) { if (TalentEntry const* depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn)) { @@ -22275,7 +22325,7 @@ void Player::LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRa if (!hasEnoughRank) return; } - } + }*/ // Find out how many points we have in this field uint32 spentPoints = 0; @@ -22330,13 +22380,13 @@ void Player::LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRa void Player::UpdateKnownCurrencies(uint32 itemId, bool apply) { - if (CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemId)) - { - if (apply) - SetFlag64(PLAYER_FIELD_KNOWN_CURRENCIES, (UI64LIT(1) << (ctEntry->BitIndex - 1))); - else - RemoveFlag64(PLAYER_FIELD_KNOWN_CURRENCIES, (UI64LIT(1) << (ctEntry->BitIndex - 1))); - } + //if(CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemId)) + //{ + // if(apply) + // SetFlag64(PLAYER_FIELD_KNOWN_CURRENCIES, (UI64LIT(1) << (ctEntry->BitIndex - 1))); + // else + // RemoveFlag64(PLAYER_FIELD_KNOWN_CURRENCIES, (UI64LIT(1) << (ctEntry->BitIndex - 1))); + //} } void Player::UpdateFallInformationIfNeed(MovementInfo const& minfo, uint16 opcode) @@ -22981,20 +23031,25 @@ void Player::SendDuelCountdown(uint32 counter) bool Player::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index) const { - switch (spellInfo->Effect[index]) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(index); + if(spellEffect) { - case SPELL_EFFECT_ATTACK_ME: - return true; - default: - break; - } - switch (spellInfo->EffectApplyAuraName[index]) - { - case SPELL_AURA_MOD_TAUNT: - return true; - default: - break; + switch(spellEffect->Effect) + { + case SPELL_EFFECT_ATTACK_ME: + return true; + default: + break; + } + switch(spellEffect->EffectApplyAuraName) + { + case SPELL_AURA_MOD_TAUNT: + return true; + default: + break; + } } + return Unit::IsImmuneToSpellEffect(spellInfo, index); } diff --git a/src/game/Player.h b/src/game/Player.h index 035b3b5e5..e99e02a0e 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -113,6 +113,36 @@ struct PlayerTalent typedef UNORDERED_MAP PlayerSpellMap; typedef UNORDERED_MAP PlayerTalentMap; +// Spell modifier (used for modify other spells) +struct SpellModifier +{ + SpellModifier() : charges(0), lastAffected(NULL) {} + + SpellModifier(SpellModOp _op, SpellModType _type, int32 _value, uint32 _spellId, uint64 _mask, uint32 _mask2 = 0, int16 _charges = 0) + : op(_op), type(_type), charges(_charges), value(_value), mask(_mask, _mask2), spellId(_spellId), lastAffected(NULL) + {} + + SpellModifier(SpellModOp _op, SpellModType _type, int32 _value, uint32 _spellId, ClassFamilyMask _mask, int16 _charges = 0) + : op(_op), type(_type), charges(_charges), value(_value), mask(_mask), spellId(_spellId), lastAffected(NULL) + {} + + SpellModifier(SpellModOp _op, SpellModType _type, int32 _value, SpellEntry const* spellEntry, SpellEffectIndex eff, int16 _charges = 0); + + SpellModifier(SpellModOp _op, SpellModType _type, int32 _value, Aura const* aura, int16 _charges = 0); + + bool isAffectedOnSpell(SpellEntry const *spell) const; + + SpellModOp op : 8; + SpellModType type : 8; + int16 charges : 16; + int32 value; + ClassFamilyMask mask; + uint32 spellId; + Spell const* lastAffected; +}; + +typedef std::list SpellModList; + struct SpellCooldown { time_t end; @@ -718,6 +748,9 @@ enum TransferAbortReason TRANSFER_ABORT_NOT_FOUND4 = 0x0E, // 3.2 TRANSFER_ABORT_REALM_ONLY = 0x0F, // All players on party must be from the same realm. TRANSFER_ABORT_MAP_NOT_ALLOWED = 0x10, // Map can't be entered at this time. + // 0x11 not found + TRANSFER_ABORT_LOCKED_TO_DIFFERENT_INSTANCE = 0x12, // 4.0.1 + TRANSFER_ABORT_ALREADY_COMPLETED_ENCOUNTER = 0x13, // 4.0.1 }; enum InstanceResetWarningType @@ -1249,7 +1282,7 @@ class MANGOS_DLL_SPEC Player : public Unit Item* GetItemFromBuyBackSlot(uint32 slot); void RemoveItemFromBuyBackSlot(uint32 slot, bool del); - void TakeExtendedCost(uint32 extendedCostId, uint32 count); + //void TakeExtendedCost(uint32 extendedCostId, uint32 count); uint32 GetMaxKeyringSize() const { return KEYRING_SLOT_END - KEYRING_SLOT_START; } void SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2 = NULL, uint32 itemid = 0) const; @@ -1579,8 +1612,8 @@ class MANGOS_DLL_SPEC Player : public Unit void learnQuestRewardedSpells(Quest const* quest); void learnSpellHighRank(uint32 spellid); - uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS1); } - void SetFreeTalentPoints(uint32 points) { SetUInt32Value(PLAYER_CHARACTER_POINTS1, points); } + uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS); } + void SetFreeTalentPoints(uint32 points) { SetUInt32Value(PLAYER_CHARACTER_POINTS, points); } void UpdateFreeTalentPoints(bool resetIfNeed = true); bool resetTalents(bool no_cost = false, bool all_specs = false); uint32 resetTalentsCost() const; @@ -1609,8 +1642,8 @@ class MANGOS_DLL_SPEC Player : public Unit void ApplyGlyph(uint8 slot, bool apply); void ApplyGlyphs(bool apply); - uint32 GetFreePrimaryProfessionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS2); } - void SetFreePrimaryProfessions(uint16 profs) { SetUInt32Value(PLAYER_CHARACTER_POINTS2, profs); } + uint32 GetFreePrimaryProfessionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS); } + void SetFreePrimaryProfessions(uint16 profs) { SetUInt32Value(PLAYER_CHARACTER_POINTS, profs); } void InitPrimaryProfessions(); PlayerSpellMap const& GetSpellMap() const { return m_spells; } @@ -1719,10 +1752,10 @@ class MANGOS_DLL_SPEC Player : public Unit void SetAllowLowLevelRaid(bool allow) { ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_ENABLE_LOW_LEVEL_RAID, allow); } bool GetAllowLowLevelRaid() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_ENABLE_LOW_LEVEL_RAID); } - void SetInGuild(uint32 GuildId) { SetUInt32Value(PLAYER_GUILDID, GuildId); } - void SetRank(uint32 rankId) { SetUInt32Value(PLAYER_GUILDRANK, rankId); } + void SetInGuild(uint32 GuildId) { m_guildId = GuildId; } + void SetRank(uint32 rankId){ SetUInt32Value(PLAYER_GUILDRANK, rankId); } void SetGuildIdInvited(uint32 GuildId) { m_GuildIdInvited = GuildId; } - uint32 GetGuildId() { return GetUInt32Value(PLAYER_GUILDID); } + uint32 GetGuildId() { return m_guildId; } static uint32 GetGuildIdFromDB(ObjectGuid guid); uint32 GetRank() { return GetUInt32Value(PLAYER_GUILDRANK); } static uint32 GetRankFromDB(ObjectGuid guid); @@ -1938,13 +1971,13 @@ class MANGOS_DLL_SPEC Player : public Unit /*********************************************************/ void UpdateArenaFields(); void UpdateHonorFields(); - bool RewardHonor(Unit* pVictim, uint32 groupsize, float honor = -1); - uint32 GetHonorPoints() const { return GetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY); } - uint32 GetArenaPoints() const { return GetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY); } - void SetHonorPoints(uint32 value); - void SetArenaPoints(uint32 value); - void ModifyHonorPoints(int32 value); - void ModifyArenaPoints(int32 value); + bool RewardHonor(Unit *pVictim, uint32 groupsize, float honor = -1); + uint32 GetHonorPoints() { return m_honorPoints; } + uint32 GetArenaPoints() { return m_arenaPoints; } + void SetHonorPoints(uint32 honor); + void SetArenaPoints(uint32 arena); + void ModifyHonorPoints( int32 value ); + void ModifyArenaPoints( int32 value ); uint32 GetMaxPersonalArenaRatingRequirement(uint32 minarenaslot); @@ -2430,6 +2463,8 @@ class MANGOS_DLL_SPEC Player : public Unit /*** HONOR SYSTEM ***/ /*********************************************************/ time_t m_lastHonorUpdateTime; + uint32 m_honorPoints; + uint32 m_arenaPoints; void outDebugStatsValues() const; ObjectGuid m_lootGuid; @@ -2529,7 +2564,7 @@ class MANGOS_DLL_SPEC Player : public Unit uint8 m_swingErrorMsg; float m_ammoDPS; - //////////////////// Rest System///////////////////// + //////////////////// Rest SystemPlayerSpell time_t time_inn_enter; uint32 inn_trigger_id; float m_rest_bonus; @@ -2545,7 +2580,8 @@ class MANGOS_DLL_SPEC Player : public Unit uint32 m_questRewardTalentCount; // Social - PlayerSocial* m_social; + PlayerSocial *m_social; + uint32 m_guildId; // Groups GroupReference m_group; diff --git a/src/game/QuestDef.cpp b/src/game/QuestDef.cpp index 55df2075f..e16c2153c 100644 --- a/src/game/QuestDef.cpp +++ b/src/game/QuestDef.cpp @@ -283,10 +283,12 @@ uint32 Quest::CalculateRewardHonor(uint32 level) const if (GetRewHonorAddition() > 0 || GetRewHonorMultiplier() > 0.0f) { // values stored from 0.. for 1... - TeamContributionPoints const* tc = sTeamContributionPoints.LookupEntry(level - 1); - if (!tc) + /* not exist in 4.x + TeamContributionPoints const* tc = sTeamContributionPoints.LookupEntry(level-1); + if(!tc) return 0; - uint32 i_honor = uint32(tc->Value * GetRewHonorMultiplier() * 0.1f); + */ + uint32 i_honor = uint32(/*tc->Value*/1.0f * GetRewHonorMultiplier() * 0.1f); honor = i_honor + GetRewHonorAddition(); } diff --git a/src/game/SQLStorages.cpp b/src/game/SQLStorages.cpp index c234e7547..f48fb73f3 100644 --- a/src/game/SQLStorages.cpp +++ b/src/game/SQLStorages.cpp @@ -37,9 +37,7 @@ const char WorldTemplatedstfmt[] = "ii"; const char ConditionsSrcFmt[] = "iiii"; const char ConditionsDstFmt[] = "iiii"; const char SpellTemplatesrcfmt[] = "iiiiiiiiiix"; -// 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 185 -const char SpellTemplatedstfmt[] = "ixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixxxxixxxxxxFxxxxxxxxxxxxxxxxxxxxxxixxxxxFFFxxxxxxixxxxxixxixxxxxFFFxxxxxxixxxxxixxFFFxxxxxxxxxxxxxppppppppppppppppppppppppppppppppxxxxxxxxxxxFFFxxxxxx"; -// Id proc DurationIndex Effect0 tarA0 effectAura0 triggerSpell0 SpellName[16] Rank[16] + SQLStorage sCreatureStorage(CreatureInfosrcfmt, CreatureInfodstfmt, "entry", "creature_template"); SQLStorage sCreatureDataAddonStorage(CreatureDataAddonInfofmt, "guid", "creature_addon"); SQLStorage sCreatureModelStorage(CreatureModelfmt, "modelid", "creature_model_info"); @@ -52,4 +50,3 @@ SQLStorage sPageTextStore(PageTextfmt, "entry", "page_text"); SQLStorage sInstanceTemplate(InstanceTemplatesrcfmt, InstanceTemplatedstfmt, "map", "instance_template"); SQLStorage sWorldTemplate(WorldTemplatesrcfmt, WorldTemplatedstfmt, "map", "world_template"); SQLStorage sConditionStorage(ConditionsSrcFmt, ConditionsDstFmt, "condition_entry", "conditions"); -SQLStorage sSpellTemplate(SpellTemplatesrcfmt, SpellTemplatedstfmt, "id", "spell_template"); diff --git a/src/game/SQLStorages.h b/src/game/SQLStorages.h index efb8bc242..7d313b995 100644 --- a/src/game/SQLStorages.h +++ b/src/game/SQLStorages.h @@ -34,6 +34,5 @@ extern SQLStorage sItemStorage; extern SQLStorage sInstanceTemplate; extern SQLStorage sWorldTemplate; extern SQLStorage sConditionStorage; -extern SQLStorage sSpellTemplate; #endif diff --git a/src/game/ScriptMgr.cpp b/src/game/ScriptMgr.cpp index 857fcca5d..ab8b22ee1 100644 --- a/src/game/ScriptMgr.cpp +++ b/src/game/ScriptMgr.cpp @@ -88,14 +88,18 @@ ScriptMgr::~ScriptMgr() // returns priority (0 == cannot start script) uint8 GetSpellStartDBScriptPriority(SpellEntry const* spellinfo, SpellEffectIndex effIdx) { - if (spellinfo->Effect[effIdx] == SPELL_EFFECT_SCRIPT_EFFECT) + SpellEffectEntry const* spellEffect = spellinfo->GetSpellEffect(effIdx); + if (!spellEffect) + return 0; + + if (spellEffect->Effect == SPELL_EFFECT_SCRIPT_EFFECT) return 10; - if (spellinfo->Effect[effIdx] == SPELL_EFFECT_DUMMY) + if (spellEffect->Effect == SPELL_EFFECT_DUMMY) return 9; // NonExisting triggered spells can also start DB-Spell-Scripts - if (spellinfo->Effect[effIdx] == SPELL_EFFECT_TRIGGER_SPELL && !sSpellStore.LookupEntry(spellinfo->EffectTriggerSpell[effIdx])) + if (spellEffect->Effect == SPELL_EFFECT_TRIGGER_SPELL && !sSpellStore.LookupEntry(spellEffect->EffectTriggerSpell)) return 5; // Can not start script @@ -598,7 +602,11 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename) if (SpellEntry const* spell = sSpellStore.LookupEntry(i)) for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if (spell->Effect[j] == SPELL_EFFECT_SEND_TAXI && spell->EffectMiscValue[j] == int32(tmp.sendTaxiPath.taxiPathId)) + SpellEffectEntry const* spellEffect = spell->GetSpellEffect(SpellEffectIndex(j)); + if (!spellEffect) + continue; + + if (spellEffect->Effect == SPELL_EFFECT_SEND_TAXI && spellEffect->EffectMiscValue == tmp.sendTaxiPath.taxiPathId) { taxiSpell = i; break; @@ -752,10 +760,14 @@ void ScriptMgr::LoadEventScripts() { for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if (spell->Effect[j] == SPELL_EFFECT_SEND_EVENT) + SpellEffectEntry const* spellEffect = spell->GetSpellEffect(SpellEffectIndex(j)); + if (!spellEffect) + continue; + + if (spellEffect->Effect == SPELL_EFFECT_SEND_EVENT) { - if (spell->EffectMiscValue[j]) - evt_scripts.insert(spell->EffectMiscValue[j]); + if (spellEffect->EffectMiscValue) + evt_scripts.insert(spellEffect->EffectMiscValue); } } } @@ -1755,10 +1767,14 @@ void ScriptMgr::LoadEventIdScripts() { for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if (spell->Effect[j] == SPELL_EFFECT_SEND_EVENT) + SpellEffectEntry const* spellEffect = spell->GetSpellEffect(SpellEffectIndex(j)); + if (!spellEffect) + continue; + + if (spellEffect->Effect == SPELL_EFFECT_SEND_EVENT) { - if (spell->EffectMiscValue[j]) - evt_scripts.insert(spell->EffectMiscValue[j]); + if (spellEffect->EffectMiscValue) + evt_scripts.insert(spellEffect->EffectMiscValue); } } } diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 4f0a10b45..91c4286ef 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -54,26 +54,27 @@ enum Races RACE_FOREST_TROLL = 18, RACE_TAUNKA = 19, RACE_NORTHREND_SKELETON = 20, - RACE_ICE_TROLL = 21 + RACE_ICE_TROLL = 21, + RACE_WORGEN = 22 }; // max+1 for player race -#define MAX_RACES 12 +#define MAX_RACES 23 #define RACEMASK_ALL_PLAYABLE \ ((1<<(RACE_HUMAN-1)) |(1<<(RACE_ORC-1)) |(1<<(RACE_DWARF-1)) | \ (1<<(RACE_NIGHTELF-1)) |(1<<(RACE_UNDEAD-1)) |(1<<(RACE_TAUREN-1)) | \ (1<<(RACE_GNOME-1)) |(1<<(RACE_TROLL-1)) |(1<<(RACE_BLOODELF-1))| \ - (1<<(RACE_DRAENEI-1))) + (1<<(RACE_DRAENEI-1)) |(1<<(RACE_GOBLIN-1)) |(1<<(RACE_WORGEN-1))) // for most cases batter use ChrRace data for team check as more safe, but when need full mask of team can be use this defines. #define RACEMASK_ALLIANCE \ ((1<<(RACE_HUMAN-1)) |(1<<(RACE_DWARF-1)) |(1<<(RACE_NIGHTELF-1))| \ - (1<<(RACE_GNOME-1)) |(1<<(RACE_DRAENEI-1))) + (1<<(RACE_GNOME-1)) |(1<<(RACE_DRAENEI-1)) |(1<<(RACE_WORGEN-1))) #define RACEMASK_HORDE \ ((1<<(RACE_ORC-1)) |(1<<(RACE_UNDEAD-1)) |(1<<(RACE_TAUREN-1)) | \ - (1<<(RACE_TROLL-1)) |(1<<(RACE_BLOODELF-1))) + (1<<(RACE_TROLL-1)) |(1<<(RACE_BLOODELF-1)) |(1<<(RACE_GOBLIN-1))) // Class value is index in ChrClasses.dbc enum Classes @@ -150,10 +151,13 @@ enum Powers POWER_HAPPINESS = 4, POWER_RUNE = 5, POWER_RUNIC_POWER = 6, + POWER_SOUL_SHARDS = 7, + POWER_ECLIPSE = 8, + POWER_HOLY_POWER = 9, POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value) }; -#define MAX_POWERS 7 +#define MAX_POWERS 10 enum SpellSchools { @@ -580,10 +584,12 @@ enum Language LANG_ZOMBIE = 36, LANG_GNOMISH_BINARY = 37, LANG_GOBLIN_BINARY = 38, + LANG_WORGEN = 39, + LANG_GOBLIN = 40, LANG_ADDON = 0xFFFFFFFF // used by addons, in 2.4.0 not exit, replaced by messagetype? }; -#define LANGUAGES_COUNT 19 +#define LANGUAGES_COUNT 21 // In fact !=0 values is alliance/horde root faction ids enum Team @@ -775,186 +781,198 @@ enum SpellCastResult SPELL_FAILED_ALREADY_BEING_TAMED = 5, SPELL_FAILED_ALREADY_HAVE_CHARM = 6, SPELL_FAILED_ALREADY_HAVE_SUMMON = 7, - SPELL_FAILED_ALREADY_OPEN = 8, - SPELL_FAILED_AURA_BOUNCED = 9, - SPELL_FAILED_AUTOTRACK_INTERRUPTED = 10, - SPELL_FAILED_BAD_IMPLICIT_TARGETS = 11, - SPELL_FAILED_BAD_TARGETS = 12, - SPELL_FAILED_CANT_BE_CHARMED = 13, - SPELL_FAILED_CANT_BE_DISENCHANTED = 14, - SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 15, - SPELL_FAILED_CANT_BE_MILLED = 16, - SPELL_FAILED_CANT_BE_PROSPECTED = 17, - SPELL_FAILED_CANT_CAST_ON_TAPPED = 18, - SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 19, - SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 20, - SPELL_FAILED_CANT_STEALTH = 21, - SPELL_FAILED_CASTER_AURASTATE = 22, - SPELL_FAILED_CASTER_DEAD = 23, - SPELL_FAILED_CHARMED = 24, - SPELL_FAILED_CHEST_IN_USE = 25, - SPELL_FAILED_CONFUSED = 26, - SPELL_FAILED_DONT_REPORT = 27, - SPELL_FAILED_EQUIPPED_ITEM = 28, - SPELL_FAILED_EQUIPPED_ITEM_CLASS = 29, - SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 30, - SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 31, - SPELL_FAILED_ERROR = 32, - SPELL_FAILED_FIZZLE = 33, - SPELL_FAILED_FLEEING = 34, - SPELL_FAILED_FOOD_LOWLEVEL = 35, - SPELL_FAILED_HIGHLEVEL = 36, - SPELL_FAILED_HUNGER_SATIATED = 37, - SPELL_FAILED_IMMUNE = 38, - SPELL_FAILED_INCORRECT_AREA = 39, - SPELL_FAILED_INTERRUPTED = 40, - SPELL_FAILED_INTERRUPTED_COMBAT = 41, - SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 42, - SPELL_FAILED_ITEM_GONE = 43, - SPELL_FAILED_ITEM_NOT_FOUND = 44, - SPELL_FAILED_ITEM_NOT_READY = 45, - SPELL_FAILED_LEVEL_REQUIREMENT = 46, - SPELL_FAILED_LINE_OF_SIGHT = 47, - SPELL_FAILED_LOWLEVEL = 48, - SPELL_FAILED_LOW_CASTLEVEL = 49, - SPELL_FAILED_MAINHAND_EMPTY = 50, - SPELL_FAILED_MOVING = 51, - SPELL_FAILED_NEED_AMMO = 52, - SPELL_FAILED_NEED_AMMO_POUCH = 53, - SPELL_FAILED_NEED_EXOTIC_AMMO = 54, - SPELL_FAILED_NEED_MORE_ITEMS = 55, - SPELL_FAILED_NOPATH = 56, - SPELL_FAILED_NOT_BEHIND = 57, - SPELL_FAILED_NOT_FISHABLE = 58, - SPELL_FAILED_NOT_FLYING = 59, - SPELL_FAILED_NOT_HERE = 60, - SPELL_FAILED_NOT_INFRONT = 61, - SPELL_FAILED_NOT_IN_CONTROL = 62, - SPELL_FAILED_NOT_KNOWN = 63, - SPELL_FAILED_NOT_MOUNTED = 64, - SPELL_FAILED_NOT_ON_TAXI = 65, - SPELL_FAILED_NOT_ON_TRANSPORT = 66, - SPELL_FAILED_NOT_READY = 67, - SPELL_FAILED_NOT_SHAPESHIFT = 68, - SPELL_FAILED_NOT_STANDING = 69, - SPELL_FAILED_NOT_TRADEABLE = 70, - SPELL_FAILED_NOT_TRADING = 71, - SPELL_FAILED_NOT_UNSHEATHED = 72, - SPELL_FAILED_NOT_WHILE_GHOST = 73, - SPELL_FAILED_NOT_WHILE_LOOTING = 74, - SPELL_FAILED_NO_AMMO = 75, - SPELL_FAILED_NO_CHARGES_REMAIN = 76, - SPELL_FAILED_NO_CHAMPION = 77, - SPELL_FAILED_NO_COMBO_POINTS = 78, - SPELL_FAILED_NO_DUELING = 79, - SPELL_FAILED_NO_ENDURANCE = 80, - SPELL_FAILED_NO_FISH = 81, - SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 82, - SPELL_FAILED_NO_MOUNTS_ALLOWED = 83, - SPELL_FAILED_NO_PET = 84, - SPELL_FAILED_NO_POWER = 85, - SPELL_FAILED_NOTHING_TO_DISPEL = 86, - SPELL_FAILED_NOTHING_TO_STEAL = 87, - SPELL_FAILED_ONLY_ABOVEWATER = 88, - SPELL_FAILED_ONLY_DAYTIME = 89, - SPELL_FAILED_ONLY_INDOORS = 90, - SPELL_FAILED_ONLY_MOUNTED = 91, - SPELL_FAILED_ONLY_NIGHTTIME = 92, - SPELL_FAILED_ONLY_OUTDOORS = 93, - SPELL_FAILED_ONLY_SHAPESHIFT = 94, - SPELL_FAILED_ONLY_STEALTHED = 95, - SPELL_FAILED_ONLY_UNDERWATER = 96, - SPELL_FAILED_OUT_OF_RANGE = 97, - SPELL_FAILED_PACIFIED = 98, - SPELL_FAILED_POSSESSED = 99, - SPELL_FAILED_REAGENTS = 100, - SPELL_FAILED_REQUIRES_AREA = 101, - SPELL_FAILED_REQUIRES_SPELL_FOCUS = 102, - SPELL_FAILED_ROOTED = 103, - SPELL_FAILED_SILENCED = 104, - SPELL_FAILED_SPELL_IN_PROGRESS = 105, - SPELL_FAILED_SPELL_LEARNED = 106, - SPELL_FAILED_SPELL_UNAVAILABLE = 107, - SPELL_FAILED_STUNNED = 108, - SPELL_FAILED_TARGETS_DEAD = 109, - SPELL_FAILED_TARGET_AFFECTING_COMBAT = 110, - SPELL_FAILED_TARGET_AURASTATE = 111, - SPELL_FAILED_TARGET_DUELING = 112, - SPELL_FAILED_TARGET_ENEMY = 113, - SPELL_FAILED_TARGET_ENRAGED = 114, - SPELL_FAILED_TARGET_FRIENDLY = 115, - SPELL_FAILED_TARGET_IN_COMBAT = 116, - SPELL_FAILED_TARGET_IS_PLAYER = 117, - SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 118, - SPELL_FAILED_TARGET_NOT_DEAD = 119, - SPELL_FAILED_TARGET_NOT_IN_PARTY = 120, - SPELL_FAILED_TARGET_NOT_LOOTED = 121, - SPELL_FAILED_TARGET_NOT_PLAYER = 122, - SPELL_FAILED_TARGET_NO_POCKETS = 123, - SPELL_FAILED_TARGET_NO_WEAPONS = 124, - SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 125, - SPELL_FAILED_TARGET_UNSKINNABLE = 126, - SPELL_FAILED_THIRST_SATIATED = 127, - SPELL_FAILED_TOO_CLOSE = 128, - SPELL_FAILED_TOO_MANY_OF_ITEM = 129, - SPELL_FAILED_TOTEM_CATEGORY = 130, - SPELL_FAILED_TOTEMS = 131, - SPELL_FAILED_TRY_AGAIN = 132, - SPELL_FAILED_UNIT_NOT_BEHIND = 133, - SPELL_FAILED_UNIT_NOT_INFRONT = 134, - SPELL_FAILED_WRONG_PET_FOOD = 135, - SPELL_FAILED_NOT_WHILE_FATIGUED = 136, - SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 137, - SPELL_FAILED_NOT_WHILE_TRADING = 138, - SPELL_FAILED_TARGET_NOT_IN_RAID = 139, - SPELL_FAILED_TARGET_FREEFORALL = 140, - SPELL_FAILED_NO_EDIBLE_CORPSES = 141, - SPELL_FAILED_ONLY_BATTLEGROUNDS = 142, - SPELL_FAILED_TARGET_NOT_GHOST = 143, - SPELL_FAILED_TRANSFORM_UNUSABLE = 144, - SPELL_FAILED_WRONG_WEATHER = 145, - SPELL_FAILED_DAMAGE_IMMUNE = 146, - SPELL_FAILED_PREVENTED_BY_MECHANIC = 147, - SPELL_FAILED_PLAY_TIME = 148, - SPELL_FAILED_REPUTATION = 149, - SPELL_FAILED_MIN_SKILL = 150, - SPELL_FAILED_NOT_IN_ARENA = 151, - SPELL_FAILED_NOT_ON_SHAPESHIFT = 152, - SPELL_FAILED_NOT_ON_STEALTHED = 153, - SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 154, - SPELL_FAILED_NOT_ON_MOUNTED = 155, - SPELL_FAILED_TOO_SHALLOW = 156, - SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 157, - SPELL_FAILED_TARGET_IS_TRIVIAL = 158, - SPELL_FAILED_BM_OR_INVISGOD = 159, - SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 160, - SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 161, - SPELL_FAILED_NOT_IDLE = 162, - SPELL_FAILED_NOT_INACTIVE = 163, - SPELL_FAILED_PARTIAL_PLAYTIME = 164, - SPELL_FAILED_NO_PLAYTIME = 165, - SPELL_FAILED_NOT_IN_BATTLEGROUND = 166, - SPELL_FAILED_NOT_IN_RAID_INSTANCE = 167, - SPELL_FAILED_ONLY_IN_ARENA = 168, - SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 169, - SPELL_FAILED_ON_USE_ENCHANT = 170, - SPELL_FAILED_NOT_ON_GROUND = 171, - SPELL_FAILED_CUSTOM_ERROR = 172, - SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 173, - SPELL_FAILED_TOO_MANY_SOCKETS = 174, - SPELL_FAILED_INVALID_GLYPH = 175, - SPELL_FAILED_UNIQUE_GLYPH = 176, - SPELL_FAILED_GLYPH_SOCKET_LOCKED = 177, - SPELL_FAILED_NO_VALID_TARGETS = 178, - SPELL_FAILED_ITEM_AT_MAX_CHARGES = 179, - SPELL_FAILED_NOT_IN_BARBERSHOP = 180, - SPELL_FAILED_FISHING_TOO_LOW = 181, - SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW = 182, - SPELL_FAILED_SUMMON_PENDING = 183, - SPELL_FAILED_MAX_SOCKETS = 184, - SPELL_FAILED_PET_CAN_RENAME = 185, - SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED = 186, - SPELL_FAILED_UNKNOWN = 187, // actually doesn't exist in client + SPELL_FAILED_ALREADY_HAVE_PET = 8, + SPELL_FAILED_ALREADY_OPEN = 9, + SPELL_FAILED_AURA_BOUNCED = 10, + SPELL_FAILED_AUTOTRACK_INTERRUPTED = 11, + SPELL_FAILED_BAD_IMPLICIT_TARGETS = 12, + SPELL_FAILED_BAD_TARGETS = 13, + SPELL_FAILED_CANT_BE_CHARMED = 14, + SPELL_FAILED_CANT_BE_DISENCHANTED = 15, + SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 16, + SPELL_FAILED_CANT_BE_MILLED = 17, + SPELL_FAILED_CANT_BE_PROSPECTED = 18, + SPELL_FAILED_CANT_CAST_ON_TAPPED = 19, + SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 20, + SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 21, + SPELL_FAILED_CANT_STEALTH = 22, + SPELL_FAILED_CASTER_AURASTATE = 23, + SPELL_FAILED_CASTER_DEAD = 24, + SPELL_FAILED_CHARMED = 25, + SPELL_FAILED_CHEST_IN_USE = 26, + SPELL_FAILED_CONFUSED = 27, + SPELL_FAILED_DONT_REPORT = 28, + SPELL_FAILED_EQUIPPED_ITEM = 29, + SPELL_FAILED_EQUIPPED_ITEM_CLASS = 30, + SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 31, + SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 32, + SPELL_FAILED_ERROR = 33, + SPELL_FAILED_FALLING = 34, + SPELL_FAILED_FIZZLE = 35, + SPELL_FAILED_FLEEING = 36, + SPELL_FAILED_FOOD_LOWLEVEL = 37, + SPELL_FAILED_HIGHLEVEL = 38, + SPELL_FAILED_HUNGER_SATIATED = 39, + SPELL_FAILED_IMMUNE = 40, + SPELL_FAILED_INCORRECT_AREA = 41, + SPELL_FAILED_INTERRUPTED = 42, + SPELL_FAILED_INTERRUPTED_COMBAT = 43, + SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 44, + SPELL_FAILED_ITEM_GONE = 45, + SPELL_FAILED_ITEM_NOT_FOUND = 46, + SPELL_FAILED_ITEM_NOT_READY = 47, + SPELL_FAILED_LEVEL_REQUIREMENT = 48, + SPELL_FAILED_LINE_OF_SIGHT = 49, + SPELL_FAILED_LOWLEVEL = 50, + SPELL_FAILED_LOW_CASTLEVEL = 51, + SPELL_FAILED_MAINHAND_EMPTY = 52, + SPELL_FAILED_MOVING = 53, + SPELL_FAILED_NEED_AMMO = 54, + SPELL_FAILED_NEED_AMMO_POUCH = 55, + SPELL_FAILED_NEED_EXOTIC_AMMO = 56, + SPELL_FAILED_NEED_MORE_ITEMS = 57, + SPELL_FAILED_NOPATH = 58, + SPELL_FAILED_NOT_BEHIND = 59, + SPELL_FAILED_NOT_FISHABLE = 60, + SPELL_FAILED_NOT_FLYING = 61, + SPELL_FAILED_NOT_HERE = 62, + SPELL_FAILED_NOT_INFRONT = 63, + SPELL_FAILED_NOT_IN_CONTROL = 64, + SPELL_FAILED_NOT_KNOWN = 65, + SPELL_FAILED_NOT_MOUNTED = 66, + SPELL_FAILED_NOT_ON_TAXI = 67, + SPELL_FAILED_NOT_ON_TRANSPORT = 68, + SPELL_FAILED_NOT_READY = 69, + SPELL_FAILED_NOT_SHAPESHIFT = 70, + SPELL_FAILED_NOT_STANDING = 71, + SPELL_FAILED_NOT_TRADEABLE = 72, + SPELL_FAILED_NOT_TRADING = 73, + SPELL_FAILED_NOT_UNSHEATHED = 74, + SPELL_FAILED_NOT_WHILE_GHOST = 75, + SPELL_FAILED_NOT_WHILE_LOOTING = 76, + SPELL_FAILED_NO_AMMO = 77, + SPELL_FAILED_NO_CHARGES_REMAIN = 78, + SPELL_FAILED_NO_CHAMPION = 79, + SPELL_FAILED_NO_COMBO_POINTS = 80, + SPELL_FAILED_NO_DUELING = 81, + SPELL_FAILED_NO_ENDURANCE = 82, + SPELL_FAILED_NO_FISH = 83, + SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 84, + SPELL_FAILED_NO_MOUNTS_ALLOWED = 85, + SPELL_FAILED_NO_PET = 86, + SPELL_FAILED_NO_POWER = 87, + SPELL_FAILED_NOTHING_TO_DISPEL = 88, + SPELL_FAILED_NOTHING_TO_STEAL = 89, + SPELL_FAILED_ONLY_ABOVEWATER = 90, + SPELL_FAILED_ONLY_DAYTIME = 91, + SPELL_FAILED_ONLY_INDOORS = 92, + SPELL_FAILED_ONLY_MOUNTED = 93, + SPELL_FAILED_ONLY_NIGHTTIME = 94, + SPELL_FAILED_ONLY_OUTDOORS = 95, + SPELL_FAILED_ONLY_SHAPESHIFT = 96, + SPELL_FAILED_ONLY_STEALTHED = 97, + SPELL_FAILED_ONLY_UNDERWATER = 98, + SPELL_FAILED_OUT_OF_RANGE = 99, + SPELL_FAILED_PACIFIED = 100, + SPELL_FAILED_POSSESSED = 101, + SPELL_FAILED_REAGENTS = 102, + SPELL_FAILED_REQUIRES_AREA = 103, + SPELL_FAILED_REQUIRES_SPELL_FOCUS = 104, + SPELL_FAILED_ROOTED = 105, + SPELL_FAILED_SILENCED = 106, + SPELL_FAILED_SPELL_IN_PROGRESS = 107, + SPELL_FAILED_SPELL_LEARNED = 108, + SPELL_FAILED_SPELL_UNAVAILABLE = 109, + SPELL_FAILED_STUNNED = 110, + SPELL_FAILED_TARGETS_DEAD = 111, + SPELL_FAILED_TARGET_AFFECTING_COMBAT = 112, + SPELL_FAILED_TARGET_AURASTATE = 113, + SPELL_FAILED_TARGET_DUELING = 114, + SPELL_FAILED_TARGET_ENEMY = 115, + SPELL_FAILED_TARGET_ENRAGED = 116, + SPELL_FAILED_TARGET_FRIENDLY = 117, + SPELL_FAILED_TARGET_IN_COMBAT = 118, + SPELL_FAILED_TARGET_IS_PLAYER = 119, + SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 120, + SPELL_FAILED_TARGET_NOT_DEAD = 121, + SPELL_FAILED_TARGET_NOT_IN_PARTY = 122, + SPELL_FAILED_TARGET_NOT_LOOTED = 123, + SPELL_FAILED_TARGET_NOT_PLAYER = 124, + SPELL_FAILED_TARGET_NO_POCKETS = 125, + SPELL_FAILED_TARGET_NO_WEAPONS = 126, + SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 127, + SPELL_FAILED_TARGET_UNSKINNABLE = 128, + SPELL_FAILED_THIRST_SATIATED = 129, + SPELL_FAILED_TOO_CLOSE = 130, + SPELL_FAILED_TOO_MANY_OF_ITEM = 131, + SPELL_FAILED_TOTEM_CATEGORY = 132, + SPELL_FAILED_TOTEMS = 133, + SPELL_FAILED_TRY_AGAIN = 134, + SPELL_FAILED_UNIT_NOT_BEHIND = 135, + SPELL_FAILED_UNIT_NOT_INFRONT = 136, + SPELL_FAILED_VISION_OBSCURED = 137, + SPELL_FAILED_WRONG_PET_FOOD = 138, + SPELL_FAILED_NOT_WHILE_FATIGUED = 139, + SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 140, + SPELL_FAILED_NOT_WHILE_TRADING = 141, + SPELL_FAILED_TARGET_NOT_IN_RAID = 142, + SPELL_FAILED_TARGET_FREEFORALL = 143, + SPELL_FAILED_NO_EDIBLE_CORPSES = 144, + SPELL_FAILED_ONLY_BATTLEGROUNDS = 145, + SPELL_FAILED_TARGET_NOT_GHOST = 146, + SPELL_FAILED_TRANSFORM_UNUSABLE = 147, + SPELL_FAILED_WRONG_WEATHER = 148, + SPELL_FAILED_DAMAGE_IMMUNE = 149, + SPELL_FAILED_PREVENTED_BY_MECHANIC = 150, + SPELL_FAILED_PLAY_TIME = 151, + SPELL_FAILED_REPUTATION = 152, + SPELL_FAILED_MIN_SKILL = 153, + SPELL_FAILED_NOT_IN_ARENA = 154, + SPELL_FAILED_NOT_ON_SHAPESHIFT = 155, + SPELL_FAILED_NOT_ON_STEALTHED = 156, + SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 157, + SPELL_FAILED_NOT_ON_MOUNTED = 158, + SPELL_FAILED_TOO_SHALLOW = 159, + SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 160, + SPELL_FAILED_TARGET_IS_TRIVIAL = 161, + SPELL_FAILED_BM_OR_INVISGOD = 162, + SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 163, + SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 164, + SPELL_FAILED_NOT_IDLE = 165, + SPELL_FAILED_NOT_INACTIVE = 166, + SPELL_FAILED_PARTIAL_PLAYTIME = 167, + SPELL_FAILED_NO_PLAYTIME = 168, + SPELL_FAILED_NOT_IN_BATTLEGROUND = 169, + SPELL_FAILED_NOT_IN_RAID_INSTANCE = 170, + SPELL_FAILED_ONLY_IN_ARENA = 171, + SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 172, + SPELL_FAILED_ON_USE_ENCHANT = 173, + SPELL_FAILED_NOT_ON_GROUND = 174, + SPELL_FAILED_CUSTOM_ERROR = 175, + SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 176, + SPELL_FAILED_TOO_MANY_SOCKETS = 177, + SPELL_FAILED_INVALID_GLYPH = 178, + SPELL_FAILED_UNIQUE_GLYPH = 179, + SPELL_FAILED_GLYPH_SOCKET_LOCKED = 180, + SPELL_FAILED_NO_VALID_TARGETS = 181, + SPELL_FAILED_ITEM_AT_MAX_CHARGES = 182, + SPELL_FAILED_NOT_IN_BARBERSHOP = 183, + SPELL_FAILED_FISHING_TOO_LOW = 184, + SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW = 185, + SPELL_FAILED_SUMMON_PENDING = 186, + SPELL_FAILED_MAX_SOCKETS = 187, + SPELL_FAILED_PET_CAN_RENAME = 188, + SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED = 189, + SPELL_FAILED_NO_ACTIONS = 190, + SPELL_FAILED_CURRENCY_WEIGHT_MISMATCH = 191, + SPELL_FAILED_CURRENCY_WEIGHT_NOT_ENOUGH = 192, + SPELL_FAILED_CURRENCY_WEIGHT_TOO_MUCH = 193, + SPELL_FAILED_NO_VACANT_SEAT = 194, + SPELL_FAILED_NO_LIQUID = 195, + SPELL_FAILED_ONLY_NOT_SWIMMING = 196, + SPELL_FAILED_BY_NOT_MOVING = 197, + SPELL_FAILED_IN_COMBAT_RES_LIMIT_REACHED = 198, + SPELL_FAILED_UNKNOWN = 199, // Value not used SPELL_CAST_OK = 255 // custom value, don't must be send to client }; @@ -2395,10 +2413,25 @@ enum SkillType SKILL_PET_WASP = 785, SKILL_PET_EXOTIC_RHINO = 786, SKILL_PET_EXOTIC_CORE_HOUND = 787, - SKILL_PET_EXOTIC_SPIRIT_BEAST = 788 + SKILL_PET_EXOTIC_SPIRIT_BEAST = 788, + SKILL_RACIAL_WORGEN = 789, + SKILL_RACIAL_GOBLIN = 790, + SKILL_LANG_WORGEN = 791, + SKILL_LANG_GOBLIN = 792, + SKILL_ARCHAEOLOGY = 794, + SKILL_GENERAL_HUNTER = 795, + SKILL_GENERAL_DEATHKNIGHT = 796, + SKILL_GENERAL_ROGUE = 797, + SKILL_GENERAL_DRUID = 798, + SKILL_GENERAL_MAGE = 799, + SKILL_GENERAL_PALADIN = 800, + SKILL_GENERAL_SHAMAN = 801, + SKILL_GENERAL_WARLOCK = 802, + SKILL_GENERAL_WARRIOR = 803, + SKILL_GENERAL_PRIEST = 804 }; -#define MAX_SKILL_TYPE 789 +#define MAX_SKILL_TYPE 805 inline SkillType SkillByLockType(LockType locktype) { @@ -2556,10 +2589,14 @@ enum ChatMsg CHAT_MSG_ACHIEVEMENT = 0x30, CHAT_MSG_GUILD_ACHIEVEMENT = 0x31, CHAT_MSG_ARENA_POINTS = 0x32, - CHAT_MSG_PARTY_LEADER = 0x33 + CHAT_MSG_PARTY_LEADER = 0x33, + CHAT_MSG_UNK52 = 0x34, // 4.0.1 + CHAT_MSG_BN_WISPER = 0x35, // 4.0.1 + CHAT_MSG_BN_WISPER_INFORM = 0x36, // 4.0.1 + CHAT_MSG_BN_CONVERSATION = 0x37 // 4.0.1 }; -#define MAX_CHAT_MSG_TYPE 0x34 +#define MAX_CHAT_MSG_TYPE 0x38 enum ChatLinkColors { @@ -2834,9 +2871,12 @@ enum BattleGroundTypeId BATTLEGROUND_DS = 10, BATTLEGROUND_RV = 11, BATTLEGROUND_IC = 30, - BATTLEGROUND_RB = 32 // random battleground + BATTLEGROUND_RB = 32, // random battleground + BATTLEGROUND_TP = 108, // 4.0.0 + BATTLEGROUND_BG = 118 // 4.0.0 }; -#define MAX_BATTLEGROUND_TYPE_ID 33 + +#define MAX_BATTLEGROUND_TYPE_ID 119 enum ArenaType { @@ -2975,6 +3015,6 @@ enum ActivateTaxiReply // account with expansion > client supported will rejected at connection by client // because if client receive unsupported expansion level it think // that it not have expansion installed and reject -#define MAX_EXPANSION 2 +#define MAX_EXPANSION 3 #endif diff --git a/src/game/SkillDiscovery.cpp b/src/game/SkillDiscovery.cpp index d00c1c04b..a7442c969 100644 --- a/src/game/SkillDiscovery.cpp +++ b/src/game/SkillDiscovery.cpp @@ -99,9 +99,9 @@ void LoadSkillDiscoveryTable() } // mechanic discovery - if (reqSpellEntry->Mechanic != MECHANIC_DISCOVERY && - // explicit discovery ability - !IsExplicitDiscoverySpell(reqSpellEntry)) + if (reqSpellEntry->GetMechanic() != MECHANIC_DISCOVERY && + // explicit discovery ability + !IsExplicitDiscoverySpell(reqSpellEntry)) { if (reportedReqSpells.find(reqSkillOrSpell) == reportedReqSpells.end()) { diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index e40ccbb6e..38edc3946 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -102,8 +102,10 @@ bool IsQuestTameSpell(uint32 spellId) if (!spellproto) return false; - return spellproto->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_THREAT - && spellproto->Effect[EFFECT_INDEX_1] == SPELL_EFFECT_APPLY_AURA && spellproto->EffectApplyAuraName[EFFECT_INDEX_1] == SPELL_AURA_DUMMY; + SpellEffectEntry const* spellEffect0 = spellproto->GetSpellEffect(EFFECT_INDEX_0); + SpellEffectEntry const* spellEffect1 = spellproto->GetSpellEffect(EFFECT_INDEX_1); + return spellEffect0 && spellEffect0->Effect == SPELL_EFFECT_THREAT && + spellEffect1 && spellEffect1->Effect == SPELL_EFFECT_APPLY_AURA && spellEffect1->EffectApplyAuraName == SPELL_AURA_DUMMY; } SpellCastTargets::SpellCastTargets() @@ -326,6 +328,9 @@ Spell::Spell(Unit* caster, SpellEntry const* info, bool triggered, ObjectGuid or m_spellInfo = info; m_triggeredBySpellInfo = triggeredBy; + + m_spellInterrupts = m_spellInfo->GetSpellInterrupts(); + m_caster = caster; m_selfContainer = NULL; m_referencedFromCurrentSpell = false; @@ -392,14 +397,17 @@ Spell::Spell(Unit* caster, SpellEntry const* info, bool triggered, ObjectGuid or m_spellFlags = SPELL_FLAG_NORMAL; - if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && !m_spellInfo->HasAttribute(SPELL_ATTR_EX2_CANT_REFLECTED)) + if (m_spellInfo->GetDmgClass() == SPELL_DAMAGE_CLASS_MAGIC && !m_spellInfo->HasAttribute(SPELL_ATTR_EX2_CANT_REFLECTED)) { for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if (m_spellInfo->Effect[j] == 0) + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); + if(!spellEffect) + continue; + if (spellEffect->Effect == 0) continue; - if (!IsPositiveTarget(m_spellInfo->EffectImplicitTargetA[j], m_spellInfo->EffectImplicitTargetB[j])) + if(!IsPositiveTarget(spellEffect->EffectImplicitTargetA, spellEffect->EffectImplicitTargetB)) m_canReflect = true; else m_canReflect = m_spellInfo->HasAttribute(SPELL_ATTR_EX_NEGATIVE); @@ -446,32 +454,40 @@ void Spell::FillTargetMap() uint8 effToIndex[MAX_EFFECT_INDEX] = {0, 1, 2}; // Helper array, to link to another tmpUnitList, if the targets for both effects match for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + // 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->Effect[i] == SPELL_EFFECT_NONE) + if(spellEffect->Effect == SPELL_EFFECT_NONE) continue; // targets for TARGET_SCRIPT_COORDINATES (A) and TARGET_SCRIPT // for TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT (A) all is checked in Spell::CheckCast and in Spell::CheckItem // filled in Spell::CheckCast call - if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT_COORDINATES || - m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT || - m_spellInfo->EffectImplicitTargetA[i] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT || - (m_spellInfo->EffectImplicitTargetB[i] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[i] != TARGET_SELF)) + if(spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES || + spellEffect->EffectImplicitTargetA == TARGET_SCRIPT || + spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT || + (spellEffect->EffectImplicitTargetB == TARGET_SCRIPT && spellEffect->EffectImplicitTargetA != TARGET_SELF)) continue; // TODO: find a way so this is not needed? // for area auras always add caster as target (needed for totems for example) - if (IsAreaAuraEffect(m_spellInfo->Effect[i])) + if (IsAreaAuraEffect(spellEffect->Effect)) AddUnitTarget(m_caster, SpellEffectIndex(i)); // no double fill for same targets for (int j = 0; j < i; ++j) { + SpellEffectEntry const* spellEffect1 = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); + if (!spellEffect) + continue; + // Check if same target, but handle i.e. AreaAuras different - if (m_spellInfo->EffectImplicitTargetA[i] == m_spellInfo->EffectImplicitTargetA[j] && m_spellInfo->EffectImplicitTargetB[i] == m_spellInfo->EffectImplicitTargetB[j] - && m_spellInfo->Effect[j] != SPELL_EFFECT_NONE - && !IsAreaAuraEffect(m_spellInfo->Effect[i]) && !IsAreaAuraEffect(m_spellInfo->Effect[j])) + if (spellEffect->EffectImplicitTargetA == spellEffect1->EffectImplicitTargetA && spellEffect->EffectImplicitTargetB == spellEffect1->EffectImplicitTargetB + && spellEffect1->Effect != SPELL_EFFECT_NONE + && !IsAreaAuraEffect(spellEffect->Effect) && !IsAreaAuraEffect(spellEffect1->Effect)) // Add further conditions here if required { effToIndex[i] = j; // effect i has same targeting list as effect j @@ -483,10 +499,10 @@ void Spell::FillTargetMap() { // TargetA/TargetB dependent from each other, we not switch to full support this dependences // but need it support in some know cases - switch (m_spellInfo->EffectImplicitTargetA[i]) + switch(spellEffect->EffectImplicitTargetA) { case TARGET_NONE: - switch (m_spellInfo->EffectImplicitTargetB[i]) + switch(spellEffect->EffectImplicitTargetB) { case TARGET_NONE: if (m_caster->GetObjectGuid().IsPet()) @@ -495,39 +511,39 @@ void Spell::FillTargetMap() SetTargetMap(SpellEffectIndex(i), TARGET_EFFECT_SELECT, tmpUnitLists[i /*==effToIndex[i]*/]); break; default: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); break; } break; case TARGET_SELF: - switch (m_spellInfo->EffectImplicitTargetB[i]) + switch(spellEffect->EffectImplicitTargetB) { case TARGET_NONE: case TARGET_EFFECT_SELECT: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); break; - case TARGET_AREAEFFECT_INSTANT: // use B case that not dependent from from A in fact - if ((m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) == 0) + case TARGET_AREAEFFECT_INSTANT: // use B case that not dependent from from A in fact + if((m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) == 0) m_targets.setDestination(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ()); - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); break; - case TARGET_BEHIND_VICTIM: // use B case that not dependent from from A in fact - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + case TARGET_BEHIND_VICTIM: // use B case that not dependent from from A in fact + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); break; default: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); break; } break; case TARGET_EFFECT_SELECT: - switch (m_spellInfo->EffectImplicitTargetB[i]) + switch(spellEffect->EffectImplicitTargetB) { case TARGET_NONE: case TARGET_EFFECT_SELECT: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); break; - // dest point setup required + // dest point setup required case TARGET_AREAEFFECT_INSTANT: case TARGET_AREAEFFECT_CUSTOM: case TARGET_ALL_ENEMY_IN_AREA: @@ -540,9 +556,9 @@ void Spell::FillTargetMap() if (!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) || m_IsTriggeredSpell) if (WorldObject* castObject = GetCastingObject()) m_targets.setDestination(castObject->GetPositionX(), castObject->GetPositionY(), castObject->GetPositionZ()); - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); break; - // target pre-selection required + // target pre-selection required case TARGET_INNKEEPER_COORDINATES: case TARGET_TABLE_X_Y_Z_COORDINATES: case TARGET_CASTER_COORDINATES: @@ -559,108 +575,107 @@ void Spell::FillTargetMap() case TARGET_POINT_AT_SE: case TARGET_POINT_AT_SW: // need some target for processing - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); break; default: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); break; } break; case TARGET_CASTER_COORDINATES: - switch (m_spellInfo->EffectImplicitTargetB[i]) + switch(spellEffect->EffectImplicitTargetB) { case TARGET_ALL_ENEMY_IN_AREA: // Note: this hack with search required until GO casting not implemented // environment damage spells already have around enemies targeting but this not help in case nonexistent GO casting support // currently each enemy selected explicitly and self cast damage - if (m_spellInfo->Effect[i] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) + if (spellEffect->Effect == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) { - if (m_targets.getUnitTarget()) + if(m_targets.getUnitTarget()) tmpUnitLists[i /*==effToIndex[i]*/].push_back(m_targets.getUnitTarget()); } else { - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); } break; - case TARGET_NONE: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + case 0: + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); tmpUnitLists[i /*==effToIndex[i]*/].push_back(m_caster); break; default: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); break; } break; case TARGET_TABLE_X_Y_Z_COORDINATES: - switch (m_spellInfo->EffectImplicitTargetB[i]) + switch(spellEffect->EffectImplicitTargetB) { - case TARGET_NONE: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + case 0: + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); - // need some target for processing + + // need some target for processing SetTargetMap(SpellEffectIndex(i), TARGET_EFFECT_SELECT, tmpUnitLists[i /*==effToIndex[i]*/]); break; - case TARGET_AREAEFFECT_INSTANT: // All 17/7 pairs used for dest teleportation, A processed in effect code - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + case TARGET_AREAEFFECT_INSTANT: // All 17/7 pairs used for dest teleportation, A processed in effect code + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); break; default: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); - break; + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); } - break; - case TARGET_SELF2: - switch (m_spellInfo->EffectImplicitTargetB[i]) + case TARGET_SELF2: + switch(spellEffect->EffectImplicitTargetB) { case TARGET_NONE: case TARGET_EFFECT_SELECT: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); break; case TARGET_AREAEFFECT_CUSTOM: // triggered spells get dest point from default target set, ignore it if (!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) || m_IsTriggeredSpell) if (WorldObject* castObject = GetCastingObject()) m_targets.setDestination(castObject->GetPositionX(), castObject->GetPositionY(), castObject->GetPositionZ()); - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); break; - // most A/B target pairs is self->negative and not expect adding caster to target list + // most A/B target pairs is self->negative and not expect adding caster to target list default: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); break; } break; case TARGET_DUELVSPLAYER_COORDINATES: - switch (m_spellInfo->EffectImplicitTargetB[i]) + switch(spellEffect->EffectImplicitTargetB) { case TARGET_NONE: case TARGET_EFFECT_SELECT: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); if (Unit* currentTarget = m_targets.getUnitTarget()) tmpUnitLists[i /*==effToIndex[i]*/].push_back(currentTarget); break; default: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); break; } break; default: - switch (m_spellInfo->EffectImplicitTargetB[i]) + switch(spellEffect->EffectImplicitTargetB) { - case TARGET_NONE: + case 0: case TARGET_EFFECT_SELECT: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); - break; - case TARGET_SCRIPT_COORDINATES: // B case filled in CheckCast but we need fill unit list base at A case - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); break; + case TARGET_SCRIPT_COORDINATES: // B case filled in CheckCast but we need fill unit list base at A case + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + break; default: - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); - SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); break; } break; @@ -718,14 +733,14 @@ void Spell::prepareDataForTriggerSystem() if (!m_canTrigger) // Exceptions (some periodic triggers) { - switch (m_spellInfo->SpellFamilyName) + switch (m_spellInfo->GetSpellFamilyName()) { case SPELLFAMILY_MAGE: - // Arcane Missiles / Blizzard triggers need do it + // Arcane Missles / Blizzard triggers need do it if (m_spellInfo->IsFitToFamilyMask(UI64LIT(0x0000000000200080))) m_canTrigger = true; // Clearcasting trigger need do it - else if (m_spellInfo->IsFitToFamilyMask(UI64LIT(0x0000000200000000))) + else if (m_spellInfo->IsFitToFamilyMask(UI64LIT(0x0000000200000000), 0x00000008)) m_canTrigger = true; // Replenish Mana, item spell with triggered cases (Mana Agate, etc mana gems) else if (m_spellInfo->IsFitToFamilyMask(UI64LIT(0x0000010000000000))) @@ -748,7 +763,7 @@ void Spell::prepareDataForTriggerSystem() break; case SPELLFAMILY_HUNTER: // Hunter Rapid Killing/Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect/Explosive Shot - if (m_spellInfo->IsFitToFamilyMask(UI64LIT(0x0100200000000214), 0x00000200)) + if (m_spellInfo->IsFitToFamilyMask(UI64LIT(0x0100200000000214), 0x200)) m_canTrigger = true; break; case SPELLFAMILY_PALADIN: @@ -762,7 +777,7 @@ void Spell::prepareDataForTriggerSystem() } // Get data for type of attack and fill base info for trigger - switch (m_spellInfo->DmgClass) + switch (m_spellInfo->GetDmgClass()) { case SPELL_DAMAGE_CLASS_MELEE: m_procAttacker = PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT; @@ -811,7 +826,7 @@ void Spell::prepareDataForTriggerSystem() // Hunter traps spells (for Entrapment trigger) // Gives your Immolation Trap, Frost Trap, Explosive Trap, and Snake Trap .... - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x000020000000001C))) + if (m_spellInfo->IsFitToFamily(SPELLFAMILY_HUNTER, UI64LIT(0x000020000000001C))) m_procAttacker |= PROC_FLAG_ON_TRAP_ACTIVATION; } @@ -825,7 +840,8 @@ void Spell::CleanupTargetList() void Spell::AddUnitTarget(Unit* pVictim, SpellEffectIndex effIndex) { - if (m_spellInfo->Effect[effIndex] == 0) + SpellEffectEntry const *spellEffect = m_spellInfo->GetSpellEffect(effIndex); + if (!spellEffect || spellEffect->Effect == 0) return; // Check for effect immune skip if immuned @@ -906,7 +922,8 @@ void Spell::AddUnitTarget(ObjectGuid unitGuid, SpellEffectIndex effIndex) void Spell::AddGOTarget(GameObject* pVictim, SpellEffectIndex effIndex) { - if (m_spellInfo->Effect[effIndex] == 0) + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(effIndex); + if (!spellEffect || spellEffect->Effect == 0) return; ObjectGuid targetGUID = pVictim->GetObjectGuid(); @@ -957,7 +974,8 @@ void Spell::AddGOTarget(ObjectGuid goGuid, SpellEffectIndex effIndex) void Spell::AddItemTarget(Item* pitem, SpellEffectIndex effIndex) { - if (m_spellInfo->Effect[effIndex] == 0) + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(effIndex); + if (!spellEffect || spellEffect->Effect == 0) return; // Lookup target in already in list @@ -1117,28 +1135,29 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) caster->ProcDamageAndSpell(unitTarget, real_caster ? procAttacker : PROC_FLAG_NONE, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo); // trigger weapon enchants for weapon based spells; exclude spells that stop attack, because may break CC - if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && + if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->GetEquippedItemClass() == ITEM_CLASS_WEAPON && !m_spellInfo->HasAttribute(SPELL_ATTR_STOP_ATTACK_TARGET)) ((Player*)m_caster)->CastItemCombatSpell(unitTarget, m_attackType); // Haunt (NOTE: for avoid use additional field damage stored in dummy value (replace unused 100%) // apply before deal damage because aura can be removed at target kill - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellIconID == 3172 && - (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0004000000000000))) - if (Aura* dummy = unitTarget->GetDummyAura(m_spellInfo->Id)) + SpellClassOptionsEntry const *classOpt = m_spellInfo->GetSpellClassOptions(); + if (classOpt && classOpt->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellIconID == 3172 && + (classOpt->SpellFamilyFlags & UI64LIT(0x0004000000000000))) + if(Aura* dummy = unitTarget->GetDummyAura(m_spellInfo->Id)) dummy->GetModifier()->m_amount = damageInfo.damage; caster->DealSpellDamage(&damageInfo, true); // Scourge Strike, here because needs to use final damage in second part of the spell - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags & UI64LIT(0x0800000000000000)) + if (classOpt && classOpt->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && classOpt->SpellFamilyFlags & UI64LIT(0x0800000000000000)) { uint32 count = 0; Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap(); for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - if (itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE && - itr->second->GetCasterGuid() == caster->GetObjectGuid()) + if(itr->second->GetSpellProto()->GetDispel() == DISPEL_DISEASE && + itr->second->GetCasterGuid() == caster->GetObjectGuid()) ++count; } @@ -1306,11 +1325,12 @@ void Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask) { if (effectMask & (1 << effectNumber)) { + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(effectNumber)); HandleEffects(unit, NULL, NULL, SpellEffectIndex(effectNumber), m_damageMultipliers[effectNumber]); if (m_applyMultiplierMask & (1 << effectNumber)) { // Get multiplier - float multiplier = m_spellInfo->DmgMultiplier[effectNumber]; + float multiplier = spellEffect ? spellEffect->DmgMultiplier : 0.0f; // Apply multiplier mods if (realCaster) if (Player* modOwner = realCaster->GetSpellModOwner()) @@ -1428,11 +1448,12 @@ void Spell::HandleDelayedSpellLaunch(TargetInfo* target) { if (mask & (1 << effectNumber) && IsEffectHandledOnDelayedSpellLaunch(m_spellInfo, SpellEffectIndex(effectNumber))) { + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(effectNumber)); HandleEffects(unit, NULL, NULL, SpellEffectIndex(effectNumber), m_damageMultipliers[effectNumber]); if (m_applyMultiplierMask & (1 << effectNumber)) { // Get multiplier - float multiplier = m_spellInfo->DmgMultiplier[effectNumber]; + float multiplier = spellEffect ? spellEffect->DmgMultiplier : 0.0f; // Apply multiplier mods if (real_caster) if (Player* modOwner = real_caster->GetSpellModOwner()) @@ -1454,17 +1475,20 @@ void Spell::InitializeDamageMultipliers() { for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (m_spellInfo->Effect[i] == 0) + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + if (spellEffect->Effect == 0) continue; - uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[i]; + uint32 EffectChainTarget = spellEffect->EffectChainTarget; if (Unit* realCaster = GetAffectiveCaster()) if (Player* modOwner = realCaster->GetSpellModOwner()) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, EffectChainTarget, this); m_damageMultipliers[i] = 1.0f; - if ((m_spellInfo->EffectImplicitTargetA[i] == TARGET_CHAIN_DAMAGE || m_spellInfo->EffectImplicitTargetA[i] == TARGET_CHAIN_HEAL) && - (EffectChainTarget > 1)) + if( (spellEffect->EffectImplicitTargetA == TARGET_CHAIN_DAMAGE || spellEffect->EffectImplicitTargetA == TARGET_CHAIN_HEAL) && + (EffectChainTarget > 1) ) m_applyMultiplierMask |= (1 << i); } } @@ -1563,13 +1587,16 @@ struct TargetDistanceOrderFarAway : public std::binary_functionGetSpellEffect(effIndex); + SpellClassOptionsEntry const* classOpt = m_spellInfo->GetSpellClassOptions(); + float radius; - if (m_spellInfo->EffectRadiusIndex[effIndex]) - radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[effIndex])); + if (spellEffect && spellEffect->EffectRadiusIndex) + radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellEffect->EffectRadiusIndex)); else radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex)); - uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[effIndex]; + uint32 EffectChainTarget = spellEffect ? spellEffect->EffectChainTarget : 0; if (Unit* realCaster = GetAffectiveCaster()) { @@ -1581,10 +1608,10 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& } // Get spell max affected targets - uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets; + uint32 unMaxTargets = m_spellInfo->GetMaxAffectedTargets(); // custom target amount cases - switch (m_spellInfo->SpellFamilyName) + switch(m_spellInfo->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { @@ -1751,11 +1778,14 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& { // overwrite EffectChainTarget for non single target spell if (Spell* currSpell = m_caster->GetCurrentSpell(CURRENT_GENERIC_SPELL)) - if (currSpell->m_spellInfo->MaxAffectedTargets > 0 || - currSpell->m_spellInfo->EffectChainTarget[EFFECT_INDEX_0] > 0 || - currSpell->m_spellInfo->EffectChainTarget[EFFECT_INDEX_1] > 0 || - currSpell->m_spellInfo->EffectChainTarget[EFFECT_INDEX_2] > 0) + { + for(int i = 0; i < MAX_EFFECT_INDEX; ++i) + if(SpellEffectEntry const* spellEffect = currSpell->m_spellInfo->GetSpellEffect(SpellEffectIndex(i))) + if(spellEffect->EffectChainTarget > 0) + EffectChainTarget = 0; // no chain targets + if (currSpell->m_spellInfo->GetMaxAffectedTargets() > 0) EffectChainTarget = 0; // no chain targets + } } break; default: @@ -1763,7 +1793,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& } // custom radius cases - switch (m_spellInfo->SpellFamilyName) + switch (m_spellInfo->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { @@ -1772,7 +1802,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& case 24811: // Draw Spirit (Lethon) { if (effIndex == EFFECT_INDEX_0) // Copy range from EFF_1 to 0 - radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[EFFECT_INDEX_1])); + radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellEffect->EffectRadiusIndex)); break; } case 28241: // Poison (Naxxramas, Grobbulus Cloud) @@ -2030,7 +2060,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& unMaxTargets = EffectChainTarget; float max_range; - if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE) + if(m_spellInfo->GetDmgClass() == SPELL_DAMAGE_CLASS_MELEE) max_range = radius; else // FIXME: This very like horrible hack and wrong for most spells @@ -2146,9 +2176,9 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& } case TARGET_AREAEFFECT_CUSTOM: { - if (m_spellInfo->Effect[effIndex] == SPELL_EFFECT_PERSISTENT_AREA_AURA) + if (spellEffect && spellEffect->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA) break; - else if (m_spellInfo->Effect[effIndex] == SPELL_EFFECT_SUMMON) + else if (spellEffect && spellEffect->Effect == SPELL_EFFECT_SUMMON) { targetUnitMap.push_back(m_caster); break; @@ -2246,7 +2276,10 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& case TARGET_ALL_ENEMY_IN_AREA_INSTANT: { // targets the ground, not the units in the area - switch (m_spellInfo->Effect[effIndex]) + if(!spellEffect) + break; + + switch(spellEffect->Effect) { case SPELL_EFFECT_PERSISTENT_AREA_AURA: break; @@ -2359,7 +2392,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& targetUnitMap.push_back(target); } // Circle of Healing - else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellInfo->SpellVisual[0] == 8253) + else if (m_spellInfo->GetSpellFamilyName() == SPELLFAMILY_PRIEST && m_spellInfo->SpellVisual[0] == 8253) { Unit* target = m_targets.getUnitTarget(); if (!target) @@ -2373,7 +2406,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& FillRaidOrPartyHealthPriorityTargets(targetUnitMap, m_caster, target, radius, count, true, false, true); } // Wild Growth - else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellIconID == 2864) + else if (m_spellInfo->GetSpellFamilyName() == SPELLFAMILY_DRUID && m_spellInfo->SpellIconID == 2864) { Unit* target = m_targets.getUnitTarget(); if (!target) @@ -2493,11 +2526,11 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& break; case TARGET_ALL_ENEMY_IN_AREA_CHANNELED: // targets the ground, not the units in the area - if (m_spellInfo->Effect[effIndex] != SPELL_EFFECT_PERSISTENT_AREA_AURA) + if (spellEffect && spellEffect->Effect!=SPELL_EFFECT_PERSISTENT_AREA_AURA) FillAreaTargets(targetUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE); break; case TARGET_MINION: - if (m_spellInfo->Effect[effIndex] != SPELL_EFFECT_DUEL) + if(spellEffect && spellEffect->Effect != SPELL_EFFECT_DUEL) targetUnitMap.push_back(m_caster); break; case TARGET_SINGLE_ENEMY: @@ -2691,7 +2724,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& // TODO - maybe use an (internal) value for the map for neat far teleport handling // far-teleport spells are handled in SpellEffect, elsewise report an error about an unexpected map (spells are always locally) - if (st->target_mapId != m_caster->GetMapId() && m_spellInfo->Effect[effIndex] != SPELL_EFFECT_TELEPORT_UNITS) + if (st->target_mapId != m_caster->GetMapId() && spellEffect && spellEffect->Effect != SPELL_EFFECT_TELEPORT_UNITS) sLog.outError("SPELL: wrong map (%u instead %u) target coordinates for spell ID %u", st->target_mapId, m_caster->GetMapId(), m_spellInfo->Id); } else @@ -2757,7 +2790,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& // "at the base of", in difference to 0 which appear to be "directly in front of". // TODO: some summoned will make caster be half inside summoned object. Need to fix // that in the below code (nearpoint vs closepoint, etc). - if (m_spellInfo->EffectRadiusIndex[effIndex] == 0) + if (!spellEffect || spellEffect->EffectRadiusIndex == 0) radius = 0.0f; if (m_spellInfo->Id == 50019) // Hawk Hunting, problematic 50K radius @@ -2834,7 +2867,10 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& { // add here custom effects that need default target. // FOR EVERY TARGET TYPE THERE IS A DIFFERENT FILL!! - switch (m_spellInfo->Effect[effIndex]) + if(!spellEffect) + break; + + switch(spellEffect->Effect) { case SPELL_EFFECT_DUMMY: { @@ -2897,7 +2933,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& if (m_targets.getUnitTarget()) targetUnitMap.push_back(m_targets.getUnitTarget()); // Triggered spells have additional spell targets - cast them even if no explicit unit target is given (required for spell 50516 for example) - else if (m_spellInfo->Effect[effIndex] == SPELL_EFFECT_TRIGGER_SPELL) + else if (spellEffect->Effect == SPELL_EFFECT_TRIGGER_SPELL) targetUnitMap.push_back(m_caster); break; case SPELL_EFFECT_SUMMON_PLAYER: @@ -2947,7 +2983,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& AddItemTarget(m_targets.getItemTarget(), effIndex); break; case SPELL_EFFECT_APPLY_AURA: - switch (m_spellInfo->EffectApplyAuraName[effIndex]) + switch(spellEffect->EffectApplyAuraName) { case SPELL_AURA_ADD_FLAT_MODIFIER: // some spell mods auras have 0 target modes instead expected TARGET_SELF(1) (and present for other ranks for same spell for example) case SPELL_AURA_ADD_PCT_MODIFIER: @@ -3251,13 +3287,15 @@ void Spell::cast(bool skipCheck) } } - // different triggered (for caster and main target after main cast) and pre-cast (casted before apply effect to each target) cases - switch (m_spellInfo->SpellFamilyName) + SpellClassOptionsEntry const* classOpt = m_spellInfo->GetSpellClassOptions(); + + // different triggered (for caster) and precast (casted before apply effect to target) cases + switch(m_spellInfo->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { // Bandages - if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) + if (m_spellInfo->GetMechanic() == MECHANIC_BANDAGE) AddPrecastSpell(11196); // Recently Bandaged // Stoneskin else if (m_spellInfo->Id == 20594) @@ -3270,7 +3308,7 @@ void Spell::cast(bool skipCheck) case SPELLFAMILY_MAGE: { // Ice Block - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000008000000000)) + if (classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x0000008000000000)) AddPrecastSpell(41425); // Hypothermia // Icy Veins else if (m_spellInfo->Id == 12472) @@ -3290,13 +3328,13 @@ void Spell::cast(bool skipCheck) case SPELLFAMILY_WARRIOR: { // Shield Slam - if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000020000000000)) && m_spellInfo->Category == 1209) + if (classOpt && (classOpt->SpellFamilyFlags & UI64LIT(0x0000020000000000)) && m_spellInfo->GetCategory()==1209) { if (m_caster->HasAura(58375)) // Glyph of Blocking AddTriggeredSpell(58374); // Glyph of Blocking } // Bloodrage - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000100)) + if (classOpt && (classOpt->SpellFamilyFlags & UI64LIT(0x0000000000000100))) { if (m_caster->HasAura(70844)) // Item - Warrior T10 Protection 4P Bonus AddTriggeredSpell(70845); // Stoicism @@ -3312,11 +3350,11 @@ void Spell::cast(bool skipCheck) case SPELLFAMILY_PRIEST: { // Power Word: Shield - if (m_spellInfo->Mechanic == MECHANIC_SHIELD && - (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000001))) + if (m_spellInfo->GetMechanic() == MECHANIC_SHIELD && + (classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x0000000000000001))) AddPrecastSpell(6788); // Weakened Soul // Prayer of Mending (jump animation), we need formal caster instead original for correct animation - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000002000000000)) + else if (classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x0000002000000000)) AddTriggeredSpell(41637); switch (m_spellInfo->Id) @@ -3389,25 +3427,26 @@ void Spell::cast(bool skipCheck) AddPrecastSpell(67485); // Hand of Rekoning (no typos in name ;) ) } // Divine Shield, Divine Protection or Hand of Protection - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000400080)) + else if (classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x0000000000400080)) { AddPrecastSpell(25771); // Forbearance AddPrecastSpell(61987); // Avenging Wrath Marker } // Lay on Hands - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000008000)) + else if (classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x0000000000008000)) { // only for self cast if (m_caster == m_targets.getUnitTarget()) AddPrecastSpell(25771); // Forbearance } // Avenging Wrath - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000200000000000)) + else if (classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x0000200000000000)) AddPrecastSpell(61987); // Avenging Wrath Marker break; } case SPELLFAMILY_SHAMAN: { + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(EFFECT_INDEX_0); // Bloodlust if (m_spellInfo->Id == 2825) AddPrecastSpell(57724); // Sated @@ -3418,7 +3457,7 @@ void Spell::cast(bool skipCheck) else if (m_spellInfo->Id == 58875) AddPrecastSpell(58876); // Totem of Wrath - else if (m_spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_APPLY_AREA_AURA_RAID && m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000004000000)) + else if (spellEffect && spellEffect->Effect==SPELL_EFFECT_APPLY_AREA_AURA_RAID && classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x0000000004000000)) // only for main totem spell cast AddTriggeredSpell(30708); // Totem of Wrath break; @@ -3592,18 +3631,19 @@ void Spell::_handle_immediate_phase() m_needSpellLog = IsNeedSendToClient(); for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if (m_spellInfo->Effect[j] == 0) + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); + if(!spellEffect || spellEffect->Effect == 0) continue; // apply Send Event effect to ground in case empty target lists - if (m_spellInfo->Effect[j] == SPELL_EFFECT_SEND_EVENT && !HaveTargetsForEffect(SpellEffectIndex(j))) + if( spellEffect->Effect == SPELL_EFFECT_SEND_EVENT && !HaveTargetsForEffect(SpellEffectIndex(j)) ) { HandleEffects(NULL, NULL, NULL, SpellEffectIndex(j)); continue; } // Don't do spell log, if is school damage spell - if (m_spellInfo->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE || m_spellInfo->Effect[j] == 0) + if(spellEffect->Effect == SPELL_EFFECT_SCHOOL_DAMAGE || spellEffect->Effect == 0) m_needSpellLog = false; } @@ -3618,8 +3658,11 @@ void Spell::_handle_immediate_phase() // process ground for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); + if(!spellEffect) + continue; // persistent area auras target only the ground - if (m_spellInfo->Effect[j] == SPELL_EFFECT_PERSISTENT_AREA_AURA) + if(spellEffect->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA) HandleEffects(NULL, NULL, NULL, SpellEffectIndex(j)); } } @@ -3664,16 +3707,19 @@ void Spell::update(uint32 difftime) return; } + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(EFFECT_INDEX_0); + SpellInterruptsEntry const* spellInterrupts = m_spellInfo->GetSpellInterrupts(); + // check if the player caster has moved before the spell finished if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) && - (m_castPositionX != m_caster->GetPositionX() || m_castPositionY != m_caster->GetPositionY() || m_castPositionZ != m_caster->GetPositionZ()) && - (m_spellInfo->Effect[EFFECT_INDEX_0] != SPELL_EFFECT_STUCK || !((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR))) + (m_castPositionX != m_caster->GetPositionX() || m_castPositionY != m_caster->GetPositionY() || m_castPositionZ != m_caster->GetPositionZ()) && + ((spellEffect && spellEffect->Effect != SPELL_EFFECT_STUCK) || !((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR))) { // always cancel for channeled spells if (m_spellState == SPELL_STATE_CASTING) cancel(); // don't cancel for melee, autorepeat, triggered and instant spells - else if (!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT)) + else if(!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_IsTriggeredSpell && (spellInterrupts && spellInterrupts->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT)) cancel(); } @@ -3707,7 +3753,7 @@ void Spell::update(uint32 difftime) cancel(); // check if player has turned if flag is set - if (m_spellInfo->ChannelInterruptFlags & CHANNEL_FLAG_TURNING && m_castOrientation != m_caster->GetOrientation()) + if( spellInterrupts && (spellInterrupts->ChannelInterruptFlags & CHANNEL_FLAG_TURNING) && m_castOrientation != m_caster->GetOrientation() ) cancel(); } @@ -3803,8 +3849,9 @@ void Spell::finish(bool ok) // Calculate chance at that moment (can be depend for example from combo points) int32 auraBasePoints = (*i)->GetBasePoints(); int32 chance = m_caster->CalculateSpellDamage(unit, auraSpellInfo, auraSpellIdx, &auraBasePoints); - if (roll_chance_i(chance)) - m_caster->CastSpell(unit, auraSpellInfo->EffectTriggerSpell[auraSpellIdx], true, NULL, (*i)); + if(roll_chance_i(chance)) + if(SpellEffectEntry const* spellEffect = auraSpellInfo->GetSpellEffect(auraSpellIdx)) + m_caster->CastSpell(unit, spellEffect->EffectTriggerSpell, true, NULL, (*i)); } } } @@ -3895,7 +3942,7 @@ void Spell::SendCastResult(Player* caster, SpellEntry const* spellInfo, uint8 ca data << uint32(0); // unknown, value 1 seen for 14177 (update cooldowns on client flag) break; case SPELL_FAILED_REQUIRES_SPELL_FOCUS: - data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id + data << uint32(spellInfo->GetRequiresSpellFocus()); break; case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id // hardcode areas limitation case @@ -3918,21 +3965,37 @@ void Spell::SendCastResult(Player* caster, SpellEntry const* spellInfo, uint8 ca } break; case SPELL_FAILED_TOTEMS: - for (int i = 0; i < MAX_SPELL_TOTEMS; ++i) - if (spellInfo->Totem[i]) - data << uint32(spellInfo->Totem[i]); // client needs only one id, not 2... + { + SpellTotemsEntry const* totems = spellInfo->GetSpellTotems(); + for(int i = 0; i < MAX_SPELL_TOTEMS; ++i) + if(totems && totems->Totem[i]) + data << uint32(totems->Totem[i]); + } break; case SPELL_FAILED_TOTEM_CATEGORY: - for (int i = 0; i < MAX_SPELL_TOTEM_CATEGORIES; ++i) - if (spellInfo->TotemCategory[i]) - data << uint32(spellInfo->TotemCategory[i]);// client needs only one id, not 2... + { + SpellTotemsEntry const* totems = spellInfo->GetSpellTotems(); + for(int i = 0; i < MAX_SPELL_TOTEM_CATEGORIES; ++i) + if(totems && totems->TotemCategory[i]) + data << uint32(totems->TotemCategory[i]); + } break; case SPELL_FAILED_EQUIPPED_ITEM_CLASS: + { + SpellEquippedItemsEntry const* eqItems = spellInfo->GetSpellEquippedItems(); + data << uint32(eqItems ? eqItems->EquippedItemClass : 0); + data << uint32(eqItems ? eqItems->EquippedItemSubClassMask : 0); + //data << uint32(eqItems ? eqItems->EquippedItemInventoryTypeMask : 0); + } + break; case SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND: case SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND: - data << uint32(spellInfo->EquippedItemClass); - data << uint32(spellInfo->EquippedItemSubClassMask); + { + SpellEquippedItemsEntry const* eqItems = spellInfo->GetSpellEquippedItems(); + data << uint32(eqItems ? eqItems->EquippedItemClass : 0); + data << uint32(eqItems ? eqItems->EquippedItemSubClassMask : 0); break; + } case SPELL_FAILED_PREVENTED_BY_MECHANIC: data << uint32(0); // SpellMechanic.dbc id break; @@ -3940,8 +4003,11 @@ void Spell::SendCastResult(Player* caster, SpellEntry const* spellInfo, uint8 ca data << uint32(0); // custom error id (see enum SpellCastResultCustom) break; case SPELL_FAILED_NEED_EXOTIC_AMMO: - data << uint32(spellInfo->EquippedItemSubClassMask);// seems correct... + { + SpellEquippedItemsEntry const* eqItems = spellInfo->GetSpellEquippedItems(); + data << uint32(eqItems ? eqItems->EquippedItemSubClassMask : 0);// seems correct... break; + } case SPELL_FAILED_REAGENTS: data << uint32(0); // item id break; @@ -4126,17 +4192,7 @@ void Spell::WriteAmmoToPacket(WorldPacket* data) ammoDisplayID = pItem->GetProto()->DisplayInfoID; else { - uint32 ammoID = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID); - if (ammoID) - { - ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(ammoID); - if (pProto) - { - ammoDisplayID = pProto->DisplayInfoID; - ammoInventoryType = pProto->InventoryType; - } - } - else if (m_caster->GetDummyAura(46699)) // Requires No Ammo + if(m_caster->GetDummyAura(46699)) // Requires No Ammo { ammoDisplayID = 5996; // normal arrow ammoInventoryType = INVTYPE_AMMO; @@ -4150,14 +4206,15 @@ void Spell::WriteAmmoToPacket(WorldPacket* data) { if (uint32 item_id = m_caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i)) { - if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id)) + if(ItemPrototype const* itemEntry = sItemStorage.LookupEntry(item_id)) + //if(ItemEntry const * itemEntry = sItemStore.LookupEntry(item_id)) { if (itemEntry->Class == ITEM_CLASS_WEAPON) { switch (itemEntry->SubClass) { case ITEM_SUBCLASS_WEAPON_THROWN: - ammoDisplayID = itemEntry->DisplayId; + ammoDisplayID = itemEntry->DisplayInfoID; ammoInventoryType = itemEntry->InventoryType; break; case ITEM_SUBCLASS_WEAPON_BOW: @@ -4248,12 +4305,16 @@ void Spell::SendLogExecute() data << uint32(count1); // count1 (effect count?) for (uint32 i = 0; i < count1; ++i) { - data << uint32(m_spellInfo->Effect[EFFECT_INDEX_0]);// spell effect + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(EFFECT_INDEX_0); + data << uint32(spellEffect ? spellEffect->Effect : 0);// spell effect uint32 count2 = 1; data << uint32(count2); // count2 (target count?) for (uint32 j = 0; j < count2; ++j) { - switch (m_spellInfo->Effect[EFFECT_INDEX_0]) + if(!spellEffect) + continue; + + switch(spellEffect->Effect) { case SPELL_EFFECT_POWER_DRAIN: if (Unit* unit = m_targets.getUnitTarget()) @@ -4294,7 +4355,7 @@ void Spell::SendLogExecute() break; case SPELL_EFFECT_CREATE_ITEM: case SPELL_EFFECT_CREATE_ITEM_2: - data << uint32(m_spellInfo->EffectItemType[EFFECT_INDEX_0]); + data << uint32(spellEffect->EffectItemType); break; case SPELL_EFFECT_SUMMON: case SPELL_EFFECT_TRANS_DOOR: @@ -4417,7 +4478,7 @@ void Spell::SendChannelStart(uint32 duration) WorldObject* target = NULL; // select dynobject created by first effect if any - if (m_spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_PERSISTENT_AREA_AURA) + if (m_spellInfo->GetSpellEffectIdByIndex(EFFECT_INDEX_0) == SPELL_EFFECT_PERSISTENT_AREA_AURA) target = m_caster->GetDynObject(m_spellInfo->Id, EFFECT_INDEX_0); // select first not resisted target from target list for _0_ effect else if (!m_UniqueTargetInfo.empty()) @@ -4687,13 +4748,17 @@ void Spell::TakeReagents() if (p_caster->CanNoReagentCast(m_spellInfo)) return; - for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x) + SpellReagentsEntry const* spellReagents = m_spellInfo->GetSpellReagents(); + + for(uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x) { - if (m_spellInfo->Reagent[x] <= 0) + if(!spellReagents) + continue; + if(spellReagents->Reagent[x] <= 0) continue; - uint32 itemid = m_spellInfo->Reagent[x]; - uint32 itemcount = m_spellInfo->ReagentCount[x]; + uint32 itemid = spellReagents->Reagent[x]; + uint32 itemcount = spellReagents->ReagentCount[x]; // if CastItem is also spell reagent if (m_CastItem) @@ -4741,8 +4806,9 @@ void Spell::HandleThreatSpells() bool positive = true; uint8 effectMask = 0; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) - if (m_spellInfo->Effect[i]) - effectMask |= (1 << i); + if (SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i))) + if (spellEffect->Effect) + effectMask |= (1<Effect[i]; + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); damage = int32(CalculateDamage(i, unitTarget) * DamageMultiplier); - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell %u Effect%d : %u Targets: %s, %s, %s", - m_spellInfo->Id, i, eff, - unitTarget ? unitTarget->GetGuidStr().c_str() : "-", - itemTarget ? itemTarget->GetGuidStr().c_str() : "-", - gameObjTarget ? gameObjTarget->GetGuidStr().c_str() : "-"); - - if (eff < TOTAL_SPELL_EFFECTS) + if(spellEffect) { - (*this.*SpellEffects[eff])(i); + if(spellEffect->Effect < TOTAL_SPELL_EFFECTS) + { + DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell %u Effect%d : %u Targets: %s, %s, %s", + m_spellInfo->Id, i, spellEffect->Effect, + unitTarget ? unitTarget->GetGuidStr().c_str() : "-", + itemTarget ? itemTarget->GetGuidStr().c_str() : "-", + gameObjTarget ? gameObjTarget->GetGuidStr().c_str() : "-"); + + (*this.*SpellEffects[spellEffect->Effect])(spellEffect); + } + else + { + sLog.outError("WORLD: Spell %u Effect%d : %u > TOTAL_SPELL_EFFECTS", m_spellInfo->Id, i, spellEffect->Effect); + } } else { - sLog.outError("WORLD: Spell FX %d > TOTAL_SPELL_EFFECTS ", eff); + sLog.outError("WORLD: Spell %u has no effect at index %u", m_spellInfo->Id, i); } } @@ -4908,25 +4981,27 @@ SpellCastResult Spell::CheckCast(bool strict) } } + SpellAuraRestrictionsEntry const* auraRestrictions = m_spellInfo->GetSpellAuraRestrictions(); + // caster state requirements - if (m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraState))) + if(auraRestrictions && auraRestrictions->CasterAuraState && !m_caster->HasAuraState(AuraState(auraRestrictions->CasterAuraState))) return SPELL_FAILED_CASTER_AURASTATE; - if (m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraStateNot))) + if(auraRestrictions && auraRestrictions->CasterAuraStateNot && m_caster->HasAuraState(AuraState(auraRestrictions->CasterAuraStateNot))) return SPELL_FAILED_CASTER_AURASTATE; // Caster aura req check if need - if (m_spellInfo->casterAuraSpell && !m_caster->HasAura(m_spellInfo->casterAuraSpell)) + if(auraRestrictions && auraRestrictions->casterAuraSpell && !m_caster->HasAura(auraRestrictions->casterAuraSpell)) return SPELL_FAILED_CASTER_AURASTATE; - if (m_spellInfo->excludeCasterAuraSpell) + if(auraRestrictions && auraRestrictions->excludeCasterAuraSpell) { // Special cases of non existing auras handling - if (m_spellInfo->excludeCasterAuraSpell == 61988) + if(auraRestrictions->excludeCasterAuraSpell == 61988) { // Avenging Wrath Marker if (m_caster->HasAura(61987)) return SPELL_FAILED_CASTER_AURASTATE; } - else if (m_caster->HasAura(m_spellInfo->excludeCasterAuraSpell)) + else if(m_caster->HasAura(auraRestrictions->excludeCasterAuraSpell)) return SPELL_FAILED_CASTER_AURASTATE; } @@ -4937,8 +5012,8 @@ SpellCastResult Spell::CheckCast(bool strict) if (((Player*)m_caster)->isMoving()) { // skip stuck spell to allow use it in falling case and apply spell limitations at movement - if ((!((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR) || m_spellInfo->Effect[EFFECT_INDEX_0] != SPELL_EFFECT_STUCK) && - (IsAutoRepeat() || (m_spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) != 0)) + if ((!((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR) || m_spellInfo->GetSpellEffectIdByIndex(EFFECT_INDEX_0) != SPELL_EFFECT_STUCK) && + (IsAutoRepeat() || (m_spellInfo->GetAuraInterruptFlags() & AURA_INTERRUPT_FLAG_NOT_SEATED) != 0)) return SPELL_FAILED_MOVING; } @@ -4948,29 +5023,32 @@ SpellCastResult Spell::CheckCast(bool strict) return m_caster->getClass() == CLASS_WARRIOR ? SPELL_FAILED_CASTER_AURASTATE : SPELL_FAILED_NO_COMBO_POINTS; } - if (Unit* target = m_targets.getUnitTarget()) + SpellClassOptionsEntry const* classOptions = m_spellInfo->GetSpellClassOptions(); + + if(Unit *target = m_targets.getUnitTarget()) { // target state requirements (not allowed state), apply to self also - if (m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot))) + if(auraRestrictions && auraRestrictions->TargetAuraStateNot && target->HasAuraState(AuraState(auraRestrictions->TargetAuraStateNot))) return SPELL_FAILED_TARGET_AURASTATE; if (!m_IsTriggeredSpell && IsDeathOnlySpell(m_spellInfo) && target->isAlive()) return SPELL_FAILED_TARGET_NOT_DEAD; // Target aura req check if need - if (m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell)) + if(auraRestrictions && auraRestrictions->targetAuraSpell && !target->HasAura(auraRestrictions->targetAuraSpell)) return SPELL_FAILED_CASTER_AURASTATE; - if (m_spellInfo->excludeTargetAuraSpell) + + if(auraRestrictions && auraRestrictions->excludeTargetAuraSpell) { // Special cases of non existing auras handling - if (m_spellInfo->excludeTargetAuraSpell == 61988) + if (auraRestrictions->excludeTargetAuraSpell == 61988) { // Avenging Wrath Marker if (target->HasAura(61987)) return SPELL_FAILED_CASTER_AURASTATE; } - else if (target->HasAura(m_spellInfo->excludeTargetAuraSpell)) + else if (target->HasAura(auraRestrictions->excludeTargetAuraSpell)) return SPELL_FAILED_CASTER_AURASTATE; } @@ -4987,8 +5065,8 @@ SpellCastResult Spell::CheckCast(bool strict) if (non_caster_target) { // target state requirements (apply to non-self only), to allow cast affects to self like Dirty Deeds - if (m_spellInfo->TargetAuraState && !target->HasAuraStateForCaster(AuraState(m_spellInfo->TargetAuraState), m_caster->GetObjectGuid()) && - !m_caster->IsIgnoreUnitState(m_spellInfo, m_spellInfo->TargetAuraState == AURA_STATE_FROZEN ? IGNORE_UNIT_TARGET_NON_FROZEN : IGNORE_UNIT_TARGET_STATE)) + if (auraRestrictions && auraRestrictions->TargetAuraState && !target->HasAuraStateForCaster(AuraState(auraRestrictions->TargetAuraState), m_caster->GetObjectGuid()) && + !m_caster->IsIgnoreUnitState(m_spellInfo, auraRestrictions->TargetAuraState == AURA_STATE_FROZEN ? IGNORE_UNIT_TARGET_NON_FROZEN : IGNORE_UNIT_TARGET_STATE)) return SPELL_FAILED_TARGET_AURASTATE; // Not allow casting on flying player @@ -5015,7 +5093,7 @@ SpellCastResult Spell::CheckCast(bool strict) // If 0 spell effect empty - client not send target data (need use selection) // TODO: check it on next client version if (m_targets.m_targetMask == TARGET_FLAG_SELF && - m_spellInfo->EffectImplicitTargetA[EFFECT_INDEX_1] == TARGET_CHAIN_DAMAGE) + m_spellInfo->GetEffectImplicitTargetAByIndex(EFFECT_INDEX_1) == TARGET_CHAIN_DAMAGE) { target = m_caster->GetMap()->GetUnit(((Player*)m_caster)->GetSelectionGuid()); if (!target) @@ -5028,8 +5106,8 @@ SpellCastResult Spell::CheckCast(bool strict) // Some special spells with non-caster only mode // Fire Shield - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && - m_spellInfo->SpellIconID == 16) + if (classOptions && classOptions->SpellFamilyName == SPELLFAMILY_WARLOCK && + m_spellInfo->SpellIconID == 16) return SPELL_FAILED_BAD_TARGETS; // Focus Magic (main spell) @@ -5037,8 +5115,8 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_BAD_TARGETS; // Lay on Hands (self cast) - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && - m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000008000)) + if (classOptions && classOptions->SpellFamilyName == SPELLFAMILY_PALADIN && + classOptions->SpellFamilyFlags & UI64LIT(0x0000000000008000)) { if (target->HasAura(25771)) // Forbearance return SPELL_FAILED_CASTER_AURASTATE; @@ -5050,7 +5128,11 @@ SpellCastResult Spell::CheckCast(bool strict) // check pet presents for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_PET) + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); + if(!spellEffect) + continue; + + if(spellEffect->EffectImplicitTargetA == TARGET_PET) { Pet* pet = m_caster->GetPet(); if (!pet) @@ -5086,7 +5168,10 @@ SpellCastResult Spell::CheckCast(bool strict) bool target_friendly_checked = false; for (int k = 0; k < MAX_EFFECT_INDEX; ++k) { - if (IsExplicitPositiveTarget(m_spellInfo->EffectImplicitTargetA[k])) + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(k)); + if(!spellEffect) + continue; + if (IsExplicitPositiveTarget(spellEffect->EffectImplicitTargetA)) { if (!target_hostile_checked) { @@ -5099,7 +5184,7 @@ SpellCastResult Spell::CheckCast(bool strict) explicit_target_mode = true; } - else if (IsExplicitNegativeTarget(m_spellInfo->EffectImplicitTargetA[k])) + else if (IsExplicitNegativeTarget(spellEffect->EffectImplicitTargetA)) { if (!target_friendly_checked) { @@ -5205,24 +5290,28 @@ SpellCastResult Spell::CheckCast(bool strict) { for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT || - (m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[j] != TARGET_SELF) || - m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || - m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES || - m_spellInfo->EffectImplicitTargetA[j] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); + if(!spellEffect) + continue; + + if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT || + (spellEffect->EffectImplicitTargetB == TARGET_SCRIPT && spellEffect->EffectImplicitTargetA != TARGET_SELF) || + spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES || + spellEffect->EffectImplicitTargetB == TARGET_SCRIPT_COORDINATES || + spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) { SpellScriptTargetBounds bounds = sSpellMgr.GetSpellScriptTargetBounds(m_spellInfo->Id); if (bounds.first == bounds.second) { - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT || m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT) + if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT || spellEffect->EffectImplicitTargetB == TARGET_SCRIPT) sLog.outErrorDb("Spell entry %u, effect %i has EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT, but creature are not defined in `spell_script_target`", m_spellInfo->Id, j); - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES) + if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES || spellEffect->EffectImplicitTargetB == TARGET_SCRIPT_COORDINATES) sLog.outErrorDb("Spell entry %u, effect %i has EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT_COORDINATES, but gameobject or creature are not defined in `spell_script_target`", m_spellInfo->Id, j); - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) + if (spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) sLog.outErrorDb("Spell entry %u, effect %i has EffectImplicitTargetA/EffectImplicitTargetB = TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT, but gameobject are not defined in `spell_script_target`", m_spellInfo->Id, j); } @@ -5322,38 +5411,38 @@ SpellCastResult Spell::CheckCast(bool strict) if (creatureScriptTarget) { // store coordinates for TARGET_SCRIPT_COORDINATES - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || - m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES) + if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES || + spellEffect->EffectImplicitTargetB == TARGET_SCRIPT_COORDINATES) { m_targets.setDestination(creatureScriptTarget->GetPositionX(), creatureScriptTarget->GetPositionY(), creatureScriptTarget->GetPositionZ()); - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES && m_spellInfo->Effect[j] != SPELL_EFFECT_PERSISTENT_AREA_AURA) + if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES && spellEffect->Effect != SPELL_EFFECT_PERSISTENT_AREA_AURA) AddUnitTarget(creatureScriptTarget, SpellEffectIndex(j)); } // store explicit target for TARGET_SCRIPT else { - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT || - m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT) + if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT || + spellEffect->EffectImplicitTargetB == TARGET_SCRIPT) AddUnitTarget(creatureScriptTarget, SpellEffectIndex(j)); } } else if (goScriptTarget) { // store coordinates for TARGET_SCRIPT_COORDINATES - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || - m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES) + if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES || + spellEffect->EffectImplicitTargetB == TARGET_SCRIPT_COORDINATES) { m_targets.setDestination(goScriptTarget->GetPositionX(), goScriptTarget->GetPositionY(), goScriptTarget->GetPositionZ()); - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES && m_spellInfo->Effect[j] != SPELL_EFFECT_PERSISTENT_AREA_AURA) + if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES && spellEffect->Effect != SPELL_EFFECT_PERSISTENT_AREA_AURA) AddGOTarget(goScriptTarget, SpellEffectIndex(j)); } // store explicit target for TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT else { - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT || - m_spellInfo->EffectImplicitTargetB[j] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) + if (spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT || + spellEffect->EffectImplicitTargetB == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) AddGOTarget(goScriptTarget, SpellEffectIndex(j)); } } @@ -5363,7 +5452,7 @@ SpellCastResult Spell::CheckCast(bool strict) /* For TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT makes DB targets optional not required for now * TODO: Makes more research for this target type */ - if (m_spellInfo->EffectImplicitTargetA[j] != TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) + if (spellEffect->EffectImplicitTargetA != TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) { // not report target not existence for triggered spells if (m_triggeredByAuraSpell || m_IsTriggeredSpell) @@ -5398,8 +5487,11 @@ SpellCastResult Spell::CheckCast(bool strict) for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; // for effects of spells that have only one target - switch (m_spellInfo->Effect[i]) + switch(spellEffect->Effect) { case SPELL_EFFECT_INSTAKILL: // Death Pact @@ -5422,8 +5514,8 @@ SpellCastResult Spell::CheckCast(bool strict) if (target->GetOwnerGuid() != m_caster->GetObjectGuid()) return SPELL_FAILED_BAD_IMPLICIT_TARGETS; - float dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); - if (!target->IsWithinDistInMap(m_caster, dist)) + float dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellEffect->EffectRadiusIndex)); + if (!target->IsWithinDistInMap(m_caster,dist)) return SPELL_FAILED_OUT_OF_RANGE; // will set in target selection code @@ -5444,7 +5536,7 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_UNIT_NOT_INFRONT; } // Fire Nova - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellIconID == 33) + if (m_spellInfo->GetSpellFamilyName() == SPELLFAMILY_SHAMAN && m_spellInfo->SpellIconID == 33) { // fire totems slot if (!m_caster->GetTotemGuid(TOTEM_SLOT_FIRE)) @@ -5526,7 +5618,7 @@ SpellCastResult Spell::CheckCast(bool strict) } case SPELL_EFFECT_LEARN_SPELL: { - if (m_spellInfo->EffectImplicitTargetA[i] != TARGET_PET) + if(spellEffect->EffectImplicitTargetA != TARGET_PET) break; Pet* pet = m_caster->GetPet(); @@ -5534,12 +5626,12 @@ SpellCastResult Spell::CheckCast(bool strict) if (!pet) return SPELL_FAILED_NO_PET; - SpellEntry const* learn_spellproto = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[i]); + SpellEntry const *learn_spellproto = sSpellStore.LookupEntry(spellEffect->EffectTriggerSpell); if (!learn_spellproto) return SPELL_FAILED_NOT_KNOWN; - if (m_spellInfo->spellLevel > pet->getLevel()) + if(m_spellInfo->GetSpellLevel() > pet->getLevel()) return SPELL_FAILED_LOWLEVEL; break; @@ -5551,21 +5643,20 @@ SpellCastResult Spell::CheckCast(bool strict) if (!pet) return SPELL_FAILED_NO_PET; - SpellEntry const* learn_spellproto = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[i]); - + SpellEntry const *learn_spellproto = sSpellStore.LookupEntry(spellEffect->EffectTriggerSpell); if (!learn_spellproto) return SPELL_FAILED_NOT_KNOWN; - if (m_spellInfo->spellLevel > pet->getLevel()) + if(m_spellInfo->GetSpellLevel() > pet->getLevel()) return SPELL_FAILED_LOWLEVEL; break; } case SPELL_EFFECT_APPLY_GLYPH: { - uint32 glyphId = m_spellInfo->EffectMiscValue[i]; - if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId)) - if (m_caster->HasAura(gp->SpellId)) + uint32 glyphId = spellEffect->EffectMiscValue; + if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyphId)) + if(m_caster->HasAura(gp->SpellId)) return SPELL_FAILED_UNIQUE_GLYPH; break; } @@ -5600,7 +5691,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 && int32(target->getPowerType()) != m_spellInfo->EffectMiscValue[i]) + if (target != m_caster && int32(target->getPowerType()) != spellEffect->EffectMiscValue) return SPELL_FAILED_BAD_TARGETS; break; } @@ -5647,7 +5738,7 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_BAD_TARGETS; // we need a go target in case of TARGET_GAMEOBJECT (for other targets acceptable GO and items) - if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_GAMEOBJECT) + if (spellEffect->EffectImplicitTargetA == TARGET_GAMEOBJECT) { if (!m_targets.getGOTarget()) return SPELL_FAILED_BAD_TARGETS; @@ -5716,7 +5807,7 @@ SpellCastResult Spell::CheckCast(bool strict) // This is generic summon effect case SPELL_EFFECT_SUMMON: { - if (SummonPropertiesEntry const* summon_prop = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i])) + if (SummonPropertiesEntry const *summon_prop = sSummonPropertiesStore.LookupEntry(spellEffect->EffectMiscValueB)) { if (summon_prop->Group == SUMMON_PROP_GROUP_PETS) { @@ -5778,7 +5869,7 @@ SpellCastResult Spell::CheckCast(bool strict) case SPELL_EFFECT_LEAP: case SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER: { - float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellEffect->EffectRadiusIndex)); float fx = m_caster->GetPositionX() + dis * cos(m_caster->GetOrientation()); float fy = m_caster->GetPositionY() + dis * sin(m_caster->GetOrientation()); // teleport a bit above terrain level to avoid falling below it @@ -5810,7 +5901,11 @@ SpellCastResult Spell::CheckCast(bool strict) for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - switch (m_spellInfo->EffectApplyAuraName[i]) + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + + switch(spellEffect->EffectApplyAuraName) { case SPELL_AURA_DUMMY: { @@ -5912,7 +6007,7 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_NO_MOUNTS_ALLOWED; // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells - if (m_caster->GetTypeId() == TYPEID_PLAYER && !sMapStore.LookupEntry(m_caster->GetMapId())->IsMountAllowed() && !m_IsTriggeredSpell && !m_spellInfo->AreaGroupId) + if (m_caster->GetTypeId() == TYPEID_PLAYER && !sMapStore.LookupEntry(m_caster->GetMapId())->IsMountAllowed() && !m_IsTriggeredSpell && !m_spellInfo->GetAreaGroupId()) return SPELL_FAILED_NO_MOUNTS_ALLOWED; if (m_caster->IsInDisallowedMountForm()) @@ -6035,12 +6130,16 @@ SpellCastResult Spell::CheckPetCast(Unit* target) bool need = false; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_CHAIN_DAMAGE || - m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND || - m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND_2 || - m_spellInfo->EffectImplicitTargetA[i] == TARGET_DUELVSPLAYER || - m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_PARTY || - m_spellInfo->EffectImplicitTargetA[i] == TARGET_CURRENT_ENEMY_COORDINATES) + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + + if (spellEffect->EffectImplicitTargetA == TARGET_CHAIN_DAMAGE || + spellEffect->EffectImplicitTargetA == TARGET_SINGLE_FRIEND || + spellEffect->EffectImplicitTargetA == TARGET_SINGLE_FRIEND_2 || + spellEffect->EffectImplicitTargetA == TARGET_DUELVSPLAYER || + spellEffect->EffectImplicitTargetA == TARGET_SINGLE_PARTY || + spellEffect->EffectImplicitTargetA == TARGET_CURRENT_ENEMY_COORDINATES) { need = true; if (!target) @@ -6068,8 +6167,8 @@ SpellCastResult Spell::CheckPetCast(Unit* target) bool duelvsplayertar = false; for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - // TARGET_DUELVSPLAYER is positive AND negative - duelvsplayertar |= (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DUELVSPLAYER); + //TARGET_DUELVSPLAYER is positive AND negative + duelvsplayertar |= (m_spellInfo->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_DUELVSPLAYER); } if (m_caster->IsFriendlyTo(target) && !duelvsplayertar) { @@ -6105,14 +6204,17 @@ SpellCastResult Spell::CheckCasterAuras() const { for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_SCHOOL_IMMUNITY) - school_immune |= uint32(m_spellInfo->EffectMiscValue[i]); - else if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MECHANIC_IMMUNITY) - mechanic_immune |= 1 << uint32(m_spellInfo->EffectMiscValue[i] - 1); - else if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MECHANIC_IMMUNITY_MASK) - mechanic_immune |= uint32(m_spellInfo->EffectMiscValue[i]); - else if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_DISPEL_IMMUNITY) - dispel_immune |= GetDispellMask(DispelType(m_spellInfo->EffectMiscValue[i])); + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + if (spellEffect->EffectApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY) + school_immune |= uint32(spellEffect->EffectMiscValue); + else if (spellEffect->EffectApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY) + mechanic_immune |= 1 << uint32(spellEffect->EffectMiscValue-1); + else if (spellEffect->EffectApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY_MASK) + mechanic_immune |= uint32(spellEffect->EffectMiscValue); + else if (spellEffect->EffectApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY) + dispel_immune |= GetDispellMask(DispelType(spellEffect->EffectMiscValue)); } // immune movement impairment and loss of control (spell data have special structure for mark this case) @@ -6129,7 +6231,7 @@ SpellCastResult Spell::CheckCasterAuras() const if (unitflag & UNIT_FLAG_STUNNED) { // Pain Suppression (have SPELL_ATTR_EX5_USABLE_WHILE_STUNNED that must be used only with glyph) - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellInfo->SpellIconID == 2178) + if (m_spellInfo->GetSpellFamilyName() == SPELLFAMILY_PRIEST && m_spellInfo->SpellIconID == 2178) { if (!m_caster->HasAura(63248)) // Glyph of Pain Suppression spellUsableWhileStunned = false; @@ -6156,9 +6258,9 @@ SpellCastResult Spell::CheckCasterAuras() const prevented_reason = SPELL_FAILED_CONFUSED; else if (unitflag & UNIT_FLAG_FLEEING && !m_spellInfo->HasAttribute(SPELL_ATTR_EX5_USABLE_WHILE_FEARED)) prevented_reason = SPELL_FAILED_FLEEING; - else if (unitflag & UNIT_FLAG_SILENCED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) + else if (unitflag & UNIT_FLAG_SILENCED && m_spellInfo->GetPreventionType() == SPELL_PREVENTION_TYPE_SILENCE) prevented_reason = SPELL_FAILED_SILENCED; - else if (unitflag & UNIT_FLAG_PACIFIED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY) + else if (unitflag & UNIT_FLAG_PACIFIED && m_spellInfo->GetPreventionType() == SPELL_PREVENTION_TYPE_PACIFY) prevented_reason = SPELL_FAILED_PACIFIED; else if (m_caster->HasAuraType(SPELL_AURA_ALLOW_ONLY_ABILITY)) { @@ -6187,7 +6289,7 @@ SpellCastResult Spell::CheckCasterAuras() const if ((GetSpellSchoolMask(pEntry) & school_immune) && !pEntry->HasAttribute(SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE)) continue; - if ((1 << (pEntry->Dispel)) & dispel_immune) + if ((1<<(pEntry->GetDispel())) & dispel_immune) continue; for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) @@ -6217,9 +6319,9 @@ SpellCastResult Spell::CheckCasterAuras() const case SPELL_AURA_MOD_SILENCE: case SPELL_AURA_MOD_PACIFY: case SPELL_AURA_MOD_PACIFY_SILENCE: - if (m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY) + if( m_spellInfo->GetPreventionType() == SPELL_PREVENTION_TYPE_PACIFY) return SPELL_FAILED_PACIFIED; - else if (m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) + else if ( m_spellInfo->GetPreventionType() == SPELL_PREVENTION_TYPE_SILENCE) return SPELL_FAILED_SILENCED; break; default: break; @@ -6240,21 +6342,24 @@ bool Spell::CanAutoCast(Unit* target) for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if (m_spellInfo->Effect[j] == SPELL_EFFECT_APPLY_AURA) + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); + if(!spellEffect) + continue; + if(spellEffect->Effect == SPELL_EFFECT_APPLY_AURA) { - if (m_spellInfo->StackAmount <= 1) + if( m_spellInfo->GetStackAmount() <= 1) { if (target->HasAura(m_spellInfo->Id, SpellEffectIndex(j))) return false; } else { - if (Aura* aura = target->GetAura(m_spellInfo->Id, SpellEffectIndex(j))) - if (aura->GetStackAmount() >= m_spellInfo->StackAmount) + if(Aura* aura = target->GetAura(m_spellInfo->Id, SpellEffectIndex(j))) + if(aura->GetStackAmount() >= m_spellInfo->GetStackAmount()) return false; } } - else if (IsAreaAuraEffect(m_spellInfo->Effect[j])) + else if ( IsAreaAuraEffect( spellEffect->Effect )) { if (target->HasAura(m_spellInfo->Id, SpellEffectIndex(j))) return false; @@ -6326,8 +6431,8 @@ SpellCastResult Spell::CheckRange(bool strict) return SPELL_FAILED_OUT_OF_RANGE; if (min_range && dist < min_range) return SPELL_FAILED_TOO_CLOSE; - if (m_caster->GetTypeId() == TYPEID_PLAYER && - (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(M_PI_F, target)) + if( m_caster->GetTypeId() == TYPEID_PLAYER && + (m_spellInfo->GetFacingCasterFlags() & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc( M_PI_F, target ) ) return SPELL_FAILED_UNIT_NOT_INFRONT; } @@ -6363,24 +6468,24 @@ uint32 Spell::CalculatePowerCost(SpellEntry const* spellInfo, Unit* caster, Spel } // Base powerCost - int32 powerCost = spellInfo->manaCost; + int32 powerCost = spellInfo->GetManaCost(); // PCT cost from total amount - if (spellInfo->ManaCostPercentage) + if (uint32 manaCostPct = spellInfo->GetManaCostPercentage()) { switch (spellInfo->powerType) { // health as power used case POWER_HEALTH: - powerCost += spellInfo->ManaCostPercentage * caster->GetCreateHealth() / 100; + powerCost += manaCostPct * caster->GetCreateHealth() / 100; break; case POWER_MANA: - powerCost += spellInfo->ManaCostPercentage * caster->GetCreateMana() / 100; + powerCost += manaCostPct * caster->GetCreateMana() / 100; break; case POWER_RAGE: case POWER_FOCUS: case POWER_ENERGY: case POWER_HAPPINESS: - powerCost += spellInfo->ManaCostPercentage * caster->GetMaxPower(Powers(spellInfo->powerType)) / 100; + powerCost += manaCostPct * caster->GetMaxPower(Powers(spellInfo->powerType)) / 100; break; case POWER_RUNE: case POWER_RUNIC_POWER: @@ -6403,7 +6508,7 @@ uint32 Spell::CalculatePowerCost(SpellEntry const* spellInfo, Unit* caster, Spel modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COST, powerCost, spell); if (spellInfo->HasAttribute(SPELL_ATTR_LEVEL_DAMAGE_CALCULATION)) - powerCost = int32(powerCost / (1.117f * spellInfo->spellLevel / caster->getLevel() - 0.1327f)); + powerCost = int32(powerCost / (1.117f * spellInfo->GetSpellLevel() / caster->getLevel() - 0.1327f)); // PCT mod from user auras by school powerCost = int32(powerCost * (1.0f + caster->GetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER + school))); @@ -6473,8 +6578,12 @@ bool Spell::IgnoreItemRequirements() const /// Some triggered spells have same reagents that have master spell /// expected in test: master spell have reagents in first slot then triggered don't must use own - if (m_triggeredBySpellInfo && !m_triggeredBySpellInfo->Reagent[0]) - return false; + if (m_triggeredBySpellInfo) + { + SpellReagentsEntry const* spellReagents = m_triggeredBySpellInfo->GetSpellReagents(); + if (!spellReagents || !spellReagents->Reagent[0]) + return false; + } return true; } @@ -6520,11 +6629,14 @@ SpellCastResult Spell::CheckItems() SpellCastResult failReason = SPELL_CAST_OK; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; // skip check, pet not required like checks, and for TARGET_PET m_targets.getUnitTarget() is not the real target but the caster - if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_PET) + if (spellEffect->EffectImplicitTargetA == TARGET_PET) continue; - if (m_spellInfo->Effect[i] == SPELL_EFFECT_HEAL) + if (spellEffect->Effect == SPELL_EFFECT_HEAL) { if (m_targets.getUnitTarget()->GetHealth() == m_targets.getUnitTarget()->GetMaxHealth()) { @@ -6539,15 +6651,15 @@ SpellCastResult Spell::CheckItems() } // Mana Potion, Rage Potion, Thistle Tea(Rogue), ... - if (m_spellInfo->Effect[i] == SPELL_EFFECT_ENERGIZE) + if (spellEffect->Effect == SPELL_EFFECT_ENERGIZE) { - if (m_spellInfo->EffectMiscValue[i] < 0 || m_spellInfo->EffectMiscValue[i] >= MAX_POWERS) + if(spellEffect->EffectMiscValue < 0 || spellEffect->EffectMiscValue >= MAX_POWERS) { failReason = SPELL_FAILED_ALREADY_AT_FULL_POWER; continue; } - Powers power = Powers(m_spellInfo->EffectMiscValue[i]); + Powers power = Powers(spellEffect->EffectMiscValue); if (m_targets.getUnitTarget()->GetPower(power) == m_targets.getUnitTarget()->GetMaxPower(power)) { failReason = SPELL_FAILED_ALREADY_AT_FULL_POWER; @@ -6594,10 +6706,10 @@ SpellCastResult Spell::CheckItems() } // check spell focus object - if (m_spellInfo->RequiresSpellFocus) + if(uint32 spellFocus = m_spellInfo->GetRequiresSpellFocus()) { GameObject* ok = NULL; - MaNGOS::GameObjectFocusCheck go_check(m_caster, m_spellInfo->RequiresSpellFocus); + MaNGOS::GameObjectFocusCheck go_check(m_caster, spellFocus); MaNGOS::GameObjectSearcher checker(ok, go_check); Cell::VisitGridObjects(m_caster, checker, m_caster->GetMap()->GetVisibilityDistance()); @@ -6612,89 +6724,100 @@ SpellCastResult Spell::CheckItems() { if (!p_caster->CanNoReagentCast(m_spellInfo)) { - for (uint32 i = 0; i < MAX_SPELL_REAGENTS; ++i) + SpellReagentsEntry const* spellReagents = m_spellInfo->GetSpellReagents(); + if(spellReagents) { - if (m_spellInfo->Reagent[i] <= 0) - continue; - - uint32 itemid = m_spellInfo->Reagent[i]; - uint32 itemcount = m_spellInfo->ReagentCount[i]; - - // if CastItem is also spell reagent - if (m_CastItem && m_CastItem->GetEntry() == itemid) + for(uint32 i = 0; i < MAX_SPELL_REAGENTS; ++i) { - ItemPrototype const* proto = m_CastItem->GetProto(); - if (!proto) - return SPELL_FAILED_REAGENTS; - for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s) + if(spellReagents->Reagent[i] <= 0) + continue; + + uint32 itemid = spellReagents->Reagent[i]; + uint32 itemcount = spellReagents->ReagentCount[i]; + + // if CastItem is also spell reagent + if (m_CastItem && m_CastItem->GetEntry() == itemid) { - // CastItem will be used up and does not count as reagent - int32 charges = m_CastItem->GetSpellCharges(s); - if (proto->Spells[s].SpellCharges < 0 && !(proto->ExtraFlags & ITEM_EXTRA_NON_CONSUMABLE) && abs(charges) < 2) + ItemPrototype const *proto = m_CastItem->GetProto(); + if (!proto) + return SPELL_FAILED_REAGENTS; + for(int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s) { - ++itemcount; - break; + // CastItem will be used up and does not count as reagent + int32 charges = m_CastItem->GetSpellCharges(s); + if (proto->Spells[s].SpellCharges < 0 && !(proto->ExtraFlags & ITEM_EXTRA_NON_CONSUMABLE) && abs(charges) < 2) + { + ++itemcount; + break; + } } } - } - if (!p_caster->HasItemCount(itemid, itemcount)) - return SPELL_FAILED_REAGENTS; + if (!p_caster->HasItemCount(itemid, itemcount)) + return SPELL_FAILED_REAGENTS; + } } } // check totem-item requirements (items presence in inventory) - uint32 totems = MAX_SPELL_TOTEMS; - for (int i = 0; i < MAX_SPELL_TOTEMS ; ++i) + SpellTotemsEntry const* spellTotems = m_spellInfo->GetSpellTotems(); + if(spellTotems) { - if (m_spellInfo->Totem[i] != 0) + uint32 totems = MAX_SPELL_TOTEMS; + for(int i = 0; i < MAX_SPELL_TOTEMS ; ++i) { - if (p_caster->HasItemCount(m_spellInfo->Totem[i], 1)) + if (spellTotems->Totem[i] != 0) { + if (p_caster->HasItemCount(spellTotems->Totem[i], 1)) + { + totems -= 1; + continue; + } + } + else totems -= 1; - continue; - } } - else - totems -= 1; - } - if (totems != 0) - return SPELL_FAILED_TOTEMS; + if (totems != 0) + return SPELL_FAILED_TOTEMS; - // Check items for TotemCategory (items presence in inventory) - uint32 TotemCategory = MAX_SPELL_TOTEM_CATEGORIES; - for (int i = 0; i < MAX_SPELL_TOTEM_CATEGORIES; ++i) - { - if (m_spellInfo->TotemCategory[i] != 0) + // Check items for TotemCategory (items presence in inventory) + uint32 TotemCategory = MAX_SPELL_TOTEM_CATEGORIES; + for(int i= 0; i < MAX_SPELL_TOTEM_CATEGORIES; ++i) { - if (p_caster->HasItemTotemCategory(m_spellInfo->TotemCategory[i])) + if (spellTotems->TotemCategory[i] != 0) { - TotemCategory -= 1; - continue; + if (p_caster->HasItemTotemCategory(spellTotems->TotemCategory[i])) + { + TotemCategory -= 1; + continue; + } } + else + TotemCategory -= 1; } - else - TotemCategory -= 1; - } - if (TotemCategory != 0) - return SPELL_FAILED_TOTEM_CATEGORY; + if (TotemCategory != 0) + return SPELL_FAILED_TOTEM_CATEGORY; + } } // special checks for spell effects for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - switch (m_spellInfo->Effect[i]) + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + switch (spellEffect->Effect) { case SPELL_EFFECT_CREATE_ITEM: { - if (!m_IsTriggeredSpell && m_spellInfo->EffectItemType[i]) + if (!m_IsTriggeredSpell && spellEffect->EffectItemType) { // Conjure Mana Gem (skip same or low level ranks for later recharge) - if (i == EFFECT_INDEX_0 && m_spellInfo->Effect[EFFECT_INDEX_1] == SPELL_EFFECT_DUMMY) + if (i == EFFECT_INDEX_0 && m_spellInfo->GetSpellEffectIdByIndex(EFFECT_INDEX_1) == SPELL_EFFECT_DUMMY) { - if (ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(m_spellInfo->EffectItemType[i])) + if (ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(spellEffect->EffectItemType)) { if (Item* item = p_caster->GetItemByLimitedCategory(itemProto->ItemLimitCategory)) { @@ -6711,10 +6834,10 @@ SpellCastResult Spell::CheckItems() } ItemPosCountVec dest; - InventoryResult msg = p_caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->EffectItemType[i], 1); - if (msg != EQUIP_ERR_OK) + InventoryResult msg = p_caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, spellEffect->EffectItemType, 1 ); + if (msg != EQUIP_ERR_OK ) { - p_caster->SendEquipError(msg, NULL, NULL, m_spellInfo->EffectItemType[i]); + p_caster->SendEquipError( msg, NULL, NULL, spellEffect->EffectItemType ); return SPELL_FAILED_DONT_REPORT; } } @@ -6722,7 +6845,7 @@ SpellCastResult Spell::CheckItems() } case SPELL_EFFECT_RESTORE_ITEM_CHARGES: { - if (Item* item = p_caster->GetItemByEntry(m_spellInfo->EffectItemType[i])) + if (Item* item = p_caster->GetItemByEntry(spellEffect->EffectItemType)) if (item->HasMaxCharges()) return SPELL_FAILED_ITEM_AT_MAX_CHARGES; @@ -6735,13 +6858,13 @@ SpellCastResult Spell::CheckItems() if (!targetItem) return SPELL_FAILED_ITEM_NOT_FOUND; - if (targetItem->GetProto()->ItemLevel < m_spellInfo->baseLevel) + if( targetItem->GetProto()->ItemLevel < m_spellInfo->GetBaseLevel() ) return SPELL_FAILED_LOWLEVEL; // Check if we can store a new scroll, enchanting vellum has implicit SPELL_EFFECT_CREATE_ITEM - if (isVellumTarget && m_spellInfo->EffectItemType[i]) + if (isVellumTarget && spellEffect->EffectItemType) { ItemPosCountVec dest; - InventoryResult msg = p_caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->EffectItemType[i], 1); + InventoryResult msg = p_caster->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellEffect->EffectItemType, 1 ); if (msg != EQUIP_ERR_OK) { p_caster->SendEquipError(msg, NULL, NULL); @@ -6751,9 +6874,9 @@ SpellCastResult Spell::CheckItems() // Not allow enchant in trade slot for some enchant type if (targetItem->GetOwner() != m_caster) { - uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; - SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); - if (!pEnchant) + uint32 enchant_id = spellEffect->EffectMiscValue; + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!pEnchant) return SPELL_FAILED_ERROR; if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND) return SPELL_FAILED_NOT_TRADEABLE; @@ -6771,9 +6894,9 @@ SpellCastResult Spell::CheckItems() // Not allow enchant in trade slot for some enchant type if (item->GetOwner() != m_caster) { - uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; - SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); - if (!pEnchant) + uint32 enchant_id = spellEffect->EffectMiscValue; + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!pEnchant) return SPELL_FAILED_ERROR; if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND) return SPELL_FAILED_NOT_TRADEABLE; @@ -6870,46 +6993,6 @@ SpellCastResult Spell::CheckItems() if (!((Player*)m_caster)->HasItemCount(ammo, 1)) return SPELL_FAILED_NO_AMMO; }; break; - case ITEM_SUBCLASS_WEAPON_GUN: - case ITEM_SUBCLASS_WEAPON_BOW: - case ITEM_SUBCLASS_WEAPON_CROSSBOW: - { - uint32 ammo = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID); - if (!ammo) - { - // Requires No Ammo - if (m_caster->GetDummyAura(46699)) - break; // skip other checks - - return SPELL_FAILED_NO_AMMO; - } - - ItemPrototype const* ammoProto = ObjectMgr::GetItemPrototype(ammo); - if (!ammoProto) - return SPELL_FAILED_NO_AMMO; - - if (ammoProto->Class != ITEM_CLASS_PROJECTILE) - return SPELL_FAILED_NO_AMMO; - - // check ammo ws. weapon compatibility - switch (pItem->GetProto()->SubClass) - { - case ITEM_SUBCLASS_WEAPON_BOW: - case ITEM_SUBCLASS_WEAPON_CROSSBOW: - if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW) - return SPELL_FAILED_NO_AMMO; - break; - case ITEM_SUBCLASS_WEAPON_GUN: - if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET) - return SPELL_FAILED_NO_AMMO; - break; - default: - return SPELL_FAILED_NO_AMMO; - } - - if (!((Player*)m_caster)->HasItemCount(ammo, 1)) - return SPELL_FAILED_NO_AMMO; - }; break; case ITEM_SUBCLASS_WEAPON_WAND: break; default: @@ -6936,7 +7019,7 @@ void Spell::Delayed() return; // spells not loosing casting time ( slam, dynamites, bombs.. ) - if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE)) + if(!(m_spellInfo->GetInterruptFlags() & SPELL_INTERRUPT_FLAG_DAMAGE)) return; // check pushback reduce @@ -7038,10 +7121,10 @@ void Spell::UpdatePointers() bool Spell::CheckTargetCreatureType(Unit* target) const { - uint32 spellCreatureTargetMask = m_spellInfo->TargetCreatureType; + uint32 spellCreatureTargetMask = m_spellInfo->GetTargetCreatureType(); // Curse of Doom: not find another way to fix spell target check :/ - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->Category == 1179) + if (m_spellInfo->GetSpellFamilyName() == SPELLFAMILY_WARLOCK && m_spellInfo->GetCategory() == 1179) { // not allow cast at player if (target->GetTypeId() == TYPEID_PLAYER) @@ -7077,18 +7160,26 @@ CurrentSpellTypes Spell::GetCurrentContainer() bool Spell::CheckTarget(Unit* target, SpellEffectIndex eff) { + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(eff); + if(!spellEffect) + return false; + // Check targets for creature type mask and remove not appropriate (skip explicit self target case, maybe need other explicit targets) - if (m_spellInfo->EffectImplicitTargetA[eff] != TARGET_SELF) + if(spellEffect->EffectImplicitTargetA != TARGET_SELF ) { if (!CheckTargetCreatureType(target)) return false; } // Check Aura spell req (need for AoE spells) - if (m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell)) - return false; - if (m_spellInfo->excludeTargetAuraSpell && target->HasAura(m_spellInfo->excludeTargetAuraSpell)) - return false; + SpellAuraRestrictionsEntry const* auraRestrictions = m_spellInfo->GetSpellAuraRestrictions(); + if(auraRestrictions) + { + if(auraRestrictions->targetAuraSpell && !target->HasAura(auraRestrictions->targetAuraSpell)) + return false; + if (auraRestrictions->excludeTargetAuraSpell && target->HasAura(auraRestrictions->excludeTargetAuraSpell)) + return false; + } // Check targets for not_selectable unit flag and remove // A player can cast spells on his pet (or other controlled unit) though in any state @@ -7101,13 +7192,13 @@ bool Spell::CheckTarget(Unit* target, SpellEffectIndex eff) // unselectable targets skipped in all cases except TARGET_SCRIPT targeting // in case TARGET_SCRIPT target selected by server always and can't be cheated if ((!m_IsTriggeredSpell || target != m_targets.getUnitTarget()) && - target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE) && - m_spellInfo->EffectImplicitTargetA[eff] != TARGET_SCRIPT && - m_spellInfo->EffectImplicitTargetB[eff] != TARGET_SCRIPT && - m_spellInfo->EffectImplicitTargetA[eff] != TARGET_AREAEFFECT_INSTANT && - m_spellInfo->EffectImplicitTargetB[eff] != TARGET_AREAEFFECT_INSTANT && - m_spellInfo->EffectImplicitTargetA[eff] != TARGET_AREAEFFECT_CUSTOM && - m_spellInfo->EffectImplicitTargetB[eff] != TARGET_AREAEFFECT_CUSTOM) + target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE) && + spellEffect->EffectImplicitTargetA != TARGET_SCRIPT && + spellEffect->EffectImplicitTargetB != TARGET_SCRIPT && + spellEffect->EffectImplicitTargetA != TARGET_AREAEFFECT_INSTANT && + spellEffect->EffectImplicitTargetB != TARGET_AREAEFFECT_INSTANT && + spellEffect->EffectImplicitTargetA != TARGET_AREAEFFECT_CUSTOM && + spellEffect->EffectImplicitTargetB != TARGET_AREAEFFECT_CUSTOM ) return false; } @@ -7122,7 +7213,7 @@ bool Spell::CheckTarget(Unit* target, SpellEffectIndex eff) } // Check targets for LOS visibility (except spells without range limitations ) - switch (m_spellInfo->Effect[eff]) + switch(spellEffect->Effect) { case SPELL_EFFECT_SUMMON_PLAYER: // from anywhere break; @@ -7179,8 +7270,8 @@ bool Spell::IsNeedSendToClient() const bool Spell::IsTriggeredSpellWithRedundentData() const { return m_triggeredByAuraSpell || m_triggeredBySpellInfo || - // possible not need after above check? - m_IsTriggeredSpell && (m_spellInfo->manaCost || m_spellInfo->ManaCostPercentage); + // possible not need after above check? + m_IsTriggeredSpell && (m_spellInfo->GetManaCost() || m_spellInfo->GetManaCostPercentage()); } bool Spell::HaveTargetsForEffect(SpellEffectIndex effect) const @@ -7348,7 +7439,7 @@ SpellCastResult Spell::CanOpenLock(SpellEffectIndex effIndex, uint32 lockId, Ski reqKey = true; // wrong locktype, skip - if (uint32(m_spellInfo->EffectMiscValue[effIndex]) != lockInfo->Index[j]) + if(uint32(m_spellInfo->GetEffectMiscValue(effIndex)) != lockInfo->Index[j]) continue; skillId = SkillByLockType(LockType(lockInfo->Index[j])); @@ -7537,7 +7628,11 @@ void Spell::SelectMountByAreaAndSkill(Unit* target, SpellEntry const* parentSpel SpellEntry const* spellInfo = sSpellStore.LookupEntry(iter->first); for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + + if(spellEffect->EffectApplyAuraName == SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED) { int32 mountSpeed = spellInfo->CalculateSimpleValue(SpellEffectIndex(i)); @@ -7585,7 +7680,7 @@ bool Spell::HasGlobalCooldown() void Spell::TriggerGlobalCooldown() { - int32 gcd = m_spellInfo->StartRecoveryTime; + int32 gcd = m_spellInfo->GetStartRecoveryTime(); if (!gcd) return; @@ -7616,7 +7711,7 @@ void Spell::TriggerGlobalCooldown() void Spell::CancelGlobalCooldown() { - if (!m_spellInfo->StartRecoveryTime) + if (!m_spellInfo->GetStartRecoveryTime()) return; // cancel global cooldown when interrupting current cast diff --git a/src/game/Spell.h b/src/game/Spell.h index b73c2cc99..37e33c6ef 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -233,125 +233,125 @@ class Spell friend void Unit::SetCurrentCastedSpell(Spell* pSpell); public: - void EffectEmpty(SpellEffectIndex eff_idx); - void EffectNULL(SpellEffectIndex eff_idx); - void EffectUnused(SpellEffectIndex eff_idx); - void EffectDistract(SpellEffectIndex eff_idx); - void EffectPull(SpellEffectIndex eff_idx); - void EffectSchoolDMG(SpellEffectIndex eff_idx); - void EffectEnvironmentalDMG(SpellEffectIndex eff_idx); - void EffectInstaKill(SpellEffectIndex eff_idx); - void EffectDummy(SpellEffectIndex eff_idx); - void EffectTeleportUnits(SpellEffectIndex eff_idx); - void EffectApplyAura(SpellEffectIndex eff_idx); - void EffectSendEvent(SpellEffectIndex eff_idx); - void EffectPowerBurn(SpellEffectIndex eff_idx); - void EffectPowerDrain(SpellEffectIndex eff_idx); - void EffectHeal(SpellEffectIndex eff_idx); - void EffectBind(SpellEffectIndex eff_idx); - void EffectHealthLeech(SpellEffectIndex eff_idx); - void EffectQuestComplete(SpellEffectIndex eff_idx); - void EffectCreateItem(SpellEffectIndex eff_idx); - void EffectCreateItem2(SpellEffectIndex eff_idx); - void EffectCreateRandomItem(SpellEffectIndex eff_idx); - void EffectPersistentAA(SpellEffectIndex eff_idx); - void EffectEnergize(SpellEffectIndex eff_idx); - void EffectOpenLock(SpellEffectIndex eff_idx); - void EffectSummonChangeItem(SpellEffectIndex eff_idx); - void EffectProficiency(SpellEffectIndex eff_idx); - void EffectApplyAreaAura(SpellEffectIndex eff_idx); - void EffectSummonType(SpellEffectIndex eff_idx); - void EffectLearnSpell(SpellEffectIndex eff_idx); - void EffectDispel(SpellEffectIndex eff_idx); - void EffectDualWield(SpellEffectIndex eff_idx); - void EffectPickPocket(SpellEffectIndex eff_idx); - void EffectAddFarsight(SpellEffectIndex eff_idx); - void EffectHealMechanical(SpellEffectIndex eff_idx); - void EffectJump(SpellEffectIndex eff_idx); - void EffectTeleUnitsFaceCaster(SpellEffectIndex eff_idx); - void EffectLearnSkill(SpellEffectIndex eff_idx); - void EffectAddHonor(SpellEffectIndex eff_idx); - void EffectTradeSkill(SpellEffectIndex eff_idx); - void EffectEnchantItemPerm(SpellEffectIndex eff_idx); - void EffectEnchantItemTmp(SpellEffectIndex eff_idx); - void EffectTameCreature(SpellEffectIndex eff_idx); - void EffectSummonPet(SpellEffectIndex eff_idx); - void EffectLearnPetSpell(SpellEffectIndex eff_idx); - void EffectWeaponDmg(SpellEffectIndex eff_idx); - void EffectClearQuest(SpellEffectIndex eff_idx); - void EffectForceCast(SpellEffectIndex eff_idx); - void EffectTriggerSpell(SpellEffectIndex eff_idx); - void EffectTriggerMissileSpell(SpellEffectIndex eff_idx); - void EffectThreat(SpellEffectIndex eff_idx); - void EffectRestoreItemCharges(SpellEffectIndex eff_idx); - void EffectHealMaxHealth(SpellEffectIndex eff_idx); - void EffectInterruptCast(SpellEffectIndex eff_idx); - void EffectSummonObjectWild(SpellEffectIndex eff_idx); - void EffectScriptEffect(SpellEffectIndex eff_idx); - void EffectSanctuary(SpellEffectIndex eff_idx); - void EffectAddComboPoints(SpellEffectIndex eff_idx); - void EffectDuel(SpellEffectIndex eff_idx); - void EffectStuck(SpellEffectIndex eff_idx); - void EffectSummonPlayer(SpellEffectIndex eff_idx); - void EffectActivateObject(SpellEffectIndex eff_idx); - void EffectApplyGlyph(SpellEffectIndex eff_idx); - void EffectEnchantHeldItem(SpellEffectIndex eff_idx); - void EffectSummonObject(SpellEffectIndex eff_idx); - void EffectResurrect(SpellEffectIndex eff_idx); - void EffectParry(SpellEffectIndex eff_idx); - void EffectBlock(SpellEffectIndex eff_idx); - void EffectLeapForward(SpellEffectIndex eff_idx); - void EffectLeapBack(SpellEffectIndex eff_idx); - void EffectTransmitted(SpellEffectIndex eff_idx); - void EffectDisEnchant(SpellEffectIndex eff_idx); - void EffectInebriate(SpellEffectIndex eff_idx); - void EffectFeedPet(SpellEffectIndex eff_idx); - void EffectDismissPet(SpellEffectIndex eff_idx); - void EffectReputation(SpellEffectIndex eff_idx); - void EffectSelfResurrect(SpellEffectIndex eff_idx); - void EffectSkinning(SpellEffectIndex eff_idx); - void EffectCharge(SpellEffectIndex eff_idx); - void EffectCharge2(SpellEffectIndex eff_idx); - void EffectProspecting(SpellEffectIndex eff_idx); - void EffectRedirectThreat(SpellEffectIndex eff_idx); - void EffectMilling(SpellEffectIndex eff_idx); - void EffectRenamePet(SpellEffectIndex eff_idx); - void EffectSendTaxi(SpellEffectIndex eff_idx); - void EffectKnockBack(SpellEffectIndex eff_idx); - void EffectPlayerPull(SpellEffectIndex eff_idx); - void EffectDispelMechanic(SpellEffectIndex eff_idx); - void EffectSummonDeadPet(SpellEffectIndex eff_idx); - void EffectSummonAllTotems(SpellEffectIndex eff_idx); - void EffectBreakPlayerTargeting(SpellEffectIndex eff_idx); - void EffectDestroyAllTotems(SpellEffectIndex eff_idx); - void EffectDurabilityDamage(SpellEffectIndex eff_idx); - void EffectSkill(SpellEffectIndex eff_idx); - void EffectTaunt(SpellEffectIndex eff_idx); - void EffectDurabilityDamagePCT(SpellEffectIndex eff_idx); - void EffectModifyThreatPercent(SpellEffectIndex eff_idx); - void EffectResurrectNew(SpellEffectIndex eff_idx); - void EffectAddExtraAttacks(SpellEffectIndex eff_idx); - void EffectSpiritHeal(SpellEffectIndex eff_idx); - void EffectSkinPlayerCorpse(SpellEffectIndex eff_idx); - void EffectStealBeneficialBuff(SpellEffectIndex eff_idx); - void EffectUnlearnSpecialization(SpellEffectIndex eff_idx); - void EffectHealPct(SpellEffectIndex eff_idx); - void EffectEnergisePct(SpellEffectIndex eff_idx); - void EffectTriggerSpellWithValue(SpellEffectIndex eff_idx); - void EffectTriggerRitualOfSummoning(SpellEffectIndex eff_idx); - void EffectKillCreditPersonal(SpellEffectIndex eff_idx); - void EffectKillCreditGroup(SpellEffectIndex eff_idx); - void EffectQuestFail(SpellEffectIndex eff_idx); - void EffectQuestOffer(SpellEffectIndex eff_idx); - void EffectActivateRune(SpellEffectIndex eff_idx); - void EffectTeachTaxiNode(SpellEffectIndex eff_idx); - void EffectTitanGrip(SpellEffectIndex eff_idx); - void EffectEnchantItemPrismatic(SpellEffectIndex eff_idx); - void EffectPlaySound(SpellEffectIndex eff_idx); - void EffectPlayMusic(SpellEffectIndex eff_idx); - void EffectSpecCount(SpellEffectIndex eff_idx); - void EffectActivateSpec(SpellEffectIndex eff_idx); - void EffectCancelAura(SpellEffectIndex eff_idx); + void EffectEmpty(SpellEffectEntry const* effect); + void EffectNULL(SpellEffectEntry const* effect); + void EffectUnused(SpellEffectEntry const* effect); + void EffectDistract(SpellEffectEntry const* effect); + void EffectPull(SpellEffectEntry const* effect); + void EffectSchoolDMG(SpellEffectEntry const* effect); + void EffectEnvironmentalDMG(SpellEffectEntry const* effect); + void EffectInstaKill(SpellEffectEntry const* effect); + void EffectDummy(SpellEffectEntry const* effect); + void EffectTeleportUnits(SpellEffectEntry const* effect); + void EffectApplyAura(SpellEffectEntry const* effect); + void EffectSendEvent(SpellEffectEntry const* effect); + void EffectPowerBurn(SpellEffectEntry const* effect); + void EffectPowerDrain(SpellEffectEntry const* effect); + void EffectHeal(SpellEffectEntry const* effect); + void EffectBind(SpellEffectEntry const* effect); + void EffectHealthLeech(SpellEffectEntry const* effect); + void EffectQuestComplete(SpellEffectEntry const* effect); + void EffectCreateItem(SpellEffectEntry const* effect); + void EffectCreateItem2(SpellEffectEntry const* effect); + void EffectCreateRandomItem(SpellEffectEntry const* effect); + void EffectPersistentAA(SpellEffectEntry const* effect); + void EffectEnergize(SpellEffectEntry const* effect); + void EffectOpenLock(SpellEffectEntry const* effect); + void EffectSummonChangeItem(SpellEffectEntry const* effect); + void EffectProficiency(SpellEffectEntry const* effect); + void EffectApplyAreaAura(SpellEffectEntry const* effect); + void EffectSummonType(SpellEffectEntry const* effect); + void EffectLearnSpell(SpellEffectEntry const* effect); + void EffectDispel(SpellEffectEntry const* effect); + void EffectDualWield(SpellEffectEntry const* effect); + void EffectPickPocket(SpellEffectEntry const* effect); + void EffectAddFarsight(SpellEffectEntry const* effect); + void EffectHealMechanical(SpellEffectEntry const* effect); + void EffectJump(SpellEffectEntry const* effect); + void EffectTeleUnitsFaceCaster(SpellEffectEntry const* effect); + void EffectLearnSkill(SpellEffectEntry const* effect); + void EffectAddHonor(SpellEffectEntry const* effect); + void EffectTradeSkill(SpellEffectEntry const* effect); + void EffectEnchantItemPerm(SpellEffectEntry const* effect); + void EffectEnchantItemTmp(SpellEffectEntry const* effect); + void EffectTameCreature(SpellEffectEntry const* effect); + void EffectSummonPet(SpellEffectEntry const* effect); + void EffectLearnPetSpell(SpellEffectEntry const* effect); + void EffectWeaponDmg(SpellEffectEntry const* effect); + void EffectClearQuest(SpellEffectEntry const* effect); + void EffectForceCast(SpellEffectEntry const* effect); + void EffectTriggerSpell(SpellEffectEntry const* effect); + void EffectTriggerMissileSpell(SpellEffectEntry const* effect); + void EffectThreat(SpellEffectEntry const* effect); + void EffectRestoreItemCharges(SpellEffectEntry const* effect); + void EffectHealMaxHealth(SpellEffectEntry const* effect); + void EffectInterruptCast(SpellEffectEntry const* effect); + void EffectSummonObjectWild(SpellEffectEntry const* effect); + void EffectScriptEffect(SpellEffectEntry const* effect); + void EffectSanctuary(SpellEffectEntry const* effect); + void EffectAddComboPoints(SpellEffectEntry const* effect); + void EffectDuel(SpellEffectEntry const* effect); + void EffectStuck(SpellEffectEntry const* effect); + void EffectSummonPlayer(SpellEffectEntry const* effect); + void EffectActivateObject(SpellEffectEntry const* effect); + void EffectApplyGlyph(SpellEffectEntry const* effect); + void EffectEnchantHeldItem(SpellEffectEntry const* effect); + void EffectSummonObject(SpellEffectEntry const* effect); + void EffectResurrect(SpellEffectEntry const* effect); + void EffectParry(SpellEffectEntry const* effect); + void EffectBlock(SpellEffectEntry const* effect); + void EffectLeapForward(SpellEffectEntry const* effect); + void EffectLeapBack(SpellEffectEntry const* effect); + void EffectTransmitted(SpellEffectEntry const* effect); + void EffectDisEnchant(SpellEffectEntry const* effect); + void EffectInebriate(SpellEffectEntry const* effect); + void EffectFeedPet(SpellEffectEntry const* effect); + void EffectDismissPet(SpellEffectEntry const* effect); + void EffectReputation(SpellEffectEntry const* effect); + void EffectSelfResurrect(SpellEffectEntry const* effect); + void EffectSkinning(SpellEffectEntry const* effect); + void EffectCharge(SpellEffectEntry const* effect); + void EffectCharge2(SpellEffectEntry const* effect); + void EffectProspecting(SpellEffectEntry const* effect); + void EffectRedirectThreat(SpellEffectEntry const* effect); + void EffectMilling(SpellEffectEntry const* effect); + void EffectRenamePet(SpellEffectEntry const* effect); + void EffectSendTaxi(SpellEffectEntry const* effect); + void EffectKnockBack(SpellEffectEntry const* effect); + void EffectPlayerPull(SpellEffectEntry const* effect); + void EffectDispelMechanic(SpellEffectEntry const* effect); + void EffectSummonDeadPet(SpellEffectEntry const* effect); + void EffectSummonAllTotems(SpellEffectEntry const* effect); + void EffectBreakPlayerTargeting (SpellEffectEntry const* effect); + void EffectDestroyAllTotems(SpellEffectEntry const* effect); + void EffectDurabilityDamage(SpellEffectEntry const* effect); + void EffectSkill(SpellEffectEntry const* effect); + void EffectTaunt(SpellEffectEntry const* effect); + void EffectDurabilityDamagePCT(SpellEffectEntry const* effect); + void EffectModifyThreatPercent(SpellEffectEntry const* effect); + void EffectResurrectNew(SpellEffectEntry const* effect); + void EffectAddExtraAttacks(SpellEffectEntry const* effect); + void EffectSpiritHeal(SpellEffectEntry const* effect); + void EffectSkinPlayerCorpse(SpellEffectEntry const* effect); + void EffectStealBeneficialBuff(SpellEffectEntry const* effect); + void EffectUnlearnSpecialization(SpellEffectEntry const* effect); + void EffectHealPct(SpellEffectEntry const* effect); + void EffectEnergisePct(SpellEffectEntry const* effect); + void EffectTriggerSpellWithValue(SpellEffectEntry const* effect); + void EffectTriggerRitualOfSummoning(SpellEffectEntry const* effect); + void EffectKillCreditPersonal(SpellEffectEntry const* effect); + void EffectKillCreditGroup(SpellEffectEntry const* effect); + void EffectQuestFail(SpellEffectEntry const* effect); + void EffectQuestOffer(SpellEffectEntry const* effect); + void EffectActivateRune(SpellEffectEntry const* effect); + void EffectTeachTaxiNode(SpellEffectEntry const* effect); + void EffectTitanGrip(SpellEffectEntry const* effect); + void EffectEnchantItemPrismatic(SpellEffectEntry const* effect); + void EffectPlaySound(SpellEffectEntry const* effect); + void EffectPlayMusic(SpellEffectEntry const* effect); + void EffectSpecCount(SpellEffectEntry const* effect); + void EffectActivateSpec(SpellEffectEntry const* effect); + void EffectCancelAura(SpellEffectEntry const* effect); Spell(Unit* caster, SpellEntry const* info, bool triggered, ObjectGuid originalCasterGUID = ObjectGuid(), SpellEntry const* triggeredBy = NULL); ~Spell(); @@ -392,7 +392,7 @@ class Spell uint32 getState() const { return m_spellState; } void setState(uint32 state) { m_spellState = state; } - void DoCreateItem(SpellEffectIndex eff_idx, uint32 itemtype); + void DoCreateItem(SpellEffectEntry const* effect, uint32 itemtype); void WriteSpellGoTargets(WorldPacket* data); void WriteAmmoToPacket(WorldPacket* data); @@ -429,6 +429,7 @@ class Spell SpellEntry const* m_spellInfo; SpellEntry const* m_triggeredBySpellInfo; + SpellInterruptsEntry const* m_spellInterrupts; int32 m_currentBasePoints[MAX_EFFECT_INDEX]; // cache SpellEntry::CalculateSimpleValue and use for set custom base points Item* m_CastItem; uint8 m_cast_count; @@ -449,8 +450,8 @@ class Spell return m_spellInfo->HasAttribute(SPELL_ATTR_RANGED); } bool IsChannelActive() const { return m_caster->GetUInt32Value(UNIT_CHANNEL_SPELL) != 0; } - bool IsMeleeAttackResetSpell() const { return !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK); } - bool IsRangedAttackResetSpell() const { return !m_IsTriggeredSpell && IsRangedSpell() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK); } + bool IsMeleeAttackResetSpell() const { return !m_IsTriggeredSpell && m_spellInterrupts && (m_spellInterrupts->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK); } + bool IsRangedAttackResetSpell() const { return !m_IsTriggeredSpell && IsRangedSpell() && m_spellInterrupts && (m_spellInterrupts->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK); } bool IsDeletable() const { return !m_referencedFromCurrentSpell && !m_executedCurrently; } void SetReferencedFromCurrent(bool yes) { m_referencedFromCurrentSpell = yes; } @@ -460,7 +461,7 @@ class Spell uint64 GetDelayMoment() const { return m_delayMoment; } bool IsNeedSendToClient() const; // use for hide spell cast for client in case when cast not have client side affect (animation or log entries) - bool IsTriggeredSpellWithRedundentData() const; // use for ignore some spell data for triggered spells like cast time, some triggered spells have redundent copy data from main spell for client use purpose + bool IsTriggeredSpellWithRedundentData() const; // use for ignore some spell data for triggered spells like cast time, some triggered spells have redundant copy data from main spell for client use purpose CurrentSpellTypes GetCurrentContainer(); @@ -659,12 +660,12 @@ class Spell typedef std::vector CreatureSummonPositions; // return true IFF further processing required - bool DoSummonPet(SpellEffectIndex eff_idx); - bool DoSummonTotem(SpellEffectIndex eff_idx, uint8 slot_dbc = 0); - bool DoSummonWild(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectIndex effIdx, uint32 level); - bool DoSummonCritter(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectIndex effIdx, uint32 level); - bool DoSummonGuardian(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectIndex effIdx, uint32 level); - bool DoSummonPossessed(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectIndex effIdx, uint32 level); + bool DoSummonPet(SpellEffectEntry const* effect); + bool DoSummonTotem(SpellEffectEntry const* effect, uint8 slot_dbc = 0); + bool DoSummonWild(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectEntry const* effect, uint32 level); + bool DoSummonCritter(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectEntry const* effect, uint32 level); + bool DoSummonGuardian(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectEntry const* effect, uint32 level); + bool DoSummonPossessed(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectEntry const* effect, uint32 level); }; enum ReplenishType @@ -889,7 +890,7 @@ namespace MaNGOS #endif } -typedef void(Spell::*pEffect)(SpellEffectIndex eff_idx); +typedef void(Spell::*pEffect)(SpellEffectEntry const* spellEffect); class SpellEvent : public BasicEvent { diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 5672eaa9b..5e16a5048 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -380,7 +380,11 @@ Aura::Aura(SpellEntry const* spellproto, SpellEffectIndex eff, int32* currentBas MANGOS_ASSERT(target); MANGOS_ASSERT(spellproto && spellproto == sSpellStore.LookupEntry(spellproto->Id) && "`info` must be pointer to sSpellStore element"); - m_currentBasePoints = currentBasePoints ? *currentBasePoints : spellproto->CalculateSimpleValue(eff); + m_spellEffect = spellproto->GetSpellEffect(m_effIndex); + + MANGOS_ASSERT(m_spellEffect); // need testing... + + m_currentBasePoints = currentBasePoints ? *currentBasePoints : m_spellEffect->CalculateSimpleValue(); m_positive = IsPositiveEffect(spellproto, m_effIndex); m_applyTime = time(NULL); @@ -420,10 +424,9 @@ Aura::Aura(SpellEntry const* spellproto, SpellEffectIndex eff, int32* currentBas } damage *= holder->GetStackAmount(); + DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Aura: construct Spellid : %u, Aura : %u Target : %d Damage : %d", spellproto->Id, m_spellEffect->EffectApplyAuraName, m_spellEffect->EffectImplicitTargetA, damage); - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Aura: construct Spellid : %u, Aura : %u Target : %d Damage : %d", spellproto->Id, spellproto->EffectApplyAuraName[eff], spellproto->EffectImplicitTargetA[eff], damage); - - SetModifier(AuraType(spellproto->EffectApplyAuraName[eff]), damage, spellproto->EffectAmplitude[eff], spellproto->EffectMiscValue[eff]); + SetModifier(AuraType(m_spellEffect->EffectApplyAuraName), damage, m_spellEffect->EffectAmplitude, m_spellEffect->EffectMiscValue); Player* modOwner = caster ? caster->GetSpellModOwner() : NULL; @@ -448,11 +451,11 @@ AreaAura::AreaAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32* cu // caster==NULL in constructor args if target==caster in fact Unit* caster_ptr = caster ? caster : target; - m_radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellproto->EffectRadiusIndex[m_effIndex])); - if (Player* modOwner = caster_ptr->GetSpellModOwner()) + m_radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellEffect->EffectRadiusIndex)); + if(Player* modOwner = caster_ptr->GetSpellModOwner()) modOwner->ApplySpellMod(spellproto->Id, SPELLMOD_RADIUS, m_radius); - switch (spellproto->Effect[eff]) + switch(m_spellEffect->Effect) { case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: m_areaAuraType = AREA_AURA_PARTY; @@ -522,16 +525,22 @@ Unit* SingleEnemyTargetAura::GetTriggerTarget() const Aura* CreateAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32* currentBasePoints, SpellAuraHolder* holder, Unit* target, Unit* caster, Item* castItem) { - if (IsAreaAuraEffect(spellproto->Effect[eff])) + SpellEffectEntry const* effectEntry = spellproto->GetSpellEffect(eff); + + if (effectEntry && IsAreaAuraEffect(effectEntry->Effect)) return new AreaAura(spellproto, eff, currentBasePoints, holder, target, caster, castItem); - uint32 triggeredSpellId = spellproto->EffectTriggerSpell[eff]; + uint32 triggeredSpellId = effectEntry ? effectEntry->EffectTriggerSpell : 0; - if (SpellEntry const* triggeredSpellInfo = sSpellStore.LookupEntry(triggeredSpellId)) + if(SpellEntry const* triggeredSpellInfo = sSpellStore.LookupEntry(triggeredSpellId)) + { for (int i = 0; i < MAX_EFFECT_INDEX; ++i) - if (triggeredSpellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_ENEMY) + { + SpellEffectEntry const* triggeredeffectEntry = triggeredSpellInfo->GetSpellEffect(SpellEffectIndex(i)); + if (triggeredeffectEntry && triggeredeffectEntry->EffectImplicitTargetA == TARGET_SINGLE_ENEMY) return new SingleEnemyTargetAura(spellproto, eff, currentBasePoints, holder, target, caster, castItem); - + } + } return new Aura(spellproto, eff, currentBasePoints, holder, target, caster, castItem); } @@ -855,7 +864,7 @@ void Aura::ApplyModifier(bool apply, bool Real) bool Aura::isAffectedOnSpell(SpellEntry const* spell) const { - return spell->IsFitToFamily(SpellFamily(GetSpellProto()->SpellFamilyName), GetAuraSpellClassMask()); + return spell->IsFitToFamily(GetSpellProto()->GetSpellFamilyName(), GetAuraSpellClassMask()); } bool Aura::CanProcFrom(SpellEntry const* spell, uint32 /*procFlag*/, uint32 EventProcEx, uint32 procEx, bool active, bool useClassMask) const @@ -902,7 +911,11 @@ bool Aura::CanProcFrom(SpellEntry const* spell, uint32 /*procFlag*/, uint32 Even { // SpellFamilyName check is performed in SpellMgr::IsSpellProcEventCanTriggeredBy and it is done once for whole holder // note: SpellFamilyName is not checked if no spell_proc_event is defined - return mask.IsFitToFamilyMask(spell->SpellFamilyFlags); + SpellClassOptionsEntry const* classOpt = spell->GetSpellClassOptions(); + if(!classOpt) + return true; + + return mask.IsFitToFamilyMask(classOpt->SpellFamilyFlags); } } @@ -966,7 +979,7 @@ struct ReapplyAffectedPassiveAurasHelper void Aura::ReapplyAffectedPassiveAuras() { // not reapply spell mods with charges (use original value because processed and at remove) - if (GetSpellProto()->procCharges) + if (GetSpellProto()->GetProcCharges()) return; // not reapply some spell mods ops (mostly speedup case) @@ -1030,21 +1043,26 @@ void Aura::HandleAddModifier(bool apply, bool Real) break; } + m_spellmod = new SpellModifier( + SpellModOp(m_modifier.m_miscvalue), + SpellModType(m_modifier.m_auraname), // SpellModType value == spell aura types + m_modifier.m_amount, + this, + // prevent expire spell mods with (charges > 0 && m_stackAmount > 1) + // all this spell expected expire not at use but at spell proc event check + GetSpellProto()->GetStackAmount() > 1 ? 0 : GetHolder()->GetAuraCharges()); + // Everlasting Affliction, overwrite wrong data, if will need more better restore support of spell_affect table - if (spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && spellProto->SpellIconID == 3169) + if (spellProto->GetSpellFamilyName() == SPELLFAMILY_WARLOCK && spellProto->SpellIconID == 3169) { // Corruption and Unstable Affliction - // TODO: drop when override will be possible - SpellEntry* entry = const_cast(spellProto); - entry->EffectSpellClassMask[GetEffIndex()].Flags = UI64LIT(0x0000010000000002); + m_spellmod->mask = ClassFamilyMask(UI64LIT(0x0000010000000002)); } // Improved Flametongue Weapon, overwrite wrong data, maybe time re-add table else if (spellProto->Id == 37212) { // Flametongue Weapon (Passive) - // TODO: drop when override will be possible - SpellEntry* entry = const_cast(spellProto); - entry->EffectSpellClassMask[GetEffIndex()].Flags = UI64LIT(0x0000000000200000); + m_spellmod->mask = ClassFamilyMask(UI64LIT(0x0000000000200000)); } } @@ -1062,7 +1080,7 @@ void Aura::TriggerSpell() return; // generic casting code with custom spells and target/caster customs - uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex]; + uint32 trigger_spell_id = m_spellEffect->EffectTriggerSpell; SpellEntry const* triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id); SpellEntry const* auraSpellInfo = GetSpellProto(); @@ -1074,7 +1092,7 @@ void Aura::TriggerSpell() // specific code for cases with no trigger spell provided in field if (triggeredSpellInfo == NULL) { - switch (auraSpellInfo->SpellFamilyName) + switch(auraSpellInfo->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { @@ -1863,8 +1881,7 @@ void Aura::TriggerSpell() for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { SpellEntry const* spell = itr->second->GetSpellProto(); - if (spell->SpellFamilyName == SPELLFAMILY_SHAMAN && - (spell->SpellFamilyFlags & UI64LIT(0x0000000000000400))) + if (spell->IsFitToFamily(SPELLFAMILY_SHAMAN, UI64LIT(0x0000000000000400))) return; } triggerTarget->RemoveAurasDueToSpell(28820); @@ -1892,9 +1909,11 @@ void Aura::TriggerSpell() } else // initial triggeredSpellInfo != NULL { + SpellEffectEntry const* spellEffect = GetSpellProto()->GetSpellEffect(GetEffIndex()); + // for channeled spell cast applied from aura owner to channel target (persistent aura affects already applied to true target) // come periodic casts applied to targets, so need seelct proper caster (ex. 15790) - if (IsChanneledSpell(GetSpellProto()) && GetSpellProto()->Effect[GetEffIndex()] != SPELL_EFFECT_PERSISTENT_AREA_AURA) + if (IsChanneledSpell(GetSpellProto()) && (spellEffect && spellEffect->Effect != SPELL_EFFECT_PERSISTENT_AREA_AURA)) { // interesting 2 cases: periodic aura at caster of channeled spell if (target->GetObjectGuid() == casterGUID) @@ -2003,6 +2022,34 @@ void Aura::TriggerSpell() } } + // for channeled spell cast applied from aura owner to channel target (persistent aura affects already applied to true target) + // come periodic casts applied to targets, so need seelct proper caster (ex. 15790) + if (IsChanneledSpell(GetSpellProto()) && GetSpellProto()->GetSpellEffectIdByIndex(GetEffIndex()) != SPELL_EFFECT_PERSISTENT_AREA_AURA) + { + // interesting 2 cases: periodic aura at caster of channeled spell + if (target->GetObjectGuid() == casterGUID) + { + triggerCaster = target; + + if (WorldObject* channelTarget = target->GetMap()->GetWorldObject(target->GetChannelObjectGuid())) + { + if (channelTarget->isType(TYPEMASK_UNIT)) + triggerTarget = (Unit*)channelTarget; + else + triggerTargetObject = channelTarget; + } + } + // or periodic aura at caster channel target + else if (Unit* caster = GetCaster()) + { + if (target->GetObjectGuid() == caster->GetChannelObjectGuid()) + { + triggerCaster = caster; + triggerTarget = target; + } + } + } + // All ok cast by default case if (triggeredSpellInfo) { @@ -2031,7 +2078,7 @@ void Aura::TriggerSpellWithValue() return; // generic casting code with custom spells and target/caster customs - uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex]; + uint32 trigger_spell_id = m_spellEffect->EffectTriggerSpell; int32 basepoints0 = GetModifier()->m_amount; target->CastCustomSpell(target, trigger_spell_id, &basepoints0, NULL, NULL, true, NULL, this, casterGuid); @@ -2049,10 +2096,12 @@ void Aura::HandleAuraDummy(bool apply, bool Real) Unit* target = GetTarget(); + SpellClassOptionsEntry const* classOptions = GetSpellProto()->GetSpellClassOptions(); + // AT APPLY if (apply) { - switch (GetSpellProto()->SpellFamilyName) + switch(GetSpellProto()->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { @@ -2353,7 +2402,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) } // Overpower - if (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000004)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000000004)) { // Must be casting target if (!target->IsNonMeleeSpellCasted(false)) @@ -2367,7 +2416,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) for (Unit::AuraList::const_iterator itr = modifierAuras.begin(); itr != modifierAuras.end(); ++itr) { // Unrelenting Assault - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARRIOR && (*itr)->GetSpellProto()->SpellIconID == 2775) + if ((*itr)->GetSpellProto()->GetSpellFamilyName()==SPELLFAMILY_WARRIOR && (*itr)->GetSpellProto()->SpellIconID == 2775) { switch ((*itr)->GetSpellProto()->Id) { @@ -2409,7 +2458,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) } // Earth Shield - if ((GetSpellProto()->SpellFamilyFlags & UI64LIT(0x40000000000))) + if (classOptions && (classOptions->SpellFamilyFlags & UI64LIT(0x40000000000))) { // prevent double apply bonuses if (target->GetTypeId() != TYPEID_PLAYER || !((Player*)target)->GetSession()->PlayerLoading()) @@ -2743,7 +2792,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) } // Living Bomb - if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_MAGE && (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x2000000000000))) + if (classOptions && classOptions->SpellFamilyName == SPELLFAMILY_MAGE && (classOptions->SpellFamilyFlags & UI64LIT(0x2000000000000))) { if (m_removeMode == AURA_REMOVE_BY_EXPIRE || m_removeMode == AURA_REMOVE_BY_DISPEL) target->CastSpell(target, m_modifier.m_amount, true, NULL, this); @@ -2753,8 +2802,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) } // AT APPLY & REMOVE - - switch (GetSpellProto()->SpellFamilyName) + switch(GetSpellProto()->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { @@ -2965,7 +3013,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) case SPELLFAMILY_WARLOCK: { // Haunt - if (GetSpellProto()->SpellIconID == 3172 && (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0004000000000000))) + if (classOptions && GetSpellProto()->SpellIconID == 3172 && (classOptions->SpellFamilyFlags & UI64LIT(0x0004000000000000))) { // NOTE: for avoid use additional field damage stored in dummy value (replace unused 100% if (apply) @@ -3014,7 +3062,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) } // Lifebloom - if (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x1000000000)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x1000000000)) { if (apply) { @@ -3042,7 +3090,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) if (Unit* caster = GetCaster()) { - int32 returnmana = (GetSpellProto()->ManaCostPercentage * caster->GetCreateMana() / 100) * GetStackAmount() / 2; + int32 returnmana = (GetSpellProto()->GetManaCostPercentage() * caster->GetCreateMana() / 100) * GetStackAmount() / 2; caster->CastCustomSpell(caster, 64372, &returnmana, NULL, NULL, true, NULL, this, GetCasterGuid()); } } @@ -3350,9 +3398,9 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real) // If spell that caused this aura has Croud Control or Daze effect if ((aurMechMask & MECHANIC_NOT_REMOVED_BY_SHAPESHIFT) || - // some Daze spells have these parameters instead of MECHANIC_DAZE (skip snare spells) - (aurSpellInfo->SpellIconID == 15 && aurSpellInfo->Dispel == 0 && - (aurMechMask & (1 << (MECHANIC_SNARE - 1))) == 0)) + // some Daze spells have these parameters instead of MECHANIC_DAZE (skip snare spells) + (aurSpellInfo->SpellIconID == 15 && aurSpellInfo->GetDispel() == 0 && + (aurMechMask & (1 << (MECHANIC_SNARE-1))) == 0)) { ++iter; continue; @@ -3454,11 +3502,9 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real) PlayerSpellMap const& sp_list = ((Player*)target)->GetSpellMap(); for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) { - if (itr->second.state == PLAYERSPELL_REMOVED) - continue; - - SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->first); - if (spellInfo && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && spellInfo->SpellIconID == 139) + if(itr->second.state == PLAYERSPELL_REMOVED) continue; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); + if (spellInfo && spellInfo->GetSpellFamilyName() == SPELLFAMILY_WARRIOR && spellInfo->SpellIconID == 139) Rage_val += target->CalculateSpellDamage(target, spellInfo, EFFECT_INDEX_0) * 10; } } @@ -3759,7 +3805,7 @@ void Aura::HandleAuraTransform(bool apply, bool Real) model_id = Creature::ChooseDisplayId(ci); // Will use the default model here // Polymorph (sheep/penguin case) - if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_MAGE && GetSpellProto()->SpellIconID == 82) + if (GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_MAGE && GetSpellProto()->SpellIconID == 82) if (Unit* caster = GetCaster()) if (caster->HasAura(52648)) // Glyph of the Penguin model_id = 26452; @@ -3866,7 +3912,7 @@ void Aura::HandleAuraModSkill(bool apply, bool /*Real*/) if (GetTarget()->GetTypeId() != TYPEID_PLAYER) return; - uint32 prot = GetSpellProto()->EffectMiscValue[m_effIndex]; + uint32 prot = m_spellEffect->EffectMiscValue; int32 points = GetModifier()->m_amount; ((Player*)GetTarget())->ModifySkillBonus(prot, (apply ? points : -points), m_modifier.m_auraname == SPELL_AURA_MOD_SKILL_TALENT); @@ -3884,8 +3930,7 @@ void Aura::HandleChannelDeathItem(bool apply, bool Real) if (m_modifier.m_amount <= 0) return; - SpellEntry const* spellInfo = GetSpellProto(); - if (spellInfo->EffectItemType[m_effIndex] == 0) + if(m_spellEffect->EffectItemType == 0) return; Unit* victim = GetTarget(); @@ -3894,7 +3939,7 @@ void Aura::HandleChannelDeathItem(bool apply, bool Real) return; // Soul Shard (target req.) - if (spellInfo->EffectItemType[m_effIndex] == 6265) + if (m_spellEffect->EffectItemType == 6265) { // Only from non-grey units if (!((Player*)caster)->isHonorOrXPTarget(victim) || @@ -3907,20 +3952,20 @@ void Aura::HandleChannelDeathItem(bool apply, bool Real) uint32 count = m_modifier.m_amount; ItemPosCountVec dest; - InventoryResult msg = ((Player*)caster)->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], count, &noSpaceForCount); - if (msg != EQUIP_ERR_OK) + InventoryResult msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, m_spellEffect->EffectItemType, count, &noSpaceForCount); + if( msg != EQUIP_ERR_OK ) { - count -= noSpaceForCount; - ((Player*)caster)->SendEquipError(msg, NULL, NULL, spellInfo->EffectItemType[m_effIndex]); - if (count == 0) + count-=noSpaceForCount; + ((Player*)caster)->SendEquipError( msg, NULL, NULL, m_spellEffect->EffectItemType ); + if (count==0) return; } - Item* newitem = ((Player*)caster)->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], true); + Item* newitem = ((Player*)caster)->StoreNewItem(dest, m_spellEffect->EffectItemType, true); ((Player*)caster)->SendNewItem(newitem, count, true, true); // Soul Shard (glyph bonus) - if (spellInfo->EffectItemType[m_effIndex] == 6265) + if (m_spellEffect->EffectItemType == 6265) { // Glyph of Soul Shard if (caster->HasAura(58070) && roll_chance_i(40)) @@ -4470,7 +4515,8 @@ void Aura::HandleAuraModStun(bool apply, bool Real) } // Wyvern Sting - if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000100000000000)) + SpellClassOptionsEntry const* classOptions = GetSpellProto()->GetSpellClassOptions(); + if (classOptions && classOptions->SpellFamilyName == SPELLFAMILY_HUNTER && classOptions->SpellFamilyFlags & UI64LIT(0x0000100000000000)) { Unit* caster = GetCaster(); if (!caster || caster->GetTypeId() != TYPEID_PLAYER) @@ -4506,6 +4552,8 @@ void Aura::HandleModStealth(bool apply, bool Real) { Unit* target = GetTarget(); + SpellClassOptionsEntry const* classOptions = GetSpellProto()->GetSpellClassOptions(); + if (apply) { // drop flag at stealth in bg @@ -4540,7 +4588,7 @@ void Aura::HandleModStealth(bool apply, bool Real) target->CastCustomSpell(target, 31665, &bp, NULL, NULL, true); } // Overkill - else if ((*i)->GetId() == 58426 && GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000400000)) + else if ((*i)->GetId() == 58426 && classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000400000)) { target->CastSpell(target, 58427, true); } @@ -4579,7 +4627,7 @@ void Aura::HandleModStealth(bool apply, bool Real) if ((*i)->GetSpellProto()->SpellIconID == 2114) target->CastSpell(target, 31666, true); // Overkill - else if ((*i)->GetId() == 58426 && GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000400000)) + else if ((*i)->GetId() == 58426 && classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000400000)) { if (SpellAuraHolder* holder = target->GetSpellAuraHolder(58427)) { @@ -4766,7 +4814,7 @@ void Aura::HandleAuraModSilence(bool apply, bool Real) // Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i) if (Spell* spell = target->GetCurrentSpell(CurrentSpellTypes(i))) - if (spell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) + if(spell->m_spellInfo->GetPreventionType() == SPELL_PREVENTION_TYPE_SILENCE) // Stop spells on prepare or casting state target->InterruptSpell(CurrentSpellTypes(i), false); } @@ -4954,7 +5002,8 @@ void Aura::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real) SpellEntry const* spellInfo = sSpellStore.LookupEntry(iter->first); for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED) + SpellEffectEntry const* effectEntry = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(effectEntry && effectEntry->EffectApplyAuraName == SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED) { int32 mountSpeed = spellInfo->CalculateSimpleValue(SpellEffectIndex(i)); if (mountSpeed > m_modifier.m_amount) @@ -5047,7 +5096,7 @@ void Aura::HandleModMechanicImmunity(bool apply, bool /*Real*/) target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, misc, apply); // Bestial Wrath - if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_HUNTER && GetSpellProto()->SpellIconID == 1680) + if (GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_HUNTER && GetSpellProto()->SpellIconID == 1680) { // The Beast Within cast on owner if talent present if (Unit* owner = target->GetOwner()) @@ -5088,8 +5137,8 @@ void Aura::HandleAuraModEffectImmunity(bool apply, bool /*Real*/) Unit* target = GetTarget(); // when removing flag aura, handle flag drop - if (!apply && target->GetTypeId() == TYPEID_PLAYER - && (GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION)) + if( !apply && target->GetTypeId() == TYPEID_PLAYER + && (GetSpellProto()->GetAuraInterruptFlags() & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION) ) { if (BattleGround* bg = ((Player*)target)->GetBattleGround()) bg->EventPlayerDroppedFlag(((Player*)target)); @@ -5152,7 +5201,7 @@ void Aura::HandleAuraModSchoolImmunity(bool apply, bool Real) } } } - if (Real && GetSpellProto()->Mechanic == MECHANIC_BANISH) + if( Real && GetSpellProto()->GetMechanic() == MECHANIC_BANISH ) { if (apply) target->addUnitState(UNIT_STAT_ISOLATED); @@ -5249,7 +5298,7 @@ void Aura::HandlePeriodicTriggerSpell(bool apply, bool /*Real*/) if (m_removeMode == AURA_REMOVE_BY_EXPIRE) { if (Unit* pCaster = GetCaster()) - pCaster->CastSpell(target, GetSpellProto()->EffectTriggerSpell[GetEffIndex()], true, NULL, this); + pCaster->CastSpell(target, m_spellEffect->EffectTriggerSpell, true, NULL, this); } return; @@ -5328,14 +5377,13 @@ void Aura::HandleAuraPeriodicDummy(bool apply, bool Real) // For prevent double apply bonuses bool loading = (target->GetTypeId() == TYPEID_PLAYER && ((Player*)target)->GetSession()->PlayerLoading()); - SpellEntry const* spell = GetSpellProto(); - switch (spell->SpellFamilyName) + switch(GetSpellProto()->GetSpellFamilyName()) { case SPELLFAMILY_ROGUE: { - switch (spell->Id) + switch(GetSpellProto()->Id) { - // Master of Subtlety + // Master of Subtlety case 31666: { if (apply) @@ -5451,6 +5499,7 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) Unit* target = GetTarget(); SpellEntry const* spellProto = GetSpellProto(); + SpellClassOptionsEntry const* classOptions = spellProto->GetSpellClassOptions(); // For prevent double apply bonuses bool loading = (target->GetTypeId() == TYPEID_PLAYER && ((Player*)target)->GetSession()->PlayerLoading()); @@ -5465,12 +5514,15 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) if (!caster) return; - switch (spellProto->SpellFamilyName) + if(!classOptions) + return; + + switch (classOptions->SpellFamilyName) { case SPELLFAMILY_WARRIOR: { // Rend - if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000020)) + if (classOptions->SpellFamilyFlags & UI64LIT(0x0000000000000020)) { // $0.2*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK); @@ -5488,7 +5540,7 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) case SPELLFAMILY_DRUID: { // Rip - if (spellProto->SpellFamilyFlags & UI64LIT(0x000000000000800000)) + if (classOptions->SpellFamilyFlags & UI64LIT(0x000000000000800000)) { if (caster->GetTypeId() != TYPEID_PLAYER) break; @@ -5513,7 +5565,7 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) case SPELLFAMILY_ROGUE: { // Rupture - if (spellProto->SpellFamilyFlags & UI64LIT(0x000000000000100000)) + if (classOptions->SpellFamilyFlags & UI64LIT(0x000000000000100000)) { if (caster->GetTypeId() != TYPEID_PLAYER) break; @@ -5532,7 +5584,7 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) case SPELLFAMILY_PALADIN: { // Holy Vengeance / Blood Corruption - if (spellProto->SpellFamilyFlags & UI64LIT(0x0000080000000000) && spellProto->SpellVisual[0] == 7902) + if (classOptions->SpellFamilyFlags & UI64LIT(0x0000080000000000) && spellProto->SpellVisual[0] == 7902) { // AP * 0.025 + SPH * 0.013 bonus per tick float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK); @@ -5550,7 +5602,8 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) if (m_modifier.m_auraname == SPELL_AURA_PERIODIC_DAMAGE) { // SpellDamageBonusDone for magic spells - if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE || spellProto->DmgClass == SPELL_DAMAGE_CLASS_MAGIC) + uint32 dmgClass = spellProto->GetDmgClass(); + if(dmgClass == SPELL_DAMAGE_CLASS_NONE || dmgClass == SPELL_DAMAGE_CLASS_MAGIC) m_modifier.m_amount = caster->SpellDamageBonusDone(target, GetSpellProto(), m_modifier.m_amount, DOT, GetStackAmount()); // MeleeDamagebonusDone for weapon based spells else @@ -6132,7 +6185,7 @@ void Aura::HandleAuraModCritPercent(bool apply, bool Real) // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask // m_modifier.m_miscvalue comparison with item generated damage types - if (GetSpellProto()->EquippedItemClass == -1) + if (GetSpellProto()->GetEquippedItemClass() == -1) { ((Player*)target)->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float(m_modifier.m_amount), apply); ((Player*)target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float(m_modifier.m_amount), apply); @@ -6340,10 +6393,12 @@ void Aura::HandleModDamageDone(bool apply, bool Real) // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask // m_modifier.m_miscvalue comparison with item generated damage types - if ((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) != 0) + SpellEquippedItemsEntry const* equippedItems = GetSpellProto()->GetSpellEquippedItems(); + + if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) != 0) { // apply generic physical damage bonuses including wand case - if (GetSpellProto()->EquippedItemClass == -1 || target->GetTypeId() != TYPEID_PLAYER) + if (equippedItems && (equippedItems->EquippedItemClass == -1 || target->GetTypeId() != TYPEID_PLAYER)) { target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(m_modifier.m_amount), apply); target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(m_modifier.m_amount), apply); @@ -6367,7 +6422,7 @@ void Aura::HandleModDamageDone(bool apply, bool Real) if ((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_MAGIC) == 0) return; - if (GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0) + if( equippedItems && (equippedItems->EquippedItemClass != -1 || equippedItems->EquippedItemInventoryTypeMask != 0) ) { // wand magic case (skip generic to all item spell bonuses) // done in Player::_ApplyWeaponDependentAuraMods @@ -6424,10 +6479,12 @@ void Aura::HandleModDamagePercentDone(bool apply, bool Real) // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask // m_modifier.m_miscvalue comparison with item generated damage types - if ((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) != 0) + SpellEquippedItemsEntry const* equippedItems = GetSpellProto()->GetSpellEquippedItems(); + + if((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_NORMAL) != 0) { // apply generic physical damage bonuses including wand case - if (GetSpellProto()->EquippedItemClass == -1 || target->GetTypeId() != TYPEID_PLAYER) + if (equippedItems && (equippedItems->EquippedItemClass == -1 || target->GetTypeId() != TYPEID_PLAYER)) { target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(m_modifier.m_amount), apply); target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_modifier.m_amount), apply); @@ -6446,7 +6503,7 @@ void Aura::HandleModDamagePercentDone(bool apply, bool Real) if ((m_modifier.m_miscvalue & SPELL_SCHOOL_MASK_MAGIC) == 0) return; - if (GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0) + if( equippedItems && (equippedItems->EquippedItemClass != -1 || equippedItems->EquippedItemInventoryTypeMask != 0) ) { // wand magic case (skip generic to all item spell bonuses) // done in Player::_ApplyWeaponDependentAuraMods @@ -6633,9 +6690,9 @@ void Aura::HandleShapeshiftBoosts(bool apply) Unit::SpellAuraHolderMap& tAuras = target->GetSpellAuraHolderMap(); for (Unit::SpellAuraHolderMap::iterator itr = tAuras.begin(); itr != tAuras.end();) { - SpellEntry const* spellInfo = itr->second->GetSpellProto(); - if (itr->second->IsPassive() && spellInfo->HasAttribute(SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) - && (spellInfo->StancesNot & (1 << (form - 1)))) + SpellEntry const *spellInfo = itr->second->GetSpellProto(); + if (itr->second->IsPassive() && (spellInfo->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) + && (spellInfo->GetStancesNot() & (1<<(form-1)))) { target->RemoveAurasDueToSpell(itr->second->GetId()); itr = tAuras.begin(); @@ -6663,8 +6720,8 @@ void Aura::HandleShapeshiftBoosts(bool apply) // Leader of the Pack if (((Player*)target)->HasSpell(17007)) { - SpellEntry const* spellInfo = sSpellStore.LookupEntry(24932); - if (spellInfo && spellInfo->Stances & (1 << (form - 1))) + SpellEntry const *spellInfo = sSpellStore.LookupEntry(24932); + if (spellInfo && spellInfo->GetStances() & (1<<(form-1))) target->CastSpell(target, 24932, true, NULL, this); } @@ -6678,8 +6735,8 @@ void Aura::HandleShapeshiftBoosts(bool apply) Unit::AuraList const& modAuras = target->GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE); for (Unit::AuraList::const_iterator i = modAuras.begin(); i != modAuras.end(); ++i) { - if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && - (*i)->GetSpellProto()->SpellIconID == 961) + if ((*i)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_DRUID && + (*i)->GetSpellProto()->SpellIconID == 961) { int32 bp = (*i)->GetSpellProto()->CalculateSimpleValue(EFFECT_INDEX_2); if (bp) @@ -6695,8 +6752,8 @@ void Aura::HandleShapeshiftBoosts(bool apply) Unit::AuraList const& dummyAuras = target->GetAurasByType(SPELL_AURA_DUMMY); for (Unit::AuraList::const_iterator i = dummyAuras.begin(); i != dummyAuras.end(); ++i) { - if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && - (*i)->GetSpellProto()->SpellIconID == 2855) + if ((*i)->GetSpellProto()->GetSpellFamilyName()==SPELLFAMILY_DRUID && + (*i)->GetSpellProto()->SpellIconID == 2855) { uint32 spell_id = 0; switch ((*i)->GetId()) @@ -6755,7 +6812,7 @@ void Aura::HandleShapeshiftBoosts(bool apply) SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->first); if (!spellInfo || !IsPassiveSpell(spellInfo)) continue; - if (spellInfo->HasAttribute(SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) && (spellInfo->StancesNot & (1 << (form - 1)))) + if (spellInfo->HasAttribute(SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) && (spellInfo->GetStancesNot() & (1 << (form - 1)))) target->CastSpell(target, itr->first, true, NULL, this); } } @@ -6979,13 +7036,15 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real) Unit* target = GetTarget(); SpellEntry const* spellProto = GetSpellProto(); + SpellClassOptionsEntry const* classOptions = spellProto->GetSpellClassOptions(); + if (apply) { // prevent double apply bonuses if (target->GetTypeId() != TYPEID_PLAYER || !((Player*)target)->GetSession()->PlayerLoading()) { float DoneActualBenefit = 0.0f; - switch (spellProto->SpellFamilyName) + switch(spellProto->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: // Stoicism @@ -6994,7 +7053,7 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real) break; case SPELLFAMILY_PRIEST: // Power Word: Shield - if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000001)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000000001)) { //+80.68% from +spell bonus DoneActualBenefit = caster->SpellBaseHealingBonusDone(GetSpellSchoolMask(spellProto)) * 0.8068f; @@ -7003,7 +7062,7 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real) for (Unit::AuraList::const_iterator itr = borrowedTime.begin(); itr != borrowedTime.end(); ++itr) { SpellEntry const* i_spell = (*itr)->GetSpellProto(); - if (i_spell->SpellFamilyName == SPELLFAMILY_PRIEST && i_spell->SpellIconID == 2899 && i_spell->EffectMiscValue[(*itr)->GetEffIndex()] == 24) + if(i_spell->GetSpellFamilyName()==SPELLFAMILY_PRIEST && i_spell->SpellIconID == 2899 && i_spell->GetEffectMiscValue((*itr)->GetEffIndex()) == 24) { DoneActualBenefit += DoneActualBenefit * (*itr)->GetModifier()->m_amount / 100; break; @@ -7049,11 +7108,11 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real) else { if (caster && - // Power Word: Shield - spellProto->SpellFamilyName == SPELLFAMILY_PRIEST && spellProto->Mechanic == MECHANIC_SHIELD && - (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000001)) && - // completely absorbed or dispelled - (m_removeMode == AURA_REMOVE_BY_SHIELD_BREAK || m_removeMode == AURA_REMOVE_BY_DISPEL)) + // Power Word: Shield + classOptions && classOptions->SpellFamilyName == SPELLFAMILY_PRIEST && spellProto->GetMechanic() == MECHANIC_SHIELD && + (classOptions->SpellFamilyFlags & UI64LIT(0x0000000000000001)) && + // completely absorbed or dispelled + (m_removeMode == AURA_REMOVE_BY_SHIELD_BREAK || m_removeMode == AURA_REMOVE_BY_DISPEL)) { Unit::AuraList const& vDummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY); for (Unit::AuraList::const_iterator itr = vDummyAuras.begin(); itr != vDummyAuras.end(); ++itr) @@ -7061,7 +7120,7 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real) SpellEntry const* vSpell = (*itr)->GetSpellProto(); // Rapture (main spell) - if (vSpell->SpellFamilyName == SPELLFAMILY_PRIEST && vSpell->SpellIconID == 2894 && vSpell->Effect[EFFECT_INDEX_1]) + if(vSpell->GetSpellFamilyName() == SPELLFAMILY_PRIEST && vSpell->SpellIconID == 2894 && vSpell->GetSpellEffectIdByIndex(EFFECT_INDEX_1)) { switch ((*itr)->GetEffIndex()) { @@ -7118,6 +7177,7 @@ void Aura::PeriodicTick() { Unit* target = GetTarget(); SpellEntry const* spellProto = GetSpellProto(); + SpellClassOptionsEntry const* classOptions = spellProto->GetSpellClassOptions(); switch (m_modifier.m_auraname) { @@ -7132,8 +7192,8 @@ void Aura::PeriodicTick() if (!pCaster) return; - if (spellProto->Effect[GetEffIndex()] == SPELL_EFFECT_PERSISTENT_AREA_AURA && - pCaster->SpellHitResult(target, spellProto, false) != SPELL_MISS_NONE) + if( spellProto->GetSpellEffectIdByIndex(GetEffIndex()) == SPELL_EFFECT_PERSISTENT_AREA_AURA && + pCaster->SpellHitResult(target, spellProto, false) != SPELL_MISS_NONE) return; // Check for immune (not use charges) @@ -7159,7 +7219,7 @@ void Aura::PeriodicTick() case 38772: { uint32 percent = - GetEffIndex() < EFFECT_INDEX_2 && spellProto->Effect[GetEffIndex()] == SPELL_EFFECT_DUMMY ? + GetEffIndex() < EFFECT_INDEX_2 && spellProto->GetSpellEffectIdByIndex(GetEffIndex()) == SPELL_EFFECT_DUMMY ? pCaster->CalculateSpellDamage(target, spellProto, SpellEffectIndex(GetEffIndex() + 1)) : 100; if (target->GetHealth() * 100 >= target->GetMaxHealth() * percent) @@ -7189,7 +7249,8 @@ void Aura::PeriodicTick() pdamage = uint32(target->GetMaxHealth() * amount / 100); // SpellDamageBonus for magic spells - if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE || spellProto->DmgClass == SPELL_DAMAGE_CLASS_MAGIC) + uint32 dmgClass = spellProto->GetDmgClass(); + if(dmgClass == SPELL_DAMAGE_CLASS_NONE || dmgClass == SPELL_DAMAGE_CLASS_MAGIC) pdamage = target->SpellDamageBonusTaken(pCaster, spellProto, pdamage, DOT, GetStackAmount()); // MeleeDamagebonus for weapon based spells else @@ -7209,7 +7270,7 @@ void Aura::PeriodicTick() } // Curse of Agony damage-per-tick calculation - if (spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000400)) && spellProto->SpellIconID == 544) + if (classOptions && classOptions->SpellFamilyName==SPELLFAMILY_WARLOCK && (classOptions->SpellFamilyFlags & UI64LIT(0x0000000000000400)) && spellProto->SpellIconID==544) { // 1..4 ticks, 1/2 from normal tick damage if (GetAuraTicks() <= 4) @@ -7262,7 +7323,7 @@ void Aura::PeriodicTick() pCaster->DealDamage(target, pdamage, &cleanDamage, DOT, GetSpellSchoolMask(spellProto), spellProto, true); // Drain Soul (chance soul shard) - if (pCaster->GetTypeId() == TYPEID_PLAYER && spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && spellProto->SpellFamilyFlags & UI64LIT(0x0000000000004000)) + if (pCaster->GetTypeId() == TYPEID_PLAYER && classOptions && classOptions->SpellFamilyName == SPELLFAMILY_WARLOCK && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000004000)) { // Only from non-grey units if (roll_chance_i(10) && // 1-2 from drain with final and without glyph, 0-1 from damage @@ -7289,8 +7350,8 @@ void Aura::PeriodicTick() if (!pCaster->isAlive()) return; - if (spellProto->Effect[GetEffIndex()] == SPELL_EFFECT_PERSISTENT_AREA_AURA && - pCaster->SpellHitResult(target, spellProto, false) != SPELL_MISS_NONE) + if( spellProto->GetSpellEffectIdByIndex(GetEffIndex()) == SPELL_EFFECT_PERSISTENT_AREA_AURA && + pCaster->SpellHitResult(target, spellProto, false) != SPELL_MISS_NONE) return; // Check for immune @@ -7337,7 +7398,7 @@ void Aura::PeriodicTick() pCaster->SendSpellNonMeleeDamageLog(target, GetId(), pdamage, GetSpellSchoolMask(spellProto), absorb, resist, false, 0, isCrit); - float multiplier = spellProto->EffectMultipleValue[GetEffIndex()] > 0 ? spellProto->EffectMultipleValue[GetEffIndex()] : 1; + float multiplier = m_spellEffect->EffectMultipleValue > 0 ? m_spellEffect->EffectMultipleValue : 1; // Set trigger flag uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC; // | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT; @@ -7396,7 +7457,7 @@ void Aura::PeriodicTick() pdamage = amount; // Wild Growth (1/7 - 6 + 2*ramainTicks) % - if (spellProto->SpellFamilyName == SPELLFAMILY_DRUID && spellProto->SpellIconID == 2864) + if (classOptions && classOptions->SpellFamilyName == SPELLFAMILY_DRUID && spellProto->SpellIconID == 2864) { int32 ticks = GetAuraMaxTicks(); int32 remainingTicks = ticks - GetAuraTicks(); @@ -7443,8 +7504,8 @@ void Aura::PeriodicTick() // heal for caster damage if (target != pCaster && spellProto->SpellVisual[0] == 163) { - uint32 dmg = spellProto->manaPerSecond; - if (pCaster->GetHealth() <= dmg && pCaster->GetTypeId() == TYPEID_PLAYER) + uint32 dmg = spellProto->GetManaPerSecond(); + if(pCaster->GetHealth() <= dmg && pCaster->GetTypeId()==TYPEID_PLAYER) { pCaster->RemoveAurasDueToSpell(GetId()); @@ -7493,8 +7554,8 @@ void Aura::PeriodicTick() if (!pCaster->isAlive()) return; - if (GetSpellProto()->Effect[GetEffIndex()] == SPELL_EFFECT_PERSISTENT_AREA_AURA && - pCaster->SpellHitResult(target, spellProto, false) != SPELL_MISS_NONE) + if( GetSpellProto()->GetSpellEffectIdByIndex(GetEffIndex()) == SPELL_EFFECT_PERSISTENT_AREA_AURA && + pCaster->SpellHitResult(target, spellProto, false) != SPELL_MISS_NONE) return; // Check for immune (not use charges) @@ -7506,7 +7567,7 @@ void Aura::PeriodicTick() // Special case: draining x% of mana (up to a maximum of 2*x% of the caster's maximum mana) // It's mana percent cost spells, m_modifier.m_amount is percent drain from target - if (spellProto->ManaCostPercentage) + if (spellProto->GetManaCostPercentage()) { // max value uint32 maxmana = pCaster->GetMaxPower(power) * pdamage * 2 / 100; @@ -7530,7 +7591,7 @@ void Aura::PeriodicTick() if (pCaster->GetMaxPower(power) > 0) { - gain_multiplier = spellProto->EffectMultipleValue[GetEffIndex()]; + gain_multiplier = m_spellEffect->EffectMultipleValue; if (Player* modOwner = pCaster->GetSpellModOwner()) modOwner->ApplySpellMod(GetId(), SPELLMOD_MULTIPLE_VALUE, gain_multiplier); @@ -7670,7 +7731,7 @@ void Aura::PeriodicTick() uint32 gain = uint32(-target->ModifyPower(powerType, -pdamage)); - gain = uint32(gain * spellProto->EffectMultipleValue[GetEffIndex()]); + gain = uint32(gain * m_spellEffect->EffectMultipleValue); // maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG SpellNonMeleeDamage damageInfo(pCaster, target, spellProto->Id, SpellSchoolMask(spellProto->SchoolMask)); @@ -7715,7 +7776,7 @@ void Aura::PeriodicTick() if (int32(pt) != m_modifier.m_miscvalue) return; - if (spellProto->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) + if ( spellProto->GetAuraInterruptFlags() & AURA_INTERRUPT_FLAG_NOT_SEATED ) { // eating anim target->HandleEmoteCommand(EMOTE_ONESHOT_EAT); @@ -7758,8 +7819,10 @@ void Aura::PeriodicTick() void Aura::PeriodicDummyTick() { SpellEntry const* spell = GetSpellProto(); - Unit* target = GetTarget(); - switch (spell->SpellFamilyName) + SpellClassOptionsEntry const* classOptions = spell->GetSpellClassOptions(); + + Unit *target = GetTarget(); + switch (spell->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { @@ -8066,7 +8129,7 @@ void Aura::PeriodicDummyTick() } // Drink (item drink spells) - if (GetEffIndex() > EFFECT_INDEX_0 && spell->EffectApplyAuraName[GetEffIndex() - 1] == SPELL_AURA_MOD_POWER_REGEN) + if (GetEffIndex() > EFFECT_INDEX_0 && spell->GetEffectApplyAuraNameByIndex(SpellEffectIndex(GetEffIndex()-1)) == SPELL_AURA_MOD_POWER_REGEN) { if (target->GetTypeId() != TYPEID_PLAYER) return; @@ -8175,7 +8238,7 @@ void Aura::PeriodicDummyTick() case SPELLFAMILY_HUNTER: { // Explosive Shot - if (spell->SpellFamilyFlags & UI64LIT(0x8000000000000000)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x8000000000000000)) { target->CastCustomSpell(target, 53352, &m_modifier.m_amount, 0, 0, true, 0, this, GetCasterGuid()); return; @@ -8214,7 +8277,7 @@ void Aura::PeriodicDummyTick() case SPELLFAMILY_DEATHKNIGHT: { // Death and Decay - if (spell->SpellFamilyFlags & UI64LIT(0x0000000000000020)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000000020)) { if (Unit* caster = GetCaster()) caster->CastCustomSpell(target, 52212, &m_modifier.m_amount, NULL, NULL, true, NULL, this); @@ -8224,7 +8287,7 @@ void Aura::PeriodicDummyTick() // if (spell->SpellFamilyFlags & UI64LIT(0x0000000000001000)) // return; // Chains of Ice - if (spell->SpellFamilyFlags & UI64LIT(0x0000400000000000)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000400000000000)) { // Get 0 effect aura Aura* slow = target->GetAura(GetId(), EFFECT_INDEX_0); @@ -8248,7 +8311,7 @@ void Aura::PeriodicDummyTick() if (spell->SpellIconID == 2653) { // Increases your attack power by $s1 for every $s2 armor value you have. - // Calculate AP bonus (from 1 efect of this spell) + // Calculate AP bonus (from 1 effect of this spell) int32 apBonus = m_modifier.m_amount * target->GetArmor() / target->CalculateSpellDamage(target, spell, EFFECT_INDEX_1); target->CastCustomSpell(target, 61217, &apBonus, &apBonus, NULL, true, NULL, this); return; @@ -8260,7 +8323,7 @@ void Aura::PeriodicDummyTick() // if (spell->SpellIconID == 30412) // return; // Hysteria - if (spell->SpellFamilyFlags & UI64LIT(0x0000000020000000)) + if (spell->IsFitToFamilyMask(UI64LIT(0x0000000020000000))) { // damage not expected to be show in logs, not any damage spell related to damage apply uint32 deal = m_modifier.m_amount * target->GetMaxHealth() / 100; @@ -8300,15 +8363,17 @@ void Aura::HandleManaShield(bool apply, bool Real) if (Unit* caster = GetCaster()) { float DoneActualBenefit = 0.0f; - switch (GetSpellProto()->SpellFamilyName) + switch(GetSpellProto()->GetSpellFamilyName()) { case SPELLFAMILY_MAGE: - if (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000008000)) { - // Mana Shield - // +50% from +spd bonus - DoneActualBenefit = caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(GetSpellProto())) * 0.5f; - break; + if (GetSpellProto()->IsFitToFamilyMask(UI64LIT(0x0000000000008000))) + { + // Mana Shield + // +50% from +spd bonus + DoneActualBenefit = caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(GetSpellProto())) * 0.5f; + break; + } } break; default: @@ -8486,8 +8551,8 @@ void Aura::HandleAuraConvertRune(bool apply, bool Real) if (plr->getClass() != CLASS_DEATH_KNIGHT) return; - RuneType runeFrom = RuneType(GetSpellProto()->EffectMiscValue[m_effIndex]); - RuneType runeTo = RuneType(GetSpellProto()->EffectMiscValueB[m_effIndex]); + RuneType runeFrom = RuneType(m_spellEffect->EffectMiscValue); + RuneType runeTo = RuneType(m_spellEffect->EffectMiscValueB); if (apply) { @@ -8623,8 +8688,10 @@ bool Aura::IsLastAuraOnHolder() bool Aura::HasMechanic(uint32 mechanic) const { - return GetSpellProto()->Mechanic == mechanic || - GetSpellProto()->EffectMechanic[m_effIndex] == mechanic; + if (GetSpellProto()->GetMechanic() == mechanic) + return true; + + return m_spellEffect->EffectMechanic == mechanic; } SpellAuraHolder::SpellAuraHolder(SpellEntry const* spellproto, Unit* target, WorldObject* caster, Item* castItem) : @@ -8649,10 +8716,10 @@ SpellAuraHolder::SpellAuraHolder(SpellEntry const* spellproto, Unit* target, Wor m_isPassive = IsPassiveSpell(spellproto); m_isDeathPersist = IsDeathPersistentSpell(spellproto); m_isSingleTarget = IsSingleTargetSpell(spellproto); - m_procCharges = spellproto->procCharges; + m_procCharges = m_spellProto->GetProcCharges(); m_isRemovedOnShapeLost = (GetCasterGuid() == m_target->GetObjectGuid() && - m_spellProto->Stances && + m_spellProto->GetStances() && !m_spellProto->HasAttribute(SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) && !m_spellProto->HasAttribute(SPELL_ATTR_NOT_SHAPESHIFT)); @@ -8684,7 +8751,7 @@ SpellAuraHolder::SpellAuraHolder(SpellEntry const* spellproto, Unit* target, Wor case 64455: // Feral Essence case 71564: // Deadly Precision case 74396: // Fingers of Frost - m_stackAmount = m_spellProto->StackAmount; + m_stackAmount = m_spellProto->GetStackAmount(); break; } @@ -8776,7 +8843,7 @@ void SpellAuraHolder::_AddSpellAuraHolder() //***************************************************** // Sitdown on apply aura req seated - if (m_spellProto->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && !m_target->IsSitState()) + if (m_spellProto->GetAuraInterruptFlags() & AURA_INTERRUPT_FLAG_NOT_SEATED && !m_target->IsSitState()) m_target->SetStandState(UNIT_STAND_STATE_SIT); // register aura diminishing on apply @@ -8808,7 +8875,7 @@ void SpellAuraHolder::_AddSpellAuraHolder() m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON, true); // Enrage aura state - if (m_spellProto->Dispel == DISPEL_ENRAGE) + if (m_spellProto->GetDispel() == DISPEL_ENRAGE) m_target->ModifyAuraState(AURA_STATE_ENRAGE, true); // Bleeding aura state @@ -8868,7 +8935,7 @@ void SpellAuraHolder::_RemoveSpellAuraHolder() // Update target aura state flag (at last aura remove) //***************************************************** // Enrage aura state - if (m_spellProto->Dispel == DISPEL_ENRAGE) + if(m_spellProto->GetDispel() == DISPEL_ENRAGE) m_target->ModifyAuraState(AURA_STATE_ENRAGE, false); // Bleeding aura state @@ -8891,8 +8958,9 @@ void SpellAuraHolder::_RemoveSpellAuraHolder() } uint32 removeState = 0; - ClassFamilyMask removeFamilyFlag = m_spellProto->SpellFamilyFlags; - switch (m_spellProto->SpellFamilyName) + SpellClassOptionsEntry const* classOptions = m_spellProto->GetSpellClassOptions(); + ClassFamilyMask removeFamilyFlag = classOptions ? classOptions->SpellFamilyFlags : ClassFamilyMask(); + switch(m_spellProto->GetSpellFamilyName()) { case SPELLFAMILY_PALADIN: if (IsSealSpell(m_spellProto)) @@ -8935,8 +9003,8 @@ void SpellAuraHolder::_RemoveSpellAuraHolder() Unit::SpellAuraHolderMap const& holders = m_target->GetSpellAuraHolderMap(); for (Unit::SpellAuraHolderMap::const_iterator i = holders.begin(); i != holders.end(); ++i) { - SpellEntry const* auraSpellInfo = (*i).second->GetSpellProto(); - if (auraSpellInfo->IsFitToFamily(SpellFamily(m_spellProto->SpellFamilyName), removeFamilyFlag)) + SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto(); + if (auraSpellInfo->IsFitToFamily(SpellFamily(m_spellProto->GetSpellFamilyName()), removeFamilyFlag)) { found = true; break; @@ -8962,11 +9030,15 @@ void SpellAuraHolder::CleanupTriggeredSpells() { for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (!m_spellProto->EffectApplyAuraName[i]) + SpellEffectEntry const* spellEffect = m_spellProto->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) continue; - uint32 tSpellId = m_spellProto->EffectTriggerSpell[i]; - if (!tSpellId) + if (!spellEffect->EffectApplyAuraName) + continue; + + uint32 tSpellId = spellEffect->EffectTriggerSpell; + if(!tSpellId) continue; SpellEntry const* tProto = sSpellStore.LookupEntry(tSpellId); @@ -8978,8 +9050,8 @@ void SpellAuraHolder::CleanupTriggeredSpells() // needed for spell 43680, maybe others // TODO: is there a spell flag, which can solve this in a more sophisticated way? - if (m_spellProto->EffectApplyAuraName[i] == SPELL_AURA_PERIODIC_TRIGGER_SPELL && - GetSpellDuration(m_spellProto) == int32(m_spellProto->EffectAmplitude[i])) + if (spellEffect->EffectApplyAuraName == SPELL_AURA_PERIODIC_TRIGGER_SPELL && + GetSpellDuration(m_spellProto) == int32(spellEffect->EffectAmplitude)) continue; m_target->RemoveAurasDueToSpell(tSpellId); @@ -8988,7 +9060,7 @@ void SpellAuraHolder::CleanupTriggeredSpells() bool SpellAuraHolder::ModStackAmount(int32 num) { - uint32 protoStackAmount = m_spellProto->StackAmount; + uint32 protoStackAmount = m_spellProto->GetStackAmount(); // Can`t mod if (!protoStackAmount) @@ -9065,11 +9137,11 @@ bool SpellAuraHolder::IsWeaponBuffCoexistableWith(SpellAuraHolder const* ref) co return false; // Exclude Non-generic Buffs [ie: Runeforging] and Executioner-Enchant - if (GetSpellProto()->SpellFamilyName != SPELLFAMILY_GENERIC || GetId() == 42976) + if (GetSpellProto()->GetSpellFamilyName() != SPELLFAMILY_GENERIC || GetId() == 42976) return false; // Exclude Stackable Buffs [ie: Blood Reserve] - if (GetSpellProto()->StackAmount) + if (GetSpellProto()->GetStackAmount()) return false; // only self applied player buffs @@ -9093,7 +9165,7 @@ bool SpellAuraHolder::IsNeedVisibleSlot(Unit const* caster) const { bool totemAura = caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->IsTotem(); - if (m_spellProto->procFlags) + if (m_spellProto->GetProcFlags()) return true; else if (HasAuraWithTriggerEffect(m_spellProto)) return true; @@ -9154,7 +9226,9 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) uint32 spellId3 = 0; uint32 spellId4 = 0; - switch (GetSpellProto()->SpellFamilyName) + SpellClassOptionsEntry const* classOptions = m_spellProto->GetSpellClassOptions(); + + switch(m_spellProto->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { @@ -9308,15 +9382,15 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) if (!apply) { // Remove Blood Frenzy only if target no longer has any Deep Wound or Rend (applying is handled by procs) - if (GetSpellProto()->Mechanic != MECHANIC_BLEED) + if (GetSpellProto()->GetMechanic() != MECHANIC_BLEED) return; // If target still has one of Warrior's bleeds, do nothing Unit::AuraList const& PeriodicDamage = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); - for (Unit::AuraList::const_iterator i = PeriodicDamage.begin(); i != PeriodicDamage.end(); ++i) - if ((*i)->GetCasterGuid() == GetCasterGuid() && - (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARRIOR && - (*i)->GetSpellProto()->Mechanic == MECHANIC_BLEED) + for(Unit::AuraList::const_iterator i = PeriodicDamage.begin(); i != PeriodicDamage.end(); ++i) + if( (*i)->GetCasterGuid() == GetCasterGuid() && + (*i)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_WARRIOR && + (*i)->GetSpellProto()->GetMechanic() == MECHANIC_BLEED) return; spellId1 = 30069; // Blood Frenzy (Rank 1) @@ -9327,7 +9401,7 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) case SPELLFAMILY_WARLOCK: { // Fear (non stacking) - if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000040000000000)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000040000000000)) { if (!apply) { @@ -9340,7 +9414,7 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) { SpellEntry const* dummyEntry = (*itr)->GetSpellProto(); // Improved Fear - if (dummyEntry->SpellFamilyName == SPELLFAMILY_WARLOCK && dummyEntry->SpellIconID == 98) + if (dummyEntry->GetSpellFamilyName() == SPELLFAMILY_WARLOCK && dummyEntry->SpellIconID == 98) { cast_at_remove = true; switch ((*itr)->GetModifier()->m_amount) @@ -9388,8 +9462,8 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) for (Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) { // Shadow Affinity - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST - && (*itr)->GetSpellProto()->SpellIconID == 178) + if ((*itr)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_PRIEST + && (*itr)->GetSpellProto()->SpellIconID == 178) { // custom cast code int32 basepoints0 = (*itr)->GetModifier()->m_amount * caster->GetCreateMana() / 100; @@ -9402,7 +9476,7 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) return; } // Power Word: Shield - else if (apply && m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000001) && m_spellProto->Mechanic == MECHANIC_SHIELD) + else if (apply && classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000000001) && m_spellProto->GetMechanic() == MECHANIC_SHIELD) { Unit* caster = GetCaster(); if (!caster) @@ -9431,8 +9505,8 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) { SpellEntry const* dummyEntry = (*itr)->GetSpellProto(); // Body and Soul (talent ranks) - if (dummyEntry->SpellFamilyName == SPELLFAMILY_PRIEST && dummyEntry->SpellIconID == 2218 && - dummyEntry->SpellVisual[0] == 0) + if (dummyEntry->GetSpellFamilyName() == SPELLFAMILY_PRIEST && dummyEntry->SpellIconID == 2218 && + dummyEntry->SpellVisual[0]==0) { chance = (*itr)->GetSpellProto()->CalculateSimpleValue(EFFECT_INDEX_1); break; @@ -9469,7 +9543,7 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) } case SPELLFAMILY_ROGUE: // Sprint (skip non player casted spells by category) - if (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000040) && GetSpellProto()->Category == 44) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000000040) && GetSpellProto()->GetCategory() == 44) { if (!apply || m_target->HasAura(58039)) // Glyph of Blurred Speed spellId1 = 61922; // Sprint (waterwalk) @@ -9539,7 +9613,7 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) } default: // Freezing Trap Effect - if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000008)) + if (m_spellProto->IsFitToFamilyMask(UI64LIT(0x0000000000000008))) { if (!apply) { @@ -9613,7 +9687,7 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) return; // Sanctified Retribution and Swift Retribution (they share one aura), but not Retribution Aura (already gets modded) - if ((GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000008)) == 0) + if (classOptions && (classOptions->SpellFamilyFlags & UI64LIT(0x0000000000000008))==0) spellId1 = 63531; // placeholder for talent spell mods // Improved Concentration Aura (auras bonus) spellId2 = 63510; // placeholder for talent spell mods @@ -9643,8 +9717,8 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) for (Unit::AuraList::const_iterator itr = bloodAuras.begin(); itr != bloodAuras.end(); ++itr) { // skip same icon - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && - (*itr)->GetSpellProto()->SpellIconID == 2636) + if ((*itr)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_DEATHKNIGHT && + (*itr)->GetSpellProto()->SpellIconID == 2636) { heal_pct = (*itr)->GetModifier()->m_amount; break; @@ -9670,8 +9744,8 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) for (Unit::AuraList::const_iterator itr = unholyAuras.begin(); itr != unholyAuras.end(); ++itr) { // skip same icon - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && - (*itr)->GetSpellProto()->SpellIconID == 2633) + if ((*itr)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_DEATHKNIGHT && + (*itr)->GetSpellProto()->SpellIconID == 2633) { power_pct = (*itr)->GetModifier()->m_amount; break; @@ -9694,8 +9768,8 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) for (Unit::AuraList::const_iterator itr = frostAuras.begin(); itr != frostAuras.end(); ++itr) { // skip same icon - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && - (*itr)->GetSpellProto()->SpellIconID == 2632) + if ((*itr)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_DEATHKNIGHT && + (*itr)->GetSpellProto()->SpellIconID == 2632) { stamina_pct = (*itr)->GetModifier()->m_amount; break; @@ -9721,8 +9795,8 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) for (Unit::AuraList::const_iterator itr = unholyAuras.begin(); itr != unholyAuras.end(); ++itr) { // skip same icon - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && - (*itr)->GetSpellProto()->SpellIconID == 2633) + if ((*itr)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_DEATHKNIGHT && + (*itr)->GetSpellProto()->SpellIconID == 2633) { power_pct = (*itr)->GetModifier()->m_amount; break; @@ -9864,15 +9938,17 @@ void SpellAuraHolder::Update(uint32 diff) if (Unit* caster = GetCaster()) { Powers powertype = Powers(GetSpellProto()->powerType); - int32 manaPerSecond = GetSpellProto()->manaPerSecond + GetSpellProto()->manaPerSecondPerLevel * caster->getLevel(); - m_timeCla = 1 * IN_MILLISECONDS; + m_timeCla = 1*IN_MILLISECONDS; - if (manaPerSecond) + if (SpellPowerEntry const* spellPower = GetSpellProto()->GetSpellPower()) { - if (powertype == POWER_HEALTH) - caster->ModifyHealth(-manaPerSecond); - else - caster->ModifyPower(powertype, -manaPerSecond); + if (int32 manaPerSecond = spellPower->manaPerSecond) + { + if (powertype == POWER_HEALTH) + caster->ModifyHealth(-manaPerSecond); + else + caster->ModifyPower(powertype, -manaPerSecond); + } } } } @@ -9934,23 +10010,33 @@ void SpellAuraHolder::SetAuraMaxDuration(int32 duration) bool SpellAuraHolder::HasMechanic(uint32 mechanic) const { - if (mechanic == m_spellProto->Mechanic) + if (mechanic == m_spellProto->GetMechanic()) return true; for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) - if (m_auras[i] && m_spellProto->EffectMechanic[i] == mechanic) - return true; + { + if (Aura* aura = m_auras[i]) + { + if (aura->GetSpellEffect()->EffectMechanic == mechanic) + return true; + } + } return false; } bool SpellAuraHolder::HasMechanicMask(uint32 mechanicMask) const { - if (mechanicMask & (1 << (m_spellProto->Mechanic - 1))) + if (mechanicMask & (1 << (m_spellProto->GetMechanic() - 1))) return true; for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) - if (m_auras[i] && m_spellProto->EffectMechanic[i] && ((1 << (m_spellProto->EffectMechanic[i] - 1)) & mechanicMask)) - return true; + { + if (Aura* aura = m_auras[i]) + { + if (aura->GetSpellEffect()->EffectMechanic && ((1 << (aura->GetSpellEffect()->EffectMechanic - 1)) & mechanicMask)) + return true; + } + } return false; } diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 06ef19da9..9c29b7335 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -380,11 +380,12 @@ class MANGOS_DLL_SPEC Aura void SetModifier(AuraType t, int32 a, uint32 pt, int32 miscValue); Modifier* GetModifier() { return &m_modifier; } Modifier const* GetModifier() const { return &m_modifier; } - int32 GetMiscValue() const { return m_spellAuraHolder->GetSpellProto()->EffectMiscValue[m_effIndex]; } - int32 GetMiscBValue() const { return m_spellAuraHolder->GetSpellProto()->EffectMiscValueB[m_effIndex]; } - + int32 GetMiscValue() const { return m_spellEffect ? m_spellEffect->EffectMiscValue : 0; } + int32 GetMiscBValue() const { return m_spellEffect ? m_spellEffect->EffectMiscValueB : 0; } + SpellEntry const* GetSpellProto() const { return GetHolder()->GetSpellProto(); } - uint32 GetId() const { return GetHolder()->GetSpellProto()->Id; } + SpellEffectEntry const* GetSpellEffect() const { return m_spellEffect; } + uint32 GetId() const{ return GetHolder()->GetSpellProto()->Id; } ObjectGuid const& GetCastItemGuid() const { return GetHolder()->GetCastItemGuid(); } ObjectGuid const& GetCasterGuid() const { return GetHolder()->GetCasterGuid(); } Unit* GetCaster() const { return GetHolder()->GetCaster(); } @@ -467,7 +468,9 @@ class MANGOS_DLL_SPEC Aura void ReapplyAffectedPassiveAuras(); Modifier m_modifier; + SpellModifier *m_spellmod; + SpellEffectEntry const* m_spellEffect; time_t m_applyTime; int32 m_currentBasePoints; // cache SpellEntry::CalculateSimpleValue and use for set custom base points diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index e1805ee2e..a6e68c58e 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -227,22 +227,22 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS] = &Spell::EffectCancelAura, //164 SPELL_EFFECT_CANCEL_AURA }; -void Spell::EffectEmpty(SpellEffectIndex /*eff_idx*/) +void Spell::EffectEmpty(SpellEffectEntry const* /*effect*/) { // NOT NEED ANY IMPLEMENTATION CODE, EFFECT POSISBLE USED AS MARKER OR CLIENT INFORM } -void Spell::EffectNULL(SpellEffectIndex /*eff_idx*/) +void Spell::EffectNULL(SpellEffectEntry const* /*effect*/) { DEBUG_LOG("WORLD: Spell Effect DUMMY"); } -void Spell::EffectUnused(SpellEffectIndex /*eff_idx*/) +void Spell::EffectUnused(SpellEffectEntry const* /*effect*/) { // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN MANGOS } -void Spell::EffectResurrectNew(SpellEffectIndex eff_idx) +void Spell::EffectResurrectNew(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->isAlive()) return; @@ -259,12 +259,12 @@ void Spell::EffectResurrectNew(SpellEffectIndex eff_idx) return; uint32 health = damage; - uint32 mana = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 mana = effect->EffectMiscValue; pTarget->setResurrectRequestData(m_caster->GetObjectGuid(), m_caster->GetMapId(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(), health, mana); SendResurrectRequest(pTarget); } -void Spell::EffectInstaKill(SpellEffectIndex /*eff_idx*/) +void Spell::EffectInstaKill(SpellEffectEntry const* /*effect*/) { if (!unitTarget || !unitTarget->isAlive()) return; @@ -283,7 +283,7 @@ void Spell::EffectInstaKill(SpellEffectIndex /*eff_idx*/) m_caster->DealDamage(unitTarget, unitTarget->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); } -void Spell::EffectEnvironmentalDMG(SpellEffectIndex eff_idx) +void Spell::EffectEnvironmentalDMG(SpellEffectEntry const* effect) { uint32 absorb = 0; uint32 resist = 0; @@ -291,7 +291,7 @@ void Spell::EffectEnvironmentalDMG(SpellEffectIndex eff_idx) // Note: this hack with damage replace required until GO casting not implemented // environment damage spells already have around enemies targeting but this not help in case nonexistent GO casting support // currently each enemy selected explicitly and self cast damage, we prevent apply self casted spell bonuses/etc - damage = m_spellInfo->CalculateSimpleValue(eff_idx); + damage = effect->CalculateSimpleValue(); m_caster->CalculateDamageAbsorbAndResist(m_caster, GetSpellSchoolMask(m_spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); @@ -300,11 +300,13 @@ void Spell::EffectEnvironmentalDMG(SpellEffectIndex eff_idx) ((Player*)m_caster)->EnvironmentalDamage(DAMAGE_FIRE, damage); } -void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) +void Spell::EffectSchoolDMG(SpellEffectEntry const* effect) { if (unitTarget && unitTarget->isAlive()) { - switch (m_spellInfo->SpellFamilyName) + SpellClassOptionsEntry const* classOptions = m_spellInfo->GetSpellClassOptions(); + + switch(m_spellInfo->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { @@ -326,8 +328,8 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) case 72624: case 72625: // Ooze Eruption { uint32 count = 0; - for (TargetList::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) - if (ihit->effectMask & (1 << effect_idx)) + for(TargetList::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + if(ihit->effectMask & (1<EffectIndex)) ++count; damage /= count; // divide to all targets @@ -366,7 +368,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) // Touch the Nightmare case 50341: { - if (effect_idx == EFFECT_INDEX_2) + if (SpellEffectIndex(effect->EffectIndex) == EFFECT_INDEX_2) damage = int32(unitTarget->GetMaxHealth() * 0.3f); break; } @@ -397,33 +399,39 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) } break; } + case SPELLFAMILY_MAGE: + // remove Arcane Blast buffs at any non-Arcane Blast arcane damage spell. + // NOTE: it removed at hit instead cast because currently spell done-damage calculated at hit instead cast + if ((m_spellInfo->SchoolMask & SPELL_SCHOOL_MASK_ARCANE) && !(classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x20000000))) + m_caster->RemoveAurasDueToSpell(36032); // Arcane Blast buff + break; case SPELLFAMILY_WARRIOR: { // Bloodthirst - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x40000000000)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x40000000000)) { damage = uint32(damage * (m_caster->GetTotalAttackPowerValue(BASE_ATTACK)) / 100); } // Shield Slam - else if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000020000000000)) && m_spellInfo->Category == 1209) + else if ((classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000020000000000)) && m_spellInfo->GetCategory()==1209) damage += int32(m_caster->GetShieldBlockValue()); // Victory Rush - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x10000000000)) + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x10000000000)) { damage = uint32(damage * m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100); m_caster->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, false); } // Revenge ${$m1+$AP*0.310} to ${$M1+$AP*0.310} - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000400)) - damage += uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.310f); + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000000400)) + damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.310f); // Heroic Throw ${$m1+$AP*.50} - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000100000000)) - damage += uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.5f); + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000100000000)) + damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.5f); // Shattering Throw ${$m1+$AP*.50} - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0040000000000000)) - damage += uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.5f); + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0040000000000000)) + damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.5f); // Shockwave ${$m3/100*$AP} - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000800000000000)) + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000800000000000)) { int32 pct = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, EFFECT_INDEX_2); if (pct > 0) @@ -431,7 +439,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) break; } // Thunder Clap - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000080)) + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000000080)) { damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 12 / 100); } @@ -440,7 +448,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) case SPELLFAMILY_WARLOCK: { // Incinerate Rank 1 & 2 - if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x00004000000000)) && m_spellInfo->SpellIconID == 2128) + if ((classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x00004000000000)) && m_spellInfo->SpellIconID==2128) { // Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff. // Check aura state for speed but aura state set not only for Immolate spell @@ -450,8 +458,11 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) for (Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) { // Immolate - if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && - ((*i)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x00000000000004))) + SpellClassOptionsEntry const* immSpellClassOpt = (*i)->GetSpellProto()->GetSpellClassOptions(); + if(!immSpellClassOpt) + continue; + if(immSpellClassOpt->SpellFamilyName == SPELLFAMILY_WARLOCK && + (immSpellClassOpt->SpellFamilyFlags & UI64LIT(0x00000000000004))) { damage += damage / 4; break; @@ -460,7 +471,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) } } // Shadowflame - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0001000000000000)) + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0001000000000000)) { // Apply DOT part switch (m_spellInfo->Id) @@ -473,7 +484,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) } } // Shadow Bite - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0040000000000000)) + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0040000000000000)) { Unit* owner = m_caster->GetOwner(); if (!owner) @@ -489,7 +500,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) damage += (counter * owner->CalculateSpellDamage(unitTarget, m_spellInfo, EFFECT_INDEX_2) * damage) / 100.0f; } // Conflagrate - consumes Immolate or Shadowflame - else if (m_spellInfo->TargetAuraState == AURA_STATE_CONFLAGRATE) + else if (m_spellInfo->GetTargetAuraState() == AURA_STATE_CONFLAGRATE) { Aura const* aura = NULL; // found req. aura for damage calculation @@ -497,8 +508,8 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) for (Unit::AuraList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i) { // for caster applied auras only - if ((*i)->GetSpellProto()->SpellFamilyName != SPELLFAMILY_WARLOCK || - (*i)->GetCasterGuid() != m_caster->GetObjectGuid()) + if ((*i)->GetSpellProto()->GetSpellFamilyName() != SPELLFAMILY_WARLOCK || + (*i)->GetCasterGuid() != m_caster->GetObjectGuid()) continue; // Immolate @@ -530,16 +541,16 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) case SPELLFAMILY_PRIEST: { // Shadow Word: Death - deals damage equal to damage done to caster - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000200000000)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000200000000)) m_caster->CastCustomSpell(m_caster, 32409, &damage, 0, 0, true); // Improved Mind Blast (Mind Blast in shadow form bonus) - else if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x00002000))) + else if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x00002000))) { Unit::AuraList const& ImprMindBlast = m_caster->GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER); for (Unit::AuraList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i) { - if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST && - ((*i)->GetSpellProto()->SpellIconID == 95)) + if ((*i)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_PRIEST && + ((*i)->GetSpellProto()->SpellIconID == 95)) { int chance = (*i)->GetSpellProto()->CalculateSimpleValue(EFFECT_INDEX_1); if (roll_chance_i(chance)) @@ -553,12 +564,13 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) } case SPELLFAMILY_DRUID: { + SpellEffectEntry const* rakeSpellEffect = m_spellInfo->GetSpellEffect(EFFECT_INDEX_2); // Ferocious Bite - if (m_caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x000800000)) && m_spellInfo->SpellVisual[0] == 6587) + if (m_caster->GetTypeId()==TYPEID_PLAYER && (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x000800000)) && m_spellInfo->SpellVisual[0]==6587) { // converts up to 30 points of energy into ($f1+$AP/410) additional damage float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); - float multiple = ap / 410 + m_spellInfo->DmgMultiplier[effect_idx]; + float multiple = ap / 410 + effect->DmgMultiplier; damage += int32(((Player*)m_caster)->GetComboPoints() * ap * 7 / 100); uint32 energy = m_caster->GetPower(POWER_ENERGY); uint32 used_energy = energy > 30 ? 30 : energy; @@ -566,13 +578,13 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) m_caster->SetPower(POWER_ENERGY, energy - used_energy); } // Rake - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000001000) && m_spellInfo->Effect[EFFECT_INDEX_2] == SPELL_EFFECT_ADD_COMBO_POINTS) + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000001000) && rakeSpellEffect && rakeSpellEffect->Effect == SPELL_EFFECT_ADD_COMBO_POINTS) { // $AP*0.01 bonus damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100); } // Swipe - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0010000000000000)) + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0010000000000000)) { damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.08f); } @@ -581,7 +593,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) case SPELLFAMILY_ROGUE: { // Envenom - if (m_caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x800000000))) + if (m_caster->GetTypeId()==TYPEID_PLAYER && (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x800000000))) { // consume from stack dozes not more that have combo-points if (uint32 combo = ((Player*)m_caster)->GetComboPoints()) @@ -589,11 +601,14 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) Aura* poison = 0; // Lookup for Deadly poison (only attacker applied) Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); - for (Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) { - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_ROGUE && - ((*itr)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x10000)) && - (*itr)->GetCasterGuid() == m_caster->GetObjectGuid()) + SpellClassOptionsEntry const* poisonClassOptions = (*itr)->GetSpellProto()->GetSpellClassOptions(); + if(!poisonClassOptions) + continue; + if( poisonClassOptions->SpellFamilyName==SPELLFAMILY_ROGUE && + (poisonClassOptions->SpellFamilyFlags & UI64LIT(0x10000)) && + (*itr)->GetCasterGuid() == m_caster->GetObjectGuid()) { poison = *itr; break; @@ -612,7 +627,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) Unit::AuraList const& auraList = ((Player*)m_caster)->GetAurasByType(SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL); for (Unit::AuraList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter) { - if ((*iter)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellProto()->SpellIconID == 1960) + if ((*iter)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_ROGUE && (*iter)->GetSpellProto()->SpellIconID == 1960) { if (int32 chance = (*iter)->GetSpellProto()->CalculateSimpleValue(EFFECT_INDEX_2)) if (roll_chance_i(chance)) @@ -634,7 +649,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) } } // Eviscerate - else if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x00020000)) && m_caster->GetTypeId() == TYPEID_PLAYER) + else if ((classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x00020000)) && m_caster->GetTypeId()==TYPEID_PLAYER) { if (uint32 combo = ((Player*)m_caster)->GetComboPoints()) { @@ -657,7 +672,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) damage *= 2; } // Steady Shot - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x100000000)) + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x100000000)) { int32 base = irand((int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE), (int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE)); damage += int32(float(base) / m_caster->GetAttackTime(RANGED_ATTACK) * 2800 + m_caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1f); @@ -676,7 +691,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) damage += int32(ap * 0.2f) + int32(holy * 32 / 100); } // Judgement of Vengeance/Corruption ${1+0.22*$SPH+0.14*$AP} + 10% for each application of Holy Vengeance/Blood Corruption on the target - else if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x800000000)) && m_spellInfo->SpellIconID == 2292) + else if ((classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x800000000)) && m_spellInfo->SpellIconID==2292) { uint32 debuf_id; switch (m_spellInfo->Id) @@ -707,7 +722,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) damage += damage * stacks * 10 / 100; } // Avenger's Shield ($m1+0.07*$SPH+0.07*$AP) - ranged sdb for future - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000004000)) + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000004000)) { float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); int32 holy = m_caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(m_spellInfo)); @@ -716,7 +731,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) damage += int32(ap * 0.07f) + int32(holy * 7 / 100); } // Hammer of Wrath ($m1+0.15*$SPH+0.15*$AP) - ranged type sdb future fix - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000008000000000)) + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000008000000000)) { float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); int32 holy = m_caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(m_spellInfo)); @@ -725,7 +740,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) damage += int32(ap * 0.15f) + int32(holy * 15 / 100); } // Hammer of the Righteous - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0004000000000000)) + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0004000000000000)) { // Add main hand dps * effect[2] amount float average = (m_caster->GetFloatValue(UNIT_FIELD_MINDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2; @@ -733,7 +748,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) damage += count * int32(average * IN_MILLISECONDS) / m_caster->GetAttackTime(BASE_ATTACK); } // Shield of Righteousness - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0010000000000000)) + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0010000000000000)) { damage += int32(m_caster->GetShieldBlockValue()); } @@ -752,13 +767,13 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) } } -void Spell::EffectDummy(SpellEffectIndex eff_idx) +void Spell::EffectDummy(SpellEffectEntry const* effect) { if (!unitTarget && !gameObjTarget && !itemTarget) return; // selection by spell family - switch (m_spellInfo->SpellFamilyName) + switch(m_spellInfo->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { @@ -1374,7 +1389,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) return; } - DoCreateItem(eff_idx, newitemid); + DoCreateItem(effect, newitemid); return; } case 40962: // Blade's Edge Terrace Demon Boss Summon Branch @@ -1649,7 +1664,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) } case 45958: // Signal Alliance { - m_caster->CastSpell(m_caster, m_spellInfo->CalculateSimpleValue(eff_idx), true); + m_caster->CastSpell(m_caster, effect->CalculateSimpleValue(), true); return; } case 45976: // Open Portal @@ -1671,7 +1686,8 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) if (const SpellEntry* pSpell = sSpellStore.LookupEntry(46022)) { m_caster->CastSpell(unitTarget, pSpell, true); - ((Player*)m_caster)->KilledMonsterCredit(pSpell->EffectMiscValue[EFFECT_INDEX_0]); + SpellEffectEntry const* killSpellEffect = pSpell->GetSpellEffect(EFFECT_INDEX_0); + ((Player*)m_caster)->KilledMonsterCredit(killSpellEffect ? killSpellEffect->EffectMiscValue : 0); } if (unitTarget->GetTypeId() == TYPEID_UNIT) @@ -1776,8 +1792,10 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) { m_caster->CastSpell(unitTarget, pSpell, true); - if (const SpellEntry* pSpellCredit = sSpellStore.LookupEntry(pSpell->EffectTriggerSpell[EFFECT_INDEX_0])) - ((Player*)m_caster)->KilledMonsterCredit(pSpellCredit->EffectMiscValue[EFFECT_INDEX_0]); + if (SpellEffectEntry const* pSpellEffect = pSpell->GetSpellEffect(EFFECT_INDEX_0)) + if (const SpellEntry *pSpellCredit = sSpellStore.LookupEntry(pSpellEffect->EffectTriggerSpell)) + if(SpellEffectEntry const* pSpellCreditEffect = pSpellCredit->GetSpellEffect(EFFECT_INDEX_0)) + ((Player*)m_caster)->KilledMonsterCredit(pSpellCreditEffect->EffectMiscValue); ((Creature*)unitTarget)->ForcedDespawn(); } @@ -1984,7 +2002,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) { const SpellEntry* pSpell = sSpellStore.LookupEntry(spellCredit[i]); - if (pSpell->EffectMiscValue[EFFECT_INDEX_0] == unitTarget->GetEntry()) + if (pSpell->GetEffectMiscValue(EFFECT_INDEX_0) == unitTarget->GetEntry()) { m_caster->CastSpell(m_caster, spellCredit[i], true); break; @@ -2247,7 +2265,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) } case 52308: // Take Sputum Sample { - switch (eff_idx) + switch(effect->EffectIndex) { case EFFECT_INDEX_0: { @@ -2347,11 +2365,11 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) if (m_caster->GetTypeId() != TYPEID_PLAYER) return; - if (eff_idx == EFFECT_INDEX_0) + if (effect->EffectIndex == EFFECT_INDEX_0) { Player* pPlayer = (Player*)m_caster; - uint32 faction_id = m_currentBasePoints[eff_idx]; + uint32 faction_id = m_currentBasePoints[effect->EffectIndex]; int32 rep_change = m_currentBasePoints[EFFECT_INDEX_1]; FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id); @@ -2614,7 +2632,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) if (!unitTarget) return; - m_caster->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(eff_idx), true); + m_caster->CastSpell(unitTarget, effect->CalculateSimpleValue(), true); return; } case 71837: // Vampiric Bite @@ -2659,9 +2677,9 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) { SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->first); - if (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && - (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_FROST) && - spellInfo->Id != 11958 && GetSpellRecoveryTime(spellInfo) > 0) + if (spellInfo->GetSpellFamilyName() == SPELLFAMILY_MAGE && + (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_FROST) && + spellInfo->Id != 11958 && GetSpellRecoveryTime(spellInfo) > 0) { ((Player*)m_caster)->RemoveSpellCooldown((itr++)->first, true); } @@ -2708,7 +2726,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) } // Conjure Mana Gem - if (eff_idx == EFFECT_INDEX_1 && m_spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_CREATE_ITEM) + if (effect->EffectIndex == EFFECT_INDEX_1 && m_spellInfo->GetSpellEffectIdByIndex(EFFECT_INDEX_0) == SPELL_EFFECT_CREATE_ITEM) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -2718,22 +2736,23 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) if (item->HasMaxCharges()) return; - unitTarget->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(eff_idx), true, m_CastItem); + unitTarget->CastSpell( unitTarget, effect->CalculateSimpleValue(), true, m_CastItem); return; } break; } case SPELLFAMILY_WARRIOR: { + SpellClassOptionsEntry const* warClassOptions = m_spellInfo->GetSpellClassOptions(); // Charge - if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x1)) && m_spellInfo->SpellVisual[0] == 867) + if (warClassOptions && (warClassOptions->SpellFamilyFlags & UI64LIT(0x1)) && m_spellInfo->SpellVisual[0] == 867) { int32 chargeBasePoints0 = damage; m_caster->CastCustomSpell(m_caster, 34846, &chargeBasePoints0, NULL, NULL, true); return; } // Execute - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x20000000)) + if (warClassOptions && warClassOptions->SpellFamilyFlags & UI64LIT(0x20000000)) { if (!unitTarget) return; @@ -2750,8 +2769,8 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) if (Aura* aura = m_caster->GetDummyAura(58367)) rage_modified += aura->GetModifier()->m_amount * 10; - int32 basePoints0 = damage + int32(rage_modified * m_spellInfo->DmgMultiplier[eff_idx] + - m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.2f); + int32 basePoints0 = damage+int32(rage_modified * effect->DmgMultiplier + + m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f); m_caster->CastCustomSpell(unitTarget, 20647, &basePoints0, NULL, NULL, true, 0); @@ -2777,7 +2796,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) return; } // Slam - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000200000)) + if (warClassOptions && warClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000200000)) { if (!unitTarget) return; @@ -2787,7 +2806,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) return; } // Concussion Blow - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000004000000)) + if (warClassOptions && warClassOptions->SpellFamilyFlags & UI64LIT(0x0000000004000000)) { m_damage += uint32(damage * m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100); return; @@ -2821,8 +2840,9 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) } case SPELLFAMILY_WARLOCK: { + SpellClassOptionsEntry const* wrlClassOptions = m_spellInfo->GetSpellClassOptions(); // Life Tap - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000040000)) + if (wrlClassOptions && wrlClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000040000)) { if (unitTarget && (int32(unitTarget->GetHealth()) > damage)) { @@ -2834,9 +2854,9 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) // Improved Life Tap mod Unit::AuraList const& auraDummy = m_caster->GetAurasByType(SPELL_AURA_DUMMY); - for (Unit::AuraList::const_iterator itr = auraDummy.begin(); itr != auraDummy.end(); ++itr) - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (*itr)->GetSpellProto()->SpellIconID == 208) - mana = ((*itr)->GetModifier()->m_amount + 100) * mana / 100; + for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr != auraDummy.end(); ++itr) + if((*itr)->GetSpellProto()->GetSpellFamilyName()==SPELLFAMILY_WARLOCK && (*itr)->GetSpellProto()->SpellIconID == 208) + mana = ((*itr)->GetModifier()->m_amount + 100)* mana / 100; m_caster->CastCustomSpell(unitTarget, 31818, &mana, NULL, NULL, true); @@ -2845,8 +2865,8 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) Unit::AuraList const& mod = m_caster->GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER); for (Unit::AuraList::const_iterator itr = mod.begin(); itr != mod.end(); ++itr) { - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (*itr)->GetSpellProto()->SpellIconID == 1982) - manaFeedVal += (*itr)->GetModifier()->m_amount; + if((*itr)->GetSpellProto()->GetSpellFamilyName()==SPELLFAMILY_WARLOCK && (*itr)->GetSpellProto()->SpellIconID == 1982) + manaFeedVal+= (*itr)->GetModifier()->m_amount; } if (manaFeedVal > 0) { @@ -2863,8 +2883,9 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) } case SPELLFAMILY_PRIEST: { + SpellClassOptionsEntry const* prtsClassOptions = m_spellInfo->GetSpellClassOptions(); // Penance - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0080000000000000)) + if (prtsClassOptions && prtsClassOptions->SpellFamilyFlags & UI64LIT(0x0080000000000000)) { if (!unitTarget) return; @@ -2955,7 +2976,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) continue; SpellEntry const* combatEntry = sSpellStore.LookupEntry(pEnchant->spellid[s]); - if (!combatEntry || combatEntry->Dispel != DISPEL_POISON) + if (!combatEntry || combatEntry->GetDispel() != DISPEL_POISON) continue; m_caster->CastSpell(unitTarget, combatEntry, true, item); @@ -2973,10 +2994,10 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) const SpellCooldowns& cm = ((Player*)m_caster)->GetSpellCooldownMap(); for (SpellCooldowns::const_iterator itr = cm.begin(); itr != cm.end();) { - SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->first); - - if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & UI64LIT(0x0000024000000860))) - ((Player*)m_caster)->RemoveSpellCooldown((itr++)->first, true); + SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); + SpellClassOptionsEntry const* prepClassOptions = spellInfo->GetSpellClassOptions(); + if (prepClassOptions && prepClassOptions->SpellFamilyName == SPELLFAMILY_ROGUE && (prepClassOptions->SpellFamilyFlags & UI64LIT(0x0000024000000860))) + ((Player*)m_caster)->RemoveSpellCooldown((itr++)->first,true); else ++itr; } @@ -2998,8 +3019,9 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) } case SPELLFAMILY_HUNTER: { + SpellClassOptionsEntry const* huntClassOptions = m_spellInfo->GetSpellClassOptions(); // Steady Shot - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x100000000)) + if (huntClassOptions && huntClassOptions->SpellFamilyFlags & UI64LIT(0x100000000)) { if (!unitTarget || !unitTarget->isAlive()) return; @@ -3010,7 +3032,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) Unit::AuraList const& decSpeedList = unitTarget->GetAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); for (Unit::AuraList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter) { - if ((*iter)->GetSpellProto()->SpellIconID == 15 && (*iter)->GetSpellProto()->Dispel == 0) + if ((*iter)->GetSpellProto()->SpellIconID==15 && (*iter)->GetSpellProto()->GetDispel()==0) { found = true; break; @@ -3023,7 +3045,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) } // Disengage - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000400000000000)) + if (huntClassOptions && huntClassOptions->SpellFamilyFlags & UI64LIT(0x0000400000000000)) { Unit* target = unitTarget; uint32 spellid; @@ -3053,8 +3075,8 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) { SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->first); - if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && spellInfo->Id != 23989 && GetSpellRecoveryTime(spellInfo) > 0) - ((Player*)m_caster)->RemoveSpellCooldown((itr++)->first, true); + if (spellInfo->GetSpellFamilyName() == SPELLFAMILY_HUNTER && spellInfo->Id != 23989 && GetSpellRecoveryTime(spellInfo) > 0 ) + ((Player*)m_caster)->RemoveSpellCooldown((itr++)->first,true); else ++itr; } @@ -3087,7 +3109,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) if (!pet || !unitTarget) return; - pet->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(eff_idx), true); + pet->CastSpell(unitTarget, effect->CalculateSimpleValue(), true); return; } } @@ -3131,7 +3153,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) if (!unitTarget) return; - uint32 spell_id = m_currentBasePoints[eff_idx]; + uint32 spell_id = m_currentBasePoints[effect->EffectIndex]; SpellEntry const* spell_proto = sSpellStore.LookupEntry(spell_id); if (!spell_proto) return; @@ -3211,15 +3233,16 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) } case SPELLFAMILY_SHAMAN: { + SpellClassOptionsEntry const* shamClassOptions = m_spellInfo->GetSpellClassOptions(); // Cleansing Totem - if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000004000000)) && m_spellInfo->SpellIconID == 1673) + if (shamClassOptions && (shamClassOptions->SpellFamilyFlags & UI64LIT(0x0000000004000000)) && m_spellInfo->SpellIconID==1673) { if (unitTarget) m_caster->CastSpell(unitTarget, 52025, true); return; } // Healing Stream Totem - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000002000)) + if (shamClassOptions && shamClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000002000)) { if (unitTarget) { @@ -3236,7 +3259,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) Unit::AuraList const& mDummyAuras = owner->GetAurasByType(SPELL_AURA_DUMMY); for (Unit::AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) // only its have dummy with specific icon - if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (*i)->GetSpellProto()->SpellIconID == 338) + if ((*i)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_SHAMAN && (*i)->GetSpellProto()->SpellIconID == 338) damage += (*i)->GetModifier()->m_amount * damage / 100; // Glyph of Healing Stream Totem @@ -3248,7 +3271,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) return; } // Mana Spring Totem - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000004000)) + if (shamClassOptions && shamClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000004000)) { if (!unitTarget || unitTarget->getPowerType() != POWER_MANA) return; @@ -3256,7 +3279,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) return; } // Flametongue Weapon Proc, Ranks - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000200000)) + if (shamClassOptions && shamClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000200000)) { if (!m_CastItem) { @@ -3298,9 +3321,8 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) Unit::AuraList const& auraDummy = m_caster->GetAurasByType(SPELL_AURA_DUMMY); for (Unit::AuraList::const_iterator itr = auraDummy.begin(); itr != auraDummy.end(); ++itr) { - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && - ((*itr)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000200000)) && - (*itr)->GetCastItemGuid() == item->GetObjectGuid()) + if ((*itr)->GetSpellProto()->IsFitToFamily(SPELLFAMILY_SHAMAN, UI64LIT(0x0000000000200000)) && + (*itr)->GetCastItemGuid() == item->GetObjectGuid()) { m_damage += m_damage * damage / 100; return; @@ -3342,8 +3364,9 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) } case SPELLFAMILY_DEATHKNIGHT: { + SpellClassOptionsEntry const* dkClassOptions = m_spellInfo->GetSpellClassOptions(); // Death Coil - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x002000)) + if (dkClassOptions && dkClassOptions->SpellFamilyFlags & UI64LIT(0x002000)) { if (m_caster->IsFriendlyTo(unitTarget)) { @@ -3361,20 +3384,20 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) return; } // Hungering Cold - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000100000000000)) + else if (dkClassOptions && dkClassOptions->SpellFamilyFlags & UI64LIT(0x0000100000000000)) { m_caster->CastSpell(m_caster, 51209, true); return; } // Death Strike - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000010)) + else if (dkClassOptions && dkClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000010)) { uint32 count = 0; Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap(); for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - if (itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE && - itr->second->GetCasterGuid() == m_caster->GetObjectGuid()) + if (itr->second->GetSpellProto()->GetDispel() == DISPEL_DISEASE && + itr->second->GetCasterGuid() == m_caster->GetObjectGuid()) { ++count; // max. 15% @@ -3383,14 +3406,15 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) } } - int32 bp = int32(count * m_caster->GetMaxHealth() * m_spellInfo->DmgMultiplier[EFFECT_INDEX_0] / 100); + SpellEffectEntry const* dsSpellEffect = m_spellInfo->GetSpellEffect(EFFECT_INDEX_0); + int32 bp = int32(count * m_caster->GetMaxHealth() * (dsSpellEffect ? dsSpellEffect->DmgMultiplier : 0.0f) / 100); // Improved Death Strike (percent stored in nonexistent EFFECT_INDEX_2 effect base points) Unit::AuraList const& auraMod = m_caster->GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER); for (Unit::AuraList::const_iterator iter = auraMod.begin(); iter != auraMod.end(); ++iter) { // only required spell have spellicon for SPELL_AURA_ADD_FLAT_MODIFIER - if ((*iter)->GetSpellProto()->SpellIconID == 2751 && (*iter)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT) + if ((*iter)->GetSpellProto()->SpellIconID == 2751 && (*iter)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_DEATHKNIGHT) { bp += (*iter)->GetSpellProto()->CalculateSimpleValue(EFFECT_INDEX_2) * bp / 100; break; @@ -3401,13 +3425,13 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) return; } // Obliterate - else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0002000000000000)) + else if (dkClassOptions && dkClassOptions->SpellFamilyFlags & UI64LIT(0x0002000000000000)) { // search for Annihilation Unit::AuraList const& dummyList = m_caster->GetAurasByType(SPELL_AURA_DUMMY); for (Unit::AuraList::const_iterator itr = dummyList.begin(); itr != dummyList.end(); ++itr) { - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && (*itr)->GetSpellProto()->SpellIconID == 2710) + if ((*itr)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_DEATHKNIGHT && (*itr)->GetSpellProto()->SpellIconID == 2710) { if (roll_chance_i((*itr)->GetModifier()->m_amount)) // don't consume if found return; @@ -3424,7 +3448,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) } // pet auras - if (PetAura const* petSpell = sSpellMgr.GetPetAura(m_spellInfo->Id, eff_idx)) + if (PetAura const* petSpell = sSpellMgr.GetPetAura(m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex))) { m_caster->AddPetAura(petSpell); return; @@ -3434,26 +3458,26 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) // So called only for not processed cases bool libraryResult = false; if (gameObjTarget) - libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, eff_idx, gameObjTarget); + libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex), gameObjTarget); else if (unitTarget && unitTarget->GetTypeId() == TYPEID_UNIT) - libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, eff_idx, (Creature*)unitTarget); + libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex), (Creature*)unitTarget); else if (itemTarget) - libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, eff_idx, itemTarget); + libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex), itemTarget); if (libraryResult || !unitTarget) return; // Previous effect might have started script - if (!ScriptMgr::CanSpellEffectStartDBScript(m_spellInfo, eff_idx)) + if (!ScriptMgr::CanSpellEffectStartDBScript(m_spellInfo, SpellEffectIndex(effect->EffectIndex))) return; DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell ScriptStart spellid %u in EffectDummy", m_spellInfo->Id); m_caster->GetMap()->ScriptsStart(sSpellScripts, m_spellInfo->Id, m_caster, unitTarget); } -void Spell::EffectTriggerSpellWithValue(SpellEffectIndex eff_idx) +void Spell::EffectTriggerSpellWithValue(SpellEffectEntry const* effect) { - uint32 triggered_spell_id = m_spellInfo->EffectTriggerSpell[eff_idx]; + uint32 triggered_spell_id = effect->EffectTriggerSpell; // normal case SpellEntry const* spellInfo = sSpellStore.LookupEntry(triggered_spell_id); @@ -3468,10 +3492,10 @@ void Spell::EffectTriggerSpellWithValue(SpellEffectIndex eff_idx) m_caster->CastCustomSpell(unitTarget, triggered_spell_id, &bp, &bp, &bp, true, NULL, NULL, m_originalCasterGUID); } -void Spell::EffectTriggerRitualOfSummoning(SpellEffectIndex eff_idx) +void Spell::EffectTriggerRitualOfSummoning(SpellEffectEntry const* effect) { - uint32 triggered_spell_id = m_spellInfo->EffectTriggerSpell[eff_idx]; - SpellEntry const* spellInfo = sSpellStore.LookupEntry(triggered_spell_id); + uint32 triggered_spell_id = effect->EffectTriggerSpell; + SpellEntry const *spellInfo = sSpellStore.LookupEntry( triggered_spell_id ); if (!spellInfo) { @@ -3484,14 +3508,14 @@ void Spell::EffectTriggerRitualOfSummoning(SpellEffectIndex eff_idx) m_caster->CastSpell(unitTarget, spellInfo, false); } -void Spell::EffectClearQuest(SpellEffectIndex eff_idx) +void Spell::EffectClearQuest(SpellEffectEntry const* effect) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; Player* player = (Player*)m_caster; - uint32 quest_id = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 quest_id = effect->EffectMiscValue; if (!sObjectMgr.GetQuestTemplate(quest_id)) { @@ -3516,12 +3540,12 @@ void Spell::EffectClearQuest(SpellEffectIndex eff_idx) player->getQuestStatusMap()[quest_id].m_rewarded = false; } -void Spell::EffectForceCast(SpellEffectIndex eff_idx) +void Spell::EffectForceCast(SpellEffectEntry const* effect) { if (!unitTarget) return; - uint32 triggered_spell_id = m_spellInfo->EffectTriggerSpell[eff_idx]; + uint32 triggered_spell_id = effect->EffectTriggerSpell; // normal case SpellEntry const* spellInfo = sSpellStore.LookupEntry(triggered_spell_id); @@ -3535,7 +3559,7 @@ void Spell::EffectForceCast(SpellEffectIndex eff_idx) unitTarget->CastSpell(unitTarget, spellInfo, true, NULL, NULL, m_originalCasterGUID, m_spellInfo); } -void Spell::EffectTriggerSpell(SpellEffectIndex effIndex) +void Spell::EffectTriggerSpell(SpellEffectEntry const* effect) { // only unit case known if (!unitTarget) @@ -3545,7 +3569,7 @@ void Spell::EffectTriggerSpell(SpellEffectIndex effIndex) return; } - uint32 triggered_spell_id = m_spellInfo->EffectTriggerSpell[effIndex]; + uint32 triggered_spell_id = effect->EffectTriggerSpell; // special cases switch (triggered_spell_id) @@ -3632,7 +3656,7 @@ void Spell::EffectTriggerSpell(SpellEffectIndex effIndex) if (!spellInfo) { // No previous Effect might have started a script - bool startDBScript = unitTarget && ScriptMgr::CanSpellEffectStartDBScript(m_spellInfo, effIndex); + bool startDBScript = unitTarget && ScriptMgr::CanSpellEffectStartDBScript(m_spellInfo, SpellEffectIndex(effect->EffectIndex)); if (startDBScript) { DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell ScriptStart spellid %u in EffectTriggerSpell", m_spellInfo->Id); @@ -3648,7 +3672,7 @@ void Spell::EffectTriggerSpell(SpellEffectIndex effIndex) Unit* caster = m_caster; // some triggered spells require specific equipment - if (spellInfo->EquippedItemClass >= 0 && m_caster->GetTypeId() == TYPEID_PLAYER) + if (spellInfo->GetEquippedItemClass() >=0 && m_caster->GetTypeId()==TYPEID_PLAYER) { // main hand weapon required if (spellInfo->HasAttribute(SPELL_ATTR_EX3_MAIN_HAND)) @@ -3688,9 +3712,9 @@ void Spell::EffectTriggerSpell(SpellEffectIndex effIndex) caster->CastSpell(unitTarget, spellInfo, true, NULL, NULL, m_originalCasterGUID); } -void Spell::EffectTriggerMissileSpell(SpellEffectIndex effect_idx) +void Spell::EffectTriggerMissileSpell(SpellEffectEntry const* effect) { - uint32 triggered_spell_id = m_spellInfo->EffectTriggerSpell[effect_idx]; + uint32 triggered_spell_id = effect->EffectTriggerSpell; // normal case SpellEntry const* spellInfo = sSpellStore.LookupEntry(triggered_spell_id); @@ -3698,7 +3722,7 @@ void Spell::EffectTriggerMissileSpell(SpellEffectIndex effect_idx) if (!spellInfo) { sLog.outError("EffectTriggerMissileSpell of spell %u (eff: %u): triggering unknown spell id %u", - m_spellInfo->Id, effect_idx, triggered_spell_id); + m_spellInfo->Id,effect->EffectIndex,triggered_spell_id); return; } @@ -3708,7 +3732,7 @@ void Spell::EffectTriggerMissileSpell(SpellEffectIndex effect_idx) m_caster->CastSpell(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, spellInfo, true, m_CastItem, 0, m_originalCasterGUID); } -void Spell::EffectJump(SpellEffectIndex eff_idx) +void Spell::EffectJump(SpellEffectEntry const* effect) { if (m_caster->IsTaxiFlying()) return; @@ -3721,7 +3745,7 @@ void Spell::EffectJump(SpellEffectIndex eff_idx) y = m_targets.m_destY; z = m_targets.m_destZ; - if (m_spellInfo->EffectImplicitTargetA[eff_idx] == TARGET_BEHIND_VICTIM) + if(effect->EffectImplicitTargetA == TARGET_BEHIND_VICTIM) { // explicit cast data from client or server-side cast // some spell at client send caster @@ -3757,15 +3781,15 @@ void Spell::EffectJump(SpellEffectIndex eff_idx) m_caster->NearTeleportTo(x, y, z, o, true); } -void Spell::EffectTeleportUnits(SpellEffectIndex eff_idx) +void Spell::EffectTeleportUnits(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->IsTaxiFlying()) return; // Target dependend on TargetB, if there is none provided, decide dependend on A - uint32 targetType = m_spellInfo->EffectImplicitTargetB[eff_idx]; + uint32 targetType = effect->EffectImplicitTargetB; if (!targetType) - targetType = m_spellInfo->EffectImplicitTargetA[eff_idx]; + targetType = effect->EffectImplicitTargetA; switch (targetType) { @@ -3832,7 +3856,7 @@ void Spell::EffectTeleportUnits(SpellEffectIndex eff_idx) // If not exist data for dest location - return if (!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)) { - sLog.outError("Spell::EffectTeleportUnits - unknown EffectImplicitTargetB[%u] = %u for spell ID %u", eff_idx, m_spellInfo->EffectImplicitTargetB[eff_idx], m_spellInfo->Id); + sLog.outError( "Spell::EffectTeleportUnits - unknown EffectImplicitTargetB[%u] = %u for spell ID %u", effect->EffectIndex, effect->EffectImplicitTargetB, m_spellInfo->Id ); return; } // Init dest coordinates @@ -3943,7 +3967,7 @@ void Spell::EffectTeleportUnits(SpellEffectIndex eff_idx) } } -void Spell::EffectApplyAura(SpellEffectIndex eff_idx) +void Spell::EffectApplyAura(SpellEffectEntry const* effect) { if (!unitTarget) return; @@ -3964,31 +3988,31 @@ void Spell::EffectApplyAura(SpellEffectIndex eff_idx) return; } - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell: Aura is: %u", m_spellInfo->EffectApplyAuraName[eff_idx]); + DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell: Aura is: %u", effect->EffectApplyAuraName); - Aura* aur = CreateAura(m_spellInfo, eff_idx, &m_currentBasePoints[eff_idx], m_spellAuraHolder, unitTarget, caster, m_CastItem); - m_spellAuraHolder->AddAura(aur, eff_idx); + Aura* aur = CreateAura(m_spellInfo, SpellEffectIndex(effect->EffectIndex), &m_currentBasePoints[effect->EffectIndex], m_spellAuraHolder, unitTarget, caster, m_CastItem); + m_spellAuraHolder->AddAura(aur, SpellEffectIndex(effect->EffectIndex)); } -void Spell::EffectUnlearnSpecialization(SpellEffectIndex eff_idx) +void Spell::EffectUnlearnSpecialization(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - Player* _player = (Player*)unitTarget; - uint32 spellToUnlearn = m_spellInfo->EffectTriggerSpell[eff_idx]; + Player *_player = (Player*)unitTarget; + uint32 spellToUnlearn = effect->EffectTriggerSpell; _player->removeSpell(spellToUnlearn); DEBUG_LOG("Spell: Player %u has unlearned spell %u from NpcGUID: %u", _player->GetGUIDLow(), spellToUnlearn, m_caster->GetGUIDLow()); } -void Spell::EffectPowerDrain(SpellEffectIndex eff_idx) +void Spell::EffectPowerDrain(SpellEffectEntry const* effect) { - if (m_spellInfo->EffectMiscValue[eff_idx] < 0 || m_spellInfo->EffectMiscValue[eff_idx] >= MAX_POWERS) + if(effect->EffectMiscValue < 0 || effect->EffectMiscValue >= MAX_POWERS) return; - Powers drain_power = Powers(m_spellInfo->EffectMiscValue[eff_idx]); + Powers drain_power = Powers(effect->EffectMiscValue); if (!unitTarget) return; @@ -4021,8 +4045,8 @@ void Spell::EffectPowerDrain(SpellEffectIndex eff_idx) // Don`t restore from self drain if (drain_power == POWER_MANA && m_caster != unitTarget) { - float manaMultiplier = m_spellInfo->EffectMultipleValue[eff_idx]; - if (manaMultiplier == 0) + float manaMultiplier = effect->EffectMultipleValue; + if(manaMultiplier==0) manaMultiplier = 1; if (Player* modOwner = m_caster->GetSpellModOwner()) @@ -4034,23 +4058,23 @@ void Spell::EffectPowerDrain(SpellEffectIndex eff_idx) } } -void Spell::EffectSendEvent(SpellEffectIndex effectIndex) +void Spell::EffectSendEvent(SpellEffectEntry const* effect) { /* we do not handle a flag dropping or clicking on flag in battleground by sendevent system */ - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell ScriptStart %u for spellid %u in EffectSendEvent ", m_spellInfo->EffectMiscValue[effectIndex], m_spellInfo->Id); + DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell ScriptStart %u for spellid %u in EffectSendEvent ", effect->EffectMiscValue, m_spellInfo->Id); - if (!sScriptMgr.OnProcessEvent(m_spellInfo->EffectMiscValue[effectIndex], m_caster, focusObject, true)) - m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->EffectMiscValue[effectIndex], m_caster, focusObject); + if (!sScriptMgr.OnProcessEvent(effect->EffectMiscValue, m_caster, focusObject, true)) + m_caster->GetMap()->ScriptsStart(sEventScripts, effect->EffectMiscValue, m_caster, focusObject); } -void Spell::EffectPowerBurn(SpellEffectIndex eff_idx) +void Spell::EffectPowerBurn(SpellEffectEntry const* effect) { - if (m_spellInfo->EffectMiscValue[eff_idx] < 0 || m_spellInfo->EffectMiscValue[eff_idx] >= MAX_POWERS) + if (effect->EffectMiscValue < 0 || effect->EffectMiscValue >= MAX_POWERS) return; - Powers powertype = Powers(m_spellInfo->EffectMiscValue[eff_idx]); + Powers powertype = Powers(effect->EffectMiscValue); if (!unitTarget) return; @@ -4062,7 +4086,7 @@ void Spell::EffectPowerBurn(SpellEffectIndex eff_idx) return; // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn) - if (m_spellInfo->ManaCostPercentage) + if (m_spellInfo->GetManaCostPercentage()) { int32 maxdamage = m_caster->GetMaxPower(powertype) * damage * 2 / 100; damage = unitTarget->GetMaxPower(powertype) * damage / 100; @@ -4080,7 +4104,7 @@ void Spell::EffectPowerBurn(SpellEffectIndex eff_idx) int32 new_damage = (curPower < power) ? curPower : power; unitTarget->ModifyPower(powertype, -new_damage); - float multiplier = m_spellInfo->EffectMultipleValue[eff_idx]; + float multiplier = effect->EffectMultipleValue; if (Player* modOwner = m_caster->GetSpellModOwner()) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_MULTIPLE_VALUE, multiplier); @@ -4089,7 +4113,7 @@ void Spell::EffectPowerBurn(SpellEffectIndex eff_idx) m_damage += new_damage; } -void Spell::EffectHeal(SpellEffectIndex /*eff_idx*/) +void Spell::EffectHeal(SpellEffectEntry const* /*effect*/) { if (unitTarget && unitTarget->isAlive() && damage >= 0) { @@ -4127,16 +4151,17 @@ void Spell::EffectHeal(SpellEffectIndex /*eff_idx*/) else if (m_spellInfo->Id == 48743) addhealth = addhealth * unitTarget->GetMaxHealth() / 100; // Swiftmend - consumes Regrowth or Rejuvenation - else if (m_spellInfo->TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND)) + else if (m_spellInfo->GetTargetAuraState() == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND)) { Unit::AuraList const& RejorRegr = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_HEAL); // find most short by duration Aura* targetAura = NULL; for (Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) { - if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && - // Regrowth or Rejuvenation 0x40 | 0x10 - ((*i)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000050))) + SpellClassOptionsEntry const* smClassOptions = (*i)->GetSpellProto()->GetSpellClassOptions(); + if (smClassOptions && smClassOptions->SpellFamilyName == SPELLFAMILY_DRUID && + // Regrowth or Rejuvenation 0x40 | 0x10 + (smClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000050))) { if (!targetAura || (*i)->GetAuraDuration() < targetAura->GetAuraDuration()) targetAura = *i; @@ -4149,15 +4174,17 @@ void Spell::EffectHeal(SpellEffectIndex /*eff_idx*/) return; } int idx = 0; - while (idx < 3) + SpellEffectEntry const* targetSpellEffect = NULL; + while(idx < 3) { - if (targetAura->GetSpellProto()->EffectApplyAuraName[idx] == SPELL_AURA_PERIODIC_HEAL) + targetSpellEffect = targetAura->GetSpellProto()->GetSpellEffect(SpellEffectIndex(idx)); + if(targetSpellEffect && targetSpellEffect->EffectApplyAuraName == SPELL_AURA_PERIODIC_HEAL) break; ++idx; } int32 tickheal = targetAura->GetModifier()->m_amount; - int32 tickcount = GetSpellDuration(targetAura->GetSpellProto()) / targetAura->GetSpellProto()->EffectAmplitude[idx] - 1; + int32 tickcount = GetSpellDuration(targetAura->GetSpellProto()) / (targetSpellEffect ? targetSpellEffect->EffectAmplitude : 1) - 1; // Glyph of Swiftmend if (!caster->HasAura(54824)) @@ -4174,7 +4201,8 @@ void Spell::EffectHeal(SpellEffectIndex /*eff_idx*/) } // Chain Healing - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000100)) + SpellClassOptionsEntry const* chClassOptions = m_spellInfo->GetSpellClassOptions(); + if (chClassOptions && chClassOptions->SpellFamilyName == SPELLFAMILY_SHAMAN && chClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000100)) { if (unitTarget == m_targets.getUnitTarget()) { @@ -4195,7 +4223,7 @@ void Spell::EffectHeal(SpellEffectIndex /*eff_idx*/) } } -void Spell::EffectHealPct(SpellEffectIndex /*eff_idx*/) +void Spell::EffectHealPct(SpellEffectEntry const* /*effect*/) { if (unitTarget && unitTarget->isAlive() && damage >= 0) { @@ -4217,7 +4245,7 @@ void Spell::EffectHealPct(SpellEffectIndex /*eff_idx*/) } } -void Spell::EffectHealMechanical(SpellEffectIndex /*eff_idx*/) +void Spell::EffectHealMechanical(SpellEffectEntry const* /*effect*/) { // Mechanic creature type should be correctly checked by targetCreatureType field if (unitTarget && unitTarget->isAlive() && damage >= 0) @@ -4237,7 +4265,7 @@ void Spell::EffectHealMechanical(SpellEffectIndex /*eff_idx*/) } } -void Spell::EffectHealthLeech(SpellEffectIndex eff_idx) +void Spell::EffectHealthLeech(SpellEffectEntry const* effect) { if (!unitTarget) return; @@ -4254,7 +4282,7 @@ void Spell::EffectHealthLeech(SpellEffectIndex eff_idx) if ((int32)curHealth < damage) damage = curHealth; - float multiplier = m_spellInfo->EffectMultipleValue[eff_idx]; + float multiplier = effect->EffectMultipleValue; if (Player* modOwner = m_caster->GetSpellModOwner()) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_MULTIPLE_VALUE, multiplier); @@ -4271,7 +4299,7 @@ void Spell::EffectHealthLeech(SpellEffectIndex eff_idx) } } -void Spell::DoCreateItem(SpellEffectIndex eff_idx, uint32 itemtype) +void Spell::DoCreateItem(SpellEffectEntry const* effect, uint32 itemtype) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -4334,7 +4362,7 @@ void Spell::DoCreateItem(SpellEffectIndex eff_idx, uint32 itemtype) else { // ignore mana gem case (next effect will recharge existing example) - if (eff_idx == EFFECT_INDEX_0 && m_spellInfo->Effect[EFFECT_INDEX_1] == SPELL_EFFECT_DUMMY) + if (effect->EffectIndex == EFFECT_INDEX_0 && m_spellInfo->GetSpellEffectIdByIndex(EFFECT_INDEX_1) == SPELL_EFFECT_DUMMY ) return; // if not created by another reason from full inventory or unique items amount limitation @@ -4368,22 +4396,22 @@ void Spell::DoCreateItem(SpellEffectIndex eff_idx, uint32 itemtype) } } -void Spell::EffectCreateItem(SpellEffectIndex eff_idx) +void Spell::EffectCreateItem(SpellEffectEntry const* effect) { - DoCreateItem(eff_idx, m_spellInfo->EffectItemType[eff_idx]); + DoCreateItem(effect, effect->EffectItemType); } -void Spell::EffectCreateItem2(SpellEffectIndex eff_idx) +void Spell::EffectCreateItem2(SpellEffectEntry const* effect) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; Player* player = (Player*)m_caster; // explicit item (possible fake) - uint32 item_id = m_spellInfo->EffectItemType[eff_idx]; + uint32 item_id = effect->EffectItemType; if (item_id) - DoCreateItem(eff_idx, item_id); + DoCreateItem(effect, item_id); // not explicit loot (with fake item drop if need) if (IsLootCraftingSpell(m_spellInfo)) @@ -4403,7 +4431,7 @@ void Spell::EffectCreateItem2(SpellEffectIndex eff_idx) } } -void Spell::EffectCreateRandomItem(SpellEffectIndex /*eff_idx*/) +void Spell::EffectCreateRandomItem(SpellEffectEntry const* /*effect*/) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -4413,21 +4441,20 @@ void Spell::EffectCreateRandomItem(SpellEffectIndex /*eff_idx*/) player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); } -void Spell::EffectPersistentAA(SpellEffectIndex eff_idx) +void Spell::EffectPersistentAA(SpellEffectEntry const* effect) { Unit* pCaster = GetAffectiveCaster(); // FIXME: in case wild GO will used wrong affective caster (target in fact) as dynobject owner if (!pCaster) pCaster = m_caster; - float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[eff_idx])); + float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->EffectRadiusIndex)); if (Player* modOwner = pCaster->GetSpellModOwner()) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius); DynamicObject* dynObj = new DynamicObject; - if (!dynObj->Create(pCaster->GetMap()->GenerateLocalLowGuid(HIGHGUID_DYNAMICOBJECT), pCaster, m_spellInfo->Id, - eff_idx, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, m_duration, radius, DYNAMIC_OBJECT_AREA_SPELL)) + if (!dynObj->Create(pCaster->GetMap()->GenerateLocalLowGuid(HIGHGUID_DYNAMICOBJECT), pCaster, m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex), m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, m_duration, radius, DYNAMIC_OBJECT_AREA_SPELL)) { delete dynObj; return; @@ -4437,17 +4464,17 @@ void Spell::EffectPersistentAA(SpellEffectIndex eff_idx) pCaster->GetMap()->Add(dynObj); } -void Spell::EffectEnergize(SpellEffectIndex eff_idx) +void Spell::EffectEnergize(SpellEffectEntry const* effect) { if (!unitTarget) return; if (!unitTarget->isAlive()) return; - if (m_spellInfo->EffectMiscValue[eff_idx] < 0 || m_spellInfo->EffectMiscValue[eff_idx] >= MAX_POWERS) + if(effect->EffectMiscValue < 0 || effect->EffectMiscValue >= MAX_POWERS) return; - Powers power = Powers(m_spellInfo->EffectMiscValue[eff_idx]); + Powers power = Powers(effect->EffectMiscValue); // Some level depends spells int level_multiplier = 0; @@ -4524,8 +4551,8 @@ void Spell::EffectEnergize(SpellEffectIndex eff_idx) if (itr->second & (ELIXIR_UNSTABLE_MASK | ELIXIR_SHATTRATH_MASK)) continue; - SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->first); - if (spellInfo && (spellInfo->spellLevel < m_spellInfo->spellLevel || spellInfo->spellLevel > unitTarget->getLevel())) + SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); + if (spellInfo && (spellInfo->GetSpellLevel() < m_spellInfo->GetSpellLevel() || spellInfo->GetSpellLevel() > unitTarget->getLevel())) continue; elixirs.push_back(itr->first); @@ -4541,17 +4568,17 @@ void Spell::EffectEnergize(SpellEffectIndex eff_idx) } } -void Spell::EffectEnergisePct(SpellEffectIndex eff_idx) +void Spell::EffectEnergisePct(SpellEffectEntry const* effect) { if (!unitTarget) return; if (!unitTarget->isAlive()) return; - if (m_spellInfo->EffectMiscValue[eff_idx] < 0 || m_spellInfo->EffectMiscValue[eff_idx] >= MAX_POWERS) + if (effect->EffectMiscValue < 0 || effect->EffectMiscValue >= MAX_POWERS) return; - Powers power = Powers(m_spellInfo->EffectMiscValue[eff_idx]); + Powers power = Powers(effect->EffectMiscValue); uint32 maxPower = unitTarget->GetMaxPower(power); if (maxPower == 0) @@ -4601,7 +4628,7 @@ void Spell::SendLoot(ObjectGuid guid, LootType loottype, LockType lockType) ((Player*)m_caster)->SendLoot(guid, loottype); } -void Spell::EffectOpenLock(SpellEffectIndex eff_idx) +void Spell::EffectOpenLock(SpellEffectEntry const* effect) { if (!m_caster || m_caster->GetTypeId() != TYPEID_PLAYER) { @@ -4661,7 +4688,7 @@ void Spell::EffectOpenLock(SpellEffectIndex eff_idx) int32 reqSkillValue = 0; int32 skillValue; - SpellCastResult res = CanOpenLock(eff_idx, lockId, skillId, reqSkillValue, skillValue); + SpellCastResult res = CanOpenLock(SpellEffectIndex(effect->EffectIndex), lockId, skillId, reqSkillValue, skillValue); if (res != SPELL_CAST_OK) { SendCastResult(res); @@ -4672,7 +4699,7 @@ void Spell::EffectOpenLock(SpellEffectIndex eff_idx) if (itemTarget) itemTarget->SetFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_UNLOCKED); - SendLoot(guid, LOOT_SKINNING, LockType(m_spellInfo->EffectMiscValue[eff_idx])); + SendLoot(guid, LOOT_SKINNING, LockType(effect->EffectMiscValue)); // not allow use skill grow at item base open if (!m_CastItem && skillId != SKILL_NONE) @@ -4696,7 +4723,7 @@ void Spell::EffectOpenLock(SpellEffectIndex eff_idx) } } -void Spell::EffectSummonChangeItem(SpellEffectIndex eff_idx) +void Spell::EffectSummonChangeItem(SpellEffectEntry const* effect) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -4711,7 +4738,7 @@ void Spell::EffectSummonChangeItem(SpellEffectIndex eff_idx) if (m_CastItem->GetOwnerGuid() != player->GetObjectGuid()) return; - uint32 newitemid = m_spellInfo->EffectItemType[eff_idx]; + uint32 newitemid = effect->EffectItemType; if (!newitemid) return; @@ -4723,41 +4750,42 @@ void Spell::EffectSummonChangeItem(SpellEffectIndex eff_idx) player->ConvertItem(oldItem, newitemid); } -void Spell::EffectProficiency(SpellEffectIndex /*eff_idx*/) +void Spell::EffectProficiency(SpellEffectEntry const* /*effect*/) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - Player* p_target = (Player*)unitTarget; + Player *p_target = (Player*)unitTarget; - uint32 subClassMask = m_spellInfo->EquippedItemSubClassMask; - if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask)) + SpellEquippedItemsEntry const* eqItems = m_spellInfo->GetSpellEquippedItems(); + + if (eqItems && eqItems->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & eqItems->EquippedItemSubClassMask)) { - p_target->AddWeaponProficiency(subClassMask); + p_target->AddWeaponProficiency(eqItems->EquippedItemSubClassMask); p_target->SendProficiency(ITEM_CLASS_WEAPON, p_target->GetWeaponProficiency()); } - if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask)) + if (eqItems && eqItems->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & eqItems->EquippedItemSubClassMask)) { - p_target->AddArmorProficiency(subClassMask); + p_target->AddArmorProficiency(eqItems->EquippedItemSubClassMask); p_target->SendProficiency(ITEM_CLASS_ARMOR, p_target->GetArmorProficiency()); } } -void Spell::EffectApplyAreaAura(SpellEffectIndex eff_idx) +void Spell::EffectApplyAreaAura(SpellEffectEntry const* effect) { if (!unitTarget) return; if (!unitTarget->isAlive()) return; - AreaAura* Aur = new AreaAura(m_spellInfo, eff_idx, &m_currentBasePoints[eff_idx], m_spellAuraHolder, unitTarget, m_caster, m_CastItem); - m_spellAuraHolder->AddAura(Aur, eff_idx); + AreaAura* Aur = new AreaAura(m_spellInfo, SpellEffectIndex(effect->EffectIndex), &m_currentBasePoints[effect->EffectIndex], m_spellAuraHolder, unitTarget, m_caster, m_CastItem); + m_spellAuraHolder->AddAura(Aur, SpellEffectIndex(effect->EffectIndex)); } -void Spell::EffectSummonType(SpellEffectIndex eff_idx) +void Spell::EffectSummonType(SpellEffectEntry const* effect) { - uint32 prop_id = m_spellInfo->EffectMiscValueB[eff_idx]; - SummonPropertiesEntry const* summon_prop = sSummonPropertiesStore.LookupEntry(prop_id); - if (!summon_prop) + uint32 prop_id = effect->EffectMiscValueB; + SummonPropertiesEntry const *summon_prop = sSummonPropertiesStore.LookupEntry(prop_id); + if(!summon_prop) { sLog.outError("EffectSummonType: Unhandled summon type %u", prop_id); return; @@ -4766,7 +4794,7 @@ void Spell::EffectSummonType(SpellEffectIndex eff_idx) // Pet's are atm handled differently if (summon_prop->Group == SUMMON_PROP_GROUP_PETS && prop_id != 1562) { - DoSummonPet(eff_idx); + DoSummonPet(effect); return; } @@ -4802,11 +4830,11 @@ void Spell::EffectSummonType(SpellEffectIndex eff_idx) m_caster->GetPosition(summonPositions[0].x, summonPositions[0].y, summonPositions[0].z); // TODO - Is this really an error? - sLog.outDebug("Spell Effect EFFECT_SUMMON (%u) - summon without destination (spell id %u, effIndex %u)", m_spellInfo->Effect[eff_idx], m_spellInfo->Id, eff_idx); + sLog.outDebug("Spell Effect EFFECT_SUMMON (%u) - summon without destination (spell id %u, effIndex %u)", effect->Effect, m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex)); } // Set summon positions - float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[eff_idx])); + float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->EffectRadiusIndex)); CreatureSummonPositions::iterator itr = summonPositions.begin(); for (++itr; itr != summonPositions.end(); ++itr) // In case of multiple summons around position for not-fist positions { @@ -4839,15 +4867,15 @@ void Spell::EffectSummonType(SpellEffectIndex eff_idx) //121: 23035, battlestands //647: 52893, Anti-Magic Zone (npc used) if (prop_id == 121 || prop_id == 647) - summonResult = DoSummonTotem(eff_idx); + summonResult = DoSummonTotem(effect); else - summonResult = DoSummonWild(summonPositions, summon_prop, eff_idx, level); + summonResult = DoSummonWild(summonPositions, summon_prop, effect, level); break; } case UNITNAME_SUMMON_TITLE_PET: case UNITNAME_SUMMON_TITLE_MINION: case UNITNAME_SUMMON_TITLE_RUNEBLADE: - summonResult = DoSummonGuardian(summonPositions, summon_prop, eff_idx, level); + summonResult = DoSummonGuardian(summonPositions, summon_prop, effect, level); break; case UNITNAME_SUMMON_TITLE_GUARDIAN: { @@ -4855,48 +4883,48 @@ void Spell::EffectSummonType(SpellEffectIndex eff_idx) { // * Stone Statue, etc -- fits much better totem AI if (m_spellInfo->SpellIconID == 2056) - summonResult = DoSummonTotem(eff_idx); + summonResult = DoSummonTotem(effect); else { // possible sort totems/guardians only by summon creature type - CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(m_spellInfo->EffectMiscValue[eff_idx]); + CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(effect->EffectMiscValue); if (!cInfo) return; - // FIXME: not all totems and similar cases seelcted by this check... + // FIXME: not all totems and similar cases selected by this check... if (cInfo->type == CREATURE_TYPE_TOTEM) - summonResult = DoSummonTotem(eff_idx); + summonResult = DoSummonTotem(effect); else - summonResult = DoSummonGuardian(summonPositions, summon_prop, eff_idx, level); + summonResult = DoSummonGuardian(summonPositions, summon_prop, effect, level); } } else - summonResult = DoSummonGuardian(summonPositions, summon_prop, eff_idx, level); + summonResult = DoSummonGuardian(summonPositions, summon_prop, effect, level); break; } case UNITNAME_SUMMON_TITLE_CONSTRUCT: { if (prop_id == 2913) // Scrapbot - summonResult = DoSummonWild(summonPositions, summon_prop, eff_idx, level); + summonResult = DoSummonWild(summonPositions, summon_prop, effect, level); else - summonResult = DoSummonGuardian(summonPositions, summon_prop, eff_idx, level); + summonResult = DoSummonGuardian(summonPositions, summon_prop, effect, level); break; } case UNITNAME_SUMMON_TITLE_TOTEM: - summonResult = DoSummonTotem(eff_idx, summon_prop->Slot); + summonResult = DoSummonTotem(effect, summon_prop->Slot); break; case UNITNAME_SUMMON_TITLE_COMPANION: // slot 6 set for critters that can help to player in fighting if (summon_prop->Slot == 6) - summonResult = DoSummonGuardian(summonPositions, summon_prop, eff_idx, level); + summonResult = DoSummonGuardian(summonPositions, summon_prop, effect, level); else - summonResult = DoSummonCritter(summonPositions, summon_prop, eff_idx, level); + summonResult = DoSummonCritter(summonPositions, summon_prop, effect, level); break; case UNITNAME_SUMMON_TITLE_OPPONENT: case UNITNAME_SUMMON_TITLE_LIGHTWELL: case UNITNAME_SUMMON_TITLE_BUTLER: - summonResult = DoSummonWild(summonPositions, summon_prop, eff_idx, level); + summonResult = DoSummonWild(summonPositions, summon_prop, effect, level); break; case UNITNAME_SUMMON_TITLE_VEHICLE: case UNITNAME_SUMMON_TITLE_MOUNT: @@ -4915,14 +4943,14 @@ void Spell::EffectSummonType(SpellEffectIndex eff_idx) // 1562 - force of nature - sid 33831 // 1161 - feral spirit - sid 51533 if (prop_id == 1562) // 3 uncontrolable instead of one controllable :/ - summonResult = DoSummonGuardian(summonPositions, summon_prop, eff_idx, level); + summonResult = DoSummonGuardian(summonPositions, summon_prop, effect, level); break; } case SUMMON_PROP_GROUP_CONTROLLABLE: { // TODO: Fix spell 46619 if (m_spellInfo->Id != 46619) - summonResult = DoSummonPossessed(summonPositions, summon_prop, eff_idx, level); + summonResult = DoSummonPossessed(summonPositions, summon_prop, effect, level); break; } case SUMMON_PROP_GROUP_VEHICLE: @@ -4967,11 +4995,11 @@ void Spell::EffectSummonType(SpellEffectIndex eff_idx) } } -bool Spell::DoSummonWild(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectIndex effIdx, uint32 level) +bool Spell::DoSummonWild(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectEntry const* effect, uint32 level) { MANGOS_ASSERT(!list.empty() && prop); - uint32 creature_entry = m_spellInfo->EffectMiscValue[effIdx]; + uint32 creature_entry = effect->EffectMiscValue; CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(creature_entry); if (!cInfo) { @@ -5002,12 +5030,12 @@ bool Spell::DoSummonWild(CreatureSummonPositions& list, SummonPropertiesEntry co return true; } -bool Spell::DoSummonCritter(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectIndex effIdx, uint32 /*level*/) +bool Spell::DoSummonCritter(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectEntry const* effect, uint32 /*level*/) { MANGOS_ASSERT(!list.empty() && prop); // ATM only first position is supported for summoning - uint32 pet_entry = m_spellInfo->EffectMiscValue[effIdx]; + uint32 pet_entry = effect->EffectMiscValue; CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(pet_entry); if (!cInfo) { @@ -5068,11 +5096,11 @@ bool Spell::DoSummonCritter(CreatureSummonPositions& list, SummonPropertiesEntry return true; } -bool Spell::DoSummonGuardian(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectIndex effIdx, uint32 level) +bool Spell::DoSummonGuardian(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectEntry const* effect, uint32 level) { MANGOS_ASSERT(!list.empty() && prop); - uint32 pet_entry = m_spellInfo->EffectMiscValue[effIdx]; + uint32 pet_entry = effect->EffectMiscValue; CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(pet_entry); if (!cInfo) { @@ -5142,7 +5170,7 @@ bool Spell::DoSummonGuardian(CreatureSummonPositions& list, SummonPropertiesEntr return true; } -bool Spell::DoSummonTotem(SpellEffectIndex eff_idx, uint8 slot_dbc) +bool Spell::DoSummonTotem(SpellEffectEntry const* effect, uint8 slot_dbc) { // DBC store slots starting from 1, with no slot 0 value) int slot = slot_dbc ? slot_dbc - 1 : TOTEM_SLOT_NONE; @@ -5158,10 +5186,10 @@ bool Spell::DoSummonTotem(SpellEffectIndex eff_idx, uint8 slot_dbc) CreatureCreatePos pos(m_caster, m_caster->GetOrientation(), 2.0f, angle); - CreatureInfo const* cinfo = ObjectMgr::GetCreatureTemplate(m_spellInfo->EffectMiscValue[eff_idx]); + CreatureInfo const* cinfo = ObjectMgr::GetCreatureTemplate(effect->EffectMiscValue); if (!cinfo) { - sLog.outErrorDb("Creature entry %u does not exist but used in spell %u totem summon.", m_spellInfo->Id, m_spellInfo->EffectMiscValue[eff_idx]); + sLog.outErrorDb("Creature entry %u does not exist but used in spell %u totem summon.", m_spellInfo->Id, effect->EffectMiscValue); return false; } @@ -5217,11 +5245,11 @@ bool Spell::DoSummonTotem(SpellEffectIndex eff_idx, uint8 slot_dbc) return false; } -bool Spell::DoSummonPossessed(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectIndex effIdx, uint32 level) +bool Spell::DoSummonPossessed(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectEntry const* effect, uint32 level) { MANGOS_ASSERT(!list.empty() && prop); - uint32 creatureEntry = m_spellInfo->EffectMiscValue[effIdx]; + uint32 creatureEntry = effect->EffectMiscValue; CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(creatureEntry); if (!cInfo) { @@ -5275,7 +5303,7 @@ bool Spell::DoSummonPossessed(CreatureSummonPositions& list, SummonPropertiesEnt return true; } -bool Spell::DoSummonPet(SpellEffectIndex eff_idx) +bool Spell::DoSummonPet(SpellEffectEntry const* effect) { if (m_caster->GetPetGuid()) return false; @@ -5283,7 +5311,7 @@ bool Spell::DoSummonPet(SpellEffectIndex eff_idx) if (!unitTarget) return false; - uint32 pet_entry = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 pet_entry = effect->EffectMiscValue; CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(pet_entry); if (!cInfo) { @@ -5369,7 +5397,7 @@ bool Spell::DoSummonPet(SpellEffectIndex eff_idx) return false; } -void Spell::EffectLearnSpell(SpellEffectIndex eff_idx) +void Spell::EffectLearnSpell(SpellEffectEntry const* effect) { if (!unitTarget) return; @@ -5377,20 +5405,20 @@ void Spell::EffectLearnSpell(SpellEffectIndex eff_idx) if (unitTarget->GetTypeId() != TYPEID_PLAYER) { if (m_caster->GetTypeId() == TYPEID_PLAYER) - EffectLearnPetSpell(eff_idx); + EffectLearnPetSpell(effect); return; } Player* player = (Player*)unitTarget; - uint32 spellToLearn = ((m_spellInfo->Id == SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id == SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[eff_idx]; + uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : effect->EffectTriggerSpell; player->learnSpell(spellToLearn, false); DEBUG_LOG("Spell: Player %u has learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow()); } -void Spell::EffectDispel(SpellEffectIndex eff_idx) +void Spell::EffectDispel(SpellEffectEntry const* effect) { if (!unitTarget) return; @@ -5399,15 +5427,15 @@ void Spell::EffectDispel(SpellEffectIndex eff_idx) std::list > dispel_list; // Create dispel mask by dispel type - uint32 dispel_type = m_spellInfo->EffectMiscValue[eff_idx]; - uint32 dispelMask = GetDispellMask(DispelType(dispel_type)); + uint32 dispel_type = effect->EffectMiscValue; + uint32 dispelMask = GetDispellMask( DispelType(dispel_type) ); Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap(); for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - SpellAuraHolder* holder = itr->second; - if ((1 << holder->GetSpellProto()->Dispel) & dispelMask) + SpellAuraHolder *holder = itr->second; + if ((1<GetSpellProto()->GetDispel()) & dispelMask) { - if (holder->GetSpellProto()->Dispel == DISPEL_MAGIC) + if(holder->GetSpellProto()->GetDispel() == DISPEL_MAGIC) { bool positive = true; if (!holder->IsPositive()) @@ -5421,7 +5449,7 @@ void Spell::EffectDispel(SpellEffectIndex eff_idx) continue; } // Unholy Blight prevents dispel of diseases from target - else if (holder->GetSpellProto()->Dispel == DISPEL_DISEASE) + else if (holder->GetSpellProto()->GetDispel() == DISPEL_DISEASE) if (unitTarget->HasAura(50536)) continue; @@ -5503,7 +5531,7 @@ void Spell::EffectDispel(SpellEffectIndex eff_idx) // On success dispel // Devour Magic - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->Category == SPELLCATEGORY_DEVOUR_MAGIC) + if (m_spellInfo->GetSpellFamilyName() == SPELLFAMILY_WARLOCK && m_spellInfo->GetCategory() == SPELLCATEGORY_DEVOUR_MAGIC) { int32 heal_amount = m_spellInfo->CalculateSimpleValue(EFFECT_INDEX_1); m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, NULL, NULL, true); @@ -5524,19 +5552,19 @@ void Spell::EffectDispel(SpellEffectIndex eff_idx) } } -void Spell::EffectDualWield(SpellEffectIndex /*eff_idx*/) +void Spell::EffectDualWield(SpellEffectEntry const* /*effect*/) { if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) ((Player*)unitTarget)->SetCanDualWield(true); } -void Spell::EffectPull(SpellEffectIndex /*eff_idx*/) +void Spell::EffectPull(SpellEffectEntry const* /*effect*/) { // TODO: create a proper pull towards distract spell center for distract DEBUG_LOG("WORLD: Spell Effect DUMMY"); } -void Spell::EffectDistract(SpellEffectIndex /*eff_idx*/) +void Spell::EffectDistract(SpellEffectEntry const* /*effect*/) { // Check for possible target if (!unitTarget || unitTarget->isInCombat()) @@ -5553,7 +5581,7 @@ void Spell::EffectDistract(SpellEffectIndex /*eff_idx*/) unitTarget->GetMotionMaster()->MoveDistract(damage * IN_MILLISECONDS); } -void Spell::EffectPickPocket(SpellEffectIndex /*eff_idx*/) +void Spell::EffectPickPocket(SpellEffectEntry const* /*effect*/) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -5582,16 +5610,16 @@ void Spell::EffectPickPocket(SpellEffectIndex /*eff_idx*/) } } -void Spell::EffectAddFarsight(SpellEffectIndex eff_idx) +void Spell::EffectAddFarsight(SpellEffectEntry const* effect) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; + int32 duration = GetSpellDuration(m_spellInfo); DynamicObject* dynObj = new DynamicObject; // set radius to 0: spell not expected to work as persistent aura - if (!dynObj->Create(m_caster->GetMap()->GenerateLocalLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, - m_spellInfo->Id, eff_idx, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, m_duration, 0, DYNAMIC_OBJECT_FARSIGHT_FOCUS)) + if(!dynObj->Create(m_caster->GetMap()->GenerateLocalLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, SpellEffectIndex(effect->EffectIndex), m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, 0, DYNAMIC_OBJECT_FARSIGHT_FOCUS)) { delete dynObj; return; @@ -5603,7 +5631,7 @@ void Spell::EffectAddFarsight(SpellEffectIndex eff_idx) ((Player*)m_caster)->GetCamera().SetView(dynObj); } -void Spell::EffectTeleUnitsFaceCaster(SpellEffectIndex eff_idx) +void Spell::EffectTeleUnitsFaceCaster(SpellEffectEntry const* effect) { if (!unitTarget) return; @@ -5611,7 +5639,7 @@ void Spell::EffectTeleUnitsFaceCaster(SpellEffectIndex eff_idx) if (unitTarget->IsTaxiFlying()) return; - float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[eff_idx])); + float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->EffectRadiusIndex)); float fx, fy, fz; m_caster->GetClosePoint(fx, fy, fz, unitTarget->GetObjectBoundingRadius(), dis); @@ -5619,7 +5647,7 @@ void Spell::EffectTeleUnitsFaceCaster(SpellEffectIndex eff_idx) unitTarget->NearTeleportTo(fx, fy, fz, -m_caster->GetOrientation(), unitTarget == m_caster); } -void Spell::EffectLearnSkill(SpellEffectIndex eff_idx) +void Spell::EffectLearnSkill(SpellEffectEntry const* effect) { if (unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -5627,12 +5655,12 @@ void Spell::EffectLearnSkill(SpellEffectIndex eff_idx) if (damage < 0) return; - uint32 skillid = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 skillid = effect->EffectMiscValue; uint16 skillval = ((Player*)unitTarget)->GetPureSkillValue(skillid); ((Player*)unitTarget)->SetSkill(skillid, skillval ? skillval : 1, damage * 75, damage); } -void Spell::EffectAddHonor(SpellEffectIndex /*eff_idx*/) +void Spell::EffectAddHonor(SpellEffectEntry const* /*effect*/) { if (unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -5660,7 +5688,7 @@ void Spell::EffectAddHonor(SpellEffectIndex /*eff_idx*/) } } -void Spell::EffectTradeSkill(SpellEffectIndex /*eff_idx*/) +void Spell::EffectTradeSkill(SpellEffectEntry const* /*effect*/) { if (unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -5669,14 +5697,14 @@ void Spell::EffectTradeSkill(SpellEffectIndex /*eff_idx*/) // ((Player*)unitTarget)->SetSkill(skillid,skillval?skillval:1,skillmax+75); } -void Spell::EffectEnchantItemPerm(SpellEffectIndex eff_idx) +void Spell::EffectEnchantItemPerm(SpellEffectEntry const* effect) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; if (!itemTarget) return; - uint32 enchant_id = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 enchant_id = effect->EffectMiscValue; if (!enchant_id) return; @@ -5694,10 +5722,10 @@ void Spell::EffectEnchantItemPerm(SpellEffectIndex eff_idx) // Enchanting a vellum requires special handling, as it creates a new item // instead of modifying an existing one. ItemPrototype const* targetProto = itemTarget->GetProto(); - if (targetProto->IsVellum() && m_spellInfo->EffectItemType[eff_idx]) + if (targetProto->IsVellum() && effect->EffectItemType) { unitTarget = m_caster; - DoCreateItem(eff_idx, m_spellInfo->EffectItemType[eff_idx]); + DoCreateItem(effect, effect->EffectItemType); // Vellum target case: Target becomes additional reagent, new scroll item created instead in Spell::EffectEnchantItemPerm() // cannot already delete in TakeReagents() unfortunately p_caster->DestroyItemCount(targetProto->ItemId, 1, true); @@ -5725,7 +5753,7 @@ void Spell::EffectEnchantItemPerm(SpellEffectIndex eff_idx) item_owner->ApplyEnchantment(itemTarget, PERM_ENCHANTMENT_SLOT, true); } -void Spell::EffectEnchantItemPrismatic(SpellEffectIndex eff_idx) +void Spell::EffectEnchantItemPrismatic(SpellEffectEntry const* effect) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -5734,7 +5762,7 @@ void Spell::EffectEnchantItemPrismatic(SpellEffectIndex eff_idx) Player* p_caster = (Player*)m_caster; - uint32 enchant_id = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 enchant_id = effect->EffectMiscValue; if (!enchant_id) return; @@ -5783,7 +5811,7 @@ void Spell::EffectEnchantItemPrismatic(SpellEffectIndex eff_idx) item_owner->ApplyEnchantment(itemTarget, PRISMATIC_ENCHANTMENT_SLOT, true); } -void Spell::EffectEnchantItemTmp(SpellEffectIndex eff_idx) +void Spell::EffectEnchantItemTmp(SpellEffectEntry const* effect) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -5791,7 +5819,8 @@ void Spell::EffectEnchantItemTmp(SpellEffectIndex eff_idx) Player* p_caster = (Player*)m_caster; // Rockbiter Weapon - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000400000)) + SpellClassOptionsEntry const* classOptions = m_spellInfo->GetSpellClassOptions(); + if (classOptions && classOptions->SpellFamilyName == SPELLFAMILY_SHAMAN && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000400000)) { uint32 spell_id = 0; @@ -5834,18 +5863,18 @@ void Spell::EffectEnchantItemTmp(SpellEffectIndex eff_idx) if (!itemTarget) return; - uint32 enchant_id = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 enchant_id = effect->EffectMiscValue; if (!enchant_id) { - sLog.outError("Spell %u Effect %u (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, eff_idx); + sLog.outError("Spell %u Effect %u (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id",m_spellInfo->Id,effect->EffectIndex); return; } SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); if (!pEnchant) { - sLog.outError("Spell %u Effect %u (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have nonexistent enchanting id %u ", m_spellInfo->Id, eff_idx, enchant_id); + sLog.outError("Spell %u Effect %u (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have nonexistent enchanting id %u ",m_spellInfo->Id,effect->EffectIndex,enchant_id); return; } @@ -5856,10 +5885,10 @@ void Spell::EffectEnchantItemTmp(SpellEffectIndex eff_idx) if (m_spellInfo->Id == 38615) duration = 1800; // 30 mins // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints) - else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE) + else if(classOptions && classOptions->SpellFamilyName == SPELLFAMILY_ROGUE) duration = 3600; // 1 hour // shaman family enchantments - else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN) + else if(classOptions && classOptions->SpellFamilyName == SPELLFAMILY_SHAMAN) duration = 1800; // 30 mins // other cases with this SpellVisual already selected else if (m_spellInfo->SpellVisual[0] == 215) @@ -5900,7 +5929,7 @@ void Spell::EffectEnchantItemTmp(SpellEffectIndex eff_idx) item_owner->ApplyEnchantment(itemTarget, TEMP_ENCHANTMENT_SLOT, true); } -void Spell::EffectTameCreature(SpellEffectIndex /*eff_idx*/) +void Spell::EffectTameCreature(SpellEffectEntry const* /*effect*/) { // Caster must be player, checked in Spell::CheckCast // Spell can be triggered, we need to check original caster prior to caster @@ -5968,9 +5997,9 @@ void Spell::EffectTameCreature(SpellEffectIndex /*eff_idx*/) plr->PetSpellInitialize(); } -void Spell::EffectSummonPet(SpellEffectIndex eff_idx) +void Spell::EffectSummonPet(SpellEffectEntry const* effect) { - uint32 petentry = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 petentry = effect->EffectMiscValue; Pet* OldSummon = m_caster->GetPet(); @@ -6103,7 +6132,7 @@ void Spell::EffectSummonPet(SpellEffectIndex eff_idx) } } -void Spell::EffectLearnPetSpell(SpellEffectIndex eff_idx) +void Spell::EffectLearnPetSpell(SpellEffectEntry const* effect) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -6116,8 +6145,8 @@ void Spell::EffectLearnPetSpell(SpellEffectIndex eff_idx) if (!pet->isAlive()) return; - SpellEntry const* learn_spellproto = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[eff_idx]); - if (!learn_spellproto) + SpellEntry const *learn_spellproto = sSpellStore.LookupEntry(effect->EffectTriggerSpell); + if(!learn_spellproto) return; pet->learnSpell(learn_spellproto->Id); @@ -6126,7 +6155,7 @@ void Spell::EffectLearnPetSpell(SpellEffectIndex eff_idx) _player->PetSpellInitialize(); } -void Spell::EffectTaunt(SpellEffectIndex /*eff_idx*/) +void Spell::EffectTaunt(SpellEffectEntry const* /*effect*/) { if (!unitTarget) return; @@ -6147,7 +6176,7 @@ void Spell::EffectTaunt(SpellEffectIndex /*eff_idx*/) unitTarget->getThreatManager().addThreat(m_caster, unitTarget->getThreatManager().getCurrentVictim()->getThreat()); } -void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) +void Spell::EffectWeaponDmg(SpellEffectEntry const* effect) { if (!unitTarget) return; @@ -6159,13 +6188,13 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) // and handle all effects at once for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - switch (m_spellInfo->Effect[j]) + switch(m_spellInfo->GetSpellEffectIdByIndex(SpellEffectIndex(j))) { case SPELL_EFFECT_WEAPON_DAMAGE: case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: - if (j < int(eff_idx)) // we must calculate only at last weapon effect + if (j < int(effect->EffectIndex)) // we must calculate only at last weapon effect return; break; } @@ -6180,7 +6209,9 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) int32 spell_bonus = 0; // bonus specific for spell - switch (m_spellInfo->SpellFamilyName) + SpellClassOptionsEntry const* classOptions = m_spellInfo->GetSpellClassOptions(); + + switch(m_spellInfo->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { @@ -6193,8 +6224,8 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) case 71021: // Saber Lash { uint32 count = 0; - for (TargetList::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) - if (ihit->effectMask & (1 << eff_idx)) + for(TargetList::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + if(ihit->effectMask & (1<EffectIndex)) ++count; totalDamagePercentMod /= float(count); // divide to all targets @@ -6220,7 +6251,7 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) // Devastate causing Sunder Armor Effect // and no need to cast over max stack amount - if (!sunder || sunder->GetStackAmount() < sunder->GetSpellProto()->StackAmount) + if (!sunder || sunder->GetStackAmount() < sunder->GetSpellProto()->GetStackAmount()) m_caster->CastSpell(unitTarget, 58567, true); } break; @@ -6228,7 +6259,7 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) case SPELLFAMILY_ROGUE: { // Mutilate (for each hand) - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x600000000)) + if(classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x600000000)) { bool found = false; // fast check @@ -6240,7 +6271,7 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap(); for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - if (itr->second->GetSpellProto()->Dispel == DISPEL_POISON) + if(itr->second->GetSpellProto()->GetDispel() == DISPEL_POISON) { found = true; break; @@ -6252,7 +6283,7 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) totalDamagePercentMod *= 1.2f; // 120% if poisoned } // Fan of Knives - else if (m_caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0004000000000000))) + else if (m_caster->GetTypeId()==TYPEID_PLAYER && classOptions && (classOptions->SpellFamilyFlags & UI64LIT(0x0004000000000000))) { Item* weapon = ((Player*)m_caster)->GetWeaponForAttack(m_attackType, true, true); if (weapon && weapon->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER) @@ -6266,7 +6297,7 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) totalDamagePercentMod *= 1.44f; // 144% to daggers } // Hemorrhage - else if (m_caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x2000000))) + else if (m_caster->GetTypeId() == TYPEID_PLAYER && classOptions && (classOptions->SpellFamilyFlags & UI64LIT(0x2000000))) { Item* weapon = ((Player*)m_caster)->GetWeaponForAttack(m_attackType, true, true); if (weapon && weapon->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER) @@ -6277,7 +6308,7 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) case SPELLFAMILY_PALADIN: { // Judgement of Command - receive benefit from Spell Damage and Attack Power - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x00020000000000)) + if(classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x00020000000000)) { float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); int32 holy = m_caster->SpellBaseDamageBonusDone(GetSpellSchoolMask(m_spellInfo)); @@ -6290,7 +6321,7 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) case SPELLFAMILY_HUNTER: { // Kill Shot - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x80000000000000)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x80000000000000)) { // 0.4*RAP added to damage (that is 0.2 if we apply PercentMod (200%) to spell_bonus, too) spellBonusNeedWeaponDamagePercentMod = true; @@ -6302,7 +6333,7 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) { // Skyshatter Harness item set bonus // Stormstrike - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x001000000000)) + if(classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x001000000000)) { Unit::AuraList const& m_OverrideClassScript = m_caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); for (Unit::AuraList::const_iterator citr = m_OverrideClassScript.begin(); citr != m_OverrideClassScript.end(); ++citr) @@ -6321,15 +6352,14 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) { // Blood Strike, Heart Strike, Obliterate // Blood-Caked Strike - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0002000001400000) || - m_spellInfo->SpellIconID == 1736) + if (m_spellInfo->SpellIconID == 1736) { uint32 count = 0; Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap(); for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - if (itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE && - itr->second->GetCasterGuid() == m_caster->GetObjectGuid()) + if(itr->second->GetSpellProto()->GetDispel() == DISPEL_DISEASE && + itr->second->GetCasterGuid() == m_caster->GetObjectGuid()) ++count; } @@ -6338,8 +6368,8 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) // Effect 1(for Blood-Caked Strike)/3(other) damage is bonus float bonus = count * CalculateDamage(m_spellInfo->SpellIconID == 1736 ? EFFECT_INDEX_0 : EFFECT_INDEX_2, unitTarget) / 100.0f; // Blood Strike, Blood-Caked Strike and Obliterate store bonus*2 - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0002000000400000) || - m_spellInfo->SpellIconID == 1736) + if ((classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0002000000400000)) || + m_spellInfo->SpellIconID == 1736) bonus /= 2.0f; totalDamagePercentMod *= 1.0f + bonus; @@ -6351,15 +6381,15 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) weaponDamagePercentMod /= 2.0f; } // Glyph of Blood Strike - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000400000) && - m_caster->HasAura(59332) && - unitTarget->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED)) + if( classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000400000) && + m_caster->HasAura(59332) && + unitTarget->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED)) { totalDamagePercentMod *= 1.2f; // 120% if snared } // Glyph of Death Strike - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000010) && - m_caster->HasAura(59336)) + if( classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000000010) && + m_caster->HasAura(59336)) { int32 rp = m_caster->GetPower(POWER_RUNIC_POWER) / 10; if (rp > 25) @@ -6367,8 +6397,8 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) totalDamagePercentMod *= 1.0f + rp / 100.0f; } // Glyph of Plague Strike - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000001) && - m_caster->HasAura(58657)) + if( classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000000001) && + m_caster->HasAura(58657) ) { totalDamagePercentMod *= 1.2f; } @@ -6379,7 +6409,11 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) int32 fixed_bonus = 0; for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - switch (m_spellInfo->Effect[j]) + SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); + if(!spellEffect) + continue; + + switch(spellEffect->Effect) { case SPELL_EFFECT_WEAPON_DAMAGE: case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: @@ -6433,7 +6467,7 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) m_damage += uint32(bonus > 0 ? bonus : 0); // Hemorrhage - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x2000000))) + if (m_spellInfo->IsFitToFamily(SPELLFAMILY_ROGUE, UI64LIT(0x0000000002000000))) { if (m_caster->GetTypeId() == TYPEID_PLAYER) ((Player*)m_caster)->AddComboPoints(unitTarget, 1); @@ -6468,12 +6502,10 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) ((Player*)m_caster)->DestroyItemCount(pItem, count, true); } } - else if (uint32 ammo = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID)) - ((Player*)m_caster)->DestroyItemCount(ammo, 1, true); } } -void Spell::EffectThreat(SpellEffectIndex /*eff_idx*/) +void Spell::EffectThreat(SpellEffectEntry const* /*effect*/) { if (!unitTarget || !unitTarget->isAlive() || !m_caster->isAlive()) return; @@ -6484,7 +6516,7 @@ void Spell::EffectThreat(SpellEffectIndex /*eff_idx*/) unitTarget->AddThreat(m_caster, float(damage), false, GetSpellSchoolMask(m_spellInfo), m_spellInfo); } -void Spell::EffectHealMaxHealth(SpellEffectIndex /*eff_idx*/) +void Spell::EffectHealMaxHealth(SpellEffectEntry const* /*effect*/) { if (!unitTarget) return; @@ -6496,7 +6528,7 @@ void Spell::EffectHealMaxHealth(SpellEffectIndex /*eff_idx*/) m_healing += heal; } -void Spell::EffectInterruptCast(SpellEffectIndex /*eff_idx*/) +void Spell::EffectInterruptCast(SpellEffectEntry const* /*effect*/) { if (!unitTarget) return; @@ -6511,7 +6543,7 @@ void Spell::EffectInterruptCast(SpellEffectIndex /*eff_idx*/) { SpellEntry const* curSpellInfo = spell->m_spellInfo; // check if we can interrupt spell - if ((curSpellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_INTERRUPT) && curSpellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) + if ((curSpellInfo->GetInterruptFlags() & SPELL_INTERRUPT_FLAG_INTERRUPT) && curSpellInfo->GetPreventionType() == SPELL_PREVENTION_TYPE_SILENCE ) { unitTarget->ProhibitSpellSchool(GetSpellSchoolMask(curSpellInfo), GetSpellDuration(m_spellInfo)); unitTarget->InterruptSpell(CurrentSpellTypes(i), false); @@ -6520,9 +6552,9 @@ void Spell::EffectInterruptCast(SpellEffectIndex /*eff_idx*/) } } -void Spell::EffectSummonObjectWild(SpellEffectIndex eff_idx) +void Spell::EffectSummonObjectWild(SpellEffectEntry const* effect) { - uint32 gameobject_id = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 gameobject_id = effect->EffectMiscValue; GameObject* pGameObj = new GameObject; @@ -6594,11 +6626,10 @@ void Spell::EffectSummonObjectWild(SpellEffectIndex eff_idx) ((Creature*)m_originalCaster)->AI()->JustSummoned(pGameObj); } -void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) +void Spell::EffectScriptEffect(SpellEffectEntry const* effect) { // TODO: we must implement hunter pet summon at login there (spell 6962) - - switch (m_spellInfo->SpellFamilyName) + switch(m_spellInfo->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { @@ -6916,7 +6947,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (!unitTarget) return; - float downToHealthPercent = (m_spellInfo->Id != 71123 ? 5 : m_spellInfo->CalculateSimpleValue(eff_idx)) * 0.01f; + float downToHealthPercent = (m_spellInfo->Id != 71123 ? 5 : effect->CalculateSimpleValue()) * 0.01f; int32 damage = unitTarget->GetHealth() - unitTarget->GetMaxHealth() * downToHealthPercent; if (damage > 0) @@ -6985,7 +7016,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) } if (item) - DoCreateItem(eff_idx, item); + DoCreateItem(effect,item); break; } @@ -7038,7 +7069,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) ((Creature*)m_caster)->SetVirtualItem(VIRTUAL_ITEM_SLOT_0, pItem->GetEntry()); // Unclear what this spell should do - unitTarget->CastSpell(m_caster, m_spellInfo->CalculateSimpleValue(eff_idx), true); + unitTarget->CastSpell(m_caster, effect->CalculateSimpleValue(), true); } return; @@ -7077,7 +7108,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) // Are there anything special with this, a random chance or condition? // Feeding Rock Falcon - unitTarget->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(eff_idx), true, NULL, NULL, unitTarget->GetObjectGuid(), m_spellInfo); + unitTarget->CastSpell(unitTarget, effect->CalculateSimpleValue(), true, NULL, NULL, unitTarget->GetObjectGuid(), m_spellInfo); return; } case 44455: // Character Script Effect Reverse Cast @@ -7087,10 +7118,10 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) Creature* pTarget = (Creature*)unitTarget; - if (const SpellEntry* pSpell = sSpellStore.LookupEntry(m_spellInfo->CalculateSimpleValue(eff_idx))) + if (const SpellEntry *pSpell = sSpellStore.LookupEntry(effect->CalculateSimpleValue())) { // if we used item at least once... - if (pTarget->IsTemporarySummon() && int32(pTarget->GetEntry()) == pSpell->EffectMiscValue[eff_idx]) + if (pTarget->IsTemporarySummon() && int32(pTarget->GetEntry()) == pSpell->GetEffectMiscValue(SpellEffectIndex(effect->EffectIndex))) { TemporarySummon* pSummon = (TemporarySummon*)pTarget; @@ -7141,7 +7172,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (!((Creature*)m_caster)->IsTemporarySummon()) return; - if (const SpellEntry* pSpell = sSpellStore.LookupEntry(m_spellInfo->CalculateSimpleValue(eff_idx))) + if (const SpellEntry *pSpell = sSpellStore.LookupEntry(effect->CalculateSimpleValue())) { TemporarySummon* pSummon = (TemporarySummon*)m_caster; @@ -7209,7 +7240,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (!unitTarget) return; - unitTarget->CastSpell(m_caster, m_spellInfo->CalculateSimpleValue(eff_idx), true); + unitTarget->CastSpell(m_caster, effect->CalculateSimpleValue(), true); return; } case 45206: // Copy Off-hand Weapon @@ -7222,7 +7253,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) ((Creature*)m_caster)->SetVirtualItem(VIRTUAL_ITEM_SLOT_1, pItem->GetEntry()); // Unclear what this spell should do - unitTarget->CastSpell(m_caster, m_spellInfo->CalculateSimpleValue(eff_idx), true); + unitTarget->CastSpell(m_caster, effect->CalculateSimpleValue(), true); } return; @@ -7334,7 +7365,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) case 45958: // Signal Alliance { // "escort" aura not present, so let nothing happen - if (!m_caster->HasAura(m_spellInfo->CalculateSimpleValue(eff_idx))) + if (!m_caster->HasAura(effect->CalculateSimpleValue())) return; // "escort" aura is present so break; and let DB table spell_scripts be used and process further. else @@ -7456,7 +7487,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (!unitTarget || !m_caster->HasAura(48714)) return; - unitTarget->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(eff_idx), true); + unitTarget->CastSpell(unitTarget, effect->CalculateSimpleValue(), true); return; } // Gender spells @@ -7553,7 +7584,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (!unitTarget) return; - unitTarget->CastSpell(m_caster, m_spellInfo->CalculateSimpleValue(eff_idx), true); + unitTarget->CastSpell(m_caster, effect->CalculateSimpleValue(), true); return; } case 50217: // The Cleansing: Script Effect Player Cast Mirror Image @@ -7575,16 +7606,16 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) return; // determine if and what weapons can be copied - switch (eff_idx) + switch(effect->EffectIndex) { case EFFECT_INDEX_1: if (((Player*)m_originalCaster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND)) - unitTarget->CastSpell(m_originalCaster, m_spellInfo->CalculateSimpleValue(eff_idx), true); + unitTarget->CastSpell(m_originalCaster, effect->CalculateSimpleValue(), true); return; case EFFECT_INDEX_2: if (((Player*)m_originalCaster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND)) - unitTarget->CastSpell(m_originalCaster, m_spellInfo->CalculateSimpleValue(eff_idx), true); + unitTarget->CastSpell(m_originalCaster, effect->CalculateSimpleValue(), true); return; default: @@ -7604,7 +7635,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (pSummon->GetSummonerGuid().IsPlayer()) { if (Player* pSummoner = sObjectMgr.GetPlayer(pSummon->GetSummonerGuid())) - pSummoner->CastSpell(pSummoner, m_spellInfo->CalculateSimpleValue(eff_idx), true); + pSummoner->CastSpell(pSummoner, effect->CalculateSimpleValue(), true); } } @@ -7621,7 +7652,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (!unitTarget) return; - unitTarget->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(eff_idx), true, NULL, NULL, m_originalCasterGUID); + unitTarget->CastSpell(unitTarget, effect->CalculateSimpleValue(), true, NULL, NULL, m_originalCasterGUID); return; } case 50439: // Script Cast Summon Image of Drakuru 05 @@ -7648,7 +7679,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (SpellAuraHolder* pHolder = unitTarget->GetSpellAuraHolder(m_spellInfo->Id)) { - if (pHolder->GetStackAmount() + 1 >= m_spellInfo->StackAmount) + if (pHolder->GetStackAmount() + 1 >= m_spellInfo->GetStackAmount()) { // Gluttonous Lurkers: Summon Gorged Lurking Basilisk unitTarget->CastSpell(m_caster, 50928, true); @@ -7703,11 +7734,11 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (const SpellEntry* pSpell = sSpellStore.LookupEntry(51865)) { // Only if he is not already there - if (!m_caster->FindGuardianWithEntry(pSpell->EffectMiscValue[EFFECT_INDEX_0])) + if (!m_caster->FindGuardianWithEntry(pSpell->GetEffectMiscValue(EFFECT_INDEX_0))) { m_caster->CastSpell(m_caster, pSpell, true); - if (Pet* pPet = m_caster->FindGuardianWithEntry(pSpell->EffectMiscValue[EFFECT_INDEX_0])) + if (Pet* pPet = m_caster->FindGuardianWithEntry(pSpell->GetEffectMiscValue(EFFECT_INDEX_0))) { // Nass Periodic Say aura pPet->CastSpell(pPet, 51868, true); @@ -7731,7 +7762,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (const SpellEntry* pSpell = sSpellStore.LookupEntry(51865)) { // Is this all to be done at completion? - if (Pet* pPet = m_caster->FindGuardianWithEntry(pSpell->EffectMiscValue[EFFECT_INDEX_0])) + if (Pet* pPet = m_caster->FindGuardianWithEntry(pSpell->GetEffectMiscValue(EFFECT_INDEX_0))) pPet->Unsummon(PET_SAVE_AS_DELETED, m_caster); } return; @@ -7809,7 +7840,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (!unitTarget) return; - unitTarget->RemoveAurasDueToSpell(m_spellInfo->CalculateSimpleValue(eff_idx)); + unitTarget->RemoveAurasDueToSpell(effect->CalculateSimpleValue()); break; } case 57337: // Great Feast @@ -7840,7 +7871,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) case 58418: // Portal to Orgrimmar case 58420: // Portal to Stormwind { - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || eff_idx != EFFECT_INDEX_0) + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || effect->EffectIndex != EFFECT_INDEX_0) return; uint32 spellID = m_spellInfo->CalculateSimpleValue(EFFECT_INDEX_0); @@ -7927,7 +7958,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) case 62521: numStacks = 25; break; }; - uint32 spellId = m_spellInfo->CalculateSimpleValue(eff_idx); + uint32 spellId = effect->CalculateSimpleValue(); unitTarget->RemoveAuraHolderFromStack(spellId, numStacks); return; } @@ -7945,7 +7976,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) } case 62688: // Summon Wave - 10 Mob { - uint32 spellId = m_spellInfo->CalculateSimpleValue(eff_idx); + uint32 spellId = effect->CalculateSimpleValue(); for (uint32 i = 0; i < 10; ++i) m_caster->CastSpell(m_caster, spellId, true); @@ -7957,7 +7988,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (!unitTarget) return; - uint32 spellId = m_spellInfo->CalculateSimpleValue(eff_idx); + uint32 spellId = effect->CalculateSimpleValue(); unitTarget->RemoveAuraHolderFromStack(spellId); return; } @@ -8012,13 +8043,13 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) return; for (uint8 i = 0; i < 11; ++i) - unitTarget->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(eff_idx), true); + unitTarget->CastSpell(unitTarget, effect->CalculateSimpleValue(), true); return; } case 68861: // Consume Soul (ICC FoS: Bronjahm) if (unitTarget) - unitTarget->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(eff_idx), true); + unitTarget->CastSpell(unitTarget, effect->CalculateSimpleValue(), true); return; case 68871: // Wailing Souls // Left or Right direction? @@ -8051,7 +8082,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (!unitTarget) return; - m_caster->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(eff_idx), true); + m_caster->CastSpell(unitTarget, effect->CalculateSimpleValue(), true); return; } case 69147: // Coldflame @@ -8059,7 +8090,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (!unitTarget) return; - unitTarget->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(eff_idx), true); + unitTarget->CastSpell(unitTarget, effect->CalculateSimpleValue(), true); return; } case 69377: // Fortitude @@ -8091,7 +8122,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) if (!unitTarget) return; - m_caster->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(eff_idx), true); + m_caster->CastSpell(unitTarget, effect->CalculateSimpleValue(), true); return; } case 72034: // Whiteout @@ -8107,7 +8138,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) return; // Cast summon spells 72701, 72702, 72703, 72704 - for (uint32 triggeredSpell = m_spellInfo->CalculateSimpleValue(eff_idx); triggeredSpell < m_spellInfo->Id; ++triggeredSpell) + for (uint32 triggeredSpell = effect->CalculateSimpleValue(); triggeredSpell < m_spellInfo->Id; ++triggeredSpell) unitTarget->CastSpell(unitTarget, triggeredSpell, true); return; @@ -8181,7 +8212,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) default: return; } - DoCreateItem(eff_idx, itemtype); + DoCreateItem( effect, itemtype ); return; } case 47193: // Demonic Empowerment @@ -8210,11 +8241,12 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) Unit::SpellAuraHolderMap& suAuras = unitTarget->GetSpellAuraHolderMap(); for (Unit::SpellAuraHolderMap::iterator itr = suAuras.begin(); itr != suAuras.end(); ++itr) { - SpellEntry const* spellInfo = (*itr).second->GetSpellProto(); - if (spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && - (spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000002)) && - (*itr).second->GetCasterGuid() == m_caster->GetObjectGuid()) - (*itr).second->RefreshHolder(); + SpellEntry const *spellInfo = (*itr).second->GetSpellProto(); + SpellClassOptionsEntry const* eaClassOptions = spellInfo->GetSpellClassOptions(); + if(eaClassOptions && eaClassOptions->SpellFamilyName == SPELLFAMILY_WARLOCK && + (eaClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000002)) && + (*itr).second->GetCasterGuid() == m_caster->GetObjectGuid()) + (*itr).second->RefreshHolder(); } return; } @@ -8242,10 +8274,11 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) Unit::SpellAuraHolderMap& auras = unitTarget->GetSpellAuraHolderMap(); for (Unit::SpellAuraHolderMap::iterator itr = auras.begin(); itr != auras.end(); ++itr) { - SpellEntry const* spellInfo = (*itr).second->GetSpellProto(); - if (spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && - (spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000008000)) && - (*itr).second->GetCasterGuid() == m_caster->GetObjectGuid()) + SpellEntry const *spellInfo = (*itr).second->GetSpellProto(); + SpellClassOptionsEntry const* swpClassOptions = spellInfo->GetSpellClassOptions(); + if (swpClassOptions && swpClassOptions->SpellFamilyName == SPELLFAMILY_PRIEST && + (swpClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000008000)) && + (*itr).second->GetCasterGuid() == m_caster->GetObjectGuid()) { (*itr).second->RefreshHolder(); return; @@ -8278,8 +8311,8 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) continue; // Search only Serpent Sting, Viper Sting, Scorpid Sting auras - ClassFamilyMask const& familyFlag = holder->GetSpellProto()->SpellFamilyFlags; - if (!familyFlag.IsFitToFamilyMask(UI64LIT(0x000000800000C000))) + SpellClassOptionsEntry const* stingClassOptions = holder->GetSpellProto()->GetSpellClassOptions(); + if (!stingClassOptions || !stingClassOptions->SpellFamilyFlags.IsFitToFamilyMask(UI64LIT(0x000000800000C000))) continue; // Refresh aura duration @@ -8291,7 +8324,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) continue; // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. - if (familyFlag.IsFitToFamilyMask(UI64LIT(0x0000000000004000))) + if (stingClassOptions->IsFitToFamilyMask(UI64LIT(0x0000000000004000))) { // m_amount already include RAP bonus basePoint = aura->GetModifier()->m_amount * aura->GetAuraMaxTicks() * 40 / 100; @@ -8299,7 +8332,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) } // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. - if (familyFlag.IsFitToFamilyMask(UI64LIT(0x0000008000000000))) + if (stingClassOptions->IsFitToFamilyMask(UI64LIT(0x0000008000000000))) { uint32 target_max_mana = unitTarget->GetMaxPower(POWER_MANA); if (!target_max_mana) @@ -8322,7 +8355,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) } // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. - if (familyFlag.IsFitToFamilyMask(UI64LIT(0x0000000000008000))) + if (stingClassOptions->IsFitToFamilyMask(UI64LIT(0x0000000000008000))) spellId = 53359; // Chimera Shot - Scorpid // ?? nothing say in spell desc (possibly need addition check) // if ((familyFlag & UI64LIT(0x0000010000000000)) || // dot @@ -8374,7 +8407,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) case SPELLFAMILY_PALADIN: { // Judgement (seal trigger) - if (m_spellInfo->Category == SPELLCATEGORY_JUDGEMENT) + if (m_spellInfo->GetCategory() == SPELLCATEGORY_JUDGEMENT) { if (!unitTarget || !unitTarget->isAlive()) return; @@ -8517,14 +8550,14 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) return; // Previous effect might have started script - if (!ScriptMgr::CanSpellEffectStartDBScript(m_spellInfo, eff_idx)) + if (!ScriptMgr::CanSpellEffectStartDBScript(m_spellInfo, SpellEffectIndex(effect->EffectIndex))) return; DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell ScriptStart spellid %u in EffectScriptEffect", m_spellInfo->Id); m_caster->GetMap()->ScriptsStart(sSpellScripts, m_spellInfo->Id, m_caster, unitTarget); } -void Spell::EffectSanctuary(SpellEffectIndex /*eff_idx*/) +void Spell::EffectSanctuary(SpellEffectEntry const* /*effect*/) { if (!unitTarget) return; @@ -8538,7 +8571,7 @@ void Spell::EffectSanctuary(SpellEffectIndex /*eff_idx*/) ((Player*)m_caster)->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT); } -void Spell::EffectAddComboPoints(SpellEffectIndex /*eff_idx*/) +void Spell::EffectAddComboPoints(SpellEffectEntry const* effect /*effect*/) { if (!unitTarget) return; @@ -8552,7 +8585,7 @@ void Spell::EffectAddComboPoints(SpellEffectIndex /*eff_idx*/) ((Player*)m_caster)->AddComboPoints(unitTarget, damage); } -void Spell::EffectDuel(SpellEffectIndex eff_idx) +void Spell::EffectDuel(SpellEffectEntry const* effect) { if (!m_caster || !unitTarget || m_caster->GetTypeId() != TYPEID_PLAYER || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -8582,7 +8615,7 @@ void Spell::EffectDuel(SpellEffectIndex eff_idx) // CREATE DUEL FLAG OBJECT GameObject* pGameObj = new GameObject; - uint32 gameobject_id = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 gameobject_id = effect->EffectMiscValue; Map* map = m_caster->GetMap(); float x = (m_caster->GetPositionX() + unitTarget->GetPositionX()) * 0.5f; @@ -8631,7 +8664,7 @@ void Spell::EffectDuel(SpellEffectIndex eff_idx) target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetObjectGuid()); } -void Spell::EffectStuck(SpellEffectIndex /*eff_idx*/) +void Spell::EffectStuck(SpellEffectEntry const* effect /*effect*/) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -8658,7 +8691,7 @@ void Spell::EffectStuck(SpellEffectIndex /*eff_idx*/) spell.SendSpellCooldown(); } -void Spell::EffectSummonPlayer(SpellEffectIndex /*eff_idx*/) +void Spell::EffectSummonPlayer(SpellEffectEntry const* /*effect*/) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -8690,19 +8723,19 @@ static ScriptInfo generateActivateCommand() return si; } -void Spell::EffectActivateObject(SpellEffectIndex eff_idx) +void Spell::EffectActivateObject(SpellEffectEntry const* effect) { if (!gameObjTarget) return; static ScriptInfo activateCommand = generateActivateCommand(); - int32 delay_secs = m_spellInfo->CalculateSimpleValue(eff_idx); + int32 delay_secs = effect->CalculateSimpleValue(); gameObjTarget->GetMap()->ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget); } -void Spell::EffectApplyGlyph(SpellEffectIndex eff_idx) +void Spell::EffectApplyGlyph(SpellEffectEntry const* effect) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -8710,7 +8743,7 @@ void Spell::EffectApplyGlyph(SpellEffectIndex eff_idx) Player* player = (Player*)m_caster; // apply new one - if (uint32 glyph = m_spellInfo->EffectMiscValue[eff_idx]) + if(uint32 glyph = effect->EffectMiscValue) { if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyph)) { @@ -8732,7 +8765,7 @@ void Spell::EffectApplyGlyph(SpellEffectIndex eff_idx) } } -void Spell::EffectEnchantHeldItem(SpellEffectIndex eff_idx) +void Spell::EffectEnchantHeldItem(SpellEffectEntry const* effect) { // this is only item spell effect applied to main-hand weapon of target player (players in area) if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) @@ -8748,12 +8781,12 @@ void Spell::EffectEnchantHeldItem(SpellEffectIndex eff_idx) if (!item ->IsEquipped()) return; - if (m_spellInfo->EffectMiscValue[eff_idx]) + if (effect->EffectMiscValue) { - uint32 enchant_id = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 enchant_id = effect->EffectMiscValue; int32 duration = m_duration; // Try duration index first... if (!duration) - duration = m_currentBasePoints[eff_idx]; // Base points after... + duration = m_currentBasePoints[SpellEffectIndex(effect->EffectIndex)]; // Base points after... if (!duration) duration = 10; // 10 seconds for enchants which don't have listed duration @@ -8774,7 +8807,7 @@ void Spell::EffectEnchantHeldItem(SpellEffectIndex eff_idx) } } -void Spell::EffectDisEnchant(SpellEffectIndex /*eff_idx*/) +void Spell::EffectDisEnchant(SpellEffectEntry const* /*effect*/) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -8790,7 +8823,7 @@ void Spell::EffectDisEnchant(SpellEffectIndex /*eff_idx*/) // item will be removed at disenchanting end } -void Spell::EffectInebriate(SpellEffectIndex /*eff_idx*/) +void Spell::EffectInebriate(SpellEffectEntry const* /*effect*/) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -8805,7 +8838,7 @@ void Spell::EffectInebriate(SpellEffectIndex /*eff_idx*/) player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0); } -void Spell::EffectFeedPet(SpellEffectIndex eff_idx) +void Spell::EffectFeedPet(SpellEffectEntry const* effect) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -8831,10 +8864,10 @@ void Spell::EffectFeedPet(SpellEffectIndex eff_idx) _player->DestroyItemCount(foodItem, count, true); // TODO: fix crash when a spell has two effects, both pointed at the same item target - m_caster->CastCustomSpell(pet, m_spellInfo->EffectTriggerSpell[eff_idx], &benefit, NULL, NULL, true); + m_caster->CastCustomSpell(pet, effect->EffectTriggerSpell, &benefit, NULL, NULL, true); } -void Spell::EffectDismissPet(SpellEffectIndex /*eff_idx*/) +void Spell::EffectDismissPet(SpellEffectEntry const* /*effect*/) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -8848,12 +8881,12 @@ void Spell::EffectDismissPet(SpellEffectIndex /*eff_idx*/) pet->Unsummon(PET_SAVE_NOT_IN_SLOT, m_caster); } -void Spell::EffectSummonObject(SpellEffectIndex eff_idx) +void Spell::EffectSummonObject(SpellEffectEntry const* effect) { - uint32 go_id = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 go_id = effect->EffectMiscValue; uint8 slot = 0; - switch (m_spellInfo->Effect[eff_idx]) + switch(effect->Effect) { case SPELL_EFFECT_SUMMON_OBJECT_SLOT1: slot = 0; break; case SPELL_EFFECT_SUMMON_OBJECT_SLOT2: slot = 1; break; @@ -8908,7 +8941,7 @@ void Spell::EffectSummonObject(SpellEffectIndex eff_idx) ((Creature*)m_originalCaster)->AI()->JustSummoned(pGameObj); } -void Spell::EffectResurrect(SpellEffectIndex /*eff_idx*/) +void Spell::EffectResurrect(SpellEffectEntry const* /*effect*/) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -8955,7 +8988,7 @@ void Spell::EffectResurrect(SpellEffectIndex /*eff_idx*/) SendResurrectRequest(pTarget); } -void Spell::EffectAddExtraAttacks(SpellEffectIndex /*eff_idx*/) +void Spell::EffectAddExtraAttacks(SpellEffectEntry const* /*effect*/) { if (!unitTarget || !unitTarget->isAlive()) return; @@ -8966,26 +8999,26 @@ void Spell::EffectAddExtraAttacks(SpellEffectIndex /*eff_idx*/) unitTarget->m_extraAttacks = damage; } -void Spell::EffectParry(SpellEffectIndex /*eff_idx*/) +void Spell::EffectParry(SpellEffectEntry const* /*effect*/) { if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) ((Player*)unitTarget)->SetCanParry(true); } -void Spell::EffectBlock(SpellEffectIndex /*eff_idx*/) +void Spell::EffectBlock(SpellEffectEntry const* /*effect*/) { if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) ((Player*)unitTarget)->SetCanBlock(true); } -void Spell::EffectLeapForward(SpellEffectIndex eff_idx) +void Spell::EffectLeapForward(SpellEffectEntry const* effect) { if (unitTarget->IsTaxiFlying()) return; if (m_spellInfo->rangeIndex == 1) // self range { - float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[eff_idx])); + float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->EffectRadiusIndex)); // before caster float fx, fy, fz; @@ -9000,23 +9033,23 @@ void Spell::EffectLeapForward(SpellEffectIndex eff_idx) } } -void Spell::EffectLeapBack(SpellEffectIndex eff_idx) +void Spell::EffectLeapBack(SpellEffectEntry const* effect) { if (unitTarget->IsTaxiFlying()) return; - m_caster->KnockBackFrom(unitTarget, float(m_spellInfo->EffectMiscValue[eff_idx]) / 10, float(damage) / 10); + m_caster->KnockBackFrom(unitTarget, float(effect->EffectMiscValue) / 10, float(damage) / 10); } -void Spell::EffectReputation(SpellEffectIndex eff_idx) +void Spell::EffectReputation(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; Player* _player = (Player*)unitTarget; - int32 rep_change = m_currentBasePoints[eff_idx]; - uint32 faction_id = m_spellInfo->EffectMiscValue[eff_idx]; + int32 rep_change = m_currentBasePoints[effect->EffectIndex]; + uint32 faction_id = effect->EffectMiscValue; FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id); @@ -9028,7 +9061,7 @@ void Spell::EffectReputation(SpellEffectIndex eff_idx) _player->GetReputationMgr().ModifyReputation(factionEntry, rep_change); } -void Spell::EffectQuestComplete(SpellEffectIndex eff_idx) +void Spell::EffectQuestComplete(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -9038,7 +9071,7 @@ void Spell::EffectQuestComplete(SpellEffectIndex eff_idx) { case 43458: // Secrets of Nifflevar { - if (!unitTarget->HasAura(m_spellInfo->CalculateSimpleValue(eff_idx))) + if (!unitTarget->HasAura(effect->CalculateSimpleValue())) return; break; @@ -9052,11 +9085,11 @@ void Spell::EffectQuestComplete(SpellEffectIndex eff_idx) break; } - uint32 quest_id = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 quest_id = effect->EffectMiscValue; ((Player*)unitTarget)->AreaExploredOrEventHappens(quest_id); } -void Spell::EffectSelfResurrect(SpellEffectIndex eff_idx) +void Spell::EffectSelfResurrect(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->isAlive()) return; @@ -9072,7 +9105,7 @@ void Spell::EffectSelfResurrect(SpellEffectIndex eff_idx) if (damage < 0) { health = uint32(-damage); - mana = m_spellInfo->EffectMiscValue[eff_idx]; + mana = effect->EffectMiscValue; } // percent case else @@ -9093,7 +9126,7 @@ void Spell::EffectSelfResurrect(SpellEffectIndex eff_idx) plr->SpawnCorpseBones(); } -void Spell::EffectSkinning(SpellEffectIndex /*eff_idx*/) +void Spell::EffectSkinning(SpellEffectEntry const* /*effect*/) { if (unitTarget->GetTypeId() != TYPEID_UNIT) return; @@ -9116,7 +9149,7 @@ void Spell::EffectSkinning(SpellEffectIndex /*eff_idx*/) ((Player*)m_caster)->UpdateGatherSkill(skill, skillValue, reqValue, creature->IsElite() ? 2 : 1); } -void Spell::EffectCharge(SpellEffectIndex /*eff_idx*/) +void Spell::EffectCharge(SpellEffectEntry const* /*effect*/) { if (!unitTarget) return; @@ -9137,7 +9170,7 @@ void Spell::EffectCharge(SpellEffectIndex /*eff_idx*/) m_caster->Attack(unitTarget, true); } -void Spell::EffectCharge2(SpellEffectIndex /*eff_idx*/) +void Spell::EffectCharge2(SpellEffectEntry const* /*effect*/) { float x, y, z; if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) @@ -9162,23 +9195,23 @@ void Spell::EffectCharge2(SpellEffectIndex /*eff_idx*/) m_caster->Attack(unitTarget, true); } -void Spell::EffectKnockBack(SpellEffectIndex eff_idx) +void Spell::EffectKnockBack(SpellEffectEntry const* effect) { if (!unitTarget) return; - unitTarget->KnockBackFrom(m_caster, float(m_spellInfo->EffectMiscValue[eff_idx]) / 10, float(damage) / 10); + unitTarget->KnockBackFrom(m_caster, float(effect->EffectMiscValue) / 10, float(damage) / 10); } -void Spell::EffectSendTaxi(SpellEffectIndex eff_idx) +void Spell::EffectSendTaxi(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - ((Player*)unitTarget)->ActivateTaxiPathTo(m_spellInfo->EffectMiscValue[eff_idx], m_spellInfo->Id); + ((Player*)unitTarget)->ActivateTaxiPathTo(effect->EffectMiscValue, m_spellInfo->Id); } -void Spell::EffectPlayerPull(SpellEffectIndex eff_idx) +void Spell::EffectPlayerPull(SpellEffectEntry const* effect) { if (!unitTarget) return; @@ -9187,15 +9220,15 @@ void Spell::EffectPlayerPull(SpellEffectIndex eff_idx) if (damage && dist > damage) dist = float(damage); - unitTarget->KnockBackFrom(m_caster, -dist, float(m_spellInfo->EffectMiscValue[eff_idx]) / 10); + unitTarget->KnockBackFrom(m_caster, -dist, float(effect->EffectMiscValue) / 10); } -void Spell::EffectDispelMechanic(SpellEffectIndex eff_idx) +void Spell::EffectDispelMechanic(SpellEffectEntry const* effect) { if (!unitTarget) return; - uint32 mechanic = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 mechanic = effect->EffectMiscValue; Unit::SpellAuraHolderMap& Auras = unitTarget->GetSpellAuraHolderMap(); for (Unit::SpellAuraHolderMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) @@ -9214,7 +9247,7 @@ void Spell::EffectDispelMechanic(SpellEffectIndex eff_idx) } } -void Spell::EffectSummonDeadPet(SpellEffectIndex /*eff_idx*/) +void Spell::EffectSummonDeadPet(SpellEffectEntry const* /*effect*/) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -9239,13 +9272,13 @@ void Spell::EffectSummonDeadPet(SpellEffectIndex /*eff_idx*/) pet->SavePetToDB(PET_SAVE_AS_CURRENT); } -void Spell::EffectSummonAllTotems(SpellEffectIndex eff_idx) +void Spell::EffectSummonAllTotems(SpellEffectEntry const* effect) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; - int32 start_button = ACTION_BUTTON_SHAMAN_TOTEMS_BAR + m_spellInfo->EffectMiscValue[eff_idx]; - int32 amount_buttons = m_spellInfo->EffectMiscValueB[eff_idx]; + int32 start_button = ACTION_BUTTON_SHAMAN_TOTEMS_BAR + effect->EffectMiscValue; + int32 amount_buttons = effect->EffectMiscValueB; for (int32 slot = 0; slot < amount_buttons; ++slot) if (ActionButton const* actionButton = ((Player*)m_caster)->GetActionButton(start_button + slot)) @@ -9254,7 +9287,7 @@ void Spell::EffectSummonAllTotems(SpellEffectIndex eff_idx) m_caster->CastSpell(unitTarget, spell_id, true); } -void Spell::EffectDestroyAllTotems(SpellEffectIndex /*eff_idx*/) +void Spell::EffectDestroyAllTotems(SpellEffectEntry const* /*effect*/) { int32 mana = 0; for (int slot = 0; slot < MAX_TOTEM_SLOT; ++slot) @@ -9266,7 +9299,7 @@ void Spell::EffectDestroyAllTotems(SpellEffectIndex /*eff_idx*/) uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL); if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell_id)) { - uint32 manacost = spellInfo->manaCost + m_caster->GetCreateMana() * spellInfo->ManaCostPercentage / 100; + uint32 manacost = m_caster->GetCreateMana() * spellInfo->GetManaCostPercentage() / 100; mana += manacost * damage / 100; } } @@ -9278,7 +9311,7 @@ void Spell::EffectDestroyAllTotems(SpellEffectIndex /*eff_idx*/) m_caster->CastCustomSpell(m_caster, 39104, &mana, NULL, NULL, true); } -void Spell::EffectBreakPlayerTargeting(SpellEffectIndex /* eff_idx */) +void Spell::EffectBreakPlayerTargeting (SpellEffectEntry const* /*effect*/) { if (!unitTarget) return; @@ -9288,12 +9321,12 @@ void Spell::EffectBreakPlayerTargeting(SpellEffectIndex /* eff_idx */) unitTarget->SendMessageToSet(&data, false); } -void Spell::EffectDurabilityDamage(SpellEffectIndex eff_idx) +void Spell::EffectDurabilityDamage(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - int32 slot = m_spellInfo->EffectMiscValue[eff_idx]; + int32 slot = effect->EffectMiscValue; // FIXME: some spells effects have value -1/-2 // Possibly its mean -1 all player equipped items and -2 all items @@ -9311,12 +9344,12 @@ void Spell::EffectDurabilityDamage(SpellEffectIndex eff_idx) ((Player*)unitTarget)->DurabilityPointsLoss(item, damage); } -void Spell::EffectDurabilityDamagePCT(SpellEffectIndex eff_idx) +void Spell::EffectDurabilityDamagePCT(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - int32 slot = m_spellInfo->EffectMiscValue[eff_idx]; + int32 slot = effect->EffectMiscValue; // FIXME: some spells effects have value -1/-2 // Possibly its mean -1 all player equipped items and -2 all items @@ -9337,7 +9370,7 @@ void Spell::EffectDurabilityDamagePCT(SpellEffectIndex eff_idx) ((Player*)unitTarget)->DurabilityLoss(item, double(damage) / 100.0f); } -void Spell::EffectModifyThreatPercent(SpellEffectIndex /*eff_idx*/) +void Spell::EffectModifyThreatPercent(SpellEffectEntry const* /*effect*/) { if (!unitTarget) return; @@ -9345,9 +9378,9 @@ void Spell::EffectModifyThreatPercent(SpellEffectIndex /*eff_idx*/) unitTarget->getThreatManager().modifyThreatPercent(m_caster, damage); } -void Spell::EffectTransmitted(SpellEffectIndex eff_idx) +void Spell::EffectTransmitted(SpellEffectEntry const* effect) { - uint32 name_id = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 name_id = effect->EffectMiscValue; GameObjectInfo const* goinfo = ObjectMgr::GetGameObjectInfo(name_id); @@ -9365,10 +9398,10 @@ void Spell::EffectTransmitted(SpellEffectIndex eff_idx) fy = m_targets.m_destY; fz = m_targets.m_destZ; } - // FIXME: this can be better check for most objects but still hack - else if (m_spellInfo->EffectRadiusIndex[eff_idx] && m_spellInfo->speed == 0) + //FIXME: this can be better check for most objects but still hack + else if(effect->EffectRadiusIndex && m_spellInfo->speed==0) { - float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[eff_idx])); + float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->EffectRadiusIndex)); m_caster->GetClosePoint(fx, fy, fz, DEFAULT_WORLD_OBJECT_SIZE, dis); } else @@ -9484,7 +9517,7 @@ void Spell::EffectTransmitted(SpellEffectIndex eff_idx) ((Creature*)m_originalCaster)->AI()->JustSummoned(pGameObj); } -void Spell::EffectProspecting(SpellEffectIndex /*eff_idx*/) +void Spell::EffectProspecting(SpellEffectEntry const* /*effect*/) { if (m_caster->GetTypeId() != TYPEID_PLAYER || !itemTarget) return; @@ -9501,7 +9534,7 @@ void Spell::EffectProspecting(SpellEffectIndex /*eff_idx*/) ((Player*)m_caster)->SendLoot(itemTarget->GetObjectGuid(), LOOT_PROSPECTING); } -void Spell::EffectMilling(SpellEffectIndex /*eff_idx*/) +void Spell::EffectMilling(SpellEffectEntry const* /*effect*/) { if (m_caster->GetTypeId() != TYPEID_PLAYER || !itemTarget) return; @@ -9518,12 +9551,12 @@ void Spell::EffectMilling(SpellEffectIndex /*eff_idx*/) ((Player*)m_caster)->SendLoot(itemTarget->GetObjectGuid(), LOOT_MILLING); } -void Spell::EffectSkill(SpellEffectIndex /*eff_idx*/) +void Spell::EffectSkill(SpellEffectEntry const* /*effect*/) { DEBUG_LOG("WORLD: SkillEFFECT"); } -void Spell::EffectSpiritHeal(SpellEffectIndex /*eff_idx*/) +void Spell::EffectSpiritHeal(SpellEffectEntry const* /*effect*/) { // TODO player can't see the heal-animation - he should respawn some ticks later if (!unitTarget || unitTarget->isAlive()) @@ -9540,7 +9573,7 @@ void Spell::EffectSpiritHeal(SpellEffectIndex /*eff_idx*/) } // remove insignia spell effect -void Spell::EffectSkinPlayerCorpse(SpellEffectIndex /*eff_idx*/) +void Spell::EffectSkinPlayerCorpse(SpellEffectEntry const* /*effect*/) { DEBUG_LOG("Effect: SkinPlayerCorpse"); if ((m_caster->GetTypeId() != TYPEID_PLAYER) || (unitTarget->GetTypeId() != TYPEID_PLAYER) || (unitTarget->isAlive())) @@ -9549,7 +9582,7 @@ void Spell::EffectSkinPlayerCorpse(SpellEffectIndex /*eff_idx*/) ((Player*)unitTarget)->RemovedInsignia((Player*)m_caster); } -void Spell::EffectStealBeneficialBuff(SpellEffectIndex eff_idx) +void Spell::EffectStealBeneficialBuff(SpellEffectEntry const* effect) { DEBUG_LOG("Effect: StealBeneficialBuff"); @@ -9559,12 +9592,12 @@ void Spell::EffectStealBeneficialBuff(SpellEffectIndex eff_idx) typedef std::vector StealList; StealList steal_list; // Create dispel mask by dispel type - uint32 dispelMask = GetDispellMask(DispelType(m_spellInfo->EffectMiscValue[eff_idx])); + uint32 dispelMask = GetDispellMask( DispelType(effect->EffectMiscValue) ); Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap(); for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - SpellAuraHolder* holder = itr->second; - if (holder && (1 << holder->GetSpellProto()->Dispel) & dispelMask) + SpellAuraHolder *holder = itr->second; + if (holder && (1<GetSpellProto()->GetDispel()) & dispelMask) { // Need check for passive? this if (holder->IsPositive() && !holder->IsPassive() && !holder->GetSpellProto()->HasAttribute(SPELL_ATTR_EX4_NOT_STEALABLE)) @@ -9621,31 +9654,31 @@ void Spell::EffectStealBeneficialBuff(SpellEffectIndex eff_idx) } } -void Spell::EffectKillCreditPersonal(SpellEffectIndex eff_idx) +void Spell::EffectKillCreditPersonal(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - ((Player*)unitTarget)->KilledMonsterCredit(m_spellInfo->EffectMiscValue[eff_idx]); + ((Player*)unitTarget)->KilledMonsterCredit(effect->EffectMiscValue); } -void Spell::EffectKillCreditGroup(SpellEffectIndex eff_idx) +void Spell::EffectKillCreditGroup(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - ((Player*)unitTarget)->RewardPlayerAndGroupAtEvent(m_spellInfo->EffectMiscValue[eff_idx], unitTarget); + ((Player*)unitTarget)->RewardPlayerAndGroupAtEvent(effect->EffectMiscValue, unitTarget); } -void Spell::EffectQuestFail(SpellEffectIndex eff_idx) +void Spell::EffectQuestFail(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - ((Player*)unitTarget)->FailQuest(m_spellInfo->EffectMiscValue[eff_idx]); + ((Player*)unitTarget)->FailQuest(effect->EffectMiscValue); } -void Spell::EffectActivateRune(SpellEffectIndex eff_idx) +void Spell::EffectActivateRune(SpellEffectEntry const* effect) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -9656,15 +9689,15 @@ void Spell::EffectActivateRune(SpellEffectIndex eff_idx) return; int32 count = damage; // max amount of reset runes - if (plr->ActivateRunes(RuneType(m_spellInfo->EffectMiscValue[eff_idx]), count)) + if (plr->ActivateRunes(RuneType(effect->EffectMiscValue), count)) plr->ResyncRunes(); } -void Spell::EffectTitanGrip(SpellEffectIndex eff_idx) +void Spell::EffectTitanGrip(SpellEffectEntry const* effect) { // Make sure "Titan's Grip" (49152) penalty spell does not silently change - if (m_spellInfo->EffectMiscValue[eff_idx] != 49152) - sLog.outError("Spell::EffectTitanGrip: Spell %u has unexpected EffectMiscValue '%u'", m_spellInfo->Id, m_spellInfo->EffectMiscValue[eff_idx]); + if (effect->EffectMiscValue != 49152) + sLog.outError("Spell::EffectTitanGrip: Spell %u has unexpected EffectMiscValue '%u'", m_spellInfo->Id, effect->EffectMiscValue); if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) { Player* plr = (Player*)m_caster; @@ -9674,7 +9707,7 @@ void Spell::EffectTitanGrip(SpellEffectIndex eff_idx) } } -void Spell::EffectRenamePet(SpellEffectIndex /*eff_idx*/) +void Spell::EffectRenamePet(SpellEffectEntry const* /*effect*/) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT || !((Creature*)unitTarget)->IsPet() || ((Pet*)unitTarget)->getPetType() != HUNTER_PET) @@ -9683,12 +9716,12 @@ void Spell::EffectRenamePet(SpellEffectIndex /*eff_idx*/) unitTarget->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED); } -void Spell::EffectPlaySound(SpellEffectIndex eff_idx) +void Spell::EffectPlaySound(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - uint32 soundId = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 soundId = effect->EffectMiscValue; if (!sSoundEntriesStore.LookupEntry(soundId)) { sLog.outError("EffectPlaySound: Sound (Id: %u) in spell %u does not exist.", soundId, m_spellInfo->Id); @@ -9698,12 +9731,12 @@ void Spell::EffectPlaySound(SpellEffectIndex eff_idx) unitTarget->PlayDirectSound(soundId, (Player*)unitTarget); } -void Spell::EffectPlayMusic(SpellEffectIndex eff_idx) +void Spell::EffectPlayMusic(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - uint32 soundId = m_spellInfo->EffectMiscValue[eff_idx]; + uint32 soundId = effect->EffectMiscValue; if (!sSoundEntriesStore.LookupEntry(soundId)) { sLog.outError("EffectPlayMusic: Sound (Id: %u) in spell %u does not exist.", soundId, m_spellInfo->Id); @@ -9715,7 +9748,7 @@ void Spell::EffectPlayMusic(SpellEffectIndex eff_idx) ((Player*)unitTarget)->GetSession()->SendPacket(&data); } -void Spell::EffectSpecCount(SpellEffectIndex /*eff_idx*/) +void Spell::EffectSpecCount(SpellEffectEntry const* /*effect*/) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -9723,7 +9756,7 @@ void Spell::EffectSpecCount(SpellEffectIndex /*eff_idx*/) ((Player*)unitTarget)->UpdateSpecCount(damage); } -void Spell::EffectActivateSpec(SpellEffectIndex /*eff_idx*/) +void Spell::EffectActivateSpec(SpellEffectEntry const* /*effect*/) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -9733,7 +9766,7 @@ void Spell::EffectActivateSpec(SpellEffectIndex /*eff_idx*/) ((Player*)unitTarget)->ActivateSpec(spec); } -void Spell::EffectBind(SpellEffectIndex eff_idx) +void Spell::EffectBind(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -9742,8 +9775,8 @@ void Spell::EffectBind(SpellEffectIndex eff_idx) uint32 area_id; WorldLocation loc; - if (m_spellInfo->EffectImplicitTargetA[eff_idx] == TARGET_TABLE_X_Y_Z_COORDINATES || - m_spellInfo->EffectImplicitTargetB[eff_idx] == TARGET_TABLE_X_Y_Z_COORDINATES) + if (effect->EffectImplicitTargetA == TARGET_TABLE_X_Y_Z_COORDINATES || + effect->EffectImplicitTargetB == TARGET_TABLE_X_Y_Z_COORDINATES) { SpellTargetPosition const* st = sSpellMgr.GetSpellTargetPosition(m_spellInfo->Id); if (!st) @@ -9789,12 +9822,14 @@ void Spell::EffectBind(SpellEffectIndex eff_idx) player->SendDirectMessage(&data); } -void Spell::EffectRestoreItemCharges(SpellEffectIndex eff_idx) +void Spell::EffectRestoreItemCharges(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(m_spellInfo->EffectItemType[eff_idx]); + Player* player = (Player*)unitTarget; + + ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(effect->EffectItemType); if (!itemProto) return; @@ -9803,7 +9838,7 @@ void Spell::EffectRestoreItemCharges(SpellEffectIndex eff_idx) if (itemProto->ItemLimitCategory) item = ((Player*)unitTarget)->GetItemByLimitedCategory(itemProto->ItemLimitCategory); else - item = ((Player*)unitTarget)->GetItemByEntry(m_spellInfo->EffectItemType[eff_idx]); + item = player->GetItemByEntry(effect->EffectItemType); if (!item) return; @@ -9811,7 +9846,7 @@ void Spell::EffectRestoreItemCharges(SpellEffectIndex eff_idx) item->RestoreCharges(); } -void Spell::EffectRedirectThreat(SpellEffectIndex eff_idx) +void Spell::EffectRedirectThreat(SpellEffectEntry const* effect) { if (!unitTarget) return; @@ -9823,17 +9858,17 @@ void Spell::EffectRedirectThreat(SpellEffectIndex eff_idx) m_caster->getHostileRefManager().SetThreatRedirection(unitTarget->GetObjectGuid(), uint32(damage)); } -void Spell::EffectTeachTaxiNode(SpellEffectIndex eff_idx) +void Spell::EffectTeachTaxiNode(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - uint32 taxiNodeId = m_spellInfo->EffectMiscValue[eff_idx]; + Player* player = (Player*)unitTarget; + + uint32 taxiNodeId = effect->EffectMiscValue; if (!sTaxiNodesStore.LookupEntry(taxiNodeId)) return; - Player* player = (Player*)unitTarget; - if (player->m_taxi.SetTaximaskNode(taxiNodeId)) { WorldPacket data(SMSG_NEW_TAXI_PATH, 0); @@ -9846,12 +9881,12 @@ void Spell::EffectTeachTaxiNode(SpellEffectIndex eff_idx) } } -void Spell::EffectQuestOffer(SpellEffectIndex eff_idx) +void Spell::EffectQuestOffer(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - if (Quest const* quest = sObjectMgr.GetQuestTemplate(m_spellInfo->EffectMiscValue[eff_idx])) + if (Quest const* quest = sObjectMgr.GetQuestTemplate(effect->EffectMiscValue)) { Player* player = (Player*)unitTarget; @@ -9860,12 +9895,12 @@ void Spell::EffectQuestOffer(SpellEffectIndex eff_idx) } } -void Spell::EffectCancelAura(SpellEffectIndex eff_idx) +void Spell::EffectCancelAura(SpellEffectEntry const* effect) { if (!unitTarget) return; - uint32 spellId = m_spellInfo->EffectTriggerSpell[eff_idx]; + uint32 spellId = effect->EffectTriggerSpell; if (!sSpellStore.LookupEntry(spellId)) { diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 8d176573c..a09604a6d 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -165,10 +165,11 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) // send spell error if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid)) { + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(EFFECT_INDEX_0); // for implicit area/coord target spells - if (IsPointEffectTarget(Targets(spellInfo->EffectImplicitTargetA[EFFECT_INDEX_0])) || - IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[EFFECT_INDEX_0]))) - Spell::SendCastResult(_player, spellInfo, cast_count, SPELL_FAILED_NO_VALID_TARGETS); + if (spellEffect && (IsPointEffectTarget(Targets(spellEffect->EffectImplicitTargetA)) || + IsAreaEffectTarget(Targets(spellEffect->EffectImplicitTargetA)))) + Spell::SendCastResult(_player,spellInfo,cast_count,SPELL_FAILED_NO_VALID_TARGETS); // for explicit target spells else Spell::SendCastResult(_player, spellInfo, cast_count, SPELL_FAILED_BAD_TARGETS); @@ -464,8 +465,9 @@ void WorldSession::HandleCancelAuraOpcode(WorldPacket& recvPacket) bool allow = false; for (int k = 0; k < MAX_EFFECT_INDEX; ++k) { - if (spellInfo->EffectApplyAuraName[k] == SPELL_AURA_MOD_POSSESS || - spellInfo->EffectApplyAuraName[k] == SPELL_AURA_MOD_POSSESS_PET) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(k)); + if (spellEffect && (spellEffect->EffectApplyAuraName == SPELL_AURA_MOD_POSSESS || + spellEffect->EffectApplyAuraName == SPELL_AURA_MOD_POSSESS_PET)) { allow = true; break; diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 95172121a..38c8e017c 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -158,12 +158,20 @@ uint32 GetSpellCastTimeForBonus(SpellEntry const* spellProto, DamageEffectType d bool AreaEffect = false; for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i) - if (IsAreaEffectTarget(Targets(spellProto->EffectImplicitTargetA[i])) || IsAreaEffectTarget(Targets(spellProto->EffectImplicitTargetB[i]))) + { + SpellEffectEntry const* spellEffect = spellProto->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + if (IsAreaEffectTarget(Targets(spellEffect->EffectImplicitTargetA)) || IsAreaEffectTarget(Targets(spellEffect->EffectImplicitTargetB))) AreaEffect = true; + } for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - switch (spellProto->Effect[i]) + SpellEffectEntry const* spellEffect = spellProto->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + switch (spellEffect->Effect) { case SPELL_EFFECT_SCHOOL_DAMAGE: case SPELL_EFFECT_POWER_DRAIN: @@ -174,7 +182,7 @@ uint32 GetSpellCastTimeForBonus(SpellEntry const* spellProto, DamageEffectType d DirectDamage = true; break; case SPELL_EFFECT_APPLY_AURA: - switch (spellProto->EffectApplyAuraName[i]) + switch (spellEffect->EffectApplyAuraName) { case SPELL_AURA_PERIODIC_DAMAGE: case SPELL_AURA_PERIODIC_HEAL: @@ -229,8 +237,11 @@ uint32 GetSpellCastTimeForBonus(SpellEntry const* spellProto, DamageEffectType d // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if (spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH || - (spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH)) + SpellEffectEntry const* spellEffect = spellProto->GetSpellEffect(SpellEffectIndex(j)); + if (!spellEffect) + continue; + if (spellEffect->Effect == SPELL_EFFECT_HEALTH_LEECH || + spellEffect->Effect == SPELL_EFFECT_APPLY_AURA && spellEffect->EffectApplyAuraName == SPELL_AURA_PERIODIC_LEECH) { CastingTime /= 2; break; @@ -256,13 +267,16 @@ uint16 GetSpellAuraMaxTicks(SpellEntry const* spellInfo) for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - if (spellInfo->Effect[j] == SPELL_EFFECT_APPLY_AURA && ( - spellInfo->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE || - spellInfo->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_HEAL || - spellInfo->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH)) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(j)); + if(!spellEffect) + continue; + if (spellEffect->Effect == SPELL_EFFECT_APPLY_AURA && ( + spellEffect->EffectApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE || + spellEffect->EffectApplyAuraName == SPELL_AURA_PERIODIC_HEAL || + spellEffect->EffectApplyAuraName == SPELL_AURA_PERIODIC_LEECH) ) { - if (spellInfo->EffectAmplitude[j] != 0) - return DotDuration / spellInfo->EffectAmplitude[j]; + if (spellEffect->EffectAmplitude != 0) + return DotDuration / spellEffect->EffectAmplitude; break; } } @@ -306,7 +320,7 @@ WeaponAttackType GetWeaponAttackType(SpellEntry const* spellInfo) if (!spellInfo) return BASE_ATTACK; - switch (spellInfo->DmgClass) + switch (spellInfo->GetDmgClass()) { case SPELL_DAMAGE_CLASS_MELEE: if (spellInfo->HasAttribute(SPELL_ATTR_EX3_REQ_OFFHAND)) @@ -349,14 +363,19 @@ bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 spellId_2) for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { + SpellEffectEntry const* effect_1 = spellInfo_1->GetSpellEffect(SpellEffectIndex(i)); + for (int32 j = 0; j < MAX_EFFECT_INDEX; ++j) { - if (spellInfo_1->Effect[i] == spellInfo_2->Effect[j] - && spellInfo_1->EffectApplyAuraName[i] == spellInfo_2->EffectApplyAuraName[j] - && spellInfo_1->EffectMiscValue[i] == spellInfo_2->EffectMiscValue[j] - && spellInfo_1->EffectItemType[i] == spellInfo_2->EffectItemType[j] - && (spellInfo_1->Effect[i] != 0 || spellInfo_1->EffectApplyAuraName[i] != 0 || - spellInfo_1->EffectMiscValue[i] != 0 || spellInfo_1->EffectItemType[i] != 0)) + SpellEffectEntry const* effect_2 = spellInfo_2->GetSpellEffect(SpellEffectIndex(j)); + if(!effect_1 || !effect_2) + continue; + if (effect_1->Effect == effect_2->Effect + && effect_1->EffectApplyAuraName == effect_2->EffectApplyAuraName + && effect_1->EffectMiscValue == effect_2->EffectMiscValue + && effect_1->EffectItemType == effect_2->EffectItemType + && (effect_1->Effect != 0 || effect_1->EffectApplyAuraName != 0 || + effect_1->EffectMiscValue != 0 || effect_1->EffectItemType != 0)) return true; } } @@ -373,9 +392,14 @@ int32 CompareAuraRanks(uint32 spellId_1, uint32 spellId_2) for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (spellInfo_1->Effect[i] != 0 && spellInfo_2->Effect[i] != 0 && spellInfo_1->Effect[i] == spellInfo_2->Effect[i]) + SpellEffectEntry const* spellEffect_1 = spellInfo_1->GetSpellEffect(SpellEffectIndex(i)); + SpellEffectEntry const* spellEffect_2 = spellInfo_2->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect_1 || !spellEffect_2) + continue; + + if (spellEffect_1->Effect != 0 && spellEffect_2->Effect != 0 && spellEffect_1->Effect == spellEffect_2->Effect) { - int32 diff = spellInfo_1->EffectBasePoints[i] - spellInfo_2->EffectBasePoints[i]; + int32 diff = spellEffect_1->EffectBasePoints - spellEffect_2->EffectBasePoints; if (spellInfo_1->CalculateSimpleValue(SpellEffectIndex(i)) < 0 && spellInfo_2->CalculateSimpleValue(SpellEffectIndex(i)) < 0) return -diff; else return diff; @@ -390,18 +414,25 @@ SpellSpecific GetSpellSpecific(uint32 spellId) if (!spellInfo) return SPELL_NORMAL; - switch (spellInfo->SpellFamilyName) + SpellClassOptionsEntry const* classOpt = spellInfo->GetSpellClassOptions(); + SpellInterruptsEntry const* interrupts = spellInfo->GetSpellInterrupts(); + + switch(spellInfo->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { // Food / Drinks (mostly) - if (spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) + if(interrupts && interrupts->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) { bool food = false; bool drink = false; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - switch (spellInfo->EffectApplyAuraName[i]) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + + switch(spellEffect->EffectApplyAuraName) { // Food case SPELL_AURA_MOD_REGEN: @@ -437,17 +468,18 @@ SpellSpecific GetSpellSpecific(uint32 spellId) case SPELLFAMILY_MAGE: { // family flags 18(Molten), 25(Frost/Ice), 28(Mage) - if (spellInfo->SpellFamilyFlags & UI64LIT(0x12040000)) + if (classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x12040000)) return SPELL_MAGE_ARMOR; - if ((spellInfo->SpellFamilyFlags & UI64LIT(0x1000000)) && spellInfo->EffectApplyAuraName[EFFECT_INDEX_0] == SPELL_AURA_MOD_CONFUSE) + SpellEffectEntry const* mageSpellEffect = spellInfo->GetSpellEffect(EFFECT_INDEX_0); + if (classOpt && (classOpt->SpellFamilyFlags & UI64LIT(0x1000000)) && mageSpellEffect && mageSpellEffect->EffectApplyAuraName == SPELL_AURA_MOD_CONFUSE) return SPELL_MAGE_POLYMORPH; break; } case SPELLFAMILY_WARRIOR: { - if (spellInfo->SpellFamilyFlags & UI64LIT(0x00008000010000)) + if (classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x00008000010000)) return SPELL_POSITIVE_SHOUT; break; @@ -455,7 +487,7 @@ SpellSpecific GetSpellSpecific(uint32 spellId) case SPELLFAMILY_WARLOCK: { // only warlock curses have this - if (spellInfo->Dispel == DISPEL_CURSE) + if (spellInfo->GetDispel() == DISPEL_CURSE) return SPELL_CURSE; // Warlock (Demon Armor | Demon Skin | Fel Armor) @@ -467,19 +499,20 @@ SpellSpecific GetSpellSpecific(uint32 spellId) return SPELL_UA_IMMOLATE; break; } + // Need Fix case SPELLFAMILY_PRIEST: { // "Well Fed" buff from Blessed Sunfruit, Blessed Sunfruit Juice, Alterac Spring Water if (spellInfo->HasAttribute(SPELL_ATTR_CASTABLE_WHILE_SITTING) && - (spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK) && - (spellInfo->SpellIconID == 52 || spellInfo->SpellIconID == 79)) + (interrupts && interrupts->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK) && + (spellInfo->SpellIconID == 52 || spellInfo->SpellIconID == 79)) return SPELL_WELL_FED; break; } case SPELLFAMILY_HUNTER: { // only hunter stings have this - if (spellInfo->Dispel == DISPEL_POISON) + if (spellInfo->GetDispel() == DISPEL_POISON) return SPELL_STING; // only hunter aspects have this @@ -521,7 +554,7 @@ SpellSpecific GetSpellSpecific(uint32 spellId) return sSpellMgr.GetSpellElixirSpecific(spellInfo->Id); case SPELLFAMILY_DEATHKNIGHT: - if (spellInfo->Category == 47) + if (spellInfo->GetCategory() == 47) return SPELL_PRESENCE; break; } @@ -674,7 +707,11 @@ bool IsExplicitNegativeTarget(uint32 targetA) bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex) { - switch (spellproto->Effect[effIndex]) + SpellEffectEntry const* spellEffect = spellproto->GetSpellEffect(effIndex); + if(!spellEffect) + return false; + + switch(spellEffect->Effect) { case SPELL_EFFECT_DUMMY: // some explicitly required dummy effect sets @@ -703,7 +740,7 @@ bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex) case SPELL_EFFECT_APPLY_AURA: case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: { - switch (spellproto->EffectApplyAuraName[effIndex]) + switch(spellEffect->EffectApplyAuraName) { case SPELL_AURA_DUMMY: { @@ -740,38 +777,41 @@ bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex) case SPELL_AURA_MOD_DODGE_PERCENT: case SPELL_AURA_MOD_HEALING_PCT: case SPELL_AURA_MOD_HEALING_DONE: - if (spellproto->CalculateSimpleValue(effIndex) < 0) + if (spellEffect->CalculateSimpleValue() < 0) return false; break; case SPELL_AURA_MOD_DAMAGE_TAKEN: // dependent from bas point sign (positive -> negative) - if (spellproto->CalculateSimpleValue(effIndex) < 0) + if (spellEffect->CalculateSimpleValue() < 0) return true; // let check by target modes (for Amplify Magic cases/etc) break; case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: case SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT: case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE: - if (spellproto->CalculateSimpleValue(effIndex) > 0) + if (spellEffect->CalculateSimpleValue() > 0) return true; // some expected positive spells have SPELL_ATTR_EX_NEGATIVE or unclear target modes break; case SPELL_AURA_ADD_TARGET_TRIGGER: return true; case SPELL_AURA_PERIODIC_TRIGGER_SPELL: - if (spellproto->Id != spellproto->EffectTriggerSpell[effIndex]) + if (spellproto->Id != spellEffect->EffectTriggerSpell) { - uint32 spellTriggeredId = spellproto->EffectTriggerSpell[effIndex]; - SpellEntry const* spellTriggeredProto = sSpellStore.LookupEntry(spellTriggeredId); + uint32 spellTriggeredId = spellEffect->EffectTriggerSpell; + SpellEntry const *spellTriggeredProto = sSpellStore.LookupEntry(spellTriggeredId); if (spellTriggeredProto) { // non-positive targets of main spell return early for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { + SpellEffectEntry const* triggerSpellEffect = spellTriggeredProto->GetSpellEffect(SpellEffectIndex(i)); + if (!triggerSpellEffect) + continue; // if non-positive trigger cast targeted to positive target this main cast is non-positive // this will place this spell auras as debuffs - if (spellTriggeredProto->Effect[i] && - IsPositiveTarget(spellTriggeredProto->EffectImplicitTargetA[i], spellTriggeredProto->EffectImplicitTargetB[i]) && - !IsPositiveEffect(spellTriggeredProto, SpellEffectIndex(i))) + if (triggerSpellEffect->Effect && + IsPositiveTarget(triggerSpellEffect->EffectImplicitTargetA,triggerSpellEffect->EffectImplicitTargetB) && + !IsPositiveEffect(spellTriggeredProto, SpellEffectIndex(i))) return false; } } @@ -780,8 +820,8 @@ bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex) case SPELL_AURA_PROC_TRIGGER_SPELL: // many positive auras have negative triggered spells at damage for example and this not make it negative (it can be canceled for example) break; - case SPELL_AURA_MOD_STUN: // have positive and negative spells, we can't sort its correctly at this moment. - if (effIndex == EFFECT_INDEX_0 && spellproto->Effect[EFFECT_INDEX_1] == 0 && spellproto->Effect[EFFECT_INDEX_2] == 0) + case SPELL_AURA_MOD_STUN: //have positive and negative spells, we can't sort its correctly at this moment. + if (effIndex == EFFECT_INDEX_0 && spellproto->GetSpellEffectIdByIndex(EFFECT_INDEX_1) == 0 && spellproto->GetSpellEffectIdByIndex(EFFECT_INDEX_2) == 0) return false; // but all single stun aura spells is negative // Petrification @@ -806,15 +846,15 @@ bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex) return false; case SPELL_AURA_PERIODIC_DAMAGE: // used in positive spells also. // part of negative spell if casted at self (prevent cancel) - if (spellproto->EffectImplicitTargetA[effIndex] == TARGET_SELF || - spellproto->EffectImplicitTargetA[effIndex] == TARGET_SELF2) + if (spellEffect->EffectImplicitTargetA == TARGET_SELF || + spellEffect->EffectImplicitTargetA == TARGET_SELF2) return false; break; case SPELL_AURA_MOD_DECREASE_SPEED: // used in positive spells also // part of positive spell if casted at self - if ((spellproto->EffectImplicitTargetA[effIndex] == TARGET_SELF || - spellproto->EffectImplicitTargetA[effIndex] == TARGET_SELF2) && - spellproto->SpellFamilyName == SPELLFAMILY_GENERIC) + if ((spellEffect->EffectImplicitTargetA == TARGET_SELF || + spellEffect->EffectImplicitTargetA == TARGET_SELF2) && + spellproto->GetSpellFamilyName() == SPELLFAMILY_GENERIC) return false; // but not this if this first effect (don't found better check) if (spellproto->HasAttribute(SPELL_ATTR_UNK26) && effIndex == EFFECT_INDEX_0) @@ -845,7 +885,7 @@ bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex) case SPELL_AURA_MECHANIC_IMMUNITY: { // non-positive immunities - switch (spellproto->EffectMiscValue[effIndex]) + switch(spellEffect->EffectMiscValue) { case MECHANIC_BANDAGE: case MECHANIC_SHIELD: @@ -860,7 +900,7 @@ bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex) case SPELL_AURA_ADD_PCT_MODIFIER: { // non-positive mods - switch (spellproto->EffectMiscValue[effIndex]) + switch(spellEffect->EffectMiscValue) { case SPELLMOD_COST: // dependent from bas point sign (negative -> positive) if (spellproto->CalculateSimpleValue(effIndex) > 0) @@ -892,7 +932,7 @@ bool IsPositiveEffect(SpellEntry const* spellproto, SpellEffectIndex effIndex) } // non-positive targets - if (!IsPositiveTarget(spellproto->EffectImplicitTargetA[effIndex], spellproto->EffectImplicitTargetB[effIndex])) + if(!IsPositiveTarget(spellEffect->EffectImplicitTargetA,spellEffect->EffectImplicitTargetB)) return false; // AttributesEx check @@ -917,7 +957,7 @@ bool IsPositiveSpell(SpellEntry const* spellproto) // spells with at least one negative effect are considered negative // some self-applied spells have negative effects but in self casting case negative check ignored. for (int i = 0; i < MAX_EFFECT_INDEX; ++i) - if (spellproto->Effect[i] && !IsPositiveEffect(spellproto, SpellEffectIndex(i))) + if (spellproto->GetSpellEffectIdByIndex(SpellEffectIndex(i)) && !IsPositiveEffect(spellproto, SpellEffectIndex(i))) return false; return true; } @@ -950,8 +990,8 @@ bool IsSingleTargetSpells(SpellEntry const* spellInfo1, SpellEntry const* spellI { // TODO - need better check // Equal icon and spellfamily - if (spellInfo1->SpellFamilyName == spellInfo2->SpellFamilyName && - spellInfo1->SpellIconID == spellInfo2->SpellIconID) + if( spellInfo1->GetSpellFamilyName() == spellInfo2->GetSpellFamilyName() && + spellInfo1->SpellIconID == spellInfo2->SpellIconID ) return true; // TODO - need found Judgements rule @@ -975,16 +1015,18 @@ SpellCastResult GetErrorAtShapeshiftedCast(SpellEntry const* spellInfo, uint32 f { // talents that learn spells can have stance requirements that need ignore // (this requirement only for client-side stance show in talent description) - if (GetTalentSpellCost(spellInfo->Id) > 0 && - (spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_LEARN_SPELL || spellInfo->Effect[EFFECT_INDEX_1] == SPELL_EFFECT_LEARN_SPELL || spellInfo->Effect[EFFECT_INDEX_2] == SPELL_EFFECT_LEARN_SPELL)) + if( GetTalentSpellCost(spellInfo->Id) > 0 && + (spellInfo->GetSpellEffectIdByIndex(EFFECT_INDEX_0) == SPELL_EFFECT_LEARN_SPELL || spellInfo->GetSpellEffectIdByIndex(EFFECT_INDEX_1) == SPELL_EFFECT_LEARN_SPELL || spellInfo->GetSpellEffectIdByIndex(EFFECT_INDEX_2) == SPELL_EFFECT_LEARN_SPELL) ) return SPELL_CAST_OK; uint32 stanceMask = (form ? 1 << (form - 1) : 0); - if (stanceMask & spellInfo->StancesNot) // can explicitly not be casted in this stance + SpellShapeshiftEntry const* shapeShift = spellInfo->GetSpellShapeshift(); + + if (shapeShift && stanceMask & shapeShift->StancesNot) // can explicitly not be casted in this stance return SPELL_FAILED_NOT_SHAPESHIFT; - if (stanceMask & spellInfo->Stances) // can explicitly be casted in this stance + if (shapeShift && stanceMask & shapeShift->Stances) // can explicitly be casted in this stance return SPELL_CAST_OK; bool actAsShifted = false; @@ -1003,13 +1045,13 @@ SpellCastResult GetErrorAtShapeshiftedCast(SpellEntry const* spellInfo, uint32 f { if (spellInfo->HasAttribute(SPELL_ATTR_NOT_SHAPESHIFT)) // not while shapeshifted return SPELL_FAILED_NOT_SHAPESHIFT; - else if (spellInfo->Stances != 0) // needs other shapeshift + else if (shapeShift && shapeShift->Stances != 0) // needs other shapeshift return SPELL_FAILED_ONLY_SHAPESHIFT; } else { // needs shapeshift - if (!spellInfo->HasAttribute(SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) && spellInfo->Stances != 0) + if(!(spellInfo->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) && shapeShift && shapeShift->Stances != 0) return SPELL_FAILED_ONLY_SHAPESHIFT; } @@ -1076,15 +1118,18 @@ void SpellMgr::LoadSpellTargetPositions() bool found = false; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (spellInfo->EffectImplicitTargetA[i] == TARGET_TABLE_X_Y_Z_COORDINATES || spellInfo->EffectImplicitTargetB[i] == TARGET_TABLE_X_Y_Z_COORDINATES) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + if (spellEffect->EffectImplicitTargetA==TARGET_TABLE_X_Y_Z_COORDINATES || spellEffect->EffectImplicitTargetB==TARGET_TABLE_X_Y_Z_COORDINATES) { // additional requirements - if (spellInfo->Effect[i] == SPELL_EFFECT_BIND && spellInfo->EffectMiscValue[i]) + if (spellEffect->Effect==SPELL_EFFECT_BIND && spellEffect->EffectMiscValue) { uint32 zone_id = sTerrainMgr.GetAreaId(st.target_mapId, st.target_X, st.target_Y, st.target_Z); - if (int32(zone_id) != spellInfo->EffectMiscValue[i]) + if (int32(zone_id) != spellEffect->EffectMiscValue) { - sLog.outErrorDb("Spell (Id: %u) listed in `spell_target_position` expected point to zone %u bit point to zone %u.", Spell_ID, spellInfo->EffectMiscValue[i], zone_id); + sLog.outErrorDb("Spell (Id: %u) listed in `spell_target_position` expected point to zone %u bit point to zone %u.",Spell_ID, spellEffect->EffectMiscValue, zone_id); break; } } @@ -1233,12 +1278,12 @@ struct DoSpellProcEvent if (spe.procFlags == 0) { - if (spell->procFlags == 0) + if (spell->GetProcFlags()==0) sLog.outErrorDb("Spell %u listed in `spell_proc_event` probally not triggered spell (no proc flags)", spell->Id); } else { - if (spell->procFlags == spe.procFlags) + if (spell->GetProcFlags()==spe.procFlags) sLog.outErrorDb("Spell %u listed in `spell_proc_event` has exactly same proc flags as in spell.dbc, field value redundant", spell->Id); else isCustom = true; @@ -1253,7 +1298,7 @@ struct DoSpellProcEvent } else { - if (spell->procChance == spe.customChance) + if (spell->GetProcChance()==spe.customChance) sLog.outErrorDb("Spell %u listed in `spell_proc_event` has exactly same custom chance as in spell.dbc, field value redundant", spell->Id); else isCustom = true; @@ -1424,13 +1469,17 @@ void SpellMgr::LoadSpellProcItemEnchant() bool IsCastEndProcModifierAura(SpellEntry const* spellInfo, SpellEffectIndex effecIdx, SpellEntry const* procSpell) { + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(effecIdx)); + if (!spellEffect) + return false; + // modifier auras that can proc on cast end - switch (AuraType(spellInfo->EffectApplyAuraName[effecIdx])) + switch (AuraType(spellEffect->EffectApplyAuraName)) { case SPELL_AURA_ADD_FLAT_MODIFIER: case SPELL_AURA_ADD_PCT_MODIFIER: { - switch (spellInfo->EffectMiscValue[effecIdx]) + switch (spellEffect->EffectMiscValue) { case SPELLMOD_RANGE: case SPELLMOD_RADIUS: @@ -1516,14 +1565,17 @@ void SpellMgr::LoadSpellBonuses() uint32 x = 0; // count all, including empty, meaning: not all existing effect is DoTs/HoTs for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (!spell->Effect[i]) + SpellEffectEntry const* spellEffect = spell->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + if (!spellEffect->Effect) { ++x; continue; } // DoTs/HoTs - switch (spell->EffectApplyAuraName[i]) + switch(spellEffect->EffectApplyAuraName) { case SPELL_AURA_PERIODIC_DAMAGE: case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: @@ -1551,11 +1603,14 @@ void SpellMgr::LoadSpellBonuses() if (sbe.direct_damage) { bool isHeal = false; - for (int i = 0; i < 3; ++i) + for(int i = 0; i < MAX_EFFECT_INDEX; ++i) { + SpellEffectEntry const* spellEffect = spell->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; // Heals (Also count Mana Shield and Absorb effects as heals) - if (spell->Effect[i] == SPELL_EFFECT_HEAL || spell->Effect[i] == SPELL_EFFECT_HEAL_MAX_HEALTH || - (spell->Effect[i] == SPELL_EFFECT_APPLY_AURA && (spell->EffectApplyAuraName[i] == SPELL_AURA_SCHOOL_ABSORB || spell->EffectApplyAuraName[i] == SPELL_AURA_PERIODIC_HEAL))) + if (spellEffect->Effect == SPELL_EFFECT_HEAL || spellEffect->Effect == SPELL_EFFECT_HEAL_MAX_HEALTH || + (spellEffect->Effect == SPELL_EFFECT_APPLY_AURA && (spellEffect->EffectApplyAuraName == SPELL_AURA_SCHOOL_ABSORB || spellEffect->EffectApplyAuraName == SPELL_AURA_PERIODIC_HEAL)) ) { isHeal = true; break; @@ -1571,10 +1626,13 @@ void SpellMgr::LoadSpellBonuses() if (sbe.dot_damage) { bool isHeal = false; - for (int i = 0; i < 3; ++i) + for(int i = 0; i < MAX_EFFECT_INDEX; ++i) { + SpellEffectEntry const* spellEffect = spell->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; // Periodic Heals - if (spell->Effect[i] == SPELL_EFFECT_APPLY_AURA && spell->EffectApplyAuraName[i] == SPELL_AURA_PERIODIC_HEAL) + if (spellEffect->Effect == SPELL_EFFECT_APPLY_AURA && spellEffect->EffectApplyAuraName == SPELL_AURA_PERIODIC_HEAL) { isHeal = true; break; @@ -1655,8 +1713,10 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & procSpell->SchoolMask) == 0) return false; + SpellClassOptionsEntry const* spellClassOptions = procSpell->GetSpellClassOptions(); + // Check (if set) for spellFamilyName - if (spellProcEvent->spellFamilyName && (spellProcEvent->spellFamilyName != procSpell->SpellFamilyName)) + if (spellProcEvent->spellFamilyName && spellClassOptions && (spellProcEvent->spellFamilyName != spellClassOptions->SpellFamilyName)) return false; } } @@ -1773,9 +1833,11 @@ struct DoSpellThreat // effects have same targets, otherwise, we'd need to seperate it by effect index if (ste.threat || ste.ap_bonus != 0.f) { - const uint32* targetA = spell->EffectImplicitTargetA; - if ((targetA[EFFECT_INDEX_1] && targetA[EFFECT_INDEX_1] != targetA[EFFECT_INDEX_0]) || - (targetA[EFFECT_INDEX_2] && targetA[EFFECT_INDEX_2] != targetA[EFFECT_INDEX_0])) + SpellEffectEntry const* spellEffect0 = spell->GetSpellEffect(EFFECT_INDEX_0); + SpellEffectEntry const* spellEffect1 = spell->GetSpellEffect(EFFECT_INDEX_1); + SpellEffectEntry const* spellEffect2 = spell->GetSpellEffect(EFFECT_INDEX_2); + if ((spellEffect1 && spellEffect1->EffectImplicitTargetA && (!spellEffect0 || spellEffect1->EffectImplicitTargetA != spellEffect0->EffectImplicitTargetA)) || + (spellEffect2 && spellEffect2->EffectImplicitTargetA && (!spellEffect0 || spellEffect2->EffectImplicitTargetA != spellEffect0->EffectImplicitTargetA))) sLog.outErrorDb("Spell %u listed in `spell_threat` has effects with different targets, threat may be assigned incorrectly", spell->Id); } ++count; @@ -1857,26 +1919,32 @@ bool SpellMgr::canStackSpellRanksInSpellBook(SpellEntry const* spellInfo) const // All stance spells. if any better way, change it. for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - switch (spellInfo->SpellFamilyName) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + switch(spellInfo->GetSpellFamilyName()) { case SPELLFAMILY_PALADIN: - // Paladin aura Spell - if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID) - return false; - // Seal of Righteousness, 2 version of same rank - if ((spellInfo->SpellFamilyFlags & UI64LIT(0x0000000008000000)) && spellInfo->SpellIconID == 25) - return false; + { + // Paladin aura Spell + if (spellEffect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID) + return false; + // Seal of Righteousness, 2 version of same rank + SpellClassOptionsEntry const* classOptions = spellInfo->GetSpellClassOptions(); + if (classOptions && (classOptions->SpellFamilyFlags & UI64LIT(0x0000000008000000)) && spellInfo->SpellIconID == 25) + return false; + } break; case SPELLFAMILY_DRUID: // Druid form Spell - if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA && - spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT) + if (spellEffect->Effect == SPELL_EFFECT_APPLY_AURA && + spellEffect->EffectApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT) return false; break; case SPELLFAMILY_ROGUE: // Rogue Stealth - if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA && - spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT) + if (spellEffect->Effect == SPELL_EFFECT_APPLY_AURA && + spellEffect->EffectApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT) return false; break; } @@ -1892,8 +1960,8 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons if (!spellInfo_1 || !spellInfo_2) return false; - if (spellId_1 == spellId_2) - return false; + SpellClassOptionsEntry const* classOptions1 = spellInfo_1->GetSpellClassOptions(); + SpellClassOptionsEntry const* classOptions2 = spellInfo_2->GetSpellClassOptions(); // Resurrection sickness if ((spellInfo_1->Id == SPELL_ID_PASSIVE_RESURRECTION_SICKNESS) != (spellInfo_2->Id == SPELL_ID_PASSIVE_RESURRECTION_SICKNESS)) @@ -1904,10 +1972,10 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return false; // Specific spell family spells - switch (spellInfo_1->SpellFamilyName) + switch(spellInfo_1->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: - switch (spellInfo_2->SpellFamilyName) + switch(spellInfo_2->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: // same family case { @@ -2005,7 +2073,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return false; // Improved Hamstring -> Hamstring (multi-family check) - if ((spellInfo_2->SpellFamilyFlags & UI64LIT(0x2)) && spellInfo_1->Id == 23694) + if (classOptions2 && (classOptions2->SpellFamilyFlags & UI64LIT(0x2)) && spellInfo_1->Id == 23694 ) return false; break; @@ -2037,7 +2105,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return false; // Improved Wing Clip -> Wing Clip (multi-family check) - if ((spellInfo_2->SpellFamilyFlags & UI64LIT(0x40)) && spellInfo_1->Id == 19229) + if (classOptions2 && (classOptions2->SpellFamilyFlags & UI64LIT(0x40)) && spellInfo_1->Id == 19229 ) return false; break; } @@ -2063,16 +2131,16 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return false; break; case SPELLFAMILY_MAGE: - if (spellInfo_2->SpellFamilyName == SPELLFAMILY_MAGE) + if (classOptions2 && classOptions2->SpellFamilyName == SPELLFAMILY_MAGE ) { // Blizzard & Chilled (and some other stacked with blizzard spells - if (((spellInfo_1->SpellFamilyFlags & UI64LIT(0x80)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x100000))) || - ((spellInfo_2->SpellFamilyFlags & UI64LIT(0x80)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x100000)))) + if (classOptions1 && (classOptions1->SpellFamilyFlags & UI64LIT(0x80)) && (classOptions2->SpellFamilyFlags & UI64LIT(0x100000)) || + (classOptions2->SpellFamilyFlags & UI64LIT(0x80)) && (classOptions1->SpellFamilyFlags & UI64LIT(0x100000)) ) return false; // Blink & Improved Blink - if (((spellInfo_1->SpellFamilyFlags & UI64LIT(0x0000000000010000)) && (spellInfo_2->SpellVisual[0] == 72 && spellInfo_2->SpellIconID == 1499)) || - ((spellInfo_2->SpellFamilyFlags & UI64LIT(0x0000000000010000)) && (spellInfo_1->SpellVisual[0] == 72 && spellInfo_1->SpellIconID == 1499))) + if (classOptions1 && (classOptions1->SpellFamilyFlags & UI64LIT(0x0000000000010000)) && (spellInfo_2->SpellVisual[0] == 72 && spellInfo_2->SpellIconID == 1499) || + (classOptions2->SpellFamilyFlags & UI64LIT(0x0000000000010000)) && (spellInfo_1->SpellVisual[0] == 72 && spellInfo_1->SpellIconID == 1499) ) return false; // Fingers of Frost effects @@ -2080,13 +2148,13 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return false; // Living Bomb & Ignite (Dots) - if (((spellInfo_1->SpellFamilyFlags & UI64LIT(0x2000000000000)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x8000000))) || - ((spellInfo_2->SpellFamilyFlags & UI64LIT(0x2000000000000)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x8000000)))) + if (classOptions1 && (classOptions1->SpellFamilyFlags & UI64LIT(0x2000000000000)) && (classOptions2->SpellFamilyFlags & UI64LIT(0x8000000)) || + (classOptions2->SpellFamilyFlags & UI64LIT(0x2000000000000)) && (classOptions1->SpellFamilyFlags & UI64LIT(0x8000000)) ) return false; // Fireball & Pyroblast (Dots) - if (((spellInfo_1->SpellFamilyFlags & UI64LIT(0x1)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x400000))) || - ((spellInfo_2->SpellFamilyFlags & UI64LIT(0x1)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x400000)))) + if (classOptions1 && (classOptions1->SpellFamilyFlags & UI64LIT(0x1)) && (classOptions2->SpellFamilyFlags & UI64LIT(0x400000)) || + (classOptions2->SpellFamilyFlags & UI64LIT(0x1)) && (classOptions1->SpellFamilyFlags & UI64LIT(0x400000)) ) return false; } // Detect Invisibility and Mana Shield (multi-family check) @@ -2103,7 +2171,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons break; case SPELLFAMILY_WARLOCK: - if (spellInfo_2->SpellFamilyName == SPELLFAMILY_WARLOCK) + if( classOptions2 && classOptions2->SpellFamilyName == SPELLFAMILY_WARLOCK ) { // Siphon Life and Drain Life if ((spellInfo_1->SpellIconID == 152 && spellInfo_2->SpellIconID == 546) || @@ -2145,11 +2213,11 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return false; break; case SPELLFAMILY_WARRIOR: - if (spellInfo_2->SpellFamilyName == SPELLFAMILY_WARRIOR) + if (classOptions2 && classOptions1->SpellFamilyName == SPELLFAMILY_WARRIOR ) { // Rend and Deep Wound - if (((spellInfo_1->SpellFamilyFlags & UI64LIT(0x20)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x1000000000))) || - ((spellInfo_2->SpellFamilyFlags & UI64LIT(0x20)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x1000000000)))) + if (classOptions1 && (classOptions1->SpellFamilyFlags & UI64LIT(0x20)) && (classOptions2->SpellFamilyFlags & UI64LIT(0x1000000000)) || + (classOptions2->SpellFamilyFlags & UI64LIT(0x20)) && (classOptions1->SpellFamilyFlags & UI64LIT(0x1000000000)) ) return false; // Battle Shout and Rampage @@ -2163,13 +2231,13 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return false; // Defensive/Berserker/Battle stance aura can not stack (needed for dummy auras) - if (((spellInfo_1->SpellFamilyFlags & UI64LIT(0x800000)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x800000))) || - ((spellInfo_2->SpellFamilyFlags & UI64LIT(0x800000)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x800000)))) + if (((classOptions1->SpellFamilyFlags & UI64LIT(0x800000)) && (classOptions2->SpellFamilyFlags & UI64LIT(0x800000))) || + ((classOptions2->SpellFamilyFlags & UI64LIT(0x800000)) && (classOptions1->SpellFamilyFlags & UI64LIT(0x800000)))) return true; } // Hamstring -> Improved Hamstring (multi-family check) - if ((spellInfo_1->SpellFamilyFlags & UI64LIT(0x2)) && spellInfo_2->Id == 23694) + if (classOptions1 && (classOptions1->SpellFamilyFlags & UI64LIT(0x2)) && spellInfo_2->Id == 23694 ) return false; // Defensive Stance and Scroll of Protection (multi-family check) @@ -2182,16 +2250,16 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons break; case SPELLFAMILY_PRIEST: - if (spellInfo_2->SpellFamilyName == SPELLFAMILY_PRIEST) + if (classOptions2 && classOptions2->SpellFamilyName == SPELLFAMILY_PRIEST ) { - // Devouring Plague and Shadow Vulnerability - if (((spellInfo_1->SpellFamilyFlags & UI64LIT(0x2000000)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x800000000))) || - ((spellInfo_2->SpellFamilyFlags & UI64LIT(0x2000000)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x800000000)))) + //Devouring Plague and Shadow Vulnerability + if (classOptions1 && (classOptions1->SpellFamilyFlags & UI64LIT(0x2000000)) && (classOptions2->SpellFamilyFlags & UI64LIT(0x800000000)) || + (classOptions2->SpellFamilyFlags & UI64LIT(0x2000000)) && (classOptions1->SpellFamilyFlags & UI64LIT(0x800000000))) return false; - // StarShards and Shadow Word: Pain - if (((spellInfo_1->SpellFamilyFlags & UI64LIT(0x200000)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x8000))) || - ((spellInfo_2->SpellFamilyFlags & UI64LIT(0x200000)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x8000)))) + //StarShards and Shadow Word: Pain + if (classOptions1 && (classOptions1->SpellFamilyFlags & UI64LIT(0x200000)) && (classOptions2->SpellFamilyFlags & UI64LIT(0x8000)) || + (classOptions2->SpellFamilyFlags & UI64LIT(0x200000)) && (classOptions1->SpellFamilyFlags & UI64LIT(0x8000))) return false; // Dispersion @@ -2201,11 +2269,11 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons } break; case SPELLFAMILY_DRUID: - if (spellInfo_2->SpellFamilyName == SPELLFAMILY_DRUID) + if (classOptions2 && classOptions2->SpellFamilyName == SPELLFAMILY_DRUID ) { - // Omen of Clarity and Blood Frenzy - if (((spellInfo_1->SpellFamilyFlags == UI64LIT(0x0) && spellInfo_1->SpellIconID == 108) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x20000000000000))) || - ((spellInfo_2->SpellFamilyFlags == UI64LIT(0x0) && spellInfo_2->SpellIconID == 108) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x20000000000000)))) + //Omen of Clarity and Blood Frenzy + if ((classOptions1 && (classOptions1->SpellFamilyFlags == UI64LIT(0x0) && spellInfo_1->SpellIconID == 108) && (classOptions2->SpellFamilyFlags & UI64LIT(0x20000000000000))) || + ((classOptions2->SpellFamilyFlags == UI64LIT(0x0) && spellInfo_2->SpellIconID == 108) && (classOptions1->SpellFamilyFlags & UI64LIT(0x20000000000000)))) return false; // Tree of Life (Shapeshift) and 34123 Tree of Life (Passive) @@ -2262,7 +2330,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons break; case SPELLFAMILY_ROGUE: - if (spellInfo_2->SpellFamilyName == SPELLFAMILY_ROGUE) + if (classOptions2 && classOptions2->SpellFamilyName == SPELLFAMILY_ROGUE ) { // Master of Subtlety if ((spellId_1 == 31665 && spellId_2 == 31666) || @@ -2271,8 +2339,8 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons // Sprint & Sprint (waterwalk) if (spellInfo_1->SpellIconID == 516 && spellInfo_2->SpellIconID == 516 && - ((spellInfo_1->Category == 44 && spellInfo_2->Category == 0) || - (spellInfo_2->Category == 44 && spellInfo_1->Category == 0))) + ((spellInfo_1->GetCategory() == 44 && spellInfo_2->GetCategory() == 0) || + (spellInfo_2->GetCategory() == 44 && spellInfo_1->GetCategory() == 0))) return false; } @@ -2285,16 +2353,16 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return false; break; case SPELLFAMILY_HUNTER: - if (spellInfo_2->SpellFamilyName == SPELLFAMILY_HUNTER) + if (classOptions2 && classOptions2->SpellFamilyName == SPELLFAMILY_HUNTER ) { // Rapid Fire & Quick Shots - if (((spellInfo_1->SpellFamilyFlags & UI64LIT(0x20)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x20000000000))) || - ((spellInfo_2->SpellFamilyFlags & UI64LIT(0x20)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x20000000000)))) + if (classOptions1 && (classOptions1->SpellFamilyFlags & UI64LIT(0x20)) && (classOptions2->SpellFamilyFlags & UI64LIT(0x20000000000)) || + (classOptions2->SpellFamilyFlags & UI64LIT(0x20)) && (classOptions1->SpellFamilyFlags & UI64LIT(0x20000000000)) ) return false; // Serpent Sting & (Immolation/Explosive Trap Effect) - if (((spellInfo_1->SpellFamilyFlags & UI64LIT(0x4)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x00000004000))) || - ((spellInfo_2->SpellFamilyFlags & UI64LIT(0x4)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x00000004000)))) + if (classOptions1 && (classOptions1->SpellFamilyFlags & UI64LIT(0x4)) && (classOptions2->SpellFamilyFlags & UI64LIT(0x00000004000)) || + (classOptions2->SpellFamilyFlags & UI64LIT(0x4)) && (classOptions1->SpellFamilyFlags & UI64LIT(0x00000004000)) ) return false; // Deterrence @@ -2311,7 +2379,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons } // Wing Clip -> Improved Wing Clip (multi-family check) - if ((spellInfo_1->SpellFamilyFlags & UI64LIT(0x40)) && spellInfo_2->Id == 19229) + if (classOptions1 && (classOptions1->SpellFamilyFlags & UI64LIT(0x40)) && spellInfo_2->Id == 19229 ) return false; // Concussive Shot and Imp. Concussive Shot (multi-family check) @@ -2319,7 +2387,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return false; break; case SPELLFAMILY_PALADIN: - if (spellInfo_2->SpellFamilyName == SPELLFAMILY_PALADIN) + if (classOptions2 && classOptions2->SpellFamilyName == SPELLFAMILY_PALADIN ) { // Paladin Seals if (IsSealSpell(spellInfo_1) && IsSealSpell(spellInfo_2)) @@ -2361,7 +2429,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return false; // *Sanctity Aura -> Unstable Currents and other (multi-family check) - if (spellInfo_1->SpellIconID == 502 && spellInfo_2->SpellFamilyName == SPELLFAMILY_GENERIC && spellInfo_2->SpellIconID == 502 && spellInfo_2->SpellVisual[0] == 969) + if (spellInfo_1->SpellIconID==502 && classOptions2->SpellFamilyName == SPELLFAMILY_GENERIC && spellInfo_2->SpellIconID==502 && spellInfo_2->SpellVisual[0]==969 ) return false; // *Seal of Command and Band of Eternal Champion (multi-family check) @@ -2369,11 +2437,11 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return false; break; case SPELLFAMILY_SHAMAN: - if (spellInfo_2->SpellFamilyName == SPELLFAMILY_SHAMAN) + if (classOptions2 && classOptions2->SpellFamilyName == SPELLFAMILY_SHAMAN ) { // Windfury weapon - if (spellInfo_1->SpellIconID == 220 && spellInfo_2->SpellIconID == 220 && - !spellInfo_1->IsFitToFamilyMask(spellInfo_2->SpellFamilyFlags)) + if (spellInfo_1->SpellIconID==220 && spellInfo_2->SpellIconID==220 && + !classOptions1->IsFitToFamilyMask(classOptions2->SpellFamilyFlags)) return false; // Ghost Wolf @@ -2389,7 +2457,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return false; break; case SPELLFAMILY_DEATHKNIGHT: - if (spellInfo_2->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT) + if (classOptions2 && classOptions2->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT) { // Lichborne and Lichborne (triggered) if (spellInfo_1->SpellIconID == 61 && spellInfo_2->SpellIconID == 61) @@ -2419,10 +2487,14 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons bool isModifier = false; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (spellInfo_1->EffectApplyAuraName[i] == SPELL_AURA_ADD_FLAT_MODIFIER || - spellInfo_1->EffectApplyAuraName[i] == SPELL_AURA_ADD_PCT_MODIFIER || - spellInfo_2->EffectApplyAuraName[i] == SPELL_AURA_ADD_FLAT_MODIFIER || - spellInfo_2->EffectApplyAuraName[i] == SPELL_AURA_ADD_PCT_MODIFIER) + SpellEffectEntry const* spellEffect1 = spellInfo_1->GetSpellEffect(SpellEffectIndex(i)); + SpellEffectEntry const* spellEffect2 = spellInfo_2->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect1 || !spellEffect2) + continue; + if (spellEffect1->EffectApplyAuraName == SPELL_AURA_ADD_FLAT_MODIFIER || + spellEffect1->EffectApplyAuraName == SPELL_AURA_ADD_PCT_MODIFIER || + spellEffect2->EffectApplyAuraName == SPELL_AURA_ADD_FLAT_MODIFIER || + spellEffect2->EffectApplyAuraName == SPELL_AURA_ADD_PCT_MODIFIER ) isModifier = true; } @@ -2433,23 +2505,27 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons if (IsRankSpellDueToSpell(spellInfo_1, spellId_2)) return true; - if (spellInfo_1->SpellFamilyName == 0 || spellInfo_2->SpellFamilyName == 0) + if ((classOptions1 && classOptions1->SpellFamilyName == 0) || (classOptions2 && classOptions2->SpellFamilyName == 0)) return false; - if (spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName) + if (classOptions1 && classOptions2 && classOptions1->SpellFamilyName != classOptions2->SpellFamilyName) return false; bool dummy_only = true; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (spellInfo_1->Effect[i] != spellInfo_2->Effect[i] || - spellInfo_1->EffectItemType[i] != spellInfo_2->EffectItemType[i] || - spellInfo_1->EffectMiscValue[i] != spellInfo_2->EffectMiscValue[i] || - spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i]) + SpellEffectEntry const* spellEffect1 = spellInfo_1->GetSpellEffect(SpellEffectIndex(i)); + SpellEffectEntry const* spellEffect2 = spellInfo_2->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect1 || !spellEffect2) + continue; + if (spellEffect1->Effect != spellEffect2->Effect || + spellEffect1->EffectItemType != spellEffect2->EffectItemType || + spellEffect1->EffectMiscValue != spellEffect2->EffectMiscValue || + spellEffect1->EffectApplyAuraName != spellEffect2->EffectApplyAuraName) return false; // ignore dummy only spells - if (spellInfo_1->Effect[i] && spellInfo_1->Effect[i] != SPELL_EFFECT_DUMMY && spellInfo_1->EffectApplyAuraName[i] != SPELL_AURA_DUMMY) + if(spellEffect1->Effect && spellEffect1->Effect != SPELL_EFFECT_DUMMY && spellEffect1->EffectApplyAuraName != SPELL_AURA_DUMMY) dummy_only = false; } if (dummy_only) @@ -2464,10 +2540,10 @@ bool SpellMgr::IsProfessionOrRidingSpell(uint32 spellId) if (!spellInfo) return false; - if (spellInfo->Effect[EFFECT_INDEX_1] != SPELL_EFFECT_SKILL) + if (spellInfo->GetSpellEffectIdByIndex(EFFECT_INDEX_1) != SPELL_EFFECT_SKILL) return false; - uint32 skill = spellInfo->EffectMiscValue[EFFECT_INDEX_1]; + uint32 skill = spellInfo->GetEffectMiscValue(EFFECT_INDEX_1); return IsProfessionOrRidingSkill(skill); } @@ -2478,10 +2554,10 @@ bool SpellMgr::IsProfessionSpell(uint32 spellId) if (!spellInfo) return false; - if (spellInfo->Effect[EFFECT_INDEX_1] != SPELL_EFFECT_SKILL) + if (spellInfo->GetSpellEffectIdByIndex(EFFECT_INDEX_1) != SPELL_EFFECT_SKILL) return false; - uint32 skill = spellInfo->EffectMiscValue[EFFECT_INDEX_1]; + uint32 skill = spellInfo->GetEffectMiscValue(EFFECT_INDEX_1); return IsProfessionSkill(skill); } @@ -2492,10 +2568,10 @@ bool SpellMgr::IsPrimaryProfessionSpell(uint32 spellId) if (!spellInfo) return false; - if (spellInfo->Effect[EFFECT_INDEX_1] != SPELL_EFFECT_SKILL) + if (spellInfo->GetSpellEffectIdByIndex(EFFECT_INDEX_1) != SPELL_EFFECT_SKILL) return false; - uint32 skill = spellInfo->EffectMiscValue[EFFECT_INDEX_1]; + uint32 skill = spellInfo->GetEffectMiscValue(EFFECT_INDEX_1); return IsPrimaryProfessionSkill(skill); } @@ -2562,7 +2638,7 @@ bool SpellMgr::IsSkillBonusSpell(uint32 spellId) const SpellEntry const* SpellMgr::SelectAuraRankForLevel(SpellEntry const* spellInfo, uint32 level) const { // fast case - if (level + 10 >= spellInfo->spellLevel) + if (level + 10 >= spellInfo->GetSpellLevel()) return spellInfo; // ignore selection for passive spells @@ -2572,13 +2648,16 @@ SpellEntry const* SpellMgr::SelectAuraRankForLevel(SpellEntry const* spellInfo, bool needRankSelection = false; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; // for simple aura in check apply to any non caster based targets, in rank search mode to any explicit targets - if (((spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA && - (IsExplicitPositiveTarget(spellInfo->EffectImplicitTargetA[i]) || - IsAreaEffectPossitiveTarget(Targets(spellInfo->EffectImplicitTargetA[i])))) || - spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY || - spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID) && - IsPositiveEffect(spellInfo, SpellEffectIndex(i))) + if (((spellEffect->Effect == SPELL_EFFECT_APPLY_AURA && + (IsExplicitPositiveTarget(spellEffect->EffectImplicitTargetA) || + IsAreaEffectPossitiveTarget(Targets(spellEffect->EffectImplicitTargetA)))) || + spellEffect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY || + spellEffect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID) && + IsPositiveEffect(spellInfo, SpellEffectIndex(i))) { needRankSelection = true; break; @@ -2596,7 +2675,7 @@ SpellEntry const* SpellMgr::SelectAuraRankForLevel(SpellEntry const* spellInfo, break; // if found appropriate level - if (level + 10 >= spellInfo->spellLevel) + if (level + 10 >= spellInfo->GetSpellLevel()) return nextSpellInfo; // one rank less then @@ -3060,10 +3139,13 @@ void SpellMgr::LoadSpellLearnSkills() for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (entry->Effect[i] == SPELL_EFFECT_SKILL) + SpellEffectEntry const* spellEffect = entry->GetSpellEffect(SpellEffectIndex(i)); + if (!spellEffect) + continue; + if (spellEffect->Effect == SPELL_EFFECT_SKILL) { SpellLearnSkillNode dbc_node; - dbc_node.skill = entry->EffectMiscValue[i]; + dbc_node.skill = spellEffect->EffectMiscValue; dbc_node.step = entry->CalculateSimpleValue(SpellEffectIndex(i)); if (dbc_node.skill != SKILL_RIDING) dbc_node.value = 1; @@ -3151,10 +3233,13 @@ void SpellMgr::LoadSpellLearnSpells() for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (entry->Effect[i] == SPELL_EFFECT_LEARN_SPELL) + SpellEffectEntry const* spellEffect = entry->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + if(spellEffect->Effect == SPELL_EFFECT_LEARN_SPELL) { SpellLearnSpellNode dbc_node; - dbc_node.spell = entry->EffectTriggerSpell[i]; + dbc_node.spell = spellEffect->EffectTriggerSpell; dbc_node.active = true; // all dbc based learned spells is active (show in spell book or hide by client itself) // ignore learning nonexistent spells (broken/outdated/or generic learning spell 483 @@ -3164,7 +3249,7 @@ void SpellMgr::LoadSpellLearnSpells() // talent or passive spells or skill-step spells auto-casted and not need dependent learning, // pet teaching spells don't must be dependent learning (casted) // other required explicit dependent learning - dbc_node.autoLearned = entry->EffectImplicitTargetA[i] == TARGET_PET || GetTalentSpellCost(spell) > 0 || IsPassiveSpell(entry) || IsSpellHaveEffect(entry, SPELL_EFFECT_SKILL_STEP); + dbc_node.autoLearned = spellEffect->EffectImplicitTargetA==TARGET_PET || GetTalentSpellCost(spell) > 0 || IsPassiveSpell(entry) || IsSpellHaveEffect(entry,SPELL_EFFECT_SKILL_STEP); SpellLearnSpellMapBounds db_node_bounds = GetSpellLearnSpellMapBounds(spell); @@ -3234,18 +3319,22 @@ void SpellMgr::LoadSpellScriptTarget() bool targetfound = false; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (spellProto->EffectImplicitTargetA[i] == TARGET_SCRIPT || - spellProto->EffectImplicitTargetB[i] == TARGET_SCRIPT || - spellProto->EffectImplicitTargetA[i] == TARGET_SCRIPT_COORDINATES || - spellProto->EffectImplicitTargetB[i] == TARGET_SCRIPT_COORDINATES || - spellProto->EffectImplicitTargetA[i] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT || - spellProto->EffectImplicitTargetB[i] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT || - spellProto->EffectImplicitTargetA[i] == TARGET_AREAEFFECT_INSTANT || - spellProto->EffectImplicitTargetB[i] == TARGET_AREAEFFECT_INSTANT || - spellProto->EffectImplicitTargetA[i] == TARGET_AREAEFFECT_CUSTOM || - spellProto->EffectImplicitTargetB[i] == TARGET_AREAEFFECT_CUSTOM || - spellProto->EffectImplicitTargetA[i] == TARGET_AREAEFFECT_GO_AROUND_DEST || - spellProto->EffectImplicitTargetB[i] == TARGET_AREAEFFECT_GO_AROUND_DEST) + SpellEffectEntry const* spellEffect = spellProto->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + + if( spellEffect->EffectImplicitTargetA == TARGET_SCRIPT || + spellEffect->EffectImplicitTargetB == TARGET_SCRIPT || + spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES || + spellEffect->EffectImplicitTargetB == TARGET_SCRIPT_COORDINATES || + spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT || + spellEffect->EffectImplicitTargetB == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT || + spellEffect->EffectImplicitTargetA == TARGET_AREAEFFECT_INSTANT || + spellEffect->EffectImplicitTargetB == TARGET_AREAEFFECT_INSTANT || + spellEffect->EffectImplicitTargetA == TARGET_AREAEFFECT_CUSTOM || + spellEffect->EffectImplicitTargetB == TARGET_AREAEFFECT_CUSTOM || + spellEffect->EffectImplicitTargetA == TARGET_AREAEFFECT_GO_AROUND_DEST || + spellEffect->EffectImplicitTargetB == TARGET_AREAEFFECT_GO_AROUND_DEST) { targetfound = true; break; @@ -3390,9 +3479,10 @@ void SpellMgr::LoadSpellPetAuras() continue; } - if (spellInfo->Effect[eff] != SPELL_EFFECT_DUMMY && - (spellInfo->Effect[eff] != SPELL_EFFECT_APPLY_AURA || - spellInfo->EffectApplyAuraName[eff] != SPELL_AURA_DUMMY)) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(eff); + if (!spellEffect || spellEffect->Effect != SPELL_EFFECT_DUMMY && + (spellEffect->Effect != SPELL_EFFECT_APPLY_AURA || + spellEffect->EffectApplyAuraName != SPELL_AURA_DUMMY)) { sLog.outError("Spell %u listed in `spell_pet_auras` does not have dummy aura or dummy effect", spell); continue; @@ -3405,8 +3495,8 @@ void SpellMgr::LoadSpellPetAuras() continue; } - PetAura pa(pet, aura, spellInfo->EffectImplicitTargetA[eff] == TARGET_PET, spellInfo->CalculateSimpleValue(eff)); - mSpellPetAuraMap[(spell << 8) + eff] = pa; + PetAura pa(pet, aura, spellEffect->EffectImplicitTargetA == TARGET_PET, spellEffect->CalculateSimpleValue()); + mSpellPetAuraMap[(spell<<8) + eff] = pa; } ++count; @@ -3451,9 +3541,9 @@ void SpellMgr::LoadPetLevelupSpellMap() if (spellSet.empty()) ++family_count; - spellSet.insert(PetLevelupSpellSet::value_type(spell->spellLevel, spell->Id)); - ++count; - } + spellSet.insert(PetLevelupSpellSet::value_type(spell->GetSpellLevel(),spell->Id)); + count++; + } } sLog.outString(); @@ -3552,9 +3642,13 @@ void SpellMgr::LoadPetDefaultSpells() for (int k = 0; k < MAX_EFFECT_INDEX; ++k) { - if (spellEntry->Effect[k] == SPELL_EFFECT_SUMMON || spellEntry->Effect[k] == SPELL_EFFECT_SUMMON_PET) + SpellEffectEntry const* spellEffect = spellEntry->GetSpellEffect(SpellEffectIndex(k)); + if(!spellEffect) + continue; + + if(spellEffect->Effect==SPELL_EFFECT_SUMMON || spellEffect->Effect==SPELL_EFFECT_SUMMON_PET) { - uint32 creature_id = spellEntry->EffectMiscValue[k]; + uint32 creature_id = spellEffect->EffectMiscValue; CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(creature_id); if (!cInfo) continue; @@ -3597,7 +3691,11 @@ bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg) // check effects for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - switch (spellInfo->Effect[i]) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + + switch(spellEffect->Effect) { case SPELL_EFFECT_NONE: continue; @@ -3606,7 +3704,7 @@ bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg) case SPELL_EFFECT_CREATE_ITEM: case SPELL_EFFECT_CREATE_ITEM_2: { - if (spellInfo->EffectItemType[i] == 0) + if (spellEffect->EffectItemType == 0) { // skip auto-loot crafting spells, its not need explicit item info (but have special fake items sometime) if (!IsLootCraftingSpell(spellInfo)) @@ -3623,14 +3721,14 @@ bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg) } // also possible IsLootCraftingSpell case but fake item must exist anyway - else if (!ObjectMgr::GetItemPrototype(spellInfo->EffectItemType[i])) + else if (!ObjectMgr::GetItemPrototype( spellEffect->EffectItemType )) { if (msg) { - if (pl) - ChatHandler(pl).PSendSysMessage("Craft spell %u create item (Entry: %u) but item does not exist in item_template.", spellInfo->Id, spellInfo->EffectItemType[i]); + if(pl) + ChatHandler(pl).PSendSysMessage("Craft spell %u create item (Entry: %u) but item does not exist in item_template.",spellInfo->Id,spellEffect->EffectItemType); else - sLog.outErrorDb("Craft spell %u create item (Entry: %u) but item does not exist in item_template.", spellInfo->Id, spellInfo->EffectItemType[i]); + sLog.outErrorDb("Craft spell %u create item (Entry: %u) but item does not exist in item_template.",spellInfo->Id,spellEffect->EffectItemType); } return false; } @@ -3640,15 +3738,15 @@ bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg) } case SPELL_EFFECT_LEARN_SPELL: { - SpellEntry const* spellInfo2 = sSpellStore.LookupEntry(spellInfo->EffectTriggerSpell[i]); - if (!IsSpellValid(spellInfo2, pl, msg)) + SpellEntry const* spellInfo2 = sSpellStore.LookupEntry(spellEffect->EffectTriggerSpell); + if( !IsSpellValid(spellInfo2,pl,msg) ) { if (msg) { - if (pl) - ChatHandler(pl).PSendSysMessage("Spell %u learn to broken spell %u, and then...", spellInfo->Id, spellInfo->EffectTriggerSpell[i]); + if(pl) + ChatHandler(pl).PSendSysMessage("Spell %u learn to broken spell %u, and then...",spellInfo->Id,spellEffect->EffectTriggerSpell); else - sLog.outErrorDb("Spell %u learn to invalid spell %u, and then...", spellInfo->Id, spellInfo->EffectTriggerSpell[i]); + sLog.outErrorDb("Spell %u learn to invalid spell %u, and then...",spellInfo->Id,spellEffect->EffectTriggerSpell); } return false; } @@ -3659,18 +3757,22 @@ bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg) if (need_check_reagents) { - for (int j = 0; j < MAX_SPELL_REAGENTS; ++j) + SpellReagentsEntry const* spellReagents = spellInfo->GetSpellReagents(); + if(spellReagents) { - if (spellInfo->Reagent[j] > 0 && !ObjectMgr::GetItemPrototype(spellInfo->Reagent[j])) + for(int j = 0; j < MAX_SPELL_REAGENTS; ++j) { - if (msg) + if(spellReagents->Reagent[j] > 0 && !ObjectMgr::GetItemPrototype( spellReagents->Reagent[j] )) { - if (pl) - ChatHandler(pl).PSendSysMessage("Craft spell %u requires reagent item (Entry: %u) but item does not exist in item_template.", spellInfo->Id, spellInfo->Reagent[j]); - else - sLog.outErrorDb("Craft spell %u requires reagent item (Entry: %u) but item does not exist in item_template.", spellInfo->Id, spellInfo->Reagent[j]); + if(msg) + { + if(pl) + ChatHandler(pl).PSendSysMessage("Craft spell %u requires reagent item (Entry: %u) but item does not exist in item_template.",spellInfo->Id,spellReagents->Reagent[j]); + else + sLog.outErrorDb("Craft spell %u requires reagent item (Entry: %u) but item does not exist in item_template.",spellInfo->Id,spellReagents->Reagent[j]); + } + return false; } - return false; } } } @@ -3795,7 +3897,11 @@ void SpellMgr::LoadSpellAreas() continue; } - switch (spellInfo->EffectApplyAuraName[EFFECT_INDEX_0]) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(EFFECT_INDEX_0); + if (!spellEffect) + continue; + + switch (spellEffect->EffectApplyAuraName) { case SPELL_AURA_DUMMY: case SPELL_AURA_PHASE: @@ -3898,7 +4004,7 @@ void SpellMgr::LoadSpellAreas() SpellCastResult SpellMgr::GetSpellAllowedInLocationError(SpellEntry const* spellInfo, uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player) { // normal case - int32 areaGroupId = spellInfo->AreaGroupId; + int32 areaGroupId = spellInfo->GetAreaGroupId(); if (areaGroupId > 0) { bool found = false; @@ -4184,9 +4290,11 @@ void SpellMgr::CheckUsedSpells(char const* table) continue; } - if (family >= 0 && spellEntry->SpellFamilyName != uint32(family)) + SpellClassOptionsEntry const* classOptions = spellEntry->GetSpellClassOptions(); + + if(family >= 0 && classOptions && classOptions->SpellFamilyName != uint32(family)) { - sLog.outError("Spell %u '%s' family(%u) <> %u but used in %s.", spell, name.c_str(), spellEntry->SpellFamilyName, family, code.c_str()); + sLog.outError("Spell %u '%s' family(%u) <> %u but used in %s.",spell,name.c_str(),classOptions->SpellFamilyName,family,code.c_str()); continue; } @@ -4194,13 +4302,12 @@ void SpellMgr::CheckUsedSpells(char const* table) { if (familyMaskA == UI64LIT(0x0000000000000000) && familyMaskB == 0x00000000) { - if (spellEntry->SpellFamilyFlags) + if (classOptions && classOptions->SpellFamilyFlags) { sLog.outError("Spell %u '%s' not fit to (" I64FMT "," I32FMT ") but used in %s.", spell, name.c_str(), familyMaskA, familyMaskB, code.c_str()); continue; } - } else { @@ -4209,7 +4316,6 @@ void SpellMgr::CheckUsedSpells(char const* table) sLog.outError("Spell %u '%s' not fit to (" I64FMT "," I32FMT ") but used in %s.", spell, name.c_str(), familyMaskA, familyMaskB, code.c_str()); continue; } - } } @@ -4225,26 +4331,27 @@ void SpellMgr::CheckUsedSpells(char const* table) continue; } - if (category >= 0 && spellEntry->Category != uint32(category)) + if(category >= 0 && spellEntry->GetCategory() != uint32(category)) { - sLog.outError("Spell %u '%s' category(%u) <> %u but used in %s.", spell, name.c_str(), spellEntry->Category, category, code.c_str()); + sLog.outError("Spell %u '%s' category(%u) <> %u but used in %s.",spell,name.c_str(),spellEntry->GetCategory(),category,code.c_str()); continue; } if (effectIdx >= EFFECT_INDEX_0) { - if (effectType >= 0 && spellEntry->Effect[effectIdx] != uint32(effectType)) + SpellEffectEntry const* spellEffect = spellEntry->GetSpellEffect(SpellEffectIndex(effectIdx)); + + if(effectType >= 0 && spellEffect && spellEffect->Effect != uint32(effectType)) { sLog.outError("Spell %u '%s' effect%d <> %u but used in %s.", spell, name.c_str(), effectIdx + 1, effectType, code.c_str()); continue; } - if (auraType >= 0 && spellEntry->EffectApplyAuraName[effectIdx] != uint32(auraType)) + if(auraType >= 0 && spellEffect && spellEffect->EffectApplyAuraName != uint32(auraType)) { sLog.outError("Spell %u '%s' aura%d <> %u but used in %s.", spell, name.c_str(), effectIdx + 1, auraType, code.c_str()); continue; } - } else { @@ -4272,14 +4379,16 @@ void SpellMgr::CheckUsedSpells(char const* table) if (!spellEntry) continue; - if (family >= 0 && spellEntry->SpellFamilyName != uint32(family)) + SpellClassOptionsEntry const* classOptions = spellEntry->GetSpellClassOptions(); + + if(family >=0 && classOptions && classOptions->SpellFamilyName != uint32(family)) continue; if (familyMaskA != UI64LIT(0xFFFFFFFFFFFFFFFF) || familyMaskB != 0xFFFFFFFF) { if (familyMaskA == UI64LIT(0x0000000000000000) && familyMaskB == 0x00000000) { - if (spellEntry->SpellFamilyFlags) + if (classOptions && classOptions->SpellFamilyFlags) continue; } else @@ -4295,15 +4404,17 @@ void SpellMgr::CheckUsedSpells(char const* table) if (spellVisual >= 0 && spellEntry->SpellVisual[0] != uint32(spellVisual)) continue; - if (category >= 0 && spellEntry->Category != uint32(category)) + if(category >= 0 && spellEntry->GetCategory() != uint32(category)) continue; if (effectIdx >= 0) { - if (effectType >= 0 && spellEntry->Effect[effectIdx] != uint32(effectType)) + SpellEffectEntry const* spellEffect = spellEntry->GetSpellEffect(SpellEffectIndex(effectIdx)); + + if(effectType >=0 && spellEffect && spellEffect->Effect != uint32(effectType)) continue; - if (auraType >= 0 && spellEntry->EffectApplyAuraName[effectIdx] != uint32(auraType)) + if(auraType >=0 && spellEffect && spellEffect->EffectApplyAuraName != uint32(auraType)) continue; } else @@ -4343,11 +4454,13 @@ void SpellMgr::CheckUsedSpells(char const* table) DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto, bool triggered) { // Explicit Diminishing Groups - switch (spellproto->SpellFamilyName) + SpellClassOptionsEntry const* classOptions = spellproto->GetSpellClassOptions(); + + switch(spellproto->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: // some generic arena related spells have by some strange reason MECHANIC_TURN - if (spellproto->Mechanic == MECHANIC_TURN) + if (spellproto->GetMechanic() == MECHANIC_TURN) return DIMINISHING_NONE; break; case SPELLFAMILY_MAGE: @@ -4358,10 +4471,10 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto case SPELLFAMILY_ROGUE: { // Blind - if (spellproto->IsFitToFamilyMask(UI64LIT(0x00001000000))) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x00001000000)) return DIMINISHING_FEAR_CHARM_BLIND; // Cheap Shot - else if (spellproto->IsFitToFamilyMask(UI64LIT(0x00000000400))) + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x00000000400)) return DIMINISHING_CHEAPSHOT_POUNCE; // Crippling poison - Limit to 10 seconds in PvP (No SpellFamilyFlags) else if (spellproto->SpellIconID == 163) @@ -4386,6 +4499,7 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto { // Judgement of Justice - Limit to 10 seconds in PvP if (spellproto->IsFitToFamilyMask(UI64LIT(0x00000100000))) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x00080000000)) return DIMINISHING_LIMITONLY; break; } @@ -4459,27 +4573,29 @@ int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellEntry cons if (!IsDiminishingReturnsGroupDurationLimited(group)) return 0; + SpellClassOptionsEntry const* classOptions = spellproto->GetSpellClassOptions(); + // Explicit diminishing duration - switch (spellproto->SpellFamilyName) + switch(spellproto->GetSpellFamilyName()) { case SPELLFAMILY_HUNTER: { // Wyvern Sting - if (spellproto->SpellFamilyFlags & UI64LIT(0x0000100000000000)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000100000000000)) return 6000; break; } case SPELLFAMILY_PALADIN: { // Repentance - limit to 6 seconds in PvP - if (spellproto->SpellFamilyFlags & UI64LIT(0x00000000004)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x00000000004)) return 6000; break; } case SPELLFAMILY_DRUID: { // Faerie Fire - limit to 40 seconds in PvP (3.1) - if (spellproto->SpellFamilyFlags & UI64LIT(0x00000000400)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x00000000400)) return 40000; break; } diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 05f07c294..6f70ebd26 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -92,35 +92,48 @@ inline float GetSpellMaxRange(SpellRangeEntry const* range, bool friendly = fals return 0; return (friendly ? range->maxRangeFriendly : range->maxRange); } -inline uint32 GetSpellRecoveryTime(SpellEntry const* spellInfo) { return spellInfo->RecoveryTime > spellInfo->CategoryRecoveryTime ? spellInfo->RecoveryTime : spellInfo->CategoryRecoveryTime; } -int32 GetSpellDuration(SpellEntry const* spellInfo); -int32 GetSpellMaxDuration(SpellEntry const* spellInfo); -int32 CalculateSpellDuration(SpellEntry const* spellInfo, Unit const* caster = NULL); +inline uint32 GetSpellRecoveryTime(SpellEntry const *spellInfo) +{ + if(SpellCooldownsEntry const* cooldowns = spellInfo->GetSpellCooldowns()) + return cooldowns->RecoveryTime > cooldowns->CategoryRecoveryTime ? cooldowns->RecoveryTime : cooldowns->CategoryRecoveryTime; + return 0; +} +int32 GetSpellDuration(SpellEntry const *spellInfo); +int32 GetSpellMaxDuration(SpellEntry const *spellInfo); +int32 CalculateSpellDuration(SpellEntry const *spellInfo, Unit const* caster = NULL); uint16 GetSpellAuraMaxTicks(SpellEntry const* spellInfo); uint16 GetSpellAuraMaxTicks(uint32 spellId); WeaponAttackType GetWeaponAttackType(SpellEntry const* spellInfo); inline bool IsSpellHaveEffect(SpellEntry const* spellInfo, SpellEffects effect) { - for (int i = 0; i < MAX_EFFECT_INDEX; ++i) - if (SpellEffects(spellInfo->Effect[i]) == effect) - return true; + for(int i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if(SpellEffectEntry const* effectEntry = spellInfo->GetSpellEffect(SpellEffectIndex(i))) + if(SpellEffects(effectEntry->Effect) == effect) + return true; + } return false; } inline bool IsAuraApplyEffect(SpellEntry const* spellInfo, SpellEffectIndex effecIdx) { - switch (spellInfo->Effect[effecIdx]) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(effecIdx)); + if (!spellEffect) + return false; + + switch (spellEffect->Effect) { - case SPELL_EFFECT_APPLY_AURA: - case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: - case SPELL_EFFECT_APPLY_AREA_AURA_RAID: - case SPELL_EFFECT_APPLY_AREA_AURA_PET: - case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: - case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY: - case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: - return true; + case SPELL_EFFECT_APPLY_AURA: + case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: + case SPELL_EFFECT_APPLY_AREA_AURA_RAID: + case SPELL_EFFECT_APPLY_AREA_AURA_PET: + case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: + case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY: + case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: + return true; } + return false; } @@ -136,7 +149,10 @@ inline bool IsSpellAppliesAura(SpellEntry const* spellInfo, uint32 effectMask = inline bool IsEffectHandledOnDelayedSpellLaunch(SpellEntry const* spellInfo, SpellEffectIndex effecIdx) { - switch (spellInfo->Effect[effecIdx]) + SpellEffectEntry const* effectEntry = spellInfo->GetSpellEffect(effecIdx); + if(!effectEntry) + return false; + switch (effectEntry->Effect) { case SPELL_EFFECT_SCHOOL_DAMAGE: case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: @@ -151,7 +167,11 @@ inline bool IsEffectHandledOnDelayedSpellLaunch(SpellEntry const* spellInfo, Spe inline bool IsPeriodicRegenerateEffect(SpellEntry const* spellInfo, SpellEffectIndex effecIdx) { - switch (AuraType(spellInfo->EffectApplyAuraName[effecIdx])) + SpellEffectEntry const* effectEntry = spellInfo->GetSpellEffect(effecIdx); + if(!effectEntry) + return false; + + switch (AuraType(effectEntry->EffectApplyAuraName)) { case SPELL_AURA_PERIODIC_ENERGIZE: case SPELL_AURA_PERIODIC_HEAL: @@ -166,17 +186,25 @@ bool IsCastEndProcModifierAura(SpellEntry const* spellInfo, SpellEffectIndex eff inline bool IsSpellHaveAura(SpellEntry const* spellInfo, AuraType aura) { - for (int i = 0; i < MAX_EFFECT_INDEX; ++i) - if (AuraType(spellInfo->EffectApplyAuraName[i]) == aura) - return true; + for(int i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if(SpellEffectEntry const* effectEntry = spellInfo->GetSpellEffect(SpellEffectIndex(i))) + if(AuraType(effectEntry->EffectApplyAuraName)==aura) + return true; + } + return false; } inline bool IsSpellLastAuraEffect(SpellEntry const* spellInfo, SpellEffectIndex effecIdx) { - for (int i = effecIdx + 1; i < MAX_EFFECT_INDEX; ++i) - if (spellInfo->EffectApplyAuraName[i]) - return false; + for(int i = effecIdx+1; i < MAX_EFFECT_INDEX; ++i) + { + if(SpellEffectEntry const* effectEntry = spellInfo->GetSpellEffect(SpellEffectIndex(i))) + if(effectEntry->EffectApplyAuraName) + return false; + } + return true; } @@ -184,32 +212,38 @@ bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 spellId_2); inline bool IsSealSpell(SpellEntry const* spellInfo) { - // Collection of all the seal family flags. No other paladin spell has any of those. + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(EFFECT_INDEX_0); + //Collection of all the seal family flags. No other paladin spell has any of those. return spellInfo->IsFitToFamily(SPELLFAMILY_PALADIN, UI64LIT(0x26000C000A000000)) && - // avoid counting target triggered effect as seal for avoid remove it or seal by it. - spellInfo->EffectImplicitTargetA[EFFECT_INDEX_0] == TARGET_SELF; + // avoid counting target triggered effect as seal for avoid remove it or seal by it. + spellEffect && spellEffect->EffectImplicitTargetA == TARGET_SELF; } inline bool IsElementalShield(SpellEntry const* spellInfo) { + SpellClassOptionsEntry const* classOptions = spellInfo->GetSpellClassOptions(); // family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus - return (spellInfo->SpellFamilyFlags & UI64LIT(0x42000000400)) || spellInfo->Id == 23552; + return (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x42000000400)) || spellInfo->Id == 23552; } inline bool IsExplicitDiscoverySpell(SpellEntry const* spellInfo) { - return (((spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_CREATE_RANDOM_ITEM - || spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_CREATE_ITEM_2) - && spellInfo->Effect[EFFECT_INDEX_1] == SPELL_EFFECT_SCRIPT_EFFECT) - || spellInfo->Id == 64323); // Book of Glyph Mastery (Effect0==SPELL_EFFECT_SCRIPT_EFFECT without any other data) + SpellEffectEntry const* spellEffect0 = spellInfo->GetSpellEffect(EFFECT_INDEX_0); + SpellEffectEntry const* spellEffect1 = spellInfo->GetSpellEffect(EFFECT_INDEX_1); + return ((spellEffect0 && (spellEffect0->Effect == SPELL_EFFECT_CREATE_RANDOM_ITEM || + spellEffect0->Effect == SPELL_EFFECT_CREATE_ITEM_2) && + (spellEffect1 && spellEffect1->Effect == SPELL_EFFECT_SCRIPT_EFFECT)) || + spellInfo->Id == 64323); // Book of Glyph Mastery (Effect0==SPELL_EFFECT_SCRIPT_EFFECT without any other data) } inline bool IsLootCraftingSpell(SpellEntry const* spellInfo) { - return (spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_CREATE_RANDOM_ITEM || - // different random cards from Inscription (121==Virtuoso Inking Set category) r without explicit item - (spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_CREATE_ITEM_2 && - (spellInfo->TotemCategory[0] != 0 || spellInfo->EffectItemType[0] == 0))); + SpellEffectEntry const* spellEffect0 = spellInfo->GetSpellEffect(EFFECT_INDEX_0); + SpellTotemsEntry const* totems = spellInfo->GetSpellTotems(); + return (spellEffect0 && (spellEffect0->Effect == SPELL_EFFECT_CREATE_RANDOM_ITEM || + // different random cards from Inscription (121==Virtuoso Inking Set category) r without explicit item + (spellEffect0->Effect == SPELL_EFFECT_CREATE_ITEM_2 && + ((totems && totems->TotemCategory[0] != 0) || spellEffect0->EffectItemType==0)))); } int32 CompareAuraRanks(uint32 spellId_1, uint32 spellId_2); @@ -232,11 +266,13 @@ inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto) inline bool IsSpellRemoveAllMovementAndControlLossEffects(SpellEntry const* spellProto) { - return spellProto->EffectApplyAuraName[EFFECT_INDEX_0] == SPELL_AURA_MECHANIC_IMMUNITY && - spellProto->EffectMiscValue[EFFECT_INDEX_0] == 1 && - spellProto->EffectApplyAuraName[EFFECT_INDEX_1] == 0 && - spellProto->EffectApplyAuraName[EFFECT_INDEX_2] == 0 && - spellProto->HasAttribute(SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)/* && -- all above selected spells have SPELL_ATTR_EX5_* mask + SpellEffectEntry const* spellEffect0 = spellProto->GetSpellEffect(EFFECT_INDEX_0); + + return spellEffect0 && spellEffect0->EffectApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY && + spellEffect0->EffectMiscValue == 1 && + spellEffect0->EffectApplyAuraName == 0 && + spellEffect0->EffectApplyAuraName == 0 && + (spellProto->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)/* && -- all above selected spells have SPELL_ATTR_EX5_* mask ((spellProto->AttributesEx5 & (SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED|SPELL_ATTR_EX5_USABLE_WHILE_FEARED|SPELL_ATTR_EX5_USABLE_WHILE_STUNNED)) == (SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED|SPELL_ATTR_EX5_USABLE_WHILE_FEARED|SPELL_ATTR_EX5_USABLE_WHILE_STUNNED))*/; @@ -302,12 +338,16 @@ inline bool IsSpellWithCasterSourceTargetsOnly(SpellEntry const* spellInfo) { for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - uint32 targetA = spellInfo->EffectImplicitTargetA[i]; - if (targetA && !IsCasterSourceTarget(targetA)) + SpellEffectEntry const* effectEntry = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!effectEntry) + continue; + + uint32 targetA = effectEntry->EffectImplicitTargetA; + if(targetA && !IsCasterSourceTarget(targetA)) return false; - uint32 targetB = spellInfo->EffectImplicitTargetB[i]; - if (targetB && !IsCasterSourceTarget(targetB)) + uint32 targetB = effectEntry->EffectImplicitTargetB; + if(targetB && !IsCasterSourceTarget(targetB)) return false; if (!targetA && !targetB) @@ -390,12 +430,16 @@ inline bool IsAreaEffectTarget(Targets target) inline bool IsAreaOfEffectSpell(SpellEntry const* spellInfo) { - if (IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[EFFECT_INDEX_0])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[EFFECT_INDEX_0]))) + SpellEffectEntry const* effectEntry = spellInfo->GetSpellEffect(EFFECT_INDEX_0); + if(effectEntry && (IsAreaEffectTarget(Targets(effectEntry->EffectImplicitTargetA)) || IsAreaEffectTarget(Targets(effectEntry->EffectImplicitTargetB)))) return true; - if (IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[EFFECT_INDEX_1])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[EFFECT_INDEX_1]))) + effectEntry = spellInfo->GetSpellEffect(EFFECT_INDEX_1); + if(effectEntry && (IsAreaEffectTarget(Targets(effectEntry->EffectImplicitTargetA)) || IsAreaEffectTarget(Targets(effectEntry->EffectImplicitTargetB)))) return true; - if (IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetA[EFFECT_INDEX_2])) || IsAreaEffectTarget(Targets(spellInfo->EffectImplicitTargetB[EFFECT_INDEX_2]))) + effectEntry = spellInfo->GetSpellEffect(EFFECT_INDEX_2); + if(effectEntry && (IsAreaEffectTarget(Targets(effectEntry->EffectImplicitTargetA)) || IsAreaEffectTarget(Targets(effectEntry->EffectImplicitTargetB)))) return true; + return false; } @@ -414,8 +458,13 @@ inline bool IsAreaAuraEffect(uint32 effect) inline bool HasAreaAuraEffect(SpellEntry const* spellInfo) { for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) - if (IsAreaAuraEffect(spellInfo->Effect[i])) + { + SpellEffectEntry const* effectEntry = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!effectEntry) + continue; + if (IsAreaAuraEffect(effectEntry->Effect)) return true; + } return false; } @@ -423,7 +472,11 @@ inline bool HasAuraWithTriggerEffect(SpellEntry const* spellInfo) { for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - switch (spellInfo->Effect[i]) + SpellEffectEntry const* effectEntry = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!effectEntry) + continue; + + switch(effectEntry->Effect) { case SPELL_AURA_PERIODIC_TRIGGER_SPELL: case SPELL_AURA_PROC_TRIGGER_SPELL: @@ -452,7 +505,7 @@ inline bool IsAutoRepeatRangedSpell(SpellEntry const* spellInfo) inline bool IsSpellRequiresRangedAP(SpellEntry const* spellInfo) { - return (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MELEE); + return (spellInfo->GetSpellFamilyName() == SPELLFAMILY_HUNTER && spellInfo->GetDmgClass() != SPELL_DAMAGE_CLASS_MELEE); } SpellCastResult GetErrorAtShapeshiftedCast(SpellEntry const* spellInfo, uint32 form); @@ -467,8 +520,12 @@ inline bool IsNeedCastSpellAtFormApply(SpellEntry const* spellInfo, ShapeshiftFo if ((!spellInfo->HasAttribute(SPELL_ATTR_PASSIVE) && !spellInfo->HasAttribute(SPELL_ATTR_UNK7)) || !form) return false; + SpellShapeshiftEntry const* shapeShift = spellInfo->GetSpellShapeshift(); + if (shapeShift) + return false; + // passive spells with SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT are already active without shapeshift, do no recast! - return (spellInfo->Stances & (1 << (form - 1)) && !spellInfo->HasAttribute(SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT)); + return (shapeShift->Stances & (1<<(form-1)) && !(spellInfo->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT)); } @@ -485,16 +542,21 @@ inline SpellSchoolMask GetSpellSchoolMask(SpellEntry const* spellInfo) inline uint32 GetSpellMechanicMask(SpellEntry const* spellInfo, uint32 effectMask) { uint32 mask = 0; - if (spellInfo->Mechanic) - mask |= 1 << (spellInfo->Mechanic - 1); + + if (uint32 mech = spellInfo->GetMechanic()) + mask |= 1 << (mech - 1); for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i) { if (!(effectMask & (1 << i))) continue; - if (spellInfo->EffectMechanic[i]) - mask |= 1 << (spellInfo->EffectMechanic[i] - 1); + SpellEffectEntry const* effectEntry = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if (!effectEntry) + continue; + + if (effectEntry->EffectMechanic) + mask |= 1 << (effectEntry->EffectMechanic - 1); } return mask; @@ -502,21 +564,29 @@ inline uint32 GetSpellMechanicMask(SpellEntry const* spellInfo, uint32 effectMas inline uint32 GetAllSpellMechanicMask(SpellEntry const* spellInfo) { + SpellCategoriesEntry const* spellCategory = spellInfo->GetSpellCategories(); uint32 mask = 0; - if (spellInfo->Mechanic) - mask |= 1 << (spellInfo->Mechanic - 1); - for (int i = 0; i < MAX_EFFECT_INDEX; ++i) - if (spellInfo->EffectMechanic[i]) - mask |= 1 << (spellInfo->EffectMechanic[i] - 1); + if (spellCategory && spellCategory->Mechanic) + mask |= 1 << (spellCategory->Mechanic - 1); + + for (int i=0; i< MAX_EFFECT_INDEX; ++i) + { + SpellEffectEntry const* effectEntry = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if (effectEntry && effectEntry->EffectMechanic) + mask |= 1 << (effectEntry->EffectMechanic-1); + } + return mask; } inline Mechanics GetEffectMechanic(SpellEntry const* spellInfo, SpellEffectIndex effect) { - if (spellInfo->EffectMechanic[effect]) - return Mechanics(spellInfo->EffectMechanic[effect]); - if (spellInfo->Mechanic) - return Mechanics(spellInfo->Mechanic); + SpellEffectEntry const* effectEntry = spellInfo->GetSpellEffect(SpellEffectIndex(effect)); + if (effectEntry && effectEntry->EffectMechanic) + return Mechanics(effectEntry->EffectMechanic); + SpellCategoriesEntry const* spellCategory = spellInfo->GetSpellCategories(); + if (spellCategory && spellCategory->Mechanic) + return Mechanics(spellCategory->Mechanic); return MECHANIC_NONE; } diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp index d034eceea..93524c21b 100644 --- a/src/game/StatSystem.cpp +++ b/src/game/StatSystem.cpp @@ -252,13 +252,13 @@ void Player::UpdateAttackPowerAndDamage(bool ranged) UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; - uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS; + uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MOD_POS; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; - index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS; + index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; switch (getClass()) @@ -703,7 +703,7 @@ void Player::UpdateExpertise(WeaponAttackType attack) for (AuraList::const_iterator itr = expAuras.begin(); itr != expAuras.end(); ++itr) { // item neutral spell - if ((*itr)->GetSpellProto()->EquippedItemClass == -1) + if((*itr)->GetSpellProto()->GetEquippedItemClass() == -1) expertise += (*itr)->GetModifier()->m_amount; // item dependent spell else if (weapon && weapon->IsFitToSpellRequirements((*itr)->GetSpellProto())) @@ -729,7 +729,7 @@ void Player::UpdateArmorPenetration() for (AuraList::const_iterator itr = armorAuras.begin(); itr != armorAuras.end(); ++itr) { // affects all weapons - if ((*itr)->GetSpellProto()->EquippedItemClass == -1) + if((*itr)->GetSpellProto()->GetEquippedItemClass() == -1) { m_armorPenetrationPct += (*itr)->GetModifier()->m_amount; continue; @@ -867,13 +867,13 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged) UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; - uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS; + uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MOD_POS; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; - index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS; + index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; } @@ -1091,9 +1091,9 @@ void Pet::UpdateAttackPowerAndDamage(bool ranged) // UNIT_FIELD_(RANGED)_ATTACK_POWER field SetInt32Value(UNIT_FIELD_ATTACK_POWER, (int32)base_attPower); - // UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field - SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, (int32)attPowerMod); - // UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field + //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field + SetInt32Value(UNIT_FIELD_ATTACK_POWER_MOD_POS, (int32)attPowerMod); + //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, attPowerMultiplier); // automatically update weapon damage after attack power modification diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp index a854c3a25..f55da4162 100644 --- a/src/game/Totem.cpp +++ b/src/game/Totem.cpp @@ -183,32 +183,28 @@ void Totem::SetTypeBySummonSpell(SpellEntry const* spellProto) bool Totem::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index) const { - switch (spellInfo->Effect[index]) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(index); + if(spellEffect) { - case SPELL_EFFECT_ATTACK_ME: - // immune to any type of regeneration effects hp/mana etc. - case SPELL_EFFECT_HEAL: - case SPELL_EFFECT_HEAL_MAX_HEALTH: - case SPELL_EFFECT_HEAL_MECHANICAL: - case SPELL_EFFECT_HEAL_PCT: - case SPELL_EFFECT_ENERGIZE: - case SPELL_EFFECT_ENERGIZE_PCT: - return true; - default: - break; - } - - if (!IsPositiveSpell(spellInfo)) - { - // immune to all negative auras - if (IsAuraApplyEffect(spellInfo, index)) - return true; - } - else - { - // immune to any type of regeneration auras hp/mana etc. - if (IsPeriodicRegenerateEffect(spellInfo, index)) - return true; + // TODO: possibly all negative auras immune? + switch(spellEffect->Effect) + { + case SPELL_EFFECT_ATTACK_ME: + return true; + default: + break; + } + switch(spellEffect->EffectApplyAuraName) + { + case SPELL_AURA_PERIODIC_DAMAGE: + case SPELL_AURA_PERIODIC_LEECH: + case SPELL_AURA_MOD_FEAR: + case SPELL_AURA_TRANSFORM: + case SPELL_AURA_MOD_TAUNT: + return true; + default: + break; + } } return Creature::IsImmuneToSpellEffect(spellInfo, index); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 5819604a5..40f9a3903 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -165,18 +165,18 @@ void MovementInfo::Write(ByteBuffer& data) const bool GlobalCooldownMgr::HasGlobalCooldown(SpellEntry const* spellInfo) const { - GlobalCooldownList::const_iterator itr = m_GlobalCooldowns.find(spellInfo->StartRecoveryCategory); + GlobalCooldownList::const_iterator itr = m_GlobalCooldowns.find(spellInfo->GetStartRecoveryCategory()); return itr != m_GlobalCooldowns.end() && itr->second.duration && WorldTimer::getMSTimeDiff(itr->second.cast_time, WorldTimer::getMSTime()) < itr->second.duration; } void GlobalCooldownMgr::AddGlobalCooldown(SpellEntry const* spellInfo, uint32 gcd) { - m_GlobalCooldowns[spellInfo->StartRecoveryCategory] = GlobalCooldown(gcd, WorldTimer::getMSTime()); + m_GlobalCooldowns[spellInfo->GetStartRecoveryCategory()] = GlobalCooldown(gcd, WorldTimer::getMSTime()); } void GlobalCooldownMgr::CancelGlobalCooldown(SpellEntry const* spellInfo) { - m_GlobalCooldowns[spellInfo->StartRecoveryCategory].duration = 0; + m_GlobalCooldowns[spellInfo->GetStartRecoveryCategory()].duration = 0; } //////////////////////////////////////////////////////////// @@ -430,10 +430,10 @@ bool Unit::haveOffhandWeapon() const else { uint32 ItemId = GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1); - ItemEntry const* itemInfo = sItemStore.LookupEntry(ItemId); + /*ItemEntry const* itemInfo = sItemStore.LookupEntry(ItemId); if (itemInfo && itemInfo->Class == ITEM_CLASS_WEAPON) - return true; + return true;*/ return false; } @@ -856,7 +856,7 @@ uint32 Unit::DealDamage(Unit* pVictim, uint32 damage, CleanDamage const* cleanDa if (damagetype == DIRECT_DAMAGE || damagetype == SPELL_DIRECT_DAMAGE) { - if (!spellProto || !(spellProto->AuraInterruptFlags & AURA_INTERRUPT_FLAG_DIRECT_DAMAGE)) + if (!spellProto || !(spellProto->GetAuraInterruptFlags() & AURA_INTERRUPT_FLAG_DIRECT_DAMAGE)) pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DIRECT_DAMAGE); } if (pVictim->GetTypeId() != TYPEID_PLAYER) @@ -899,7 +899,7 @@ uint32 Unit::DealDamage(Unit* pVictim, uint32 damage, CleanDamage const* cleanDa next = i; ++next; if (spellProto && spellProto->Id == se->Id) // Not drop auras added by self continue; - if (!se->procFlags && (se->AuraInterruptFlags & AURA_INTERRUPT_FLAG_DAMAGE)) + if (!se->GetProcFlags() && (se->GetAuraInterruptFlags() & AURA_INTERRUPT_FLAG_DAMAGE)) { pVictim->RemoveAurasDueToSpell(i->second->GetId()); next = vAuras.begin(); @@ -920,7 +920,7 @@ uint32 Unit::DealDamage(Unit* pVictim, uint32 damage, CleanDamage const* cleanDa { if (spell->getState() == SPELL_STATE_PREPARING) { - if (spell->m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_ABORT_ON_DMG) + if(spell->m_spellInfo->GetInterruptFlags() & SPELL_INTERRUPT_FLAG_ABORT_ON_DMG) pVictim->InterruptSpell(CurrentSpellTypes(i)); else spell->Delayed(); @@ -933,8 +933,8 @@ uint32 Unit::DealDamage(Unit* pVictim, uint32 damage, CleanDamage const* cleanDa { if (spell->getState() == SPELL_STATE_CASTING) { - uint32 channelInterruptFlags = spell->m_spellInfo->ChannelInterruptFlags; - if (channelInterruptFlags & CHANNEL_FLAG_DELAY) + uint32 channelInterruptFlags = spell->m_spellInfo->GetChannelInterruptFlags(); + if( channelInterruptFlags & CHANNEL_FLAG_DELAY ) { if (pVictim != this) // don't shorten the duration of channeling if you damage yourself spell->DelayedChannel(); @@ -1137,9 +1137,9 @@ void Unit::CastSpell(Unit* Victim, SpellEntry const* spellInfo, bool triggered, SpellCastTargets targets; targets.setUnitTarget(Victim); - if (spellInfo->Targets & TARGET_FLAG_DEST_LOCATION) + if (spellInfo->GetTargets() & TARGET_FLAG_DEST_LOCATION) targets.setDestination(Victim->GetPositionX(), Victim->GetPositionY(), Victim->GetPositionZ()); - if (spellInfo->Targets & TARGET_FLAG_SOURCE_LOCATION) + if (spellInfo->GetTargets() & TARGET_FLAG_SOURCE_LOCATION) if (WorldObject* caster = spell->GetCastingObject()) targets.setSource(caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ()); @@ -1200,9 +1200,9 @@ void Unit::CastCustomSpell(Unit* Victim, SpellEntry const* spellInfo, int32 cons targets.setUnitTarget(Victim); spell->m_CastItem = castItem; - if (spellInfo->Targets & TARGET_FLAG_DEST_LOCATION) + if (spellInfo->GetTargets() & TARGET_FLAG_DEST_LOCATION) targets.setDestination(Victim->GetPositionX(), Victim->GetPositionY(), Victim->GetPositionZ()); - if (spellInfo->Targets & TARGET_FLAG_SOURCE_LOCATION) + if (spellInfo->GetTargets() & TARGET_FLAG_SOURCE_LOCATION) if (WorldObject* caster = spell->GetCastingObject()) targets.setSource(caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ()); @@ -1253,9 +1253,9 @@ void Unit::CastSpell(float x, float y, float z, SpellEntry const* spellInfo, boo SpellCastTargets targets; - if (spellInfo->Targets & TARGET_FLAG_DEST_LOCATION) + if (spellInfo->GetTargets() & TARGET_FLAG_DEST_LOCATION) targets.setDestination(x, y, z); - if (spellInfo->Targets & TARGET_FLAG_SOURCE_LOCATION) + if (spellInfo->GetTargets() & TARGET_FLAG_SOURCE_LOCATION) targets.setSource(x, y, z); // Spell cast with x,y,z but without dbc target-mask, set destination @@ -1296,7 +1296,7 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage* damageInfo, int32 damage, S bool crit = IsSpellCrit(pVictim, spellInfo, damageSchoolMask, attackType); // damage bonus (per damage class) - switch (spellInfo->DmgClass) + switch (spellInfo->GetDmgClass()) { // Melee and Ranged Spells case SPELL_DAMAGE_CLASS_RANGED: @@ -1969,8 +1969,9 @@ void Unit::CalculateDamageAbsorbAndResist(Unit* pCaster, SpellSchoolMask schoolM continue; SpellEntry const* i_spellProto = (*i)->GetSpellProto(); + SpellClassOptionsEntry const* adsClassOptions = i_spellProto->GetSpellClassOptions(); // Fire Ward or Frost Ward - if (i_spellProto->SpellFamilyName == SPELLFAMILY_MAGE && i_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000108)) + if(adsClassOptions && adsClassOptions->SpellFamilyName == SPELLFAMILY_MAGE && adsClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000108)) { int chance = 0; Unit::AuraList const& auras = GetAurasByType(SPELL_AURA_ADD_PCT_MODIFIER); @@ -1978,7 +1979,7 @@ void Unit::CalculateDamageAbsorbAndResist(Unit* pCaster, SpellSchoolMask schoolM { SpellEntry const* itr_spellProto = (*itr)->GetSpellProto(); // Frost Warding (chance full absorb) - if (itr_spellProto->SpellFamilyName == SPELLFAMILY_MAGE && itr_spellProto->SpellIconID == 501) + if (itr_spellProto->GetSpellFamilyName() == SPELLFAMILY_MAGE && itr_spellProto->SpellIconID == 501) { // chance stored in next dummy effect chance = itr_spellProto->CalculateSimpleValue(EFFECT_INDEX_1); @@ -2025,8 +2026,9 @@ void Unit::CalculateDamageAbsorbAndResist(Unit* pCaster, SpellSchoolMask schoolM // Handle custom absorb auras // TODO: try find better way + SpellClassOptionsEntry const* classOptions = spellProto->GetSpellClassOptions(); - switch (spellProto->SpellFamilyName) + switch(spellProto->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { @@ -2277,7 +2279,9 @@ void Unit::CalculateDamageAbsorbAndResist(Unit* pCaster, SpellSchoolMask schoolM else currentAbsorb = RemainingDamage; - if (float manaMultiplier = (*i)->GetSpellProto()->EffectMultipleValue[(*i)->GetEffIndex()]) + SpellEffectEntry const* spellEffect = (*i)->GetSpellProto()->GetSpellEffect((*i)->GetEffIndex()); + + if (float manaMultiplier = (spellEffect ? spellEffect->EffectMultipleValue : 0)) { if (Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod((*i)->GetId(), SPELLMOD_MULTIPLE_VALUE, manaMultiplier); @@ -2315,8 +2319,8 @@ void Unit::CalculateDamageAbsorbAndResist(Unit* pCaster, SpellSchoolMask schoolM SpellEntry const* itr_spellProto = (*itr)->GetSpellProto(); // Incanter's Absorption - if (itr_spellProto->SpellFamilyName == SPELLFAMILY_GENERIC && - itr_spellProto->SpellIconID == 2941) + if (itr_spellProto->GetSpellFamilyName() == SPELLFAMILY_GENERIC && + itr_spellProto->SpellIconID == 2941) { int32 amount = int32(incanterAbsorption * (*itr)->GetModifier()->m_amount / 100); @@ -2398,7 +2402,7 @@ void Unit::CalculateDamageAbsorbAndResist(Unit* pCaster, SpellSchoolMask schoolM // Apply death prevention spells effects if (preventDeathSpell && RemainingDamage >= (int32)GetHealth()) { - switch (preventDeathSpell->SpellFamilyName) + switch(preventDeathSpell->GetSpellFamilyName()) { // Cheat Death case SPELLFAMILY_ROGUE: @@ -2437,7 +2441,7 @@ void Unit::CalculateAbsorbResistBlock(Unit* pCaster, SpellNonMeleeDamage* damage { bool blocked = false; // Get blocked status - switch (spellProto->DmgClass) + switch (spellProto->GetDmgClass()) { // Melee and Ranged Spells case SPELL_DAMAGE_CLASS_RANGED: @@ -2823,8 +2827,8 @@ uint32 Unit::CalculateDamage(WeaponAttackType attType, bool normalized) float Unit::CalculateLevelPenalty(SpellEntry const* spellProto) const { - uint32 spellLevel = spellProto->spellLevel; - if (spellLevel <= 0) + uint32 spellLevel = spellProto->GetSpellLevel(); + if(spellLevel <= 0) return 1.0f; float LvlPenalty = 0.0f; @@ -2950,11 +2954,11 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* pVictim, SpellEntry const* spell) { WeaponAttackType attType = BASE_ATTACK; - if (spell->DmgClass == SPELL_DAMAGE_CLASS_RANGED) + if (spell->GetDmgClass() == SPELL_DAMAGE_CLASS_RANGED) attType = RANGED_ATTACK; // bonus from skills is 0.04% per skill Diff - int32 attackerWeaponSkill = (spell->EquippedItemClass == ITEM_CLASS_WEAPON) ? int32(GetWeaponSkillValue(attType, pVictim)) : GetMaxSkillValueForLevel(); + int32 attackerWeaponSkill = (spell->GetEquippedItemClass() == ITEM_CLASS_WEAPON) ? int32(GetWeaponSkillValue(attType,pVictim)) : GetMaxSkillValueForLevel(); int32 skillDiff = attackerWeaponSkill - int32(pVictim->GetMaxSkillValueForLevel(this)); int32 fullSkillDiff = attackerWeaponSkill - int32(pVictim->GetDefenseSkillValue(this)); @@ -3136,7 +3140,7 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* pVictim, SpellEntry const* spell) modHitChance -= resist_mech; // Chance resist debuff - modHitChance -= pVictim->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spell->Dispel)); + modHitChance-=pVictim->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spell->GetDispel())); int32 HitChance = modHitChance * 100; // Increase hit chance from attacker SPELL_AURA_MOD_SPELL_HIT_CHANCE and attacker ratings @@ -3217,7 +3221,7 @@ SpellMissInfo Unit::SpellHitResult(Unit* pVictim, SpellEntry const* spell, bool } } - switch (spell->DmgClass) + switch (spell->GetDmgClass()) { case SPELL_DAMAGE_CLASS_NONE: return SPELL_MISS_NONE; @@ -4007,7 +4011,7 @@ bool Unit::AddSpellAuraHolder(SpellAuraHolder* holder) if (foundHolder->GetCasterGuid() == holder->GetCasterGuid()) { // Aura can stack on self -> Stack it; - if (aurSpellInfo->StackAmount) + if (aurSpellInfo->GetStackAmount()) { // can be created with >1 stack by some spell mods foundHolder->ModStackAmount(holder->GetStackAmount()); @@ -4027,7 +4031,8 @@ bool Unit::AddSpellAuraHolder(SpellAuraHolder* holder) if (Aura* aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i))) { // m_auraname can be modified to SPELL_AURA_NONE for area auras, use original - AuraType aurNameReal = AuraType(aurSpellInfo->EffectApplyAuraName[i]); + SpellEffectEntry const* spellEffect = aurSpellInfo->GetSpellEffect(SpellEffectIndex(i)); + AuraType aurNameReal = AuraType(spellEffect ? spellEffect->EffectApplyAuraName : 0); if (aurNameReal == SPELL_AURA_PERIODIC_DAMAGE && aur->GetAuraDuration() > 0) { @@ -4059,7 +4064,8 @@ bool Unit::AddSpellAuraHolder(SpellAuraHolder* holder) continue; // m_auraname can be modified to SPELL_AURA_NONE for area auras, use original - AuraType aurNameReal = AuraType(aurSpellInfo->EffectApplyAuraName[i]); + SpellEffectEntry const* spellEffect = aurSpellInfo->GetSpellEffect(SpellEffectIndex(i)); + AuraType aurNameReal = AuraType(spellEffect ? spellEffect->EffectApplyAuraName : SPELL_AURA_NONE); switch (aurNameReal) { @@ -4233,14 +4239,25 @@ bool Unit::RemoveNoStackAurasDueToAuraHolder(SpellAuraHolder* holder) bool is_triggered_by_spell = false; // prevent triggering aura of removing aura that triggered it - for (int j = 0; j < MAX_EFFECT_INDEX; ++j) - if (i_spellProto->EffectTriggerSpell[j] == spellId) + for(int j = 0; j < MAX_EFFECT_INDEX; ++j) + { + SpellEffectEntry const* iSpellEffect = i_spellProto->GetSpellEffect(SpellEffectIndex(j)); + if(!iSpellEffect) + continue; + + if (iSpellEffect->EffectTriggerSpell == spellId) is_triggered_by_spell = true; + } // prevent triggered aura of removing aura that triggering it (triggered effect early some aura of parent spell - for (int j = 0; j < MAX_EFFECT_INDEX; ++j) - if (spellProto->EffectTriggerSpell[j] == i_spellId) + for(int j = 0; j < MAX_EFFECT_INDEX; ++j) + { + SpellEffectEntry const* spellEffect = i_spellProto->GetSpellEffect(SpellEffectIndex(j)); + if(!spellEffect) + continue; + if (spellEffect->EffectTriggerSpell == i_spellId) is_triggered_by_spell = true; + } if (is_triggered_by_spell) continue; @@ -4318,7 +4335,7 @@ bool Unit::RemoveNoStackAurasDueToAuraHolder(SpellAuraHolder* holder) } // Potions stack aura by aura (elixirs/flask already checked) - if (spellProto->SpellFamilyName == SPELLFAMILY_POTION && i_spellProto->SpellFamilyName == SPELLFAMILY_POTION) + if( spellProto->GetSpellFamilyName() == SPELLFAMILY_POTION && i_spellProto->GetSpellFamilyName() == SPELLFAMILY_POTION ) { if (IsNoStackAuraDueToAura(spellId, i_spellId)) { @@ -4396,10 +4413,11 @@ void Unit::RemoveSingleAuraFromSpellAuraHolder(uint32 spellId, SpellEffectIndex void Unit::RemoveAuraHolderDueToSpellByDispel(uint32 spellId, uint32 stackAmount, ObjectGuid casterGuid, Unit* dispeller) { SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellId); + SpellClassOptionsEntry const* classOptions = spellEntry->GetSpellClassOptions(); // Custom dispel case // Unstable Affliction - if (spellEntry->SpellFamilyName == SPELLFAMILY_WARLOCK && (spellEntry->SpellFamilyFlags & UI64LIT(0x010000000000))) + if(classOptions && classOptions->SpellFamilyName == SPELLFAMILY_WARLOCK && (classOptions->SpellFamilyFlags & UI64LIT(0x010000000000))) { if (Aura* dotAura = GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, UI64LIT(0x010000000000), 0x00000000, casterGuid)) { @@ -4416,7 +4434,7 @@ void Unit::RemoveAuraHolderDueToSpellByDispel(uint32 spellId, uint32 stackAmount } } // Lifebloom - else if (spellEntry->SpellFamilyName == SPELLFAMILY_DRUID && (spellEntry->SpellFamilyFlags & UI64LIT(0x0000001000000000))) + else if (classOptions && classOptions->SpellFamilyName == SPELLFAMILY_DRUID && (classOptions->SpellFamilyFlags & UI64LIT(0x0000001000000000))) { if (Aura* dotAura = GetAura(SPELL_AURA_DUMMY, SPELLFAMILY_DRUID, UI64LIT(0x0000001000000000), 0x00000000, casterGuid)) { @@ -4425,13 +4443,13 @@ void Unit::RemoveAuraHolderDueToSpellByDispel(uint32 spellId, uint32 stackAmount if (Unit* caster = dotAura->GetCaster()) { - int32 returnmana = (spellEntry->ManaCostPercentage * caster->GetCreateMana() / 100) * stackAmount / 2; + int32 returnmana = (spellEntry->GetManaCostPercentage() * caster->GetCreateMana() / 100) * stackAmount / 2; caster->CastCustomSpell(caster, 64372, &returnmana, NULL, NULL, true, NULL, dotAura, casterGuid); } } } // Flame Shock - else if (spellEntry->SpellFamilyName == SPELLFAMILY_SHAMAN && (spellEntry->SpellFamilyFlags & UI64LIT(0x10000000))) + else if (classOptions && classOptions->SpellFamilyName == SPELLFAMILY_SHAMAN && (classOptions->SpellFamilyFlags & UI64LIT(0x10000000))) { Unit* caster = NULL; uint32 triggeredSpell = 0; @@ -4464,7 +4482,7 @@ void Unit::RemoveAuraHolderDueToSpellByDispel(uint32 spellId, uint32 stackAmount return; } // Vampiric touch (first dummy aura) - else if (spellEntry->SpellFamilyName == SPELLFAMILY_PRIEST && spellEntry->SpellFamilyFlags & UI64LIT(0x0000040000000000)) + else if (classOptions && classOptions->SpellFamilyName == SPELLFAMILY_PRIEST && classOptions->SpellFamilyFlags & UI64LIT(0x0000040000000000)) { if (Aura* dot = GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, UI64LIT(0x0000040000000000), 0x00000000, casterGuid)) { @@ -4550,7 +4568,7 @@ void Unit::RemoveAurasWithDispelType(DispelType type, ObjectGuid casterGuid) for (SpellAuraHolderMap::iterator itr = auras.begin(); itr != auras.end();) { SpellEntry const* spell = itr->second->GetSpellProto(); - if (((1 << spell->Dispel) & dispelMask) && (!casterGuid || casterGuid == itr->second->GetCasterGuid())) + if (((1<GetDispel()) & dispelMask) && (!casterGuid || casterGuid == itr->second->GetCasterGuid())) { // Dispel aura RemoveAurasDueToSpell(spell->Id); @@ -4618,7 +4636,7 @@ void Unit::RemoveAurasWithInterruptFlags(uint32 flags) { for (SpellAuraHolderMap::iterator iter = m_spellAuraHolders.begin(); iter != m_spellAuraHolders.end();) { - if (iter->second->GetSpellProto()->AuraInterruptFlags & flags) + if (iter->second->GetSpellProto()->GetAuraInterruptFlags() & flags) { RemoveSpellAuraHolder(iter->second); iter = m_spellAuraHolders.begin(); @@ -5886,7 +5904,7 @@ void Unit::ModifyAuraState(AuraState flag, bool apply) if (itr->second.state == PLAYERSPELL_REMOVED) continue; SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->first); if (!spellInfo || !IsPassiveSpell(spellInfo)) continue; - if (AuraState(spellInfo->CasterAuraState) == flag) + if (AuraState(spellInfo->GetCasterAuraState()) == flag) CastSpell(this, itr->first, true, NULL); } } @@ -5904,7 +5922,7 @@ void Unit::ModifyAuraState(AuraState flag, bool apply) for (Unit::SpellAuraHolderMap::iterator itr = tAuras.begin(); itr != tAuras.end();) { SpellEntry const* spellProto = (*itr).second->GetSpellProto(); - if (AuraState(spellProto->CasterAuraState) == flag) + if (AuraState(spellProto->GetCasterAuraState()) == flag) { RemoveSpellAuraHolder(itr->second); itr = tAuras.begin(); @@ -6167,7 +6185,7 @@ Unit* Unit::SelectMagnetTarget(Unit* victim, Spell* spell, SpellEffectIndex eff) return NULL; // Magic case - if (spell && spell->m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC) + if (spell && (spell->m_spellInfo->GetDmgClass() == SPELL_DAMAGE_CLASS_NONE || spell->m_spellInfo->GetDmgClass() == SPELL_DAMAGE_CLASS_MAGIC)) { Unit::AuraList const& magnetAuras = victim->GetAurasByType(SPELL_AURA_SPELL_MAGNET); for (Unit::AuraList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr) @@ -6251,7 +6269,7 @@ int32 Unit::SpellBonusWithCoeffs(SpellEntry const* spellProto, int32 total, int3 float ap_bonus = damagetype == DOT ? bonus->ap_dot_bonus : bonus->ap_bonus; // Impurity - if (GetTypeId() == TYPEID_PLAYER && spellProto->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT) + if (GetTypeId() == TYPEID_PLAYER && spellProto->GetSpellFamilyName() == SPELLFAMILY_DEATHKNIGHT) { if (SpellEntry const* spell = ((Player*)this)->GetKnownTalentRankById(2005)) ap_bonus += ((spell->CalculateSimpleValue(EFFECT_INDEX_0) * ap_bonus) / 100.0f); @@ -6308,11 +6326,12 @@ uint32 Unit::SpellDamageBonusDone(Unit* pVictim, SpellEntry const* spellProto, u AuraList const& mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); for (AuraList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) { - if (((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) && - (*i)->GetSpellProto()->EquippedItemClass == -1 && - // -1 == any item class (not wand then) - (*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0) - // 0 == any inventory type (not wand then) + SpellEquippedItemsEntry const* spellEquip = (*i)->GetSpellProto()->GetSpellEquippedItems(); + if( ((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) && + spellEquip && spellEquip->EquippedItemClass == -1 && + // -1 == any item class (not wand then) + spellEquip->EquippedItemInventoryTypeMask == 0 ) + // 0 == any inventory type (not wand then) { DoneTotalMod *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f; } @@ -6367,7 +6386,8 @@ uint32 Unit::SpellDamageBonusDone(Unit* pVictim, SpellEntry const* spellProto, u for (SpellAuraHolderMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr) { SpellEntry const* m_spell = itr->second->GetSpellProto(); - if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK || !(m_spell->SpellFamilyFlags & UI64LIT(0x0004071B8044C402))) + SpellClassOptionsEntry const* itrClassOptions = m_spell->GetSpellClassOptions(); + if (itrClassOptions && (itrClassOptions->SpellFamilyName != SPELLFAMILY_WARLOCK || !(itrClassOptions->SpellFamilyFlags & UI64LIT(0x0004071B8044C402)))) continue; modPercent += stepPercent * itr->second->GetStackAmount(); if (modPercent >= maxPercent) @@ -6449,8 +6469,10 @@ uint32 Unit::SpellDamageBonusDone(Unit* pVictim, SpellEntry const* spellProto, u } } - // Custom scripted damage - switch (spellProto->SpellFamilyName) + SpellClassOptionsEntry const* classOptions = spellProto->GetSpellClassOptions(); + + // Custom scripted damage + switch(spellProto->GetSpellFamilyName()) { case SPELLFAMILY_MAGE: { @@ -6471,8 +6493,8 @@ uint32 Unit::SpellDamageBonusDone(Unit* pVictim, SpellEntry const* spellProto, u } } // Torment the weak affected (Arcane Barrage, Arcane Blast, Frostfire Bolt, Arcane Missiles, Fireball) - if ((spellProto->SpellFamilyFlags & UI64LIT(0x0000900020200021)) && - (pVictim->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED) || pVictim->HasAuraType(SPELL_AURA_HASTE_ALL))) + if (classOptions && (classOptions->SpellFamilyFlags & UI64LIT(0x0000900020200021)) && + (pVictim->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED) || pVictim->HasAuraType(SPELL_AURA_HASTE_ALL))) { // Search for Torment the weak dummy aura Unit::AuraList const& ttw = GetAurasByType(SPELL_AURA_DUMMY); @@ -6490,7 +6512,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* pVictim, SpellEntry const* spellProto, u case SPELLFAMILY_WARLOCK: { // Drain Soul - if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000004000)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000004000)) { if (pVictim->GetHealth() * 100 / pVictim->GetMaxHealth() <= 25) DoneTotalMod *= 4; @@ -6525,7 +6547,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* pVictim, SpellEntry const* spellProto, u case SPELLFAMILY_DRUID: { // Improved Insect Swarm (Wrath part) - if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000001)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000000000001)) { // if Insect Swarm on target if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, UI64LIT(0x000000000200000), 0, GetObjectGuid())) @@ -6546,14 +6568,14 @@ uint32 Unit::SpellDamageBonusDone(Unit* pVictim, SpellEntry const* spellProto, u case SPELLFAMILY_DEATHKNIGHT: { // Icy Touch and Howling Blast - if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000200000002)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000200000002)) { // search disease bool found = false; Unit::SpellAuraHolderMap const& auras = pVictim->GetSpellAuraHolderMap(); for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - if (itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE) + if(itr->second->GetSpellProto()->GetDispel() == DISPEL_DISEASE) { found = true; break; @@ -6566,7 +6588,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* pVictim, SpellEntry const* spellProto, u Unit::AuraList const& dummyAuras = GetAurasByType(SPELL_AURA_DUMMY); for (Unit::AuraList::const_iterator i = dummyAuras.begin(); i != dummyAuras.end(); ++i) { - if ((*i)->GetSpellProto()->EffectMiscValue[(*i)->GetEffIndex()] == 7244) + if ((*i)->GetSpellProto()->GetEffectMiscValue((*i)->GetEffIndex()) == 7244) { DoneTotalMod *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f; break; @@ -6574,7 +6596,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* pVictim, SpellEntry const* spellProto, u } } // Death Coil (bonus from Item - Death Knight T8 DPS Relic) - else if (spellProto->SpellFamilyFlags & UI64LIT(0x00002000)) + else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x00002000)) { if (Aura* sigil = GetDummyAura(64962)) DoneTotal += sigil->GetModifier()->m_amount; @@ -6693,10 +6715,11 @@ int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) AuraList const& mDamageDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE); for (AuraList::const_iterator i = mDamageDone.begin(); i != mDamageDone.end(); ++i) { + SpellEquippedItemsEntry const* spellEquip = (*i)->GetSpellProto()->GetSpellEquippedItems(); if (((*i)->GetModifier()->m_miscvalue & schoolMask) != 0 && - (*i)->GetSpellProto()->EquippedItemClass == -1 && // -1 == any item class (not wand then) - (*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0) // 0 == any inventory type (not wand then) - DoneAdvertisedBenefit += (*i)->GetModifier()->m_amount; + spellEquip && spellEquip->EquippedItemClass == -1 && // -1 == any item class (not wand then) + spellEquip->EquippedItemInventoryTypeMask == 0) // 0 == any inventory type (not wand then) + DoneAdvertisedBenefit += (*i)->GetModifier()->m_amount; } if (GetTypeId() == TYPEID_PLAYER) @@ -6749,7 +6772,7 @@ bool Unit::IsSpellCrit(Unit* pVictim, SpellEntry const* spellProto, SpellSchoolM return false; float crit_chance = 0.0f; - switch (spellProto->DmgClass) + switch(spellProto->GetDmgClass()) { case SPELL_DAMAGE_CLASS_NONE: return false; @@ -6813,8 +6836,9 @@ bool Unit::IsSpellCrit(Unit* pVictim, SpellEntry const* spellProto, SpellSchoolM } } + SpellClassOptionsEntry const* classOptions = spellProto->GetSpellClassOptions(); // Custom crit by class - switch (spellProto->SpellFamilyName) + switch(spellProto->GetSpellFamilyName()) { case SPELLFAMILY_MAGE: { @@ -6838,8 +6862,8 @@ bool Unit::IsSpellCrit(Unit* pVictim, SpellEntry const* spellProto, SpellSchoolM for (AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) { // Improved Flash Heal - if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST && - (*i)->GetSpellProto()->SpellIconID == 2542) + if ((*i)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_PRIEST && + (*i)->GetSpellProto()->SpellIconID == 2542) { crit_chance += (*i)->GetModifier()->m_amount; break; @@ -6868,14 +6892,14 @@ bool Unit::IsSpellCrit(Unit* pVictim, SpellEntry const* spellProto, SpellSchoolM break; case SPELLFAMILY_PALADIN: // Sacred Shield - if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000040000000)) + if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000000040000000)) { Aura* aura = pVictim->GetDummyAura(58597); if (aura && aura->GetCasterGuid() == GetObjectGuid()) crit_chance += aura->GetModifier()->m_amount; } // Exorcism - else if (spellProto->Category == 19) + else if (spellProto->GetCategory() == 19) { if (pVictim->GetCreatureTypeMask() & CREATURE_TYPEMASK_DEMON_OR_UNDEAD) return true; @@ -6921,7 +6945,7 @@ uint32 Unit::SpellCriticalDamageBonus(SpellEntry const* spellProto, uint32 damag { // Calculate critical bonus int32 crit_bonus; - switch (spellProto->DmgClass) + switch(spellProto->GetDmgClass()) { case SPELL_DAMAGE_CLASS_MELEE: // for melee based spells is 100% case SPELL_DAMAGE_CLASS_RANGED: @@ -6940,7 +6964,7 @@ uint32 Unit::SpellCriticalDamageBonus(SpellEntry const* spellProto, uint32 damag return damage += crit_bonus; int32 critPctDamageMod = 0; - if (spellProto->DmgClass >= SPELL_DAMAGE_CLASS_MELEE) + if(spellProto->GetDmgClass() >= SPELL_DAMAGE_CLASS_MELEE) { if (GetWeaponAttackType(spellProto) == RANGED_ATTACK) critPctDamageMod += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE); @@ -6968,7 +6992,7 @@ uint32 Unit::SpellCriticalHealingBonus(SpellEntry const* spellProto, uint32 dama { // Calculate critical bonus int32 crit_bonus; - switch (spellProto->DmgClass) + switch(spellProto->GetDmgClass()) { case SPELL_DAMAGE_CLASS_MELEE: // for melee based spells is 100% case SPELL_DAMAGE_CLASS_RANGED: @@ -7006,7 +7030,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* pVictim, SpellEntry const* spellProto, return owner->SpellHealingBonusDone(pVictim, spellProto, healamount, damagetype, stack); // No heal amount for this class spells - if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE) + if (spellProto->GetDmgClass() == SPELL_DAMAGE_CLASS_NONE) return healamount < 0 ? 0 : healamount; // Healing Done @@ -7058,9 +7082,9 @@ uint32 Unit::SpellHealingBonusDone(Unit* pVictim, SpellEntry const* spellProto, int ownHotCount = 0; // counted HoT types amount, not stacks Unit::AuraList const& RejorRegr = pVictim->GetAurasByType(SPELL_AURA_PERIODIC_HEAL); - for (Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) - if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && - (*i)->GetCasterGuid() == GetObjectGuid()) + for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) + if ((*i)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_DRUID && + (*i)->GetCasterGuid() == GetObjectGuid()) ++ownHotCount; if (ownHotCount) @@ -7078,25 +7102,23 @@ uint32 Unit::SpellHealingBonusDone(Unit* pVictim, SpellEntry const* spellProto, } } - if (spellProto->SpellFamilyName == SPELLFAMILY_DRUID) + // Nourish 20% of heal increase if target is affected by Druids HOTs + SpellClassOptionsEntry const* classOptions = spellProto->GetSpellClassOptions(); + if (classOptions && classOptions->SpellFamilyName == SPELLFAMILY_DRUID && (classOptions->SpellFamilyFlags & UI64LIT(0x0200000000000000))) { - // Nourish 20% of heal increase if target is affected by Druids HOTs - if (spellProto->SpellFamilyFlags & UI64LIT(0x0200000000000000)) + int ownHotCount = 0; // counted HoT types amount, not stacks + Unit::AuraList const& RejorRegr = pVictim->GetAurasByType(SPELL_AURA_PERIODIC_HEAL); + for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) + if ((*i)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_DRUID && + (*i)->GetCasterGuid() == GetObjectGuid()) + ++ownHotCount; + + if (ownHotCount) { - int ownHotCount = 0; // counted HoT types amount, not stacks - Unit::AuraList const& RejorRegr = pVictim->GetAurasByType(SPELL_AURA_PERIODIC_HEAL); - for (Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) - if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && - (*i)->GetCasterGuid() == GetObjectGuid()) - ++ownHotCount; + DoneTotalMod *= 1.2f; // base bonus at HoTs - if (ownHotCount) - { - DoneTotalMod *= 1.2f; // base bonus at HoTs - - if (Aura* glyph = GetAura(62971, EFFECT_INDEX_0))// Glyph of Nourish - DoneTotalMod *= (glyph->GetModifier()->m_amount * ownHotCount + 100.0f) / 100.0f; - } + if (Aura* glyph = GetAura(62971, EFFECT_INDEX_0))// Glyph of Nourish + DoneTotalMod *= (glyph->GetModifier()->m_amount * ownHotCount + 100.0f) / 100.0f; } // Lifebloom else if (spellProto->IsFitToFamilyMask(UI64LIT(0x0000001000000000))) @@ -7155,7 +7177,7 @@ uint32 Unit::SpellHealingBonusTaken(Unit* pCaster, SpellEntry const* spellProto, TakenTotalMod *= (100.0f + maxval) / 100.0f; // No heal amount for this class spells - if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE) + if (spellProto->GetDmgClass() == SPELL_DAMAGE_CLASS_NONE) { healamount = int32(healamount * TakenTotalMod); return healamount < 0 ? 0 : healamount; @@ -7202,7 +7224,7 @@ int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) for (AuraList::const_iterator i = mHealingDoneOfStatPercent.begin(); i != mHealingDoneOfStatPercent.end(); ++i) { // stat used dependent from misc value (stat index) - Stats usedStat = Stats((*i)->GetSpellProto()->EffectMiscValue[(*i)->GetEffIndex()]); + Stats usedStat = Stats((*i)->GetSpellProto()->GetEffectMiscValue((*i)->GetEffIndex())); AdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetModifier()->m_amount / 100.0f); } @@ -7252,8 +7274,8 @@ bool Unit::IsImmuneToSpell(SpellEntry const* spellInfo) // SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_EFFECT]; SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_DISPEL]; - for (SpellImmuneList::const_iterator itr = dispelList.begin(); itr != dispelList.end(); ++itr) - if (itr->type == spellInfo->Dispel) + for(SpellImmuneList::const_iterator itr = dispelList.begin(); itr != dispelList.end(); ++itr) + if (itr->type == spellInfo->GetDispel()) return true; if (!spellInfo->HasAttribute(SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE) && // unaffected by school immunity @@ -7266,7 +7288,7 @@ bool Unit::IsImmuneToSpell(SpellEntry const* spellInfo) return true; } - if (uint32 mechanic = spellInfo->Mechanic) + if(uint32 mechanic = spellInfo->GetMechanic()) { SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) @@ -7284,14 +7306,18 @@ bool Unit::IsImmuneToSpell(SpellEntry const* spellInfo) bool Unit::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index) const { - // If m_immuneToEffect type contain this effect type, IMMUNE effect. - uint32 effect = spellInfo->Effect[index]; + //If m_immuneToEffect type contain this effect type, IMMUNE effect. + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(index); + if(!spellEffect) + return false; + + uint32 effect = spellEffect->Effect; SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT]; for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr) if (itr->type == effect) return true; - if (uint32 mechanic = spellInfo->EffectMechanic[index]) + if(uint32 mechanic = spellEffect->EffectMechanic) { SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) @@ -7304,7 +7330,7 @@ bool Unit::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex i return true; } - if (uint32 aura = spellInfo->EffectApplyAuraName[index]) + if(uint32 aura = spellEffect->EffectApplyAuraName) { SpellImmuneList const& list = m_spellImmune[IMMUNITY_STATE]; for (SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr) @@ -7314,8 +7340,8 @@ bool Unit::IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex i // Check for immune to application of harmful magical effects AuraList const& immuneAuraApply = GetAurasByType(SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL); if (!immuneAuraApply.empty() && - spellInfo->Dispel == DISPEL_MAGIC && // Magic debuff) - !IsPositiveEffect(spellInfo, index)) // Harmful + spellInfo->GetDispel() == DISPEL_MAGIC && // Magic debuff) + !IsPositiveEffect(spellInfo, index)) // Harmful { // Check school SpellSchoolMask schoolMask = GetSpellSchoolMask(spellInfo); @@ -7354,10 +7380,10 @@ uint32 Unit::MeleeDamageBonusDone(Unit* pVictim, uint32 pdamage, WeaponAttackTyp AuraList const& mModDamageDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE); for (AuraList::const_iterator i = mModDamageDone.begin(); i != mModDamageDone.end(); ++i) { - if ((*i)->GetModifier()->m_miscvalue & schoolMask && // schoolmask has to fit with the intrinsic spell school - (*i)->GetModifier()->m_miscvalue & GetMeleeDamageSchoolMask() && // AND schoolmask has to fit with weapon damage school (essential for non-physical spells) - (((*i)->GetSpellProto()->EquippedItemClass == -1) || // general, weapon independent - (pWeapon && pWeapon->IsFitToSpellRequirements((*i)->GetSpellProto())))) // OR used weapon fits aura requirements + if (((*i)->GetModifier()->m_miscvalue & schoolMask && // schoolmask has to fit with the intrinsic spell school + (*i)->GetModifier()->m_miscvalue & GetMeleeDamageSchoolMask() && // AND schoolmask has to fit with weapon damage school (essential for non-physical spells) + ((*i)->GetSpellProto()->GetEquippedItemClass() == -1) || // general, weapon independent + (pWeapon && pWeapon->IsFitToSpellRequirements((*i)->GetSpellProto())))) // OR used weapon fits aura requirements { DoneFlat += (*i)->GetModifier()->m_amount; } @@ -7393,10 +7419,10 @@ uint32 Unit::MeleeDamageBonusDone(Unit* pVictim, uint32 pdamage, WeaponAttackTyp AuraList const& mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); for (AuraList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i) { - if ((*i)->GetModifier()->m_miscvalue & schoolMask && // schoolmask has to fit with the intrinsic spell school - (*i)->GetModifier()->m_miscvalue & GetMeleeDamageSchoolMask() && // AND schoolmask has to fit with weapon damage school (essential for non-physical spells) - (((*i)->GetSpellProto()->EquippedItemClass == -1) || // general, weapon independent - (pWeapon && pWeapon->IsFitToSpellRequirements((*i)->GetSpellProto())))) // OR used weapon fits aura requirements + if (((*i)->GetModifier()->m_miscvalue & schoolMask && // schoolmask has to fit with the intrinsic spell school + (*i)->GetModifier()->m_miscvalue & GetMeleeDamageSchoolMask() && // AND schoolmask has to fit with weapon damage school (essential for non-physical spells) + ((*i)->GetSpellProto()->GetEquippedItemClass()) == -1 || // general, weapon independent + (pWeapon && pWeapon->IsFitToSpellRequirements((*i)->GetSpellProto())))) // OR used weapon fits aura requirements { DonePercent *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f; } @@ -7493,15 +7519,17 @@ uint32 Unit::MeleeDamageBonusDone(Unit* pVictim, uint32 pdamage, WeaponAttackTyp if (spellProto) { + SpellClassOptionsEntry const* classOptions = spellProto->GetSpellClassOptions(); + // Frost Strike - if (spellProto->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && spellProto->SpellFamilyFlags & UI64LIT(0x0000000400000000)) + if (classOptions && classOptions->IsFitToFamily(SPELLFAMILY_DEATHKNIGHT, UI64LIT(0x0000000400000000))) { // search disease bool found = false; Unit::SpellAuraHolderMap const& auras = pVictim->GetSpellAuraHolderMap(); for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - if (itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE) + if(itr->second->GetSpellProto()->GetDispel() == DISPEL_DISEASE) { found = true; break; @@ -7514,7 +7542,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* pVictim, uint32 pdamage, WeaponAttackTyp Unit::AuraList const& dummyAuras = GetAurasByType(SPELL_AURA_DUMMY); for (Unit::AuraList::const_iterator i = dummyAuras.begin(); i != dummyAuras.end(); ++i) { - if ((*i)->GetSpellProto()->EffectMiscValue[(*i)->GetEffIndex()] == 7244) + if ((*i)->GetSpellProto()->GetEffectMiscValue((*i)->GetEffIndex()) == 7244) { DonePercent *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f; break; @@ -7523,7 +7551,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* pVictim, uint32 pdamage, WeaponAttackTyp } } // Glyph of Steady Shot (Steady Shot check) - else if (spellProto->SpellFamilyName == SPELLFAMILY_HUNTER && spellProto->SpellFamilyFlags & UI64LIT(0x0000000100000000)) + else if (classOptions && classOptions->IsFitToFamily(SPELLFAMILY_HUNTER, UI64LIT(0x0000000100000000))) { // search for glyph dummy aura if (Aura* aur = GetDummyAura(56826)) @@ -7598,8 +7626,9 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* pCaster, uint32 pdamage, WeaponAttackTy uint32 mechanicMask = spellProto ? GetAllSpellMechanicMask(spellProto) : 0; // Shred also have bonus as MECHANIC_BLEED damages - if (spellProto && spellProto->SpellFamilyName == SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags & UI64LIT(0x00008000)) - mechanicMask |= (1 << (MECHANIC_BLEED - 1)); + SpellClassOptionsEntry const* classOptions = spellProto ? spellProto->GetSpellClassOptions() : NULL; + if (classOptions && classOptions->SpellFamilyName==SPELLFAMILY_DRUID && classOptions->SpellFamilyFlags & UI64LIT(0x00008000)) + mechanicMask |= (1 << (MECHANIC_BLEED-1)); // FLAT damage bonus auras // ======================= @@ -8790,17 +8819,24 @@ int32 Unit::CalculateSpellDamage(Unit const* target, SpellEntry const* spellProt uint8 comboPoints = unitPlayer ? unitPlayer->GetComboPoints() : 0; int32 level = int32(getLevel()); - if (level > (int32)spellProto->maxLevel && spellProto->maxLevel > 0) - level = (int32)spellProto->maxLevel; - else if (level < (int32)spellProto->baseLevel) - level = (int32)spellProto->baseLevel; - level -= (int32)spellProto->spellLevel; + uint32 maxLevel = spellProto->GetMaxLevel(); + uint32 baseLevel = spellProto->GetBaseLevel(); + uint32 spellLevel = spellProto->GetSpellLevel(); + if (level > (int32)maxLevel && maxLevel > 0) + level = (int32)maxLevel; + else if (level < (int32)baseLevel) + level = (int32)baseLevel; + level-= (int32)spellLevel; - float basePointsPerLevel = spellProto->EffectRealPointsPerLevel[effect_index]; - int32 basePoints = effBasePoints ? *effBasePoints - 1 : spellProto->EffectBasePoints[effect_index]; + SpellEffectEntry const* spellEffect = spellProto->GetSpellEffect(effect_index); + if(!spellEffect) + return 0; + + float basePointsPerLevel = spellEffect->EffectRealPointsPerLevel; + int32 basePoints = effBasePoints ? *effBasePoints - 1 : spellEffect->EffectBasePoints; basePoints += int32(level * basePointsPerLevel); - int32 randomPoints = int32(spellProto->EffectDieSides[effect_index]); - float comboDamage = spellProto->EffectPointsPerComboPoint[effect_index]; + int32 randomPoints = int32(spellEffect->EffectDieSides); + float comboDamage = spellEffect->EffectPointsPerComboPoint; switch (randomPoints) { @@ -8842,11 +8878,11 @@ int32 Unit::CalculateSpellDamage(Unit const* target, SpellEntry const* spellProt } } - if (spellProto->HasAttribute(SPELL_ATTR_LEVEL_DAMAGE_CALCULATION) && spellProto->spellLevel && - spellProto->Effect[effect_index] != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE && - spellProto->Effect[effect_index] != SPELL_EFFECT_KNOCK_BACK && - (spellProto->Effect[effect_index] != SPELL_EFFECT_APPLY_AURA || spellProto->EffectApplyAuraName[effect_index] != SPELL_AURA_MOD_DECREASE_SPEED)) - value = int32(value * 0.25f * exp(getLevel() * (70 - spellProto->spellLevel) / 1000.0f)); + if(spellProto->Attributes & SPELL_ATTR_LEVEL_DAMAGE_CALCULATION && spellLevel && + spellEffect->Effect != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE && + spellEffect->Effect != SPELL_EFFECT_KNOCK_BACK && + (spellEffect->Effect != SPELL_EFFECT_APPLY_AURA || spellEffect->EffectApplyAuraName != SPELL_AURA_MOD_DECREASE_SPEED)) + value = int32(value*0.25f*exp(getLevel()*(70-spellLevel)/1000.0f)); return value; } @@ -8875,8 +8911,8 @@ int32 Unit::CalculateAuraDuration(SpellEntry const* spellProto, uint32 effectMas if (!IsPositiveSpell(spellProto)) { - dispelMod = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL, spellProto->Dispel); - dmgClassMod = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS, spellProto->DmgClass); + dispelMod = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL, spellProto->GetDispel()); + dmgClassMod = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS, spellProto->GetDmgClass()); } int32 durationMod = std::min(mechanicMod, std::min(dispelMod, dmgClassMod)); @@ -8891,11 +8927,11 @@ int32 Unit::CalculateAuraDuration(SpellEntry const* spellProto, uint32 effectMas if (caster == this) { - switch (spellProto->SpellFamilyName) + switch(spellProto->GetSpellFamilyName()) { case SPELLFAMILY_DRUID: // Thorns - if (spellProto->SpellIconID == 53 && (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000100))) + if (spellProto->SpellIconID == 53 && spellProto->IsFitToFamilyMask(UI64LIT(0x0000000000000100))) { // Glyph of Thorns if (Aura* aur = GetAura(57862, EFFECT_INDEX_0)) @@ -8904,14 +8940,14 @@ int32 Unit::CalculateAuraDuration(SpellEntry const* spellProto, uint32 effectMas break; case SPELLFAMILY_PALADIN: // Blessing of Might - if (spellProto->SpellIconID == 298 && spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000002)) + if (spellProto->SpellIconID == 298 && spellProto->IsFitToFamilyMask(UI64LIT(0x0000000000000002))) { // Glyph of Blessing of Might if (Aura* aur = GetAura(57958, EFFECT_INDEX_0)) duration += aur->GetModifier()->m_amount * MINUTE * IN_MILLISECONDS; } // Blessing of Wisdom - else if (spellProto->SpellIconID == 306 && spellProto->SpellFamilyFlags & UI64LIT(0x0000000000010000)) + else if (spellProto->SpellIconID == 306 && spellProto->IsFitToFamilyMask(UI64LIT(0x0000000000010000))) { // Glyph of Blessing of Wisdom if (Aura* aur = GetAura(57979, EFFECT_INDEX_0)) @@ -9240,14 +9276,14 @@ float Unit::GetTotalAttackPowerValue(WeaponAttackType attType) const { if (attType == RANGED_ATTACK) { - int32 ap = GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER) + GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS); + int32 ap = GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER) + GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS); if (ap < 0) return 0.0f; return ap * (1.0f + GetFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER)); } else { - int32 ap = GetInt32Value(UNIT_FIELD_ATTACK_POWER) + GetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS); + int32 ap = GetInt32Value(UNIT_FIELD_ATTACK_POWER) + GetInt32Value(UNIT_FIELD_ATTACK_POWER_MOD_POS); if (ap < 0) return 0.0f; return ap * (1.0f + GetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER)); @@ -9456,11 +9492,17 @@ uint32 Unit::GetCreatePowers(Powers power) const case POWER_HEALTH: return 0; // is it really should be here? case POWER_MANA: return GetCreateMana(); case POWER_RAGE: return 1000; - case POWER_FOCUS: return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->IsPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : 100); + case POWER_FOCUS: + if(GetTypeId() == TYPEID_PLAYER && ((Player const*)this)->getClass() == CLASS_HUNTER) + return 100; + return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->IsPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : 100); case POWER_ENERGY: return 100; case POWER_HAPPINESS: return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->IsPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : 1050000); case POWER_RUNE: return (GetTypeId() == TYPEID_PLAYER && ((Player const*)this)->getClass() == CLASS_DEATH_KNIGHT ? 8 : 0); case POWER_RUNIC_POWER: return (GetTypeId() == TYPEID_PLAYER && ((Player const*)this)->getClass() == CLASS_DEATH_KNIGHT ? 1000 : 0); + case POWER_SOUL_SHARDS: return 0; // TODO: fix me + case POWER_ECLIPSE: return 0; // TODO: fix me + case POWER_HOLY_POWER: return 0; } return 0; @@ -9597,7 +9639,10 @@ void CharmInfo::InitCharmCreateSpells() if (!spellInfo) onlyselfcast = false; for (uint32 i = 0; i < 3 && onlyselfcast; ++i) // nonexistent spell will not make any problems as onlyselfcast would be false -> break right away { - if (spellInfo->EffectImplicitTargetA[i] != TARGET_SELF && spellInfo->EffectImplicitTargetA[i] != 0) + SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + if(spellEffect->EffectImplicitTargetA != TARGET_SELF && spellEffect->EffectImplicitTargetA != 0) onlyselfcast = false; } @@ -9890,6 +9935,10 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* pTarget, uint32 procFlag, if (!triggeredByAura) continue; + SpellEffectEntry const* spellEffect = triggeredByHolder->GetSpellProto()->GetSpellEffect(SpellEffectIndex(i)); + if (!spellEffect) + continue; + if (procSpell) { if (spellProcEvent) @@ -9918,7 +9967,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* pTarget, uint32 procFlag, continue; } - SpellAuraProcResult procResult = (*this.*AuraProcHandler[triggeredByHolder->GetSpellProto()->EffectApplyAuraName[i]])(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown); + SpellAuraProcResult procResult = (*this.*AuraProcHandler[spellEffect->EffectApplyAuraName])(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown); switch (procResult) { case SPELL_AURA_PROC_CANT_TRIGGER: @@ -10398,7 +10447,7 @@ bool Unit::hasNegativeAuraWithInterruptFlag(uint32 flag) { for (SpellAuraHolderMap::const_iterator iter = m_spellAuraHolders.begin(); iter != m_spellAuraHolders.end(); ++iter) { - if (!iter->second->IsPositive() && iter->second->GetSpellProto()->AuraInterruptFlags & flag) + if (!iter->second->IsPositive() && iter->second->GetSpellProto()->GetAuraInterruptFlags() & flag) return true; } return false; diff --git a/src/game/Unit.h b/src/game/Unit.h index 07b456de1..8eb112bc2 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -479,8 +479,8 @@ enum CombatRating CR_HIT_TAKEN_MELEE = 11, CR_HIT_TAKEN_RANGED = 12, CR_HIT_TAKEN_SPELL = 13, - CR_CRIT_TAKEN_MELEE = 14, - CR_CRIT_TAKEN_RANGED = 15, + CR_CRIT_TAKEN_MELEE = 14, // COMBAT_RATING_RESILIENCE_CRIT_TAKEN + CR_CRIT_TAKEN_RANGED = 15, // COMBAT_RATING_RESILIENCE_PLAYER_DAMAGE_TAKEN CR_CRIT_TAKEN_SPELL = 16, CR_HASTE_MELEE = 17, CR_HASTE_RANGED = 18, @@ -489,10 +489,11 @@ enum CombatRating CR_WEAPON_SKILL_OFFHAND = 21, CR_WEAPON_SKILL_RANGED = 22, CR_EXPERTISE = 23, - CR_ARMOR_PENETRATION = 24 + CR_ARMOR_PENETRATION = 24, + CR_MASTERY = 25 }; -#define MAX_COMBAT_RATING 25 +#define MAX_COMBAT_RATING 26 /// internal used flags for marking special auras - for example some dummy-auras enum UnitAuraFlags @@ -562,6 +563,9 @@ enum UnitFlags2 UNIT_FLAG2_UNK9 = 0x00000200, UNIT_FLAG2_DISARM_RANGED = 0x00000400, UNIT_FLAG2_REGENERATE_POWER = 0x00000800, + UNIT_FLAG2_WORGEN_TRANSFORM = 0x00080000, // transform to worgen + UNIT_FLAG2_WORGEN_TRANSFORM2 = 0x00100000, // transform to worgen, but less animation? + UNIT_FLAG2_WORGEN_TRANSFORM3 = 0x00200000 // transform to worgen, but less animation? }; /// Non Player Character flags diff --git a/src/game/UnitAuraProcHandler.cpp b/src/game/UnitAuraProcHandler.cpp index 0ebdc5f98..877094446 100644 --- a/src/game/UnitAuraProcHandler.cpp +++ b/src/game/UnitAuraProcHandler.cpp @@ -360,10 +360,10 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit* pVictim, SpellAuraHolder* holder, S // Get EventProcFlag uint32 EventProcFlag; - if (spellProcEvent && spellProcEvent->procFlags) // if exist get custom spellProcEvent->procFlags + if (spellProcEvent && spellProcEvent->procFlags) // if exist get custom spellProcEvent->procFlags EventProcFlag = spellProcEvent->procFlags; else - EventProcFlag = spellProto->procFlags; // else get from spell proto + EventProcFlag = spellProto->GetProcFlags(); // else get from spell proto // Continue if no trigger exist if (!EventProcFlag) return false; @@ -390,7 +390,9 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit* pVictim, SpellAuraHolder* holder, S // Check if current equipment allows aura to proc if (!isVictim && GetTypeId() == TYPEID_PLAYER) { - if (spellProto->EquippedItemClass == ITEM_CLASS_WEAPON) + SpellEquippedItemsEntry const* eqItems = spellProto->GetSpellEquippedItems(); + + if(eqItems && eqItems->EquippedItemClass == ITEM_CLASS_WEAPON) { Item* item = NULL; if (attType == BASE_ATTACK) @@ -400,19 +402,19 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit* pVictim, SpellAuraHolder* holder, S else item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED); - if (!item || item->IsBroken() || item->GetProto()->Class != ITEM_CLASS_WEAPON || !((1 << item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) + if(!item || item->IsBroken() || item->GetProto()->Class != ITEM_CLASS_WEAPON || !((1<GetProto()->SubClass) & eqItems->EquippedItemSubClassMask)) return false; } - else if (spellProto->EquippedItemClass == ITEM_CLASS_ARMOR) + else if(eqItems && eqItems->EquippedItemClass == ITEM_CLASS_ARMOR) { // Check if player is wearing shield - Item* item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); - if (!item || item->IsBroken() || !CanUseEquippedWeapon(OFF_ATTACK) || item->GetProto()->Class != ITEM_CLASS_ARMOR || !((1 << item->GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) + Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); + if(!item || item->IsBroken() || !CanUseEquippedWeapon(OFF_ATTACK) || item->GetProto()->Class != ITEM_CLASS_ARMOR || !((1<GetProto()->SubClass) & eqItems->EquippedItemSubClassMask)) return false; } } // Get chance from spell - float chance = (float)spellProto->procChance; + float chance = (float)spellProto->GetProcChance(); // If in spellProcEvent exist custom chance, chance = spellProcEvent->customChance; if (spellProcEvent && spellProcEvent->customChance) chance = spellProcEvent->customChance; @@ -443,7 +445,7 @@ SpellAuraProcResult Unit::HandleHasteAuraProc(Unit* pVictim, uint32 damage, Aura Unit* target = pVictim; int32 basepoints0 = 0; - switch (hasteSpell->SpellFamilyName) + switch(hasteSpell->GetSpellFamilyName()) { case SPELLFAMILY_ROGUE: { @@ -509,7 +511,7 @@ SpellAuraProcResult Unit::HandleSpellCritChanceAuraProc(Unit* pVictim, uint32 /* Unit* target = pVictim; int32 basepoints0 = 0; - switch (triggeredByAuraSpell->SpellFamilyName) + switch(triggeredByAuraSpell->GetSpellFamilyName()) { case SPELLFAMILY_MAGE: { @@ -562,19 +564,22 @@ SpellAuraProcResult Unit::HandleSpellCritChanceAuraProc(Unit* pVictim, uint32 /* SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown) { - SpellEntry const* dummySpell = triggeredByAura->GetSpellProto(); + SpellEntry const *dummySpell = triggeredByAura->GetSpellProto(); SpellEffectIndex effIndex = triggeredByAura->GetEffIndex(); + SpellEffectEntry const* dummySpellEffect = dummySpell->GetSpellEffect(effIndex); + SpellClassOptionsEntry const* dummyClassOptions = dummySpell->GetSpellClassOptions(); + SpellClassOptionsEntry const* procClassOptions = procSpell->GetSpellClassOptions(); int32 triggerAmount = triggeredByAura->GetModifier()->m_amount; Item* castItem = triggeredByAura->GetCastItemGuid() && GetTypeId() == TYPEID_PLAYER ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGuid()) : NULL; // some dummy spells have trigger spell in spell data already (from 3.0.3) - uint32 triggered_spell_id = dummySpell->EffectApplyAuraName[effIndex] == SPELL_AURA_DUMMY ? dummySpell->EffectTriggerSpell[effIndex] : 0; + uint32 triggered_spell_id = dummySpellEffect->EffectApplyAuraName == SPELL_AURA_DUMMY ? dummySpellEffect->EffectTriggerSpell : 0; Unit* target = pVictim; int32 basepoints[MAX_EFFECT_INDEX] = {0, 0, 0}; - switch (dummySpell->SpellFamilyName) + switch(dummySpell->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: { @@ -640,7 +645,8 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura { if (SpellEntry const* iterSpellProto = (*iter)->GetSpellProto()) { - if (iterSpellProto->SpellFamilyName == SPELLFAMILY_MAGE && (iterSpellProto->SpellFamilyFlags & UI64LIT(0x10000000))) + SpellClassOptionsEntry const* iterClassOptions = iterSpellProto->GetSpellClassOptions(); + if(iterClassOptions && iterClassOptions->SpellFamilyName == SPELLFAMILY_MAGE && (iterClassOptions->SpellFamilyFlags & UI64LIT(0x10000000))) { found = true; break; @@ -996,7 +1002,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura else if (aurHolder->GetStackAmount() + 1 == 6) CastSpell(this, 72523, true); // Shadowmourne Visual High // full stack - else if (aurHolder->GetStackAmount() + 1 >= aurHolder->GetSpellProto()->StackAmount) + else if (aurHolder->GetStackAmount() + 1 >= aurHolder->GetSpellProto()->GetStackAmount()) { RemoveAurasDueToSpell(triggered_spell_id); CastSpell(this, 71904, true); // Chaos Bane @@ -1028,9 +1034,9 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura return SPELL_AURA_PROC_FAILED; // mana cost save - int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100; - basepoints[0] = cost * triggerAmount / 100; - if (basepoints[0] <= 0) + int32 cost = procSpell->GetManaCost() + procSpell->GetManaCostPercentage() * GetCreateMana() / 100; + basepoints[0] = cost * triggerAmount/100; + if (basepoints[0] <=0) return SPELL_AURA_PROC_FAILED; target = this; @@ -1085,9 +1091,9 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura if (!procSpell) return SPELL_AURA_PROC_FAILED; - int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100; - basepoints[0] = cost * triggerAmount / 100; - if (basepoints[0] <= 0) + int32 cost = procSpell->GetManaCost() + procSpell->GetManaCostPercentage() * GetCreateMana() / 100; + basepoints[0] = cost * triggerAmount/100; + if (basepoints[0] <=0) return SPELL_AURA_PROC_FAILED; triggered_spell_id = 44450; target = this; @@ -1213,7 +1219,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura case SPELLFAMILY_WARLOCK: { // Seed of Corruption - if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000001000000000)) + if (dummyClassOptions && dummyClassOptions->SpellFamilyFlags & UI64LIT(0x0000001000000000)) { Modifier* mod = triggeredByAura->GetModifier(); // if damage is more than need or target die from damage deal finish spell @@ -1235,7 +1241,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura return SPELL_AURA_PROC_OK; } // Seed of Corruption (Mobs cast) - no die req - if (dummySpell->SpellFamilyFlags == UI64LIT(0x0) && dummySpell->SpellIconID == 1932) + if (dummyClassOptions && dummyClassOptions->SpellFamilyFlags == UI64LIT(0x0) && dummySpell->SpellIconID == 1932) { Modifier* mod = triggeredByAura->GetModifier(); // if damage is more than need deal finish spell @@ -1328,7 +1334,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura case SPELLFAMILY_PRIEST: { // Vampiric Touch - if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000040000000000)) + if (dummyClassOptions && dummyClassOptions->SpellFamilyFlags & UI64LIT(0x0000040000000000)) { if (!pVictim || !pVictim->isAlive()) return SPELL_AURA_PROC_FAILED; @@ -1414,10 +1420,10 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura case 40438: { // Shadow Word: Pain - if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000008000)) + if (procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000008000)) triggered_spell_id = 40441; // Renew - else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000010)) + else if (procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000010)) triggered_spell_id = 40440; else return SPELL_AURA_PROC_FAILED; @@ -1515,7 +1521,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura case 28719: { // mana back - basepoints[0] = int32(procSpell->manaCost * 30 / 100); + basepoints[0] = int32(procSpell->GetManaCost() * 30 / 100); target = this; triggered_spell_id = 28742; break; @@ -1541,19 +1547,19 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura float chance; // Starfire - if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000004)) + if (procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000004)) { triggered_spell_id = 40445; chance = 25.0f; } // Rejuvenation - else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000010)) + else if (procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000010)) { triggered_spell_id = 40446; chance = 25.0f; } // Mangle (Bear) and Mangle (Cat) - else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000044000000000)) + else if (procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x0000044000000000)) { triggered_spell_id = 40452; chance = 40.0f; @@ -1597,8 +1603,9 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura return SPELL_AURA_PROC_FAILED; float radius; - if (procSpell->EffectRadiusIndex[EFFECT_INDEX_0]) - radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(procSpell->EffectRadiusIndex[EFFECT_INDEX_0])); + SpellEffectEntry const* spellEffect = procSpell->GetSpellEffect(EFFECT_INDEX_0); + if (spellEffect && spellEffect->EffectRadiusIndex) + radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellEffect->EffectRadiusIndex)); else radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(procSpell->rangeIndex)); @@ -1649,7 +1656,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura return SPELL_AURA_PROC_FAILED; // Wrath crit - if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000001)) + if (procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000001)) { if (HasAura(48517)) return SPELL_AURA_PROC_FAILED; @@ -1660,7 +1667,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura break; } // Starfire crit - if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000004)) + if (procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000004)) { if (HasAura(48518)) return SPELL_AURA_PROC_FAILED; @@ -1686,7 +1693,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura // Clean Escape case 23582: // triggered spell have same masks and etc with main Vanish spell - if (!procSpell || procSpell->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_NONE) + if (!procSpell || procSpell->GetSpellEffectIdByIndex(EFFECT_INDEX_0) == SPELL_EFFECT_NONE) return SPELL_AURA_PROC_FAILED; triggered_spell_id = 23583; break; @@ -1720,9 +1727,10 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura AuraList const& sd = GetAurasByType(SPELL_AURA_MOD_MELEE_HASTE); for (AuraList::const_iterator itr = sd.begin(); itr != sd.end(); ++itr) { - SpellEntry const* spellProto = (*itr)->GetSpellProto(); - if (spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && - (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000040000))) + SpellEntry const *spellProto = (*itr)->GetSpellProto(); + SpellClassOptionsEntry const* itrClassOptions = spellProto->GetSpellClassOptions(); + if (itrClassOptions && itrClassOptions->SpellFamilyName == SPELLFAMILY_ROGUE && + (itrClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000040000))) { (*itr)->GetHolder()->RefreshHolder(); return SPELL_AURA_PROC_OK; @@ -1743,7 +1751,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura return SPELL_AURA_PROC_FAILED; // energy cost save - basepoints[0] = procSpell->manaCost * triggerAmount / 100; + basepoints[0] = procSpell->GetManaCost() * triggerAmount/100; if (basepoints[0] <= 0) return SPELL_AURA_PROC_FAILED; @@ -1762,8 +1770,8 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura return SPELL_AURA_PROC_FAILED; // mana cost save - int32 mana = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100; - basepoints[0] = mana * 40 / 100; + int32 mana = procSpell->GetManaCost() + procSpell->GetManaCostPercentage() * GetCreateMana() / 100; + basepoints[0] = mana * 40/100; if (basepoints[0] <= 0) return SPELL_AURA_PROC_FAILED; @@ -1792,7 +1800,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura if (dummySpell->SpellIconID == 3560) { // This effect only from Rapid Killing (mana regen) - if (!(procSpell->SpellFamilyFlags & UI64LIT(0x0100000000000000))) + if (!(procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x0100000000000000))) return SPELL_AURA_PROC_FAILED; target = this; @@ -1826,7 +1834,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura case SPELLFAMILY_PALADIN: { // Seal of Righteousness - melee proc dummy (addition ${$MWS*(0.022*$AP+0.044*$SPH)} damage) - if ((dummySpell->SpellFamilyFlags & UI64LIT(0x000000008000000)) && effIndex == EFFECT_INDEX_0) + if (dummyClassOptions && (dummyClassOptions->SpellFamilyFlags & UI64LIT(0x000000008000000)) && effIndex == EFFECT_INDEX_0) { triggered_spell_id = 25742; float ap = GetTotalAttackPowerValue(BASE_ATTACK); @@ -1982,7 +1990,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura case 31877: case 31878: // triggered only at casted Judgement spells, not at additional Judgement effects - if (!procSpell || procSpell->Category != 1210) + if(!procSpell || procSpell->GetCategory() != 1210) return SPELL_AURA_PROC_FAILED; target = this; @@ -2000,7 +2008,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura float chance; // Flash of light/Holy light - if (procSpell->SpellFamilyFlags & UI64LIT(0x00000000C0000000)) + if (procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x00000000C0000000)) { triggered_spell_id = 40471; chance = 15.0f; @@ -2090,7 +2098,15 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura case 58597: { triggered_spell_id = 66922; - basepoints[0] = int32(damage / GetSpellAuraMaxTicks(triggered_spell_id)); + SpellEntry const* triggeredEntry = sSpellStore.LookupEntry(triggered_spell_id); + if (!triggeredEntry) + return SPELL_AURA_PROC_FAILED; + + SpellEffectEntry const* spellEffect = triggeredEntry->GetSpellEffect(EFFECT_INDEX_0); + if(!spellEffect) + return SPELL_AURA_PROC_FAILED; + + basepoints[0] = int32(damage / (GetSpellDuration(triggeredEntry) / spellEffect->EffectAmplitude)); target = this; break; } @@ -2118,7 +2134,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura SpellEntry const* mote = sSpellStore.LookupEntry(71432); if (!mote) return SPELL_AURA_PROC_FAILED; - uint32 maxStack = mote->StackAmount - (dummySpell->Id == 71545 ? 1 : 0); + uint32 maxStack = mote->GetStackAmount() - (dummySpell->Id == 71545 ? 1 : 0); SpellAuraHolder* aurHolder = GetSpellAuraHolder(71432); if (aurHolder && uint32(aurHolder->GetStackAmount() + 1) >= maxStack) @@ -2289,18 +2305,18 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura if (!procSpell) return SPELL_AURA_PROC_FAILED; - float chance; - if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000001)) + float chance; + if (procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000001)) { triggered_spell_id = 40465; // Lightning Bolt chance = 15.0f; } - else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080)) + else if (procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000080)) { triggered_spell_id = 40465; // Lesser Healing Wave chance = 10.0f; } - else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000001000000000)) + else if (procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x0000001000000000)) { triggered_spell_id = 40466; // Stormstrike chance = 50.0f; @@ -2348,8 +2364,10 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura for (AuraList::const_iterator i = spellPower.begin(); i != spellPower.end(); ++i) { // select proper aura for format aura type in spell proto - if ((*i)->GetTarget() == totem && (*i)->GetSpellProto()->EffectApplyAuraName[(*i)->GetEffIndex()] == SPELL_AURA_MOD_HEALING_DONE && - (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (*i)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000004000000)) + SpellEffectEntry const* itrSpellEffect = (*i)->GetSpellProto()->GetSpellEffect((*i)->GetEffIndex()); + SpellClassOptionsEntry const* itrClassOptions = (*i)->GetSpellProto()->GetSpellClassOptions(); + if ((*i)->GetTarget()==totem && itrSpellEffect && itrSpellEffect->EffectApplyAuraName == SPELL_AURA_MOD_HEALING_DONE && + itrClassOptions && itrClassOptions->SpellFamilyName == SPELLFAMILY_SHAMAN && itrClassOptions->SpellFamilyFlags & UI64LIT(0x0000000004000000)) { basepoints[0] = triggerAmount * (*i)->GetModifier()->m_amount / 100; break; @@ -2408,7 +2426,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura break; } // Flametongue Weapon (Passive), Ranks - if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000000000200000)) + if (dummyClassOptions && dummyClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000200000)) { if (GetTypeId() != TYPEID_PLAYER || !castItem) return SPELL_AURA_PROC_FAILED; @@ -2436,7 +2454,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura break; } // Earth Shield - if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000040000000000)) + if (dummyClassOptions && dummyClassOptions->SpellFamilyFlags & UI64LIT(0x0000040000000000)) { target = this; basepoints[0] = triggerAmount; @@ -2461,19 +2479,21 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura return SPELL_AURA_PROC_FAILED; // Lesser Healing Wave need aditional 60% roll - if ((procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080)) && !roll_chance_i(60)) + if (procClassOptions && (procClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000080)) && !roll_chance_i(60)) return SPELL_AURA_PROC_FAILED; // Chain Heal needs additional 30% roll - if ((procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000100)) && !roll_chance_i(30)) + if (procClassOptions && (procClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000100)) && !roll_chance_i(30)) return SPELL_AURA_PROC_FAILED; // lookup water shield AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL); for (AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr) { - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && - ((*itr)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000002000000000))) + SpellClassOptionsEntry const* itrClassOptions = (*itr)->GetSpellProto()->GetSpellClassOptions(); + if (itrClassOptions && itrClassOptions->SpellFamilyName == SPELLFAMILY_SHAMAN && + (itrClassOptions->SpellFamilyFlags & UI64LIT(0x0000002000000000))) { - uint32 spell = (*itr)->GetSpellProto()->EffectTriggerSpell[(*itr)->GetEffIndex()]; + SpellEffectEntry const* itrSpellEffect = (*itr)->GetSpellProto()->GetSpellEffect((*itr)->GetEffIndex()); + uint32 spell = itrSpellEffect ? itrSpellEffect->EffectTriggerSpell : 0; CastSpell(this, spell, true, castItem, triggeredByAura); return SPELL_AURA_PROC_OK; } @@ -2524,7 +2544,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura } // Remove cooldown (Chain Lightning - have Category Recovery time) - if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000002)) + if (procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000002)) ((Player*)this)->RemoveSpellCooldown(spellId); CastSpell(pVictim, spellId, true, castItem, triggeredByAura); @@ -2541,8 +2561,9 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL); for (AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr) { - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && - ((*itr)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000400))) + SpellClassOptionsEntry const* itrClassOptions = (*itr)->GetSpellProto()->GetSpellClassOptions(); + if (itrClassOptions && itrClassOptions->SpellFamilyName == SPELLFAMILY_SHAMAN && + (itrClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000400))) { uint32 spell = 0; switch ((*itr)->GetId()) @@ -2618,7 +2639,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura break; } // Vendetta - if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000000000010000)) + if (dummyClassOptions && dummyClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000010000)) { basepoints[0] = triggerAmount * GetMaxHealth() / 100; triggered_spell_id = 50181; @@ -2791,12 +2812,15 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d { // Get triggered aura spell info SpellEntry const* auraSpellInfo = triggeredByAura->GetSpellProto(); + SpellClassOptionsEntry const* auraClassOptions = auraSpellInfo->GetSpellClassOptions(); + SpellClassOptionsEntry const* procClassOptions = procSpell->GetSpellClassOptions(); // Basepoints of trigger aura int32 triggerAmount = triggeredByAura->GetModifier()->m_amount; // Set trigger spell id, target, custom basepoints - uint32 trigger_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()]; + SpellEffectEntry const* spellEffect = auraSpellInfo->GetSpellEffect(triggeredByAura->GetEffIndex()); + uint32 trigger_spell_id = spellEffect ? spellEffect->EffectTriggerSpell : 0; Unit* target = NULL; int32 basepoints[MAX_EFFECT_INDEX] = {0, 0, 0}; @@ -2809,7 +2833,7 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d // Try handle unknown trigger spells // Custom requirements (not listed in procEx) Warning! damage dealing after this // Custom triggered spells - switch (auraSpellInfo->SpellFamilyName) + switch (auraSpellInfo->GetSpellFamilyName()) { case SPELLFAMILY_GENERIC: switch (auraSpellInfo->Id) @@ -3027,7 +3051,7 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d break; case SPELLFAMILY_WARRIOR: // Deep Wounds (replace triggered spells to directly apply DoT), dot spell have familyflags - if (auraSpellInfo->SpellFamilyFlags == UI64LIT(0x0) && auraSpellInfo->SpellIconID == 243) + if (auraClassOptions && auraClassOptions->SpellFamilyFlags == UI64LIT(0x0) && auraSpellInfo->SpellIconID == 243) { float weaponDamage; // DW should benefit of attack power, damage percent mods etc. @@ -3072,7 +3096,7 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d Unit::AuraList const& mDummyAura = GetAurasByType(SPELL_AURA_DUMMY); for (Unit::AuraList::const_iterator i = mDummyAura.begin(); i != mDummyAura.end(); ++i) { - if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (*i)->GetSpellProto()->SpellIconID == 113) + if ((*i)->GetSpellProto()->GetSpellFamilyName() == SPELLFAMILY_WARLOCK && (*i)->GetSpellProto()->SpellIconID == 113) { // basepoints of trigger spell stored in dummyeffect of spellProto int32 basepoints = GetMaxPower(POWER_MANA) * (*i)->GetSpellProto()->CalculateSimpleValue(EFFECT_INDEX_2) / 100; @@ -3219,7 +3243,7 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d else if (auraSpellInfo->Id == 53228 || auraSpellInfo->Id == 53232) { // This effect only from Rapid Fire (ability cast) - if (!(procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000020))) + if (!(procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000020))) return SPELL_AURA_PROC_FAILED; } // Lock and Load @@ -3275,7 +3299,7 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d // procspell is triggered spell but we need mana cost of original casted spell uint32 originalSpellId = procSpell->Id; // Holy Shock heal - if (procSpell->SpellFamilyFlags & UI64LIT(0x0001000000000000)) + if (procClassOptions && procClassOptions->SpellFamilyFlags & UI64LIT(0x0001000000000000)) { switch (procSpell->Id) { @@ -3298,8 +3322,8 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d return SPELL_AURA_PROC_FAILED; } // percent stored in effect 1 (class scripts) base points - int32 cost = originalSpell->manaCost + originalSpell->ManaCostPercentage * GetCreateMana() / 100; - basepoints[0] = cost * auraSpellInfo->CalculateSimpleValue(EFFECT_INDEX_1) / 100; + int32 cost = originalSpell->GetManaCost() + originalSpell->GetManaCostPercentage() * GetCreateMana() / 100; + basepoints[0] = cost*auraSpellInfo->CalculateSimpleValue(EFFECT_INDEX_1)/100; trigger_spell_id = 20272; target = this; } @@ -3350,7 +3374,7 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d case SPELLFAMILY_SHAMAN: { // Lightning Shield (overwrite non existing triggered spell call in spell.dbc - if (auraSpellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000400)) + if (auraClassOptions && auraClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000400)) { switch (auraSpellInfo->Id) { @@ -3395,7 +3419,7 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d { if (!procSpell) return SPELL_AURA_PROC_FAILED; - basepoints[0] = procSpell->manaCost * 35 / 100; + basepoints[0] = procSpell->GetManaCost() * 35 / 100; trigger_spell_id = 23571; target = this; } @@ -3519,7 +3543,8 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d // Enlightenment (trigger only from mana cost spells) case 35095: { - if (!procSpell || procSpell->powerType != POWER_MANA || (procSpell->manaCost == 0 && procSpell->ManaCostPercentage == 0 && procSpell->manaCostPerlevel == 0)) + SpellPowerEntry const* spellPower = procSpell->GetSpellPower(); + if(!spellPower || !procSpell || procSpell->powerType!=POWER_MANA || spellPower->manaCost==0 && spellPower->ManaCostPercentage==0 && spellPower->manaCostPerlevel==0) return SPELL_AURA_PROC_FAILED; break; } @@ -3576,7 +3601,7 @@ SpellAuraProcResult Unit::HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 d if (!procSpell) return SPELL_AURA_PROC_FAILED; // For trigger from Blizzard need exist Improved Blizzard - if (procSpell->SpellFamilyName == SPELLFAMILY_MAGE && (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080))) + if (procClassOptions && procClassOptions->SpellFamilyName==SPELLFAMILY_MAGE && (procClassOptions->SpellFamilyFlags & UI64LIT(0x0000000000000080))) { bool found = false; AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); @@ -3808,9 +3833,10 @@ SpellAuraProcResult Unit::HandleMendingAuraProc(Unit* /*pVictim*/, uint32 /*dama // next target selection if (jumps > 0 && GetTypeId() == TYPEID_PLAYER && caster_guid.IsPlayer()) { + SpellEffectEntry const* spellEffect = spellProto->GetSpellEffect(effIdx); float radius; - if (spellProto->EffectRadiusIndex[effIdx]) - radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx])); + if (spellEffect && spellEffect->EffectRadiusIndex) + radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellEffect->EffectRadiusIndex)); else radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex)); @@ -3865,15 +3891,15 @@ SpellAuraProcResult Unit::HandleModPowerCostSchoolAuraProc(Unit* /*pVictim*/, ui { // Skip melee hits and spells ws wrong school or zero cost return !(procSpell == NULL || - (procSpell->manaCost == 0 && procSpell->ManaCostPercentage == 0) || // Cost check - (triggeredByAura->GetModifier()->m_miscvalue & procSpell->SchoolMask) == 0) ? SPELL_AURA_PROC_OK : SPELL_AURA_PROC_FAILED; // School check + (procSpell->GetManaCost() == 0 && procSpell->GetManaCostPercentage() == 0) || // Cost check + (triggeredByAura->GetModifier()->m_miscvalue & procSpell->SchoolMask) == 0) ? SPELL_AURA_PROC_OK : SPELL_AURA_PROC_FAILED; // School check } SpellAuraProcResult Unit::HandleMechanicImmuneResistanceAuraProc(Unit* /*pVictim*/, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 /*cooldown*/) { // Compare mechanic - return !(procSpell == NULL || int32(procSpell->Mechanic) != triggeredByAura->GetModifier()->m_miscvalue) - ? SPELL_AURA_PROC_OK : SPELL_AURA_PROC_FAILED; + return !(procSpell==NULL || int32(procSpell->GetMechanic()) != triggeredByAura->GetModifier()->m_miscvalue) + ? SPELL_AURA_PROC_OK : SPELL_AURA_PROC_FAILED; } SpellAuraProcResult Unit::HandleModDamageFromCasterAuraProc(Unit* pVictim, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const* /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 /*cooldown*/) @@ -3913,7 +3939,7 @@ SpellAuraProcResult Unit::HandleAddPctModifierAuraProc(Unit* /*pVictim*/, uint32 Item* castItem = triggeredByAura->GetCastItemGuid() && GetTypeId() == TYPEID_PLAYER ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGuid()) : NULL; - switch (spellInfo->SpellFamilyName) + switch(spellInfo->GetSpellFamilyName()) { case SPELLFAMILY_MAGE: { @@ -3937,7 +3963,10 @@ SpellAuraProcResult Unit::HandleAddPctModifierAuraProc(Unit* /*pVictim*/, uint32 // Lookup base amount mana restore for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (procSpell->Effect[i] == SPELL_EFFECT_ENERGIZE) + SpellEffectEntry const* spellEffect = procSpell->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; + if (spellEffect->Effect == SPELL_EFFECT_ENERGIZE) { int32 mana = procSpell->CalculateSimpleValue(SpellEffectIndex(i)); CastCustomSpell(this, 54986, NULL, &mana, NULL, true, castItem, triggeredByAura); @@ -3959,7 +3988,8 @@ SpellAuraProcResult Unit::HandleModDamagePercentDoneAuraProc(Unit* /*pVictim*/, ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGuid()) : NULL; // Aspect of the Viper - if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && spellInfo->SpellFamilyFlags & UI64LIT(0x4000000000000)) + SpellClassOptionsEntry const* classOptions = spellInfo->GetSpellClassOptions(); + if (classOptions && classOptions->SpellFamilyName == SPELLFAMILY_HUNTER && classOptions->SpellFamilyFlags & UI64LIT(0x4000000000000)) { uint32 maxmana = GetMaxPower(POWER_MANA); int32 bp = int32(maxmana * GetAttackTime(RANGED_ATTACK) / 1000.0f / 100.0f); @@ -3970,7 +4000,7 @@ SpellAuraProcResult Unit::HandleModDamagePercentDoneAuraProc(Unit* /*pVictim*/, CastCustomSpell(this, 34075, &bp, NULL, NULL, true, castItem, triggeredByAura); } // Arcane Blast - else if (spellInfo->Id == 36032 && procSpell->SpellFamilyName == SPELLFAMILY_MAGE && procSpell->SpellIconID == 2294) + else if (spellInfo->Id == 36032 && procSpell->GetSpellFamilyName() == SPELLFAMILY_MAGE && procSpell->SpellIconID == 2294) // prevent proc from self(spell that triggered this aura) return SPELL_AURA_PROC_FAILED; @@ -4007,7 +4037,8 @@ SpellAuraProcResult Unit::HandleSpellMagnetAuraProc(Unit* /*pVictim*/, uint32 da SpellAuraProcResult Unit::HandleManaShieldAuraProc(Unit* pVictim, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const* /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown) { - SpellEntry const* dummySpell = triggeredByAura->GetSpellProto(); + SpellEntry const *dummySpell = triggeredByAura->GetSpellProto (); + SpellClassOptionsEntry const* dummyClassOptions = dummySpell->GetSpellClassOptions(); Item* castItem = triggeredByAura->GetCastItemGuid() && GetTypeId() == TYPEID_PLAYER ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGuid()) : NULL; @@ -4015,12 +4046,12 @@ SpellAuraProcResult Unit::HandleManaShieldAuraProc(Unit* pVictim, uint32 /*damag uint32 triggered_spell_id = 0; Unit* target = pVictim; - switch (dummySpell->SpellFamilyName) + switch(dummyClassOptions->SpellFamilyName) { case SPELLFAMILY_MAGE: { // Incanter's Regalia set (add trigger chance to Mana Shield) - if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000000000008000)) + if (dummyClassOptions->IsFitToFamilyMask(UI64LIT(0x0000000000008000))) { if (GetTypeId() != TYPEID_PLAYER) return SPELL_AURA_PROC_FAILED; @@ -4091,4 +4122,4 @@ SpellAuraProcResult Unit::HandleRemoveByDamageChanceProc(Unit* /*pVictim*/, uint } return SPELL_AURA_PROC_FAILED; -} \ No newline at end of file +} diff --git a/src/game/UpdateFields.h b/src/game/UpdateFields.h index 5bec8787c..32cd40a4f 100644 --- a/src/game/UpdateFields.h +++ b/src/game/UpdateFields.h @@ -19,16 +19,17 @@ #ifndef _UPDATEFIELDS_AUTO_H #define _UPDATEFIELDS_AUTO_H -// Auto generated for version 3, 3, 5, 12340 +// Auto generated for version 4, 0, 3, 13287 enum EObjectFields { OBJECT_FIELD_GUID = 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC - OBJECT_FIELD_TYPE = 0x0002, // Size: 1, Type: INT, Flags: PUBLIC + OBJECT_FIELD_TYPE = 0x0002, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC OBJECT_FIELD_ENTRY = 0x0003, // Size: 1, Type: INT, Flags: PUBLIC OBJECT_FIELD_SCALE_X = 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC - OBJECT_FIELD_PADDING = 0x0005, // Size: 1, Type: INT, Flags: NONE - OBJECT_END = 0x0006, + OBJECT_FIELD_DATA = 0x0005, // Size: 2, Type: LONG, Flags: PUBLIC + OBJECT_FIELD_PADDING = 0x0007, // Size: 1, Type: INT, Flags: NONE + OBJECT_END = 0x0008, }; enum EItemFields @@ -65,13 +66,17 @@ enum EItemFields ITEM_FIELD_ENCHANTMENT_11_3 = OBJECT_END + 0x0030, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC ITEM_FIELD_ENCHANTMENT_12_1 = OBJECT_END + 0x0031, // Size: 2, Type: INT, Flags: PUBLIC ITEM_FIELD_ENCHANTMENT_12_3 = OBJECT_END + 0x0033, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC - ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC - ITEM_FIELD_DURABILITY = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER - ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER - ITEM_FIELD_CREATE_PLAYED_TIME = OBJECT_END + 0x0038, // Size: 1, Type: INT, Flags: PUBLIC - ITEM_FIELD_PAD = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: NONE - ITEM_END = OBJECT_END + 0x003A, + ITEM_FIELD_ENCHANTMENT_13_1 = OBJECT_END + 0x0034, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_13_3 = OBJECT_END + 0x0036, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_14_1 = OBJECT_END + 0x0037, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_14_3 = OBJECT_END + 0x0039, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x003A, // Size: 1, Type: INT, Flags: PUBLIC + ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x003B, // Size: 1, Type: INT, Flags: PUBLIC + ITEM_FIELD_DURABILITY = OBJECT_END + 0x003C, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER + ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER + ITEM_FIELD_CREATE_PLAYED_TIME = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC + ITEM_FIELD_PAD = OBJECT_END + 0x003F, // Size: 1, Type: INT, Flags: NONE + ITEM_END = OBJECT_END + 0x0040, }; enum EContainerFields @@ -102,295 +107,407 @@ enum EUnitFields UNIT_FIELD_POWER5 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC UNIT_FIELD_POWER6 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC UNIT_FIELD_POWER7 = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001E, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001F, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER6 = OBJECT_END + 0x0020, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER7 = OBJECT_END + 0x0021, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER = OBJECT_END + 0x0022, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER = OBJECT_END + 0x0029, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_LEVEL = OBJECT_END + 0x0030, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x0031, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x0032, // Size: 3, Type: INT, Flags: PUBLIC - UNIT_FIELD_FLAGS = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_AURASTATE = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x0038, // Size: 2, Type: INT, Flags: PUBLIC - UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x003A, // Size: 1, Type: INT, Flags: PRIVATE - UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x003B, // Size: 1, Type: FLOAT, Flags: PUBLIC - UNIT_FIELD_COMBATREACH = OBJECT_END + 0x003C, // Size: 1, Type: FLOAT, Flags: PUBLIC - UNIT_FIELD_DISPLAYID = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x003F, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x0040, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER - UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0041, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER - UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0042, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER - UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0043, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER - UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0044, // Size: 1, Type: BYTES, Flags: PUBLIC - UNIT_FIELD_PETNUMBER = OBJECT_END + 0x0045, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x0046, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x0047, // Size: 1, Type: INT, Flags: OWNER - UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x0048, // Size: 1, Type: INT, Flags: OWNER - UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x0049, // Size: 1, Type: INT, Flags: DYNAMIC - UNIT_MOD_CAST_SPEED = OBJECT_END + 0x004A, // Size: 1, Type: FLOAT, Flags: PUBLIC - UNIT_CREATED_BY_SPELL = OBJECT_END + 0x004B, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_NPC_FLAGS = OBJECT_END + 0x004C, // Size: 1, Type: INT, Flags: DYNAMIC - UNIT_NPC_EMOTESTATE = OBJECT_END + 0x004D, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_STAT0 = OBJECT_END + 0x004E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_STAT1 = OBJECT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_STAT2 = OBJECT_END + 0x0050, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_STAT3 = OBJECT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_STAT4 = OBJECT_END + 0x0052, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x0057, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x0058, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x005A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x005C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_RESISTANCES = OBJECT_END + 0x005D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER, PARTY_LEADER - UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x0064, // Size: 7, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x006B, // Size: 7, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_BASE_MANA = OBJECT_END + 0x0072, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x0073, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_BYTES_2 = OBJECT_END + 0x0074, // Size: 1, Type: BYTES, Flags: PUBLIC - UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x0075, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x0076, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER - UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0077, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x0078, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x0079, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER - UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x007A, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x007B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x007C, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x007D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x0084, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x008B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x008C, // Size: 1, Type: FLOAT, Flags: PUBLIC - UNIT_FIELD_PADDING = OBJECT_END + 0x008D, // Size: 1, Type: INT, Flags: NONE - UNIT_END = OBJECT_END + 0x008E, + UNIT_FIELD_POWER8 = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER9 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER10 = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER11 = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x001E, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x001F, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x0020, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x0021, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x0022, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x0023, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER6 = OBJECT_END + 0x0024, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER7 = OBJECT_END + 0x0025, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER8 = OBJECT_END + 0x0026, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER9 = OBJECT_END + 0x0027, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER10 = OBJECT_END + 0x0028, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER11 = OBJECT_END + 0x0029, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER = OBJECT_END + 0x002A, // Size: 11, Type: FLOAT, Flags: PRIVATE, OWNER + UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER = OBJECT_END + 0x0035, // Size: 11, Type: FLOAT, Flags: PRIVATE, OWNER + UNIT_FIELD_LEVEL = OBJECT_END + 0x0040, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x0041, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x0042, // Size: 3, Type: INT, Flags: PUBLIC + UNIT_FIELD_FLAGS = OBJECT_END + 0x0045, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0046, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_AURASTATE = OBJECT_END + 0x0047, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x0048, // Size: 2, Type: INT, Flags: PUBLIC + UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x004A, // Size: 1, Type: INT, Flags: PRIVATE + UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x004B, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_FIELD_COMBATREACH = OBJECT_END + 0x004C, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_FIELD_DISPLAYID = OBJECT_END + 0x004D, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x004E, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x004F, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x0050, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER + UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0051, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER + UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0052, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER + UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0053, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER + UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0054, // Size: 1, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_PETNUMBER = OBJECT_END + 0x0055, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x0056, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x0057, // Size: 1, Type: INT, Flags: OWNER + UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x0058, // Size: 1, Type: INT, Flags: OWNER + UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x0059, // Size: 1, Type: INT, Flags: DYNAMIC + UNIT_MOD_CAST_SPEED = OBJECT_END + 0x005A, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_CREATED_BY_SPELL = OBJECT_END + 0x005B, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_NPC_FLAGS = OBJECT_END + 0x005C, // Size: 1, Type: INT, Flags: DYNAMIC + UNIT_NPC_EMOTESTATE = OBJECT_END + 0x005D, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_STAT0 = OBJECT_END + 0x005E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_STAT1 = OBJECT_END + 0x005F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_STAT2 = OBJECT_END + 0x0060, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_STAT3 = OBJECT_END + 0x0061, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_STAT4 = OBJECT_END + 0x0062, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x0063, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x0064, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x0065, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x0066, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x0067, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x0068, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x0069, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x006A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x006B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x006C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_RESISTANCES = OBJECT_END + 0x006D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER, PARTY_LEADER + UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x0074, // Size: 7, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x007B, // Size: 7, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_BASE_MANA = OBJECT_END + 0x0082, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x0083, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_BYTES_2 = OBJECT_END + 0x0084, // Size: 1, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x0085, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_ATTACK_POWER_MOD_POS = OBJECT_END + 0x0086, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_ATTACK_POWER_MOD_NEG = OBJECT_END + 0x0087, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0088, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER + UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x0089, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS = OBJECT_END + 0x008A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG = OBJECT_END + 0x008B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x008C, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER + UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x008D, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER + UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x008E, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER + UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x008F, // Size: 7, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x0096, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER + UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x009D, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER + UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x009E, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_FIELD_MAXITEMLEVEL = OBJECT_END + 0x009F, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_END = OBJECT_END + 0x00A0, PLAYER_DUEL_ARBITER = UNIT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC PLAYER_FLAGS = UNIT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_GUILDID = UNIT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_GUILDRANK = UNIT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_BYTES = UNIT_END + 0x0005, // Size: 1, Type: BYTES, Flags: PUBLIC - PLAYER_BYTES_2 = UNIT_END + 0x0006, // Size: 1, Type: BYTES, Flags: PUBLIC - PLAYER_BYTES_3 = UNIT_END + 0x0007, // Size: 1, Type: BYTES, Flags: PUBLIC - PLAYER_DUEL_TEAM = UNIT_END + 0x0008, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_GUILD_TIMESTAMP = UNIT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_QUEST_LOG_1_1 = UNIT_END + 0x000A, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_1_2 = UNIT_END + 0x000B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_1_3 = UNIT_END + 0x000C, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_1_4 = UNIT_END + 0x000E, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_2_1 = UNIT_END + 0x000F, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_2_2 = UNIT_END + 0x0010, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_2_3 = UNIT_END + 0x0011, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_2_5 = UNIT_END + 0x0013, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_3_1 = UNIT_END + 0x0014, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_3_2 = UNIT_END + 0x0015, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_3_3 = UNIT_END + 0x0016, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_3_5 = UNIT_END + 0x0018, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_4_1 = UNIT_END + 0x0019, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_4_2 = UNIT_END + 0x001A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_4_3 = UNIT_END + 0x001B, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_4_5 = UNIT_END + 0x001D, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_5_1 = UNIT_END + 0x001E, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_5_2 = UNIT_END + 0x001F, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_5_3 = UNIT_END + 0x0020, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_5_5 = UNIT_END + 0x0022, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_6_1 = UNIT_END + 0x0023, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_6_2 = UNIT_END + 0x0024, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_6_3 = UNIT_END + 0x0025, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_6_5 = UNIT_END + 0x0027, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_7_1 = UNIT_END + 0x0028, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_7_2 = UNIT_END + 0x0029, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_7_3 = UNIT_END + 0x002A, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_7_5 = UNIT_END + 0x002C, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_8_1 = UNIT_END + 0x002D, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_8_2 = UNIT_END + 0x002E, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_8_3 = UNIT_END + 0x002F, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_8_5 = UNIT_END + 0x0031, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_9_1 = UNIT_END + 0x0032, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_9_2 = UNIT_END + 0x0033, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_9_3 = UNIT_END + 0x0034, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_9_5 = UNIT_END + 0x0036, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_10_1 = UNIT_END + 0x0037, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_10_2 = UNIT_END + 0x0038, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_10_3 = UNIT_END + 0x0039, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_10_5 = UNIT_END + 0x003B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_11_1 = UNIT_END + 0x003C, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_11_2 = UNIT_END + 0x003D, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_11_3 = UNIT_END + 0x003E, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_11_5 = UNIT_END + 0x0040, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_12_1 = UNIT_END + 0x0041, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_12_2 = UNIT_END + 0x0042, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_12_3 = UNIT_END + 0x0043, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_12_5 = UNIT_END + 0x0045, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_13_1 = UNIT_END + 0x0046, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_13_2 = UNIT_END + 0x0047, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_13_3 = UNIT_END + 0x0048, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_13_5 = UNIT_END + 0x004A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_14_1 = UNIT_END + 0x004B, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_14_2 = UNIT_END + 0x004C, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_14_3 = UNIT_END + 0x004D, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_14_5 = UNIT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_15_1 = UNIT_END + 0x0050, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_15_2 = UNIT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_15_3 = UNIT_END + 0x0052, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_15_5 = UNIT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_16_1 = UNIT_END + 0x0055, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_16_2 = UNIT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_16_3 = UNIT_END + 0x0057, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_16_5 = UNIT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_17_1 = UNIT_END + 0x005A, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_17_2 = UNIT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_17_3 = UNIT_END + 0x005C, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_17_5 = UNIT_END + 0x005E, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_18_1 = UNIT_END + 0x005F, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_18_2 = UNIT_END + 0x0060, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_18_3 = UNIT_END + 0x0061, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_18_5 = UNIT_END + 0x0063, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_19_1 = UNIT_END + 0x0064, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_19_2 = UNIT_END + 0x0065, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_19_3 = UNIT_END + 0x0066, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_19_5 = UNIT_END + 0x0068, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_20_1 = UNIT_END + 0x0069, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_20_2 = UNIT_END + 0x006A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_20_3 = UNIT_END + 0x006B, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_20_5 = UNIT_END + 0x006D, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_21_1 = UNIT_END + 0x006E, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_21_2 = UNIT_END + 0x006F, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_21_3 = UNIT_END + 0x0070, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_21_5 = UNIT_END + 0x0072, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_22_1 = UNIT_END + 0x0073, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_22_2 = UNIT_END + 0x0074, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_22_3 = UNIT_END + 0x0075, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_22_5 = UNIT_END + 0x0077, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_23_1 = UNIT_END + 0x0078, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_23_2 = UNIT_END + 0x0079, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_23_3 = UNIT_END + 0x007A, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_23_5 = UNIT_END + 0x007C, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_24_1 = UNIT_END + 0x007D, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_24_2 = UNIT_END + 0x007E, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_24_3 = UNIT_END + 0x007F, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_24_5 = UNIT_END + 0x0081, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_25_1 = UNIT_END + 0x0082, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_25_2 = UNIT_END + 0x0083, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_25_3 = UNIT_END + 0x0084, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_25_5 = UNIT_END + 0x0086, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_VISIBLE_ITEM_1_ENTRYID = UNIT_END + 0x0087, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_1_ENCHANTMENT = UNIT_END + 0x0088, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_2_ENTRYID = UNIT_END + 0x0089, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_2_ENCHANTMENT = UNIT_END + 0x008A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_3_ENTRYID = UNIT_END + 0x008B, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_3_ENCHANTMENT = UNIT_END + 0x008C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_4_ENTRYID = UNIT_END + 0x008D, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_4_ENCHANTMENT = UNIT_END + 0x008E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_5_ENTRYID = UNIT_END + 0x008F, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_5_ENCHANTMENT = UNIT_END + 0x0090, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_6_ENTRYID = UNIT_END + 0x0091, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_6_ENCHANTMENT = UNIT_END + 0x0092, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_7_ENTRYID = UNIT_END + 0x0093, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_7_ENCHANTMENT = UNIT_END + 0x0094, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_8_ENTRYID = UNIT_END + 0x0095, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_8_ENCHANTMENT = UNIT_END + 0x0096, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_9_ENTRYID = UNIT_END + 0x0097, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_9_ENCHANTMENT = UNIT_END + 0x0098, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_10_ENTRYID = UNIT_END + 0x0099, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_10_ENCHANTMENT = UNIT_END + 0x009A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_11_ENTRYID = UNIT_END + 0x009B, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_11_ENCHANTMENT = UNIT_END + 0x009C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_12_ENTRYID = UNIT_END + 0x009D, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_12_ENCHANTMENT = UNIT_END + 0x009E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_13_ENTRYID = UNIT_END + 0x009F, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_13_ENCHANTMENT = UNIT_END + 0x00A0, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_14_ENTRYID = UNIT_END + 0x00A1, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_14_ENCHANTMENT = UNIT_END + 0x00A2, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_15_ENTRYID = UNIT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_15_ENCHANTMENT = UNIT_END + 0x00A4, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_16_ENTRYID = UNIT_END + 0x00A5, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_16_ENCHANTMENT = UNIT_END + 0x00A6, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_17_ENTRYID = UNIT_END + 0x00A7, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_17_ENCHANTMENT = UNIT_END + 0x00A8, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_18_ENTRYID = UNIT_END + 0x00A9, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_18_ENCHANTMENT = UNIT_END + 0x00AA, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_19_ENTRYID = UNIT_END + 0x00AB, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_19_ENCHANTMENT = UNIT_END + 0x00AC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_CHOSEN_TITLE = UNIT_END + 0x00AD, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_FAKE_INEBRIATION = UNIT_END + 0x00AE, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_FIELD_PAD_0 = UNIT_END + 0x00AF, // Size: 1, Type: INT, Flags: NONE - PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x00B0, // Size: 46, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x00DE, // Size: 32, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x00FE, // Size: 56, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x0136, // Size: 14, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x0144, // Size: 24, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x015C, // Size: 64, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_CURRENCYTOKEN_SLOT_1 = UNIT_END + 0x019C, // Size: 64, Type: LONG, Flags: PRIVATE - PLAYER_FARSIGHT = UNIT_END + 0x01DC, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x01DE, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x01E0, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER__FIELD_KNOWN_TITLES2 = UNIT_END + 0x01E2, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_KNOWN_CURRENCIES = UNIT_END + 0x01E4, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER_XP = UNIT_END + 0x01E6, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x01E7, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x01E8, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x0368, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x0369, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_TRACK_CREATURES = UNIT_END + 0x036A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_TRACK_RESOURCES = UNIT_END + 0x036B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x036C, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x036D, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x036E, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_EXPERTISE = UNIT_END + 0x036F, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x0370, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x0371, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x0372, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x0373, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x0374, // Size: 7, Type: FLOAT, Flags: PRIVATE - PLAYER_SHIELD_BLOCK = UNIT_END + 0x037B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x037C, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x037D, // Size: 128, Type: BYTES, Flags: PRIVATE - PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x03FD, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_COINAGE = UNIT_END + 0x03FE, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x03FF, // Size: 7, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x0406, // Size: 7, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x040D, // Size: 7, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x0414, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_HEALING_PCT = UNIT_END + 0x0415, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_FIELD_MOD_HEALING_DONE_PCT = UNIT_END + 0x0416, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x0417, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x0418, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BYTES = UNIT_END + 0x0419, // Size: 1, Type: BYTES, Flags: PRIVATE - PLAYER_AMMO_ID = UNIT_END + 0x041A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_SELF_RES_SPELL = UNIT_END + 0x041B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x041C, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x041D, // Size: 12, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x0429, // Size: 12, Type: INT, Flags: PRIVATE - PLAYER_FIELD_KILLS = UNIT_END + 0x0435, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x0436, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x0437, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x0438, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BYTES2 = UNIT_END + 0x0439, // Size: 1, Type: 6, Flags: PRIVATE - PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x043A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x043B, // Size: 25, Type: INT, Flags: PRIVATE - PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x0454, // Size: 21, Type: INT, Flags: PRIVATE - PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x0469, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x046A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x046B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x046C, // Size: 25, Type: INT, Flags: PRIVATE - PLAYER_RUNE_REGEN_1 = UNIT_END + 0x0485, // Size: 4, Type: FLOAT, Flags: PRIVATE - PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x0489, // Size: 3, Type: INT, Flags: PRIVATE - PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x048C, // Size: 6, Type: INT, Flags: PRIVATE - PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x0492, // Size: 6, Type: INT, Flags: PRIVATE - PLAYER_GLYPHS_ENABLED = UNIT_END + 0x0498, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_PET_SPELL_POWER = UNIT_END + 0x0499, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_END = UNIT_END + 0x049A, + PLAYER_GUILDRANK = UNIT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_GUILDDELETE_DATE = UNIT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_GUILDLEVEL = UNIT_END + 0x0005, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_BYTES = UNIT_END + 0x0006, // Size: 1, Type: BYTES, Flags: PUBLIC + PLAYER_BYTES_2 = UNIT_END + 0x0007, // Size: 1, Type: BYTES, Flags: PUBLIC + PLAYER_BYTES_3 = UNIT_END + 0x0008, // Size: 1, Type: BYTES, Flags: PUBLIC + PLAYER_DUEL_TEAM = UNIT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_GUILD_TIMESTAMP = UNIT_END + 0x000A, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_QUEST_LOG_1_1 = UNIT_END + 0x000B, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_1_2 = UNIT_END + 0x000C, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_1_3 = UNIT_END + 0x000D, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_1_4 = UNIT_END + 0x000F, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_2_1 = UNIT_END + 0x0010, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_2_2 = UNIT_END + 0x0011, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_2_3 = UNIT_END + 0x0012, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_2_5 = UNIT_END + 0x0014, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_3_1 = UNIT_END + 0x0015, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_3_2 = UNIT_END + 0x0016, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_3_3 = UNIT_END + 0x0017, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_3_5 = UNIT_END + 0x0019, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_4_1 = UNIT_END + 0x001A, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_4_2 = UNIT_END + 0x001B, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_4_3 = UNIT_END + 0x001C, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_4_5 = UNIT_END + 0x001E, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_5_1 = UNIT_END + 0x001F, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_5_2 = UNIT_END + 0x0020, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_5_3 = UNIT_END + 0x0021, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_5_5 = UNIT_END + 0x0023, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_6_1 = UNIT_END + 0x0024, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_6_2 = UNIT_END + 0x0025, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_6_3 = UNIT_END + 0x0026, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_6_5 = UNIT_END + 0x0028, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_7_1 = UNIT_END + 0x0029, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_7_2 = UNIT_END + 0x002A, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_7_3 = UNIT_END + 0x002B, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_7_5 = UNIT_END + 0x002D, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_8_1 = UNIT_END + 0x002E, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_8_2 = UNIT_END + 0x002F, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_8_3 = UNIT_END + 0x0030, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_8_5 = UNIT_END + 0x0032, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_9_1 = UNIT_END + 0x0033, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_9_2 = UNIT_END + 0x0034, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_9_3 = UNIT_END + 0x0035, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_9_5 = UNIT_END + 0x0037, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_10_1 = UNIT_END + 0x0038, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_10_2 = UNIT_END + 0x0039, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_10_3 = UNIT_END + 0x003A, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_10_5 = UNIT_END + 0x003C, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_11_1 = UNIT_END + 0x003D, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_11_2 = UNIT_END + 0x003E, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_11_3 = UNIT_END + 0x003F, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_11_5 = UNIT_END + 0x0041, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_12_1 = UNIT_END + 0x0042, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_12_2 = UNIT_END + 0x0043, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_12_3 = UNIT_END + 0x0044, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_12_5 = UNIT_END + 0x0046, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_13_1 = UNIT_END + 0x0047, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_13_2 = UNIT_END + 0x0048, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_13_3 = UNIT_END + 0x0049, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_13_5 = UNIT_END + 0x004B, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_14_1 = UNIT_END + 0x004C, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_14_2 = UNIT_END + 0x004D, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_14_3 = UNIT_END + 0x004E, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_14_5 = UNIT_END + 0x0050, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_15_1 = UNIT_END + 0x0051, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_15_2 = UNIT_END + 0x0052, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_15_3 = UNIT_END + 0x0053, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_15_5 = UNIT_END + 0x0055, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_16_1 = UNIT_END + 0x0056, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_16_2 = UNIT_END + 0x0057, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_16_3 = UNIT_END + 0x0058, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_16_5 = UNIT_END + 0x005A, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_17_1 = UNIT_END + 0x005B, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_17_2 = UNIT_END + 0x005C, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_17_3 = UNIT_END + 0x005D, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_17_5 = UNIT_END + 0x005F, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_18_1 = UNIT_END + 0x0060, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_18_2 = UNIT_END + 0x0061, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_18_3 = UNIT_END + 0x0062, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_18_5 = UNIT_END + 0x0064, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_19_1 = UNIT_END + 0x0065, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_19_2 = UNIT_END + 0x0066, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_19_3 = UNIT_END + 0x0067, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_19_5 = UNIT_END + 0x0069, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_20_1 = UNIT_END + 0x006A, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_20_2 = UNIT_END + 0x006B, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_20_3 = UNIT_END + 0x006C, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_20_5 = UNIT_END + 0x006E, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_21_1 = UNIT_END + 0x006F, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_21_2 = UNIT_END + 0x0070, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_21_3 = UNIT_END + 0x0071, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_21_5 = UNIT_END + 0x0073, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_22_1 = UNIT_END + 0x0074, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_22_2 = UNIT_END + 0x0075, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_22_3 = UNIT_END + 0x0076, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_22_5 = UNIT_END + 0x0078, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_23_1 = UNIT_END + 0x0079, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_23_2 = UNIT_END + 0x007A, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_23_3 = UNIT_END + 0x007B, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_23_5 = UNIT_END + 0x007D, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_24_1 = UNIT_END + 0x007E, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_24_2 = UNIT_END + 0x007F, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_24_3 = UNIT_END + 0x0080, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_24_5 = UNIT_END + 0x0082, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_25_1 = UNIT_END + 0x0083, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_25_2 = UNIT_END + 0x0084, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_25_3 = UNIT_END + 0x0085, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_25_5 = UNIT_END + 0x0087, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_26_1 = UNIT_END + 0x0088, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_26_2 = UNIT_END + 0x0089, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_26_3 = UNIT_END + 0x008A, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_26_5 = UNIT_END + 0x008C, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_27_1 = UNIT_END + 0x008D, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_27_2 = UNIT_END + 0x008E, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_27_3 = UNIT_END + 0x008F, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_27_5 = UNIT_END + 0x0091, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_28_1 = UNIT_END + 0x0092, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_28_2 = UNIT_END + 0x0093, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_28_3 = UNIT_END + 0x0094, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_28_5 = UNIT_END + 0x0096, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_29_1 = UNIT_END + 0x0097, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_29_2 = UNIT_END + 0x0098, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_29_3 = UNIT_END + 0x0099, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_29_5 = UNIT_END + 0x009B, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_30_1 = UNIT_END + 0x009C, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_30_2 = UNIT_END + 0x009D, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_30_3 = UNIT_END + 0x009E, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_30_5 = UNIT_END + 0x00A0, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_31_1 = UNIT_END + 0x00A1, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_31_2 = UNIT_END + 0x00A2, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_31_3 = UNIT_END + 0x00A3, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_31_5 = UNIT_END + 0x00A5, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_32_1 = UNIT_END + 0x00A6, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_32_2 = UNIT_END + 0x00A7, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_32_3 = UNIT_END + 0x00A8, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_32_5 = UNIT_END + 0x00AA, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_33_1 = UNIT_END + 0x00AB, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_33_2 = UNIT_END + 0x00AC, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_33_3 = UNIT_END + 0x00AD, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_33_5 = UNIT_END + 0x00AF, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_34_1 = UNIT_END + 0x00B0, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_34_2 = UNIT_END + 0x00B1, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_34_3 = UNIT_END + 0x00B2, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_34_5 = UNIT_END + 0x00B4, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_35_1 = UNIT_END + 0x00B5, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_35_2 = UNIT_END + 0x00B6, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_35_3 = UNIT_END + 0x00B7, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_35_5 = UNIT_END + 0x00B9, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_36_1 = UNIT_END + 0x00BA, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_36_2 = UNIT_END + 0x00BB, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_36_3 = UNIT_END + 0x00BC, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_36_5 = UNIT_END + 0x00BE, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_37_1 = UNIT_END + 0x00BF, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_37_2 = UNIT_END + 0x00C0, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_37_3 = UNIT_END + 0x00C1, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_37_5 = UNIT_END + 0x00C3, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_38_1 = UNIT_END + 0x00C4, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_38_2 = UNIT_END + 0x00C5, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_38_3 = UNIT_END + 0x00C6, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_38_5 = UNIT_END + 0x00C8, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_39_1 = UNIT_END + 0x00C9, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_39_2 = UNIT_END + 0x00CA, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_39_3 = UNIT_END + 0x00CB, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_39_5 = UNIT_END + 0x00CD, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_40_1 = UNIT_END + 0x00CE, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_40_2 = UNIT_END + 0x00CF, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_40_3 = UNIT_END + 0x00D0, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_40_5 = UNIT_END + 0x00D2, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_41_1 = UNIT_END + 0x00D3, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_41_2 = UNIT_END + 0x00D4, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_41_3 = UNIT_END + 0x00D5, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_41_5 = UNIT_END + 0x00D7, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_42_1 = UNIT_END + 0x00D8, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_42_2 = UNIT_END + 0x00D9, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_42_3 = UNIT_END + 0x00DA, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_42_5 = UNIT_END + 0x00DC, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_43_1 = UNIT_END + 0x00DD, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_43_2 = UNIT_END + 0x00DE, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_43_3 = UNIT_END + 0x00DF, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_43_5 = UNIT_END + 0x00E1, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_44_1 = UNIT_END + 0x00E2, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_44_2 = UNIT_END + 0x00E3, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_44_3 = UNIT_END + 0x00E4, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_44_5 = UNIT_END + 0x00E6, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_45_1 = UNIT_END + 0x00E7, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_45_2 = UNIT_END + 0x00E8, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_45_3 = UNIT_END + 0x00E9, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_45_5 = UNIT_END + 0x00EB, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_46_1 = UNIT_END + 0x00EC, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_46_2 = UNIT_END + 0x00ED, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_46_3 = UNIT_END + 0x00EE, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_46_5 = UNIT_END + 0x00F0, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_47_1 = UNIT_END + 0x00F1, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_47_2 = UNIT_END + 0x00F2, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_47_3 = UNIT_END + 0x00F3, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_47_5 = UNIT_END + 0x00F5, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_48_1 = UNIT_END + 0x00F6, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_48_2 = UNIT_END + 0x00F7, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_48_3 = UNIT_END + 0x00F8, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_48_5 = UNIT_END + 0x00FA, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_49_1 = UNIT_END + 0x00FB, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_49_2 = UNIT_END + 0x00FC, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_49_3 = UNIT_END + 0x00FD, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_49_5 = UNIT_END + 0x00FF, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_50_1 = UNIT_END + 0x0100, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_50_2 = UNIT_END + 0x0101, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_50_3 = UNIT_END + 0x0102, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_50_5 = UNIT_END + 0x0104, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_VISIBLE_ITEM_1_ENTRYID = UNIT_END + 0x0105, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_1_ENCHANTMENT = UNIT_END + 0x0106, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_2_ENTRYID = UNIT_END + 0x0107, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_2_ENCHANTMENT = UNIT_END + 0x0108, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_3_ENTRYID = UNIT_END + 0x0109, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_3_ENCHANTMENT = UNIT_END + 0x010A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_4_ENTRYID = UNIT_END + 0x010B, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_4_ENCHANTMENT = UNIT_END + 0x010C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_5_ENTRYID = UNIT_END + 0x010D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_5_ENCHANTMENT = UNIT_END + 0x010E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_6_ENTRYID = UNIT_END + 0x010F, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_6_ENCHANTMENT = UNIT_END + 0x0110, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_7_ENTRYID = UNIT_END + 0x0111, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_7_ENCHANTMENT = UNIT_END + 0x0112, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_8_ENTRYID = UNIT_END + 0x0113, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_8_ENCHANTMENT = UNIT_END + 0x0114, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_9_ENTRYID = UNIT_END + 0x0115, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_9_ENCHANTMENT = UNIT_END + 0x0116, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_10_ENTRYID = UNIT_END + 0x0117, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_10_ENCHANTMENT = UNIT_END + 0x0118, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_11_ENTRYID = UNIT_END + 0x0119, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_11_ENCHANTMENT = UNIT_END + 0x011A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_12_ENTRYID = UNIT_END + 0x011B, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_12_ENCHANTMENT = UNIT_END + 0x011C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_13_ENTRYID = UNIT_END + 0x011D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_13_ENCHANTMENT = UNIT_END + 0x011E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_14_ENTRYID = UNIT_END + 0x011F, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_14_ENCHANTMENT = UNIT_END + 0x0120, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_15_ENTRYID = UNIT_END + 0x0121, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_15_ENCHANTMENT = UNIT_END + 0x0122, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_16_ENTRYID = UNIT_END + 0x0123, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_16_ENCHANTMENT = UNIT_END + 0x0124, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_17_ENTRYID = UNIT_END + 0x0125, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_17_ENCHANTMENT = UNIT_END + 0x0126, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_18_ENTRYID = UNIT_END + 0x0127, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_18_ENCHANTMENT = UNIT_END + 0x0128, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_19_ENTRYID = UNIT_END + 0x0129, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_19_ENCHANTMENT = UNIT_END + 0x012A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_CHOSEN_TITLE = UNIT_END + 0x012B, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_FAKE_INEBRIATION = UNIT_END + 0x012C, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_FIELD_PAD_0 = UNIT_END + 0x012D, // Size: 1, Type: INT, Flags: NONE + PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x012E, // Size: 46, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x015C, // Size: 32, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x017C, // Size: 56, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x01B4, // Size: 14, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x01C2, // Size: 24, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x01DA, // Size: 64, Type: LONG, Flags: PRIVATE + PLAYER_FARSIGHT = UNIT_END + 0x021A, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x021C, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x021E, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER__FIELD_KNOWN_TITLES2 = UNIT_END + 0x0220, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER_XP = UNIT_END + 0x0222, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x0223, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x0224, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_CHARACTER_POINTS = UNIT_END + 0x03A4, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_TRACK_CREATURES = UNIT_END + 0x03A5, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_TRACK_RESOURCES = UNIT_END + 0x03A6, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x03A7, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x03A8, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x03A9, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_EXPERTISE = UNIT_END + 0x03AA, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x03AB, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x03AC, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x03AD, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x03AE, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x03AF, // Size: 7, Type: FLOAT, Flags: PRIVATE + PLAYER_SHIELD_BLOCK = UNIT_END + 0x03B6, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x03B7, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_MASTERY = UNIT_END + 0x03B8, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x03B9, // Size: 144, Type: BYTES, Flags: PRIVATE + PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x0449, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_COINAGE = UNIT_END + 0x044A, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x044C, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x0453, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x045A, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x0461, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_HEALING_PCT = UNIT_END + 0x0462, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MOD_HEALING_DONE_PCT = UNIT_END + 0x0463, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MOD_SPELL_POWER_PCT = UNIT_END + 0x0464, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x0465, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x0466, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BYTES = UNIT_END + 0x0467, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_SELF_RES_SPELL = UNIT_END + 0x0468, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x0469, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x046A, // Size: 12, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x0476, // Size: 12, Type: INT, Flags: PRIVATE + PLAYER_FIELD_KILLS = UNIT_END + 0x0482, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x0483, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BYTES2 = UNIT_END + 0x0484, // Size: 1, Type: TWO_BYTES_SHORT, Flags: PRIVATE + PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x0485, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x0486, // Size: 26, Type: INT, Flags: PRIVATE + PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x04A0, // Size: 21, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BATTLEGROUND_RATING = UNIT_END + 0x04B5, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x04B6, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x04B7, // Size: 25, Type: INT, Flags: PRIVATE + PLAYER_RUNE_REGEN_1 = UNIT_END + 0x04D0, // Size: 4, Type: FLOAT, Flags: PRIVATE + PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x04D4, // Size: 3, Type: INT, Flags: PRIVATE + PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x04D7, // Size: 9, Type: INT, Flags: PRIVATE + PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x04E0, // Size: 9, Type: INT, Flags: PRIVATE + PLAYER_GLYPHS_ENABLED = UNIT_END + 0x04E9, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_PET_SPELL_POWER = UNIT_END + 0x04EA, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_RESEARCHING_1 = UNIT_END + 0x04EB, // Size: 8, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_FIELD_RESERACH_SITE_1 = UNIT_END + 0x04F3, // Size: 8, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_PROFESSION_SKILL_LINE_1 = UNIT_END + 0x04FB, // Size: 2, Type: INT, Flags: PRIVATE + PLAYER_FIELD_UI_HIT_MODIFIER = UNIT_END + 0x04FD, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_UI_SPELL_HIT_MODIFIER = UNIT_END + 0x04FE, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_HOME_REALM_TIME_OFFSET = UNIT_END + 0x04FF, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_END = UNIT_END + 0x0500, }; enum EGameObjectFields @@ -424,10 +541,8 @@ enum ECorpseFields CORPSE_FIELD_ITEM = OBJECT_END + 0x0005, // Size: 19, Type: INT, Flags: PUBLIC CORPSE_FIELD_BYTES_1 = OBJECT_END + 0x0018, // Size: 1, Type: BYTES, Flags: PUBLIC CORPSE_FIELD_BYTES_2 = OBJECT_END + 0x0019, // Size: 1, Type: BYTES, Flags: PUBLIC - CORPSE_FIELD_GUILD = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC - CORPSE_FIELD_FLAGS = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC - CORPSE_FIELD_DYNAMIC_FLAGS = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: DYNAMIC - CORPSE_FIELD_PAD = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: NONE - CORPSE_END = OBJECT_END + 0x001E, + CORPSE_FIELD_FLAGS = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC + CORPSE_FIELD_DYNAMIC_FLAGS = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: DYNAMIC + CORPSE_END = OBJECT_END + 0x001C, }; #endif diff --git a/src/game/World.cpp b/src/game/World.cpp index 00c43843f..9b4ccfdb8 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -925,7 +925,7 @@ void World::SetInitialWorldSettings() { sLog.outError("Correct *.map files not found in path '%smaps' or *.vmtree/*.vmtile files in '%svmaps'. Please place *.map and vmap files in appropriate directories or correct the DataDir value in the mangosd.conf file.", m_dataPath.c_str(), m_dataPath.c_str()); Log::WaitBeforeContinueIfNeed(); - exit(1); + //exit(1); } ///- Loading strings. Getting no records means core load has to be canceled because no error message can be output. @@ -954,9 +954,6 @@ void World::SetInitialWorldSettings() DetectDBCLang(); sObjectMgr.SetDBCLocaleIndex(GetDefaultDbcLocale()); // Get once for all the locale index of DBC language (console/broadcasts) - sLog.outString("Loading SpellTemplate..."); - sObjectMgr.LoadSpellTemplate(); - sLog.outString("Loading Script Names..."); sScriptMgr.LoadScriptNames(); diff --git a/src/game/WorldSocket.cpp b/src/game/WorldSocket.cpp index 765bb538d..ed2dc0500 100644 --- a/src/game/WorldSocket.cpp +++ b/src/game/WorldSocket.cpp @@ -243,9 +243,7 @@ int WorldSocket::open(void* a) m_Address = remote_addr.get_host_addr(); // Send startup packet. - WorldPacket packet(SMSG_AUTH_CHALLENGE, 40); - packet << uint32(1); // 1...31 - packet << m_Seed; + WorldPacket packet (SMSG_AUTH_CHALLENGE, 37); BigNumber seed1; seed1.SetRand(16 * 8); @@ -255,7 +253,10 @@ int WorldSocket::open(void* a) seed2.SetRand(16 * 8); packet.append(seed2.AsByteArray(16), 16); // new encryption seeds - if (SendPacket(packet) == -1) + packet << uint8(1); // 1...31 + packet << uint32(m_Seed); + + if (SendPacket (packet) == -1) return -1; // Register with ACE Reactor @@ -477,7 +478,7 @@ int WorldSocket::handle_input_header(void) EndianConvertReverse(header.size); EndianConvert(header.cmd); - if ((header.size < 4) || (header.size > 10240) || (header.cmd > 10240)) + if ((header.size < 4) || (header.size > 10240)) { sLog.outError("WorldSocket::handle_input_header: client sent malformed packet size = %d , cmd = %d", header.size, header.cmd); @@ -743,7 +744,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) // NOTE: ATM the socket is singlethread, have this in mind ... uint8 digest[20]; uint32 clientSeed, id, security; - uint32 ClientBuild; + uint16 ClientBuild; uint8 expansion = 0; LocaleConstant locale; std::string account; @@ -752,16 +753,14 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) WorldPacket packet; // Read the content of the packet - recvPacket >> ClientBuild; - recvPacket.read_skip(); - recvPacket >> account; + recvPacket.read(digest, 20); + recvPacket.read_skip(); recvPacket.read_skip(); recvPacket >> clientSeed; - recvPacket.read_skip(); - recvPacket.read_skip(); - recvPacket.read_skip(); - recvPacket.read_skip(); - recvPacket.read(digest, 20); + recvPacket >> ClientBuild; + recvPacket.read_skip(); + recvPacket >> account; + recvPacket.read_skip(); // addon data size DEBUG_LOG("WorldSocket::HandleAuthSession: client build %u, account %s, clientseed %X", ClientBuild, diff --git a/src/game/debugcmds.cpp b/src/game/debugcmds.cpp index 36fa0db73..913a68405 100644 --- a/src/game/debugcmds.cpp +++ b/src/game/debugcmds.cpp @@ -1058,9 +1058,12 @@ bool ChatHandler::HandleDebugSpellCoefsCommand(char* args) bool isDirectHeal = false; for (int i = 0; i < 3; ++i) { + SpellEffectEntry const* spellEffect = spellEntry->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; // Heals (Also count Mana Shield and Absorb effects as heals) - if (spellEntry->Effect[i] == SPELL_EFFECT_HEAL || spellEntry->Effect[i] == SPELL_EFFECT_HEAL_MAX_HEALTH || - (spellEntry->Effect[i] == SPELL_EFFECT_APPLY_AURA && (spellEntry->EffectApplyAuraName[i] == SPELL_AURA_SCHOOL_ABSORB || spellEntry->EffectApplyAuraName[i] == SPELL_AURA_PERIODIC_HEAL))) + if (spellEffect->Effect == SPELL_EFFECT_HEAL || spellEffect->Effect == SPELL_EFFECT_HEAL_MAX_HEALTH || + (spellEffect->Effect == SPELL_EFFECT_APPLY_AURA && (spellEffect->EffectApplyAuraName == SPELL_AURA_SCHOOL_ABSORB || spellEffect->EffectApplyAuraName == SPELL_AURA_PERIODIC_HEAL))) { isDirectHeal = true; break; @@ -1070,8 +1073,11 @@ bool ChatHandler::HandleDebugSpellCoefsCommand(char* args) bool isDotHeal = false; for (int i = 0; i < 3; ++i) { + SpellEffectEntry const* spellEffect = spellEntry->GetSpellEffect(SpellEffectIndex(i)); + if(!spellEffect) + continue; // Periodic Heals - if (spellEntry->Effect[i] == SPELL_EFFECT_APPLY_AURA && spellEntry->EffectApplyAuraName[i] == SPELL_AURA_PERIODIC_HEAL) + if (spellEffect->Effect == SPELL_EFFECT_APPLY_AURA && spellEffect->EffectApplyAuraName == SPELL_AURA_PERIODIC_HEAL) { isDotHeal = true; break; diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index 0c8b1418d..049dd5e29 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -764,7 +764,7 @@ LogColors = "" GameType = 1 RealmZone = 1 -Expansion = 2 +Expansion = 3 DBC.Locale = 255 DeclinedNames = 0 StrictPlayerNames = 0 @@ -779,7 +779,7 @@ CharactersPerRealm = 10 HeroicCharactersPerRealm = 1 MinLevelForHeroicCharacterCreating = 55 SkipCinematics = 0 -MaxPlayerLevel = 80 +MaxPlayerLevel = 85 StartPlayerLevel = 1 StartHeroicPlayerLevel = 55 StartPlayerMoney = 0 diff --git a/src/shared/Database/DBCFileLoader.cpp b/src/shared/Database/DBCFileLoader.cpp index 2628c15d6..12eaa53e2 100644 --- a/src/shared/Database/DBCFileLoader.cpp +++ b/src/shared/Database/DBCFileLoader.cpp @@ -141,6 +141,16 @@ uint32 DBCFileLoader::GetFormatRecordSize(const char* format, int32* index_pos) return recordsize; } +uint32 DBCFileLoader::GetFormatStringsFields(const char * format) +{ + uint32 stringfields = 0; + for(uint32 x=0; format[x];++x) + if (format[x] == FT_STRING) + ++stringfields; + + return stringfields; +} + char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable) { /* @@ -234,13 +244,77 @@ char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char** return dataTable; } -char* DBCFileLoader::AutoProduceStrings(const char* format, char* dataTable) +static char const* const nullStr = ""; + +char* DBCFileLoader::AutoProduceStringsArrayHolders(const char* format, char* dataTable) +{ + if(strlen(format)!=fieldCount) + return NULL; + + // we store flat holders pool as single memory block + size_t stringFields = GetFormatStringsFields(format); + // each string field at load have array of string for each locale + size_t stringHolderSize = sizeof(char*) * MAX_LOCALE; + size_t stringHoldersRecordPoolSize = stringFields * stringHolderSize; + size_t stringHoldersPoolSize = stringHoldersRecordPoolSize * recordCount; + + char* stringHoldersPool= new char[stringHoldersPoolSize]; + + // dbc strings expected to have at least empty string + for(size_t i = 0; i < stringHoldersPoolSize / sizeof(char*); ++i) + ((char const**)stringHoldersPool)[i] = nullStr; + + uint32 offset=0; + + // assign string holders to string field slots + for(uint32 y =0;y enum @@ -94,10 +95,12 @@ class DBCFileLoader uint32 GetOffset(size_t id) const { return (fieldsOffset != NULL && id < fieldCount) ? fieldsOffset[id] : 0; } bool IsLoaded() {return (data != NULL);} char* AutoProduceData(const char* fmt, uint32& count, char**& indexTable); - char* AutoProduceStrings(const char* fmt, char* dataTable); - static uint32 GetFormatRecordSize(const char* format, int32* index_pos = NULL); - private: + char* AutoProduceStringsArrayHolders(const char* fmt, char* dataTable); + char* AutoProduceStrings(const char* fmt, char* dataTable, LocaleConstant loc); + static uint32 GetFormatRecordSize(const char * format, int32 * index_pos = NULL); + static uint32 GetFormatStringsFields(const char * format); + private: uint32 recordSize; uint32 recordCount; uint32 fieldCount; diff --git a/src/shared/Database/DBCStore.h b/src/shared/Database/DBCStore.h index 0d83b0a85..3636d54be 100644 --- a/src/shared/Database/DBCStore.h +++ b/src/shared/Database/DBCStore.h @@ -34,7 +34,7 @@ class DBCStorage char const* GetFormat() const { return fmt; } uint32 GetFieldCount() const { return fieldCount; } - bool Load(char const* fn) + bool Load(char const* fn, LocaleConstant loc) { DBCFileLoader dbc; // Check if load was sucessful, only then continue @@ -46,14 +46,17 @@ class DBCStorage // load raw non-string data m_dataTable = (T*)dbc.AutoProduceData(fmt, nCount, (char**&)indexTable); + // create string holders for loaded string fields + m_stringPoolList.push_back(dbc.AutoProduceStringsArrayHolders(fmt,(char*)m_dataTable)); + // load strings from dbc data - m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt, (char*)m_dataTable)); + m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt,(char*)m_dataTable,loc)); // error in dbc file at loading if NULL return indexTable != NULL; } - bool LoadStringsFrom(char const* fn) + bool LoadStringsFrom(char const* fn, LocaleConstant loc) { // DBC must be already loaded using Load if (!indexTable) @@ -65,7 +68,7 @@ class DBCStorage return false; // load strings from another locale dbc data - m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt, (char*)m_dataTable)); + m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt,(char*)m_dataTable,loc)); return true; } diff --git a/src/shared/Database/Field.cpp b/src/shared/Database/Field.cpp index 21e856092..91094595d 100644 --- a/src/shared/Database/Field.cpp +++ b/src/shared/Database/Field.cpp @@ -17,4 +17,3 @@ */ //#include "DatabaseEnv.h" - diff --git a/win/VC100/game.vcxproj b/win/VC100/game.vcxproj index cb2f00693..34b98a40c 100644 --- a/win/VC100/game.vcxproj +++ b/win/VC100/game.vcxproj @@ -389,6 +389,7 @@ + diff --git a/win/VC100/game.vcxproj.filters b/win/VC100/game.vcxproj.filters index dd1cf6d67..247339451 100644 --- a/win/VC100/game.vcxproj.filters +++ b/win/VC100/game.vcxproj.filters @@ -466,6 +466,9 @@ Object + + Server + World/Handlers diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj index 0d7db3220..cc16df7c3 100644 --- a/win/VC90/game.vcproj +++ b/win/VC90/game.vcproj @@ -1518,6 +1518,10 @@ RelativePath="..\..\src\game\DBCStores.h" > + +