Aura.Channel.Skills.Combat.ArrowRevolver.Use C# (CSharp) Метод

Use() публичный Метод

Uses the skill.
public Use ( Creature attacker, Skill skill, long targetEntityId ) : CombatSkillResult
attacker Aura.Channel.World.Entities.Creature
skill Skill
targetEntityId long
Результат CombatSkillResult
		public CombatSkillResult Use(Creature attacker, Skill skill, long targetEntityId)
		{
			// Get target
			var target = attacker.Region.GetCreature(targetEntityId);
			if (target == null)
				return CombatSkillResult.InvalidTarget;

			// "Cancels" the skill
			// 800 = old load time? == aAction.Stun? Varies? Doesn't seem to be a stun.
			Send.SkillUse(attacker, skill.Info.Id, AttackerStun, 1);

			var chance = attacker.AimMeter.GetAimChance(target);
			var rnd = RandomProvider.Get().NextDouble() * 100;
			var successfulHit = (rnd < chance);

			// Actions
			var cap = new CombatActionPack(attacker, skill.Info.Id);

			var aAction = new AttackerAction(CombatActionType.RangeHit, attacker, targetEntityId);
			aAction.Set(AttackerOptions.Result);
			aAction.Stun = AttackerStun;
			cap.Add(aAction);

			// Target action if hit
			if (successfulHit)
			{
				target.StopMove();

				var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id);
				tAction.Set(TargetOptions.Result);
				tAction.Stun = TargetStun;

				cap.Add(tAction);

				// Damage
				// Formula unofficial, but it kinda matches what you would
				// expect from the skill, and what players believed the damage
				// to be, back in G2.
				// bonus = (100 - (6 - stacks) * 5 + rank, +var2 on last shot
				// I'm using rank instead of Var1, which goes from 1-15 in
				// AR2, so AR1 gets a little bonus as well, as AR1's Var1 and
				// 2 are 0.
				// With this formula, the bonus range (1st shot rF vs 5th shot
				// r1) is 76~110% for AR1, and 76~140% for AR2.
				var bonus = 100f - (6 - skill.Stacks) * 5f + (byte)skill.Info.Rank;
				if (skill.Stacks == 1)
					bonus += skill.RankData.Var2;

				var damage = attacker.GetRndRangedDamage() * (bonus / 100f);

				// Elementals
				damage *= attacker.CalculateElementalDamageMultiplier(target);

				// More damage with fire arrow
				if (attacker.Temp.FireArrow)
					damage *= FireBonus;

				// Critical Hit
				var critChance = attacker.GetRightCritChance(target.Protection);
				CriticalHit.Handle(attacker, critChance, ref damage, tAction);

				// Subtract target def/prot
				SkillHelper.HandleDefenseProtection(target, ref damage);

				// Conditions
				SkillHelper.HandleConditions(attacker, target, ref damage);

				// Defense
				Defense.Handle(aAction, tAction, ref damage);

				// Mana Shield
				ManaShield.Handle(target, ref damage, tAction);

				// Natural Shield
				var nsResult = NaturalShield.Handle(attacker, target, ref damage, tAction);
				var delayReduction = nsResult.DelayReduction;
				var pinged = nsResult.Pinged;

				// Deal with it!
				if (damage > 0)
				{
					target.TakeDamage(tAction.Damage = damage, attacker);
					SkillHelper.HandleInjury(attacker, target, damage);
				}

				// Aggro
				target.Aggro(attacker);

				// Knock down on deadly
				if (target.Conditions.Has(ConditionsA.Deadly))
					tAction.Set(TargetOptions.KnockDown);

				// Death/Knockback
				if (target.IsDead)
				{
					tAction.Set(TargetOptions.FinishingKnockDown);
				}
				else
				{
					// Insta-recover in knock down
					if (target.IsKnockedDown)
					{
						tAction.Stun = 0;
					}
					// Knock down if hit repeatedly
					else if (target.Stability < 30)
					{
						tAction.Set(TargetOptions.KnockDown);
					}
					// Normal stability reduction
					else
					{
						var stabilityReduction = StabilityReduction;

						// Reduce reduction, based on ping
						// According to the Wiki, "the Knockdown Gauge
						// [does not] build up", but it's still possible
						// to knock back with repeated hits. The stability
						// reduction is probably reduced, just like stun.
						if (delayReduction > 0)
							stabilityReduction = (short)Math.Max(0, stabilityReduction - (stabilityReduction / 100 * delayReduction));

						target.Stability -= stabilityReduction;
						if (target.IsUnstable)
						{
							tAction.Set(TargetOptions.KnockBack);
						}
					}
				}

				// Knock Back
				if (tAction.IsKnockBack)
					attacker.Shove(target, KnockBackDistance);

				// Reduce stun, based on ping
				if (pinged && delayReduction > 0)
					tAction.Stun = (short)Math.Max(0, tAction.Stun - (tAction.Stun / 100 * delayReduction));
			}

			// Update current weapon
			SkillHelper.UpdateWeapon(attacker, target, ProficiencyGainType.Ranged, attacker.RightHand);

			// Skill training
			if (skill.Info.Rank == SkillRank.RF)
				skill.Train(1); // Try attacking with Arrow Revolver.

			// Reduce arrows
			if (attacker.Magazine != null && !ChannelServer.Instance.Conf.World.InfiniteArrows && !attacker.Magazine.HasTag("/unlimited_arrow/"))
				attacker.Inventory.Decrement(attacker.Magazine);

			// Reduce stack
			skill.Stacks--;

			// Handle
			cap.Handle();

			// Disable fire arrow effect
			if (attacker.Temp.FireArrow)
				Send.Effect(attacker, Effect.FireArrow, false);

			return CombatSkillResult.Okay;
		}