diff options
author | Matan Shukry <matanshukry@gmail.com> | 2021-04-11 20:23:19 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-11 19:23:19 +0200 |
commit | b92e20f6c860bd1b5f3e7ce3f614dd48fc5b49c4 (patch) | |
tree | a64ebcfe0d953c78a54f39af457f33c3e5d52efc /src | |
parent | 5fdd2c95ef013e6828de70e160ff091fe886451f (diff) |
Script/Spells: shaman spell fixes (#26192)
* Flametongue Weapon
* Tremor Totem
* Healing Stream Totem
* Liquid Magma Totem
* Healing Rain
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Item/ItemTemplate.h | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 14 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 1 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_shaman.cpp | 186 |
4 files changed, 180 insertions, 25 deletions
diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h index 990ee108dc6..cdee1d0265d 100644 --- a/src/server/game/Entities/Item/ItemTemplate.h +++ b/src/server/game/Entities/Item/ItemTemplate.h @@ -817,9 +817,11 @@ struct TC_GAME_API ItemTemplate bool IsConjuredConsumable() const { return GetClass() == ITEM_CLASS_CONSUMABLE && (GetFlags() & ITEM_FLAG_CONJURED); } bool IsCraftingReagent() const { return (GetFlags2() & ITEM_FLAG2_USED_IN_A_TRADESKILL) != 0; } + bool IsWeapon() const { return GetClass() == ITEM_CLASS_WEAPON; } + bool IsRangedWeapon() const { - return GetClass() == ITEM_CLASS_WEAPON || + return IsWeapon() || GetSubClass() == ITEM_SUBCLASS_WEAPON_BOW || GetSubClass() == ITEM_SUBCLASS_WEAPON_GUN || GetSubClass() == ITEM_SUBCLASS_WEAPON_CROSSBOW; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index ffa959fedc5..1e2396560da 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -1130,6 +1130,20 @@ void Unit::CastSpell(GameObject* go, uint32 spellId, bool triggered, Item* castI CastSpell(targets, spellInfo, nullptr, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster); } +void Unit::CastSpell(Item* target, uint32 spellId, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, ObjectGuid originalCaster) +{ + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, GetMap()->GetDifficultyID()); + if (!spellInfo) + { + TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s", spellId, GetGUID().ToString().c_str()); + return; + } + SpellCastTargets targets; + targets.SetItemTarget(target); + + CastSpell(targets, spellInfo, nullptr, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster); +} + void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType, bool crit) { if (damage < 0) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 36f5f01bc41..d950b89122a 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1335,6 +1335,7 @@ class TC_GAME_API Unit : public WorldObject void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty); void CastSpell(float x, float y, float z, uint32 spellId, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty); void CastSpell(GameObject* go, uint32 spellId, bool triggered, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty); + void CastSpell(Item* target, uint32 spellId, bool triggered, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty); void CastCustomSpell(Unit* victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty); void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* victim, bool triggered, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty); void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* victim = nullptr, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty); diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index e2052359cc0..adef5e55ed6 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -25,6 +25,7 @@ #include "CellImpl.h" #include "CreatureAIImpl.h" // for RAND() #include "GridNotifiersImpl.h" +#include "Item.h" #include "ObjectAccessor.h" #include "Player.h" #include "SpellAuraEffects.h" @@ -52,14 +53,19 @@ enum ShamanSpells SPELL_SHAMAN_FLAME_SHOCK = 8050, SPELL_SHAMAN_FLAME_SHOCK_MAELSTROM = 188389, SPELL_SHAMAN_FLAMETONGUE_ATTACK = 10444, + SPELL_SHAMAN_FLAMETONGUE_WEAPON_ENCHANT = 334294, + SPELL_SHAMAN_FLAMETONGUE_WEAPON_AURA = 319778, SPELL_SHAMAN_GATHERING_STORMS = 198299, SPELL_SHAMAN_GATHERING_STORMS_BUFF = 198300, + SPELL_SHAMAN_HEALING_RAIN_VISUAL = 147490, + SPELL_SHAMAN_HEALING_RAIN_HEAL = 73921, SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD = 23552, SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD_DAMAGE = 27635, SPELL_SHAMAN_ITEM_MANA_SURGE = 23571, SPELL_SHAMAN_LAVA_BURST = 51505, SPELL_SHAMAN_LAVA_BURST_BONUS_DAMAGE = 71824, SPELL_SHAMAN_LAVA_SURGE = 77762, + SPELL_SHAMAN_LIQUID_MAGMA_HIT = 192231, SPELL_SHAMAN_PATH_OF_FLAMES_SPREAD = 210621, SPELL_SHAMAN_PATH_OF_FLAMES_TALENT = 201909, SPELL_SHAMAN_POWER_SURGE = 40466, @@ -69,7 +75,7 @@ enum ShamanSpells SPELL_SHAMAN_TOTEMIC_POWER_SPELL_POWER = 28825, SPELL_SHAMAN_TOTEMIC_POWER_ATTACK_POWER = 28826, SPELL_SHAMAN_TOTEMIC_POWER_ARMOR = 28827, - SPELL_SHAMAN_WINDFURY_ATTACK = 25504 + SPELL_SHAMAN_WINDFURY_ATTACK = 25504, }; enum MiscSpells @@ -79,6 +85,11 @@ enum MiscSpells SPELL_PET_NETHERWINDS_FATIGUED = 160455 }; +enum MiscNpcs +{ + NPC_HEALING_RAIN_INVISIBLE_STALKER = 73400, +}; + // 108281 - Ancestral Guidance class spell_sha_ancestral_guidance : public SpellScriptLoader { @@ -415,39 +426,129 @@ public: } }; -// 194084 - Flametongue -class spell_sha_flametongue : public SpellScriptLoader +// 318038 - Flametongue Weapon +class spell_sha_flametongue_weapon : public SpellScript +{ + PrepareSpellScript(spell_sha_flametongue_weapon); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_FLAMETONGUE_WEAPON_ENCHANT }); + } + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleEffectHitTarget(SpellEffIndex /*effIndex*/) + { + Player* player = GetCaster()->ToPlayer(); + uint8 slot = EQUIPMENT_SLOT_MAINHAND; + if (player->GetPrimarySpecialization() == TALENT_SPEC_SHAMAN_ENHANCEMENT) + slot = EQUIPMENT_SLOT_OFFHAND; + + Item* targetItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); + if (!targetItem || !targetItem->GetTemplate()->IsWeapon()) + return; + + player->CastSpell(targetItem, SPELL_SHAMAN_FLAMETONGUE_WEAPON_ENCHANT, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_sha_flametongue_weapon::HandleEffectHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 319778 - Flametongue - SPELL_SHAMAN_FLAMETONGUE_WEAPON_AURA +class spell_sha_flametongue_weapon_aura : public AuraScript +{ + PrepareAuraScript(spell_sha_flametongue_weapon_aura); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_FLAMETONGUE_ATTACK }); + } + + void HandleEffectProc(AuraEffect* aurEff, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + + Unit* attacker = eventInfo.GetActor(); + int32 damage = std::max(1, int32(attacker->GetTotalAttackPowerValue(BASE_ATTACK) * 0.0264f)); + attacker->CastCustomSpell(SPELL_SHAMAN_FLAMETONGUE_ATTACK, SPELLVALUE_BASE_POINT0, damage, eventInfo.GetActionTarget(), TRIGGERED_FULL_MASK, nullptr, aurEff); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_flametongue_weapon_aura::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + +// 73920 - Healing Rain (Aura) +class spell_sha_healing_rain_aura : public AuraScript { public: - spell_sha_flametongue() : SpellScriptLoader("spell_sha_flametongue") { } + static constexpr const char ScriptName[] = "spell_sha_healing_rain"; - class spell_sha_flametongue_AuraScript : public AuraScript + void SetVisualDummy(TempSummon* summon) { - PrepareAuraScript(spell_sha_flametongue_AuraScript); + _visualDummy = summon->GetGUID(); + summon->GetPosition(_x, _y, _z); + } - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SHAMAN_FLAMETONGUE_ATTACK }); - } +private: + PrepareAuraScript(spell_sha_healing_rain_aura); - void HandleEffectProc(AuraEffect* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); + void HandleEffectPeriodic(AuraEffect const* aurEff) + { + GetTarget()->CastSpell(_x, _y, _z, SPELL_SHAMAN_HEALING_RAIN_HEAL, true, nullptr, aurEff); + } - Unit* attacker = eventInfo.GetActor(); - int32 damage = int32(attacker->GetTotalAttackPowerValue(BASE_ATTACK) * 0.125f / 2600 * attacker->GetBaseAttackTime(BASE_ATTACK)); - attacker->CastCustomSpell(SPELL_SHAMAN_FLAMETONGUE_ATTACK, SPELLVALUE_BASE_POINT0, damage, eventInfo.GetActionTarget(), TRIGGERED_FULL_MASK, nullptr, aurEff); - } + void HandleEffecRemoved(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* summon = ObjectAccessor::GetCreature(*GetTarget(), _visualDummy)) + summon->DespawnOrUnsummon(); + } - void Register() override + void Register() override + { + OnEffectRemove += AuraEffectRemoveFn(spell_sha_healing_rain_aura::HandleEffecRemoved, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_sha_healing_rain_aura::HandleEffectPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY); + } + + ObjectGuid _visualDummy; + float _x = 0.0f, _y = 0.0f, _z = 0.0f; +}; + +// 73920 - Healing Rain +class spell_sha_healing_rain : public SpellScript +{ + PrepareSpellScript(spell_sha_healing_rain); + + void InitializeVisualStalker() + { + if (Aura* aura = GetHitAura()) { - OnEffectProc += AuraEffectProcFn(spell_sha_flametongue_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + if (WorldLocation const* dest = GetExplTargetDest()) + { + int32 duration = GetSpellInfo()->CalcDuration(GetOriginalCaster()); + TempSummon* summon = GetCaster()->GetMap()->SummonCreature(NPC_HEALING_RAIN_INVISIBLE_STALKER, *dest, nullptr, duration, GetOriginalCaster()); + if (!summon) + return; + + summon->CastSpell(summon, SPELL_SHAMAN_HEALING_RAIN_VISUAL, true); + + if (spell_sha_healing_rain_aura* script = aura->GetScript<spell_sha_healing_rain_aura>(spell_sha_healing_rain_aura::ScriptName)) + script->SetVisualDummy(summon); + } } - }; + } - AuraScript* GetAuraScript() const override + void Register() override { - return new spell_sha_flametongue_AuraScript(); + OnHit += SpellHitFn(spell_sha_healing_rain::InitializeVisualStalker); } }; @@ -474,7 +575,7 @@ class spell_sha_healing_stream_totem_heal : public SpellScriptLoader targets.push_back(GetOriginalCaster()); } - void Register() + void Register() override { OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_healing_stream_totem_heal_SpellScript::SelectTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY); } @@ -881,6 +982,40 @@ class spell_sha_lava_surge_proc : public SpellScriptLoader } }; +// 192223 - Liquid Magma Totem (erupting hit spell) +class spell_sha_liquid_magma_totem : public SpellScript +{ + PrepareSpellScript(spell_sha_liquid_magma_totem); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SHAMAN_LIQUID_MAGMA_HIT }); + } + + void HandleEffectHitTarget(SpellEffIndex /*effIndex*/) + { + if (Unit* hitUnit = GetHitUnit()) + GetCaster()->CastSpell(hitUnit, SPELL_SHAMAN_LIQUID_MAGMA_HIT, true); + } + + void HandleTargetSelect(std::list<WorldObject*>& targets) + { + // choose one random target from targets + if (targets.size() > 1) + { + WorldObject* selected = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(selected); + } + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_liquid_magma_totem::HandleTargetSelect, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_sha_liquid_magma_totem::HandleEffectHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + // 210621 - Path of Flames Spread class spell_sha_path_of_flames_spread : public SpellScriptLoader { @@ -1293,7 +1428,9 @@ void AddSC_shaman_spell_scripts() new spell_sha_earthen_rage_passive(); new spell_sha_earthen_rage_proc_aura(); new spell_sha_elemental_blast(); - new spell_sha_flametongue(); + RegisterSpellScript(spell_sha_flametongue_weapon); + RegisterAuraScript(spell_sha_flametongue_weapon_aura); + RegisterSpellAndAuraScriptPair(spell_sha_healing_rain, spell_sha_healing_rain_aura); new spell_sha_healing_stream_totem_heal(); new spell_sha_heroism(); new spell_sha_item_lightning_shield(); @@ -1305,6 +1442,7 @@ void AddSC_shaman_spell_scripts() new spell_sha_lava_burst(); new spell_sha_lava_surge(); new spell_sha_lava_surge_proc(); + RegisterSpellScript(spell_sha_liquid_magma_totem); new spell_sha_path_of_flames_spread(); new spell_sha_tidal_waves(); new spell_sha_t3_6p_bonus(); |