/// <summary> /// Do a single attack using the given Weapon and AttackAction. /// </summary> /// <param name="weapon"></param> /// <param name="action"></param> public void Strike(IWeapon weapon, DamageAction action, Unit target) { if (!target.IsInWorld) { return; } if (weapon == null) { log.Error("Trying to strike without weapon: " + this); return; } //if (IsMovementConrolled) //{ // // stop running when landing a hit // m_Movement.Stop(); //} target.IsInCombat = true; action.Victim = target; action.Attacker = this; action.Weapon = weapon; if (m_pendingCombatAbility != null && m_pendingCombatAbility.IsCasting) { // Pending combat ability var ability = m_pendingCombatAbility; // send pending animation if (ability.IsInstant) { m_pendingCombatAbility.SendCastStart(); } if (!ability.Spell.IsRangedAbility) { m_pendingCombatAbility.CheckHitAndSendSpellGo(true); } // prevent the ability from cancelling itself m_pendingCombatAbility = null; action.Schools = ability.Spell.SchoolMask; action.SpellEffect = ability.Spell.Effects[0]; if (ability.Targets.Count > 0) { action.IsDot = false; // AoE spell foreach (var targ in ability.Targets) { var dmg = GetWeaponDamage(weapon, ability); action.Reset(this, (Unit)targ, weapon, dmg); action.DoAttack(); if (ability.Spell.IsDualWieldAbility) { action.Reset(this, (Unit)targ, weapon, Utility.Random((int)MinOffHandDamage, (int)MaxOffHandDamage + 1)); action.DoAttack(); } } } else { // single target // calc damage action.Damage = GetWeaponDamage(weapon, m_pendingCombatAbility); if (!action.DoAttack() && ability.Spell.AttributesExC.HasFlag(SpellAttributesExC.RequiresTwoWeapons)) { // missed and is not attacking with both weapons -> don't trigger spell CancelPendingAbility(); return; } } // Impact and trigger remaining effects (if not cancelled) if (!ability.Spell.IsRangedAbility) { ability.Impact(ability.Spell.IsOnNextStrike); } } else { // no combat ability m_extraAttacks += 1; do { // calc damage action.Damage = GetWeaponDamage(weapon, m_pendingCombatAbility); action.Schools = weapon.Damages.AllSchools(); if (action.Schools == DamageSchoolMask.None) { action.Schools = DamageSchoolMask.Physical; } // normal attack action.DoAttack(); } while (--m_extraAttacks > 0); } action.OnFinished(); }
/// <summary> /// Do a single attack on the target using given weapon, ability and action. /// </summary> public ProcHitFlags Strike(IWeapon weapon, DamageAction action, Unit target, SpellCast ability) { ProcHitFlags procHitFlags = ProcHitFlags.None; EnsureContext(); if (!IsAlive) { return procHitFlags; } if (!target.IsInContext || !target.IsAlive) { return procHitFlags; } if (weapon == null) { log.Error("Trying to strike without weapon: " + this); return procHitFlags; } //if (IsMovementControlled) //{ // // stop running when landing a hit // m_Movement.Stop(); //} target.IsInCombat = true; action.Victim = target; action.Attacker = this; action.Weapon = weapon; if (ability != null) { action.Schools = ability.Spell.SchoolMask; action.SpellEffect = ability.Spell.Effects[0]; // calc damage GetWeaponDamage(action, weapon, ability); procHitFlags = action.DoAttack(); if (ability.Spell.AttributesExC.HasFlag(SpellAttributesExC.RequiresTwoWeapons) && m_offhandWeapon != null) { // also strike with offhand action.Reset(this, target, m_offhandWeapon); GetWeaponDamage(action, m_offhandWeapon, ability); procHitFlags |= action.DoAttack(); m_lastOffhandStrike = Environment.TickCount; } } else { // no combat ability m_extraAttacks += 1; do { // calc damage GetWeaponDamage(action, weapon, null); action.Schools = weapon.Damages.AllSchools(); if (action.Schools == DamageSchoolMask.None) { action.Schools = DamageSchoolMask.Physical; } // normal attack action.DoAttack(); } while (--m_extraAttacks > 0); } action.OnFinished(); return procHitFlags; }
/// <summary> /// Do a single attack using the given Weapon and AttackAction. /// </summary> /// <param name="weapon"></param> /// <param name="action"></param> public void Strike(IWeapon weapon, DamageAction action, Unit target) { if (weapon == null) { log.Error("Trying to strike without weapon: " + this); return; } //if (IsMovementConrolled) //{ // // stop running when landing a hit // m_Movement.Stop(); //} // calc damage if (weapon == m_offhandWeapon) { action.Damage = Utility.Random((int)MinOffHandDamage, (int)MaxOffHandDamage + 1); } else { if (weapon.IsRanged) { action.Damage = Utility.Random((int)MinRangedDamage, (int)MaxRangedDamage + 1); } else { action.Damage = Utility.Random((int)MinDamage, (int)MaxDamage + 1); } } action.Victim = target; action.Attacker = this; action.Weapon = weapon; if (m_pendingCombatAbility != null && m_pendingCombatAbility.IsCasting) { // Pending combat ability var ability = m_pendingCombatAbility; // get boni, damage and let the Spell impact var multiplier = 100; SpellEffect effect = null; foreach (var effectHandler in ability.Handlers) { if (effectHandler.Effect.IsStrikeEffectFlat) { action.Damage += effectHandler.CalcEffectValue(); } else if (effectHandler.Effect.IsStrikeEffectPct) { multiplier += effectHandler.CalcEffectValue(); } if (effect == null) { // use the first effect effect = effectHandler.Effect; } } action.Damage = (action.Damage * multiplier) / 100; // send pending animation if (ability.IsInstant) { m_pendingCombatAbility.SendCastStart(); } if (!ability.Spell.IsRangedAbility) { m_pendingCombatAbility.CheckHitAndSendSpellGo(true); } // prevent the ability from cancelling itself m_pendingCombatAbility = null; action.Schools = ability.Spell.SchoolMask; action.SpellEffect = effect; if (ability.Spell.IsAreaSpell) { var totalDmg = action.Damage; action.IsDot = false; // AoE spell foreach (var targ in ability.Targets) { action.Reset(this, (Unit)targ, weapon, totalDmg); action.DoAttack(); if (ability.Spell.IsDualWieldAbility) { action.Reset(this, (Unit)targ, weapon, Utility.Random((int)MinOffHandDamage, (int)MaxOffHandDamage + 1)); action.DoAttack(); } } } else { // single target if (!action.DoAttack() && ability.Spell.AttributesExC.HasFlag(SpellAttributesExC.RequiresTwoWeapons)) { // missed and is not attacking with both weapons -> don't trigger spell CancelPendingAbility(); return; } } // Impact and trigger remaining effects (if not cancelled) if (!ability.Spell.IsRangedAbility) { ability.Impact(ability.Spell.IsOnNextStrike); } } else { m_extraAttacks += 1; do { action.Schools = weapon.Damages.AllSchools(); if (action.Schools == DamageSchoolMask.None) { action.Schools = DamageSchoolMask.Physical; } // normal attack action.DoAttack(); } while (--m_extraAttacks > 0); } action.OnFinished(); }