/// <summary>
/// Uses WM, attacking targets.
/// </summary>
/// <param name="attacker"></param>
/// <param name="skill"></param>
/// <param name="targetAreaId"></param>
/// <param name="unkInt1"></param>
/// <param name="unkInt2"></param>
public void Use(Creature attacker, Skill skill, long targetAreaId, int unkInt1, int unkInt2)
{
var range = this.GetRange(attacker, skill);
var targets = attacker.GetTargetableCreaturesInRange(range, TargetableOptions.AddAttackRange);
// Check targets
if (targets.Count == 0)
{
Send.Notice(attacker, Localization.Get("There isn't a target nearby to use that on."));
Send.SkillUseSilentCancel(attacker);
return;
}
// Create actions
var cap = new CombatActionPack(attacker, skill.Info.Id);
var aAction = new AttackerAction(CombatActionType.SpecialHit, attacker, targetAreaId);
aAction.Set(AttackerOptions.Result);
aAction.Stun = CombatMastery.GetAttackerStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true);
cap.Add(aAction);
var survived = new List <Creature>();
var rnd = RandomProvider.Get();
// Check crit
var crit = false;
if (attacker.Skills.Has(SkillId.CriticalHit, SkillRank.RF))
{
crit = (rnd.Next(100) < attacker.GetTotalCritChance(0));
}
// Handle all targets
foreach (var target in targets)
{
target.StopMove();
var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id);
tAction.Delay = 300; // Usually 300, sometimes 350?
// Calculate damage
var damage = attacker.GetRndTotalDamage();
damage *= skill.RankData.Var1 / 100f;
// Elementals
damage *= attacker.CalculateElementalDamageMultiplier(target);
// Crit bonus
if (crit)
{
CriticalHit.Handle(attacker, 100, ref damage, tAction);
}
// Handle skills and reductions
SkillHelper.HandleDefenseProtection(target, ref damage);
SkillHelper.HandleConditions(attacker, target, ref damage);
Defense.Handle(aAction, tAction, ref damage);
ManaShield.Handle(target, ref damage, tAction);
HeavyStander.Handle(attacker, target, ref damage, tAction);
// Clean Hit if not defended nor critical
if (tAction.SkillId != SkillId.Defense && !tAction.Has(TargetOptions.Critical))
{
tAction.Set(TargetOptions.CleanHit);
}
// Take damage if any is left
if (damage > 0)
{
target.TakeDamage(tAction.Damage = damage, attacker);
}
// Knock down on deadly
if (target.Conditions.Has(ConditionsA.Deadly))
{
tAction.Set(TargetOptions.KnockDown);
tAction.Stun = CombatMastery.GetTargetStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true);
}
// Finish if dead, knock down if not defended
if (target.IsDead)
{
tAction.Set(TargetOptions.KnockDownFinish);
}
else if (tAction.SkillId != SkillId.Defense)
{
tAction.Set(TargetOptions.KnockDown);
}
// Anger Management
if (!target.IsDead)
{
survived.Add(target);
}
// Stun and shove if not defended
if (target.IsDead || tAction.SkillId != SkillId.Defense || target.Conditions.Has(ConditionsA.Deadly))
{
tAction.Stun = CombatMastery.GetTargetStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true);
target.Stability = Creature.MinStability;
attacker.Shove(target, KnockbackDistance);
}
// Add action
cap.Add(tAction);
}
// Update current weapon
SkillHelper.UpdateWeapon(attacker, targets.FirstOrDefault(), ProficiencyGainType.Melee, attacker.RightHand, attacker.LeftHand);
// Only select a random aggro if there is no aggro yet,
// WM only aggroes one target at a time.
if (survived.Count != 0 && attacker.Region.CountAggro(attacker) < 1)
{
var aggroTarget = survived.Random();
aggroTarget.Aggro(attacker);
}
// Reduce life in old combat system
if (!AuraData.FeaturesDb.IsEnabled("CombatSystemRenewal"))
{
var amount = (attacker.LifeMax < 10 ? 2 : attacker.LifeMax / 10);
attacker.ModifyLife(-amount);
// TODO: Invincibility
}
// Spin it~
Send.UseMotion(attacker, 8, 4);
cap.Handle();
Send.SkillUse(attacker, skill.Info.Id, targetAreaId, unkInt1, unkInt2);
skill.Stacks = 0;
}