public void Use(Creature attacker, Skill skill, Packet packet)
{
// Set full charge variable
attacker.Temp.LightningRodFullCharge = (DateTime.Now >= attacker.Temp.LightningRodPrepareTime.AddMilliseconds(skill.RankData.Var3));
// Get direction for target Area
var direction = Mabi.MabiMath.ByteToRadian(attacker.Direction);
var attackerPos = attacker.GetPosition();
// Calculate polygon points
var r = MabiMath.ByteToRadian(attacker.Direction);
var poe = attackerPos.GetRelative(r, 800);
var pivot = new Point(poe.X, poe.Y);
var p1 = new Point(pivot.X - SkillLength / 2, pivot.Y - SkillWidth / 2);
var p2 = new Point(pivot.X - SkillLength / 2, pivot.Y + SkillWidth / 2);
var p3 = new Point(pivot.X + SkillLength / 2, pivot.Y + SkillWidth / 2);
var p4 = new Point(pivot.X + SkillLength / 2, pivot.Y - SkillWidth / 2);
p1 = this.RotatePoint(p1, pivot, r);
p2 = this.RotatePoint(p2, pivot, r);
p3 = this.RotatePoint(p3, pivot, r);
p4 = this.RotatePoint(p4, pivot, r);
// TargetProp
var lProp = new Prop(280, attacker.RegionId, poe.X, poe.Y, MabiMath.ByteToRadian(attacker.Direction), 1f, 0f, "single");
attacker.Region.AddProp(lProp);
// Prepare Combat Actions
var cap = new CombatActionPack(attacker, skill.Info.Id);
var targetAreaId = new Location(attacker.RegionId, poe).ToLocationId();
var aAction = new AttackerAction(CombatActionType.SpecialHit, attacker, targetAreaId);
aAction.Set(AttackerOptions.KnockBackHit1 | AttackerOptions.UseEffect);
aAction.PropId = lProp.EntityId;
cap.Add(aAction);
// Get targets in Polygon - includes collission check
var targets = attacker.Region.GetCreaturesInPolygon(p1, p2, p3, p4).Where(x => attacker.CanTarget(x) && !attacker.Region.Collisions.Any(attacker.GetPosition(), x.GetPosition())).ToList();
var rnd = RandomProvider.Get();
// Check crit
var crit = false;
var critSkill = attacker.Skills.Get(SkillId.CriticalHit);
if (critSkill != null && critSkill.Info.Rank > SkillRank.Novice)
{
var critChance = Math2.Clamp(0, 30, attacker.GetTotalCritChance(0));
if (rnd.NextDouble() * 100 < critChance)
crit = true;
}
foreach (var target in targets)
{
var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, SkillId.CombatMastery);
tAction.Set(TargetOptions.None);
tAction.AttackerSkillId = skill.Info.Id;
cap.Add(tAction);
var damage = attacker.GetRndMagicDamage(skill, skill.RankData.Var1, skill.RankData.Var2);
// Add damage if the skill is fully charged
var dmgMultiplier = skill.RankData.Var4 / 100f;
if (attacker.Temp.LightningRodFullCharge)
{
damage += (damage * dmgMultiplier);
}
// Critical Hit
if (crit)
{
var bonus = critSkill.RankData.Var1 / 100f;
damage = damage + (damage * bonus);
tAction.Set(TargetOptions.Critical);
}
// MDef and MProt
SkillHelper.HandleMagicDefenseProtection(target, ref damage);
// Conditions
SkillHelper.HandleConditions(attacker, target, ref damage);
// Mana Deflector
var delayReduction = ManaDeflector.Handle(attacker, target, ref damage, tAction);
// Mana Shield
ManaShield.Handle(target, ref damage, tAction);
// Apply Damage
target.TakeDamage(tAction.Damage = damage, attacker);
// Stun Time
tAction.Stun = TargetStun;
// Death or Knockback
if (target.IsDead)
{
tAction.Set(TargetOptions.FinishingKnockDown);
attacker.Shove(target, KnockbackDistance);
}
else
{
// Always knock down
if (target.Is(RaceStands.KnockDownable))
{
tAction.Set(TargetOptions.KnockDown);
attacker.Shove(target, KnockbackDistance);
}
}
}
// Update current weapon
SkillHelper.UpdateWeapon(attacker, targets.FirstOrDefault(), ProficiencyGainType.Melee, attacker.RightHand);
cap.Handle();
Send.Effect(attacker, Effect.LightningRod, (int)LightningRodEffect.Attack, poe.X, poe.Y);
Send.SkillUse(attacker, skill.Info.Id, targetAreaId, 0, 1);
skill.Train(1); // Use the Skill
attacker.Region.RemoveProp(lProp);
}