コード例 #1
0
ファイル: Unit.Combat.cs プロジェクト: ray2006/WCell
		/// <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();
		}
コード例 #2
0
ファイル: Unit.Combat.cs プロジェクト: KroneckerX/WCell
		/// <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;
		}
コード例 #3
0
ファイル: Unit.Combat.cs プロジェクト: WCellFR/WCellFR
		/// <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();
		}