Files
CypherCore/Source/Scripts/Spells/Hunter.cs
T
2023-10-07 14:04:50 -04:00

744 lines
24 KiB
C#

// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Constants;
using Game.Entities;
using Game.Scripting;
using Game.Spells;
using System;
using static Global;
namespace Scripts.Spells.Hunter
{
struct SpellIds
{
public const uint AMurderOfCrowsDamage = 131900;
public const uint AMurderOfCrowsVisual1 = 131637;
public const uint AMurderOfCrowsVisual2 = 131951;
public const uint AMurderOfCrowsVisual3 = 131952;
public const uint AspectCheetahSlow = 186258;
public const uint Exhilaration = 109304;
public const uint ExhilarationPet = 128594;
public const uint ExhilarationR2 = 231546;
public const uint ExplosiveShotDamage = 212680;
public const uint LatentPoisonStack = 378015;
public const uint LatentPoisonDamage = 378016;
public const uint LatentPoisonInjectorsStack = 336903;
public const uint LatentPoisonInjectorsDamage = 336904;
public const uint LoneWolf = 155228;
public const uint MastersCallTriggered = 62305;
public const uint Misdirection = 34477;
public const uint MisdirectionProc = 35079;
public const uint MultiShotFocus = 213363;
public const uint PetLastStandTriggered = 53479;
public const uint PetHeartOfThePhoenixTriggered = 54114;
public const uint PetHeartOfThePhoenixDebuff = 55711;
public const uint PosthasteIncreaseSpeed = 118922;
public const uint PosthasteTalent = 109215;
public const uint RapidFireDamage = 257045;
public const uint RapidFireEnergize = 263585;
public const uint SteadyShotFocus = 77443;
public const uint T94PGreatness = 68130;
public const uint T292PMarksmanshipDamage = 394371;
public const uint RoarOfSacrificeTriggered = 67481;
public const uint DraeneiGiftOfTheNaaru = 59543;
}
[Script] // 131894 - A Murder of Crows
class spell_hun_a_murder_of_crows : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.AMurderOfCrowsDamage, SpellIds.AMurderOfCrowsVisual1, SpellIds.AMurderOfCrowsVisual2, SpellIds.AMurderOfCrowsVisual3);
}
void HandleDummyTick(AuraEffect aurEff)
{
Unit target = GetTarget();
Unit caster = GetCaster();
if (caster != null)
caster.CastSpell(target, SpellIds.AMurderOfCrowsDamage, true);
target.CastSpell(target, SpellIds.AMurderOfCrowsVisual1, true);
target.CastSpell(target, SpellIds.AMurderOfCrowsVisual2, true);
target.CastSpell(target, SpellIds.AMurderOfCrowsVisual3, true);
target.CastSpell(target, SpellIds.AMurderOfCrowsVisual3, true); // not a mistake, it is intended to cast twice
}
void RemoveEffect(AuraEffect aurEff, AuraEffectHandleModes mode)
{
if (GetTargetApplication().GetRemoveMode() == AuraRemoveMode.Death)
{
Unit caster = GetCaster();
if (caster != null)
caster.GetSpellHistory().ResetCooldown(GetId(), true);
}
}
public override void Register()
{
OnEffectPeriodic.Add(new(HandleDummyTick, 0, AuraType.PeriodicDummy));
OnEffectRemove.Add(new(RemoveEffect, 0, AuraType.PeriodicDummy, AuraEffectHandleModes.Real));
}
}
[Script] // 186257 - Aspect of the Cheetah
class spell_hun_aspect_cheetah : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.AspectCheetahSlow);
}
void HandleOnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
if (GetTargetApplication().GetRemoveMode() == AuraRemoveMode.Expire)
GetTarget().CastSpell(GetTarget(), SpellIds.AspectCheetahSlow, true);
}
public override void Register()
{
AfterEffectRemove.Add(new(HandleOnRemove, 0, AuraType.ModIncreaseSpeed, AuraEffectHandleModes.Real));
}
}
[Script] // 378750 - Cobra Sting
class spell_hun_cobra_sting : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellEffect((spellInfo.Id, 1));
}
bool RollProc(AuraEffect aurEff, ProcEventInfo procInfo)
{
return RandomHelper.randChance(GetEffect(1).GetAmount());
}
public override void Register()
{
DoCheckEffectProc.Add(new(RollProc, 0, AuraType.ProcTriggerSpell));
}
}
[Script] // 109304 - Exhilaration
class spell_hun_exhilaration : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.ExhilarationR2, SpellIds.LoneWolf);
}
void HandleOnHit()
{
if (GetCaster().HasAura(SpellIds.ExhilarationR2) && !GetCaster().HasAura(SpellIds.LoneWolf))
GetCaster().CastSpell(null, SpellIds.ExhilarationPet, true);
}
public override void Register()
{
OnHit.Add(new(HandleOnHit));
}
}
[Script] // 212431 - Explosive Shot
class spell_hun_explosive_shot : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.ExplosiveShotDamage);
}
void HandlePeriodic(AuraEffect aurEff)
{
Unit caster = GetCaster();
if (caster != null)
caster.CastSpell(GetTarget(), SpellIds.ExplosiveShotDamage, true);
}
public override void Register()
{
OnEffectPeriodic.Add(new(HandlePeriodic, 0, AuraType.PeriodicDummy));
}
}
[Script] // 212658 - Hunting Party
class spell_hun_hunting_party : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.Exhilaration, SpellIds.ExhilarationPet);
}
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
{
PreventDefaultAction();
GetTarget().GetSpellHistory().ModifyCooldown(SpellIds.Exhilaration, -TimeSpan.FromSeconds(aurEff.GetAmount()));
GetTarget().GetSpellHistory().ModifyCooldown(SpellIds.ExhilarationPet, -TimeSpan.FromSeconds(aurEff.GetAmount()));
}
public override void Register()
{
OnEffectProc.Add(new(HandleProc, 0, AuraType.Dummy));
}
}
[Script] // 53478 - Last Stand Pet
class spell_hun_last_stand_pet : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.PetLastStandTriggered);
}
void HandleDummy(uint effIndex)
{
Unit caster = GetCaster();
CastSpellExtraArgs args = new(TriggerCastFlags.FullMask);
args.AddSpellMod(SpellValueMod.BasePoint0, (int)caster.CountPctFromMaxHealth(30));
caster.CastSpell(caster, SpellIds.PetLastStandTriggered, args);
}
public override void Register()
{
OnEffectHitTarget.Add(new(HandleDummy, 0, SpellEffectName.Dummy));
}
}
[Script] // 378016 - Latent Poison
class spell_hun_latent_poison_damage : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.LatentPoisonStack);
}
void CalculateDamage()
{
Aura stack = GetHitUnit().GetAura(SpellIds.LatentPoisonStack, GetCaster().GetGUID());
if (stack != null)
{
SetHitDamage(GetHitDamage() * stack.GetStackAmount());
stack.Remove();
}
}
public override void Register()
{
OnHit.Add(new(CalculateDamage));
}
}
// 19434 - Aimed Shot
// 186270 - Raptor Strike
// 217200 - Barbed Shot
[Script] // 259387 - Mongoose Bite
class spell_hun_latent_poison_trigger : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.LatentPoisonStack, SpellIds.LatentPoisonDamage);
}
void TriggerDamage()
{
if (GetHitUnit().HasAura(SpellIds.LatentPoisonStack, GetCaster().GetGUID()))
GetCaster().CastSpell(GetHitUnit(), SpellIds.LatentPoisonDamage, GetSpell());
}
public override void Register()
{
AfterHit.Add(new(TriggerDamage));
}
}
[Script] // 336904 - Latent Poison Injectors
class spell_hun_latent_poison_injectors_damage : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.LatentPoisonInjectorsStack);
}
void CalculateDamage()
{
Aura stack = GetHitUnit().GetAura(SpellIds.LatentPoisonInjectorsStack, GetCaster().GetGUID());
if (stack != null)
{
SetHitDamage(GetHitDamage() * stack.GetStackAmount());
stack.Remove();
}
}
public override void Register()
{
OnHit.Add(new(CalculateDamage));
}
}
// 186270 - Raptor Strike
[Script] // 259387 - Mongoose Bite
class spell_hun_latent_poison_injectors_trigger : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.LatentPoisonInjectorsStack, SpellIds.LatentPoisonInjectorsDamage);
}
void TriggerDamage()
{
if (GetHitUnit().HasAura(SpellIds.LatentPoisonInjectorsStack, GetCaster().GetGUID()))
GetCaster().CastSpell(GetHitUnit(), SpellIds.LatentPoisonInjectorsDamage, GetSpell());
}
public override void Register()
{
AfterHit.Add(new(TriggerDamage));
}
}
[Script] // 53271 - Masters Call
class spell_hun_masters_call : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellEffect((spellInfo.Id, 0))
&& ValidateSpellInfo(SpellIds.MastersCallTriggered, (uint)spellInfo.GetEffect(0).CalcValue());
}
public override bool Load()
{
return GetCaster().IsPlayer();
}
SpellCastResult DoCheckCast()
{
Guardian pet = GetCaster().ToPlayer().GetGuardianPet();
Cypher.Assert(pet != null); // checked in Spell.CheckCast
if (!pet.IsPet() || !pet.IsAlive())
return SpellCastResult.NoPet;
// Do a mini Spell.CheckCasterAuras on the pet, no other way of doing this
SpellCastResult result = SpellCastResult.SpellCastOk;
UnitFlags unitflag = (UnitFlags)(uint)pet.m_unitData.Flags;
if (!pet.GetCharmerGUID().IsEmpty())
result = SpellCastResult.Charmed;
else if (unitflag.HasFlag(UnitFlags.Stunned))
result = SpellCastResult.Stunned;
else if (unitflag.HasFlag(UnitFlags.Fleeing))
result = SpellCastResult.Fleeing;
else if (unitflag.HasFlag(UnitFlags.Confused))
result = SpellCastResult.Confused;
if (result != SpellCastResult.SpellCastOk)
return result;
Unit target = GetExplTargetUnit();
if (target == null)
return SpellCastResult.BadTargets;
if (!pet.IsWithinLOSInMap(target))
return SpellCastResult.LineOfSight;
return SpellCastResult.SpellCastOk;
}
void HandleDummy(uint effIndex)
{
GetCaster().ToPlayer().GetPet().CastSpell(GetHitUnit(), (uint)GetEffectValue(), true);
}
void HandleScriptEffect(uint effIndex)
{
GetHitUnit().CastSpell(null, SpellIds.MastersCallTriggered, true);
}
public override void Register()
{
OnCheckCast.Add(new(DoCheckCast));
OnEffectHitTarget.Add(new(HandleDummy, 0, SpellEffectName.Dummy));
OnEffectHitTarget.Add(new(HandleScriptEffect, 1, SpellEffectName.ScriptEffect));
}
}
[Script] // 34477 - Misdirection
class spell_hun_misdirection : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.MisdirectionProc);
}
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
if (GetTargetApplication().GetRemoveMode() == AuraRemoveMode.Default || GetTargetApplication().GetRemoveMode() == AuraRemoveMode.Interrupt)
return;
if (!GetTarget().HasAura(SpellIds.MisdirectionProc))
GetTarget().GetThreatManager().UnregisterRedirectThreat(SpellIds.Misdirection);
}
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
{
PreventDefaultAction();
GetTarget().CastSpell(GetTarget(), SpellIds.MisdirectionProc, aurEff);
}
public override void Register()
{
AfterEffectRemove.Add(new(OnRemove, 1, AuraType.Dummy, AuraEffectHandleModes.Real));
OnEffectProc.Add(new(HandleProc, 1, AuraType.Dummy));
}
}
[Script] // 35079 - Misdirection (Proc)
class spell_hun_misdirection_proc : AuraScript
{
void OnRemove(AuraEffect aurEff, AuraEffectHandleModes mode)
{
GetTarget().GetThreatManager().UnregisterRedirectThreat(SpellIds.Misdirection);
}
public override void Register()
{
AfterEffectRemove.Add(new(OnRemove, 0, AuraType.Dummy, AuraEffectHandleModes.Real));
}
}
[Script] // 2643 - Multi-Shot
class spell_hun_multi_shot : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.MultiShotFocus);
}
public override bool Load()
{
return GetCaster().IsPlayer();
}
void HandleOnHit()
{
// We need to check hunter's spec because it doesn't generate focus on other specs than Mm
if (GetCaster().ToPlayer().GetPrimarySpecialization() == ChrSpecialization.HunterMarksmanship)
GetCaster().CastSpell(GetCaster(), SpellIds.MultiShotFocus, true);
}
public override void Register()
{
OnHit.Add(new(HandleOnHit));
}
}
[Script] // 55709 - Pet Heart of the Phoenix
class spell_hun_pet_heart_of_the_phoenix : SpellScript
{
public override bool Load()
{
if (!GetCaster().IsPet())
return false;
return true;
}
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.PetHeartOfThePhoenixTriggered, SpellIds.PetHeartOfThePhoenixDebuff);
}
void HandleScript(uint effIndex)
{
Unit caster = GetCaster();
Unit owner = caster.GetOwner();
if (owner != null)
{
if (!caster.HasAura(SpellIds.PetHeartOfThePhoenixDebuff))
{
CastSpellExtraArgs args = new(TriggerCastFlags.FullMask);
args.AddSpellMod(SpellValueMod.BasePoint0, 100);
owner.CastSpell(caster, SpellIds.PetHeartOfThePhoenixTriggered, args);
caster.CastSpell(caster, SpellIds.PetHeartOfThePhoenixDebuff, true);
}
}
}
public override void Register()
{
OnEffectHitTarget.Add(new(HandleScript, 0, SpellEffectName.ScriptEffect));
}
}
[Script] // 781 - Disengage
class spell_hun_posthaste : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.PosthasteTalent, SpellIds.PosthasteIncreaseSpeed);
}
void HandleAfterCast()
{
if (GetCaster().HasAura(SpellIds.PosthasteTalent))
{
GetCaster().RemoveMovementImpairingAuras(true);
GetCaster().CastSpell(GetCaster(), SpellIds.PosthasteIncreaseSpeed, GetSpell());
}
}
public override void Register()
{
AfterCast.Add(new(HandleAfterCast));
}
}
[Script] // 257044 - Rapid Fire
class spell_hun_rapid_fire : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.RapidFireDamage);
}
void HandlePeriodic(AuraEffect aurEff)
{
Unit caster = GetCaster();
if (caster != null)
caster.CastSpell(GetTarget(), SpellIds.RapidFireDamage, true);
}
public override void Register()
{
OnEffectPeriodic.Add(new(HandlePeriodic, 1, AuraType.PeriodicDummy));
}
}
[Script] // 257045 - Rapid Fire Damage
class spell_hun_rapid_fire_damage : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.RapidFireEnergize);
}
void HandleHit(uint effIndex)
{
GetCaster().CastSpell(null, SpellIds.RapidFireEnergize, true);
}
public override void Register()
{
OnEffectHitTarget.Add(new(HandleHit, 0, SpellEffectName.SchoolDamage));
}
}
[Script] // 53480 - Roar of Sacrifice
class spell_hun_roar_of_sacrifice : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.RoarOfSacrificeTriggered);
}
bool CheckProc(AuraEffect aurEff, ProcEventInfo eventInfo)
{
DamageInfo damageInfo = eventInfo.GetDamageInfo();
if (damageInfo == null || (damageInfo.GetSchoolMask() & (SpellSchoolMask)aurEff.GetMiscValue()) == 0)
return false;
if (GetCaster() == null)
return false;
return true;
}
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
{
PreventDefaultAction();
CastSpellExtraArgs args = new(aurEff);
args.AddSpellMod(SpellValueMod.BasePoint0, (int)MathFunctions.CalculatePct(eventInfo.GetDamageInfo().GetDamage(), aurEff.GetAmount()));
eventInfo.GetActor().CastSpell(GetCaster(), SpellIds.RoarOfSacrificeTriggered, args);
}
public override void Register()
{
DoCheckEffectProc.Add(new(CheckProc, 1, AuraType.Dummy));
OnEffectProc.Add(new(HandleProc, 1, AuraType.Dummy));
}
}
[Script] // 37506 - Scatter Shot
class spell_hun_scatter_shot : SpellScript
{
public override bool Load()
{
return GetCaster().IsPlayer();
}
void HandleDummy(uint effIndex)
{
Player caster = GetCaster().ToPlayer();
// break var Shot and autohit
caster.InterruptSpell(CurrentSpellTypes.AutoRepeat);
caster.AttackStop();
caster.SendAttackSwingCancelAttack();
}
public override void Register()
{
OnEffectHitTarget.Add(new(HandleDummy, 0, SpellEffectName.Dummy));
}
}
[Script] // 56641 - Steady Shot
class spell_hun_steady_shot : SpellScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.SteadyShotFocus);
}
public override bool Load()
{
return GetCaster().IsPlayer();
}
void HandleOnHit()
{
GetCaster().CastSpell(GetCaster(), SpellIds.SteadyShotFocus, true);
}
public override void Register()
{
OnHit.Add(new(HandleOnHit));
}
}
[Script] // 1515 - Tame Beast
class spell_hun_tame_beast : SpellScript
{
uint[] CallPetSpellIds = { 883, 83242, 83243, 83244, 83245, };
SpellCastResult CheckCast()
{
Player caster = GetCaster().ToPlayer();
if (caster == null)
return SpellCastResult.DontReport;
if (GetExplTargetUnit() == null)
return SpellCastResult.BadImplicitTargets;
Creature target = GetExplTargetUnit().ToCreature();
if (target != null)
{
if (target.GetLevelForTarget(caster) > caster.GetLevel())
return SpellCastResult.Highlevel;
// use SmsgPetTameFailure?
if (!target.GetCreatureTemplate().IsTameable(caster.CanTameExoticPets(), target.GetCreatureDifficulty()))
return SpellCastResult.BadTargets;
PetStable petStable = caster.GetPetStable();
if (petStable != null)
{
if (petStable.CurrentPetIndex.HasValue)
return SpellCastResult.AlreadyHaveSummon;
var freeSlotIndex = Array.FindIndex(petStable.ActivePets, petInfo => petInfo == null);
if (freeSlotIndex == -1)
{
caster.SendTameFailure(PetTameResult.TooMany);
return SpellCastResult.DontReport;
}
// Check for known Call Pet X spells
if (!caster.HasSpell(CallPetSpellIds[freeSlotIndex]))
{
caster.SendTameFailure(PetTameResult.TooMany);
return SpellCastResult.DontReport;
}
}
if (!caster.GetCharmedGUID().IsEmpty())
return SpellCastResult.AlreadyHaveCharm;
if (!target.GetOwnerGUID().IsEmpty())
{
caster.SendTameFailure(PetTameResult.CreatureAlreadyOwned);
return SpellCastResult.DontReport;
}
}
else
return SpellCastResult.BadImplicitTargets;
return SpellCastResult.SpellCastOk;
}
public override void Register()
{
OnCheckCast.Add(new(CheckCast));
}
}
[Script] // 67151 - Item - Hunter T9 4P Bonus (Steady Shot)
class spell_hun_t9_4p_bonus : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellInfo(SpellIds.T94PGreatness);
}
bool CheckProc(ProcEventInfo eventInfo)
{
if (eventInfo.GetActor().IsPlayer() && eventInfo.GetActor().ToPlayer().GetPet() != null)
return true;
return false;
}
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
{
PreventDefaultAction();
Unit caster = eventInfo.GetActor();
caster.CastSpell(caster.ToPlayer().GetPet(), SpellIds.T94PGreatness, aurEff);
}
public override void Register()
{
DoCheckProc.Add(new(CheckProc));
OnEffectProc.Add(new(HandleProc, 0, AuraType.ProcTriggerSpell));
}
}
[Script] // 394366 - Find The Mark
class spell_hun_t29_2p_marksmanship_bonus : AuraScript
{
public override bool Validate(SpellInfo spellInfo)
{
return ValidateSpellEffect((SpellIds.T292PMarksmanshipDamage, 0))
&& SpellMgr.GetSpellInfo(SpellIds.T292PMarksmanshipDamage, Difficulty.None).GetMaxTicks() != 0;
}
void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo)
{
PreventDefaultAction();
Unit caster = eventInfo.GetActor();
uint ticks = SpellMgr.GetSpellInfo(SpellIds.T292PMarksmanshipDamage, Difficulty.None).GetMaxTicks();
uint damage = MathFunctions.CalculatePct(eventInfo.GetDamageInfo().GetOriginalDamage(), aurEff.GetAmount()) / ticks;
caster.CastSpell(eventInfo.GetActionTarget(), SpellIds.T292PMarksmanshipDamage, new CastSpellExtraArgs(aurEff)
.SetTriggeringSpell(eventInfo.GetProcSpell())
.AddSpellMod(SpellValueMod.BasePoint0, (int)damage));
}
public override void Register()
{
OnEffectProc.Add(new(HandleProc, 0, AuraType.Dummy));
}
}
}