Aura.Channel.Skills.CombatActionPack.Handle C# (CSharp) Метод

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

Handles actions and broadcasts action pack.
public Handle ( ) : void
Результат void
		public void Handle()
		{
			foreach (var action in this.Actions)
			{
				// Stat update
				Send.StatUpdate(action.Creature, StatUpdateType.Private, Stat.Life, Stat.LifeInjured, Stat.Mana, Stat.Stamina);
				Send.StatUpdate(action.Creature, StatUpdateType.Public, Stat.Life, Stat.LifeInjured);

				// If target action
				if (action.Category == CombatActionCategory.Target)
				{
					var tAction = action as TargetAction;

					if (action.Creature.IsPlayer)
					{
						// Max target stun for players == 2000?
						action.Stun = Math.Min((short)2000, action.Stun);

						// Break eggs on knock back
						if (tAction.IsKnockBack && ChannelServer.Instance.Conf.World.BrokenEggs)
						{
							// Search for usable (non-broken) eggs, sparing VIP eggs.
							var eggs = action.Creature.Inventory.GetItems(a => a.HasTag("/usable/food/cooking/solid/*egg/") && a.Info.Pocket != Pocket.VIPInventory);
							foreach (var egg in eggs)
							{
								// Replace egg
								var brokenEgg = new Item(50011);
								brokenEgg.Amount = egg.Amount;

								// Remove egg and place the broken one at the
								// same spot.
								if (action.Creature.Inventory.Remove(egg))
									action.Creature.Inventory.Add(brokenEgg, egg.Info.Pocket);
							}
						}
					}

					// Put target into battle stance if it was hit.
					// Fix for #435, Mimics not opening after being got hit
					// by Windmill "passively", because they didn't aggro.
					if (!action.Creature.IsInBattleStance)
						action.Creature.IsInBattleStance = true;

					// Reduce stun if pinged
					// If the second hit of the second set of dual wield hits
					// pings, the monster's stun on the client is longer than
					// on the server, which causes a little glitch, where a
					// monster might attack while it's still visibly stunned.
					// Should stun from combat be *added*, instead of *set*?
					if (!tAction.IsKnockBack && tAction.Has(EffectFlags.HeavyStander))
						action.Stun = Math.Min((short)1000, action.Stun);

					action.Creature.Stun = action.Stun;

					// Mana Shield flag
					if (tAction.ManaDamage > 0 && tAction.Damage == 0)
						tAction.Set(TargetOptions.ManaShield);

					// On attack events
					ChannelServer.Instance.Events.OnCreatureAttacked(tAction);
					if (this.Attacker.IsPlayer)
						ChannelServer.Instance.Events.OnCreatureAttackedByPlayer(tAction);

					// OnHit AI event
					//action.Creature.Aggro(tAction.Attacker);
					var npc = action.Creature as NPC;
					if (npc != null && npc.AI != null)
					{
						npc.AI.OnTargetActionHit(tAction);
					}

					// Cancel target's skill
					// Don't cancel Defense, which is still active at this point,
					// a Complete for it is sent by the client shortly after.
					// That won't happen if Smash is the attacker skill,
					// but that's official behavior.
					var activeSkill = action.Creature.Skills.ActiveSkill;
					if (activeSkill != null && activeSkill.Info.Id != SkillId.Defense)
					{
						var custom = ChannelServer.Instance.SkillManager.GetHandler(activeSkill.Info.Id) as ICustomHitCanceler;
						var stackMax = activeSkill.RankData.StackMax;
						var cancel = false;

						// Cancel non stackable skills on hit, wait for a
						// knock back for stackables
						if (stackMax > 1)
							cancel = action.IsKnockBack;
						else
							cancel = true;

						if (cancel)
						{
							if (custom == null)
								action.Creature.Skills.CancelActiveSkill();
							else
								custom.CustomHitCancel(action.Creature, tAction);
						}
					}

					// Cancel rest
					if (action.Creature.Has(CreatureStates.SitDown))
					{
						var restHandler = ChannelServer.Instance.SkillManager.GetHandler<Rest>(SkillId.Rest);
						if (restHandler != null)
							restHandler.Stop(action.Creature, action.Creature.Skills.Get(SkillId.Rest));
					}

					// Remember knock back/down
					tAction.Creature.WasKnockedBack = tAction.Has(TargetOptions.KnockBack) || tAction.Has(TargetOptions.KnockDown) || tAction.Has(TargetOptions.Smash);

					if (tAction.Has(TargetOptions.KnockDown))
						tAction.Creature.KnockDownTime = DateTime.Now.AddMilliseconds(tAction.Stun);

					// Stability meter
					// TODO: Limit it to "targetees"?
					var visibleCreatures = tAction.Creature.Region.GetVisibleCreaturesInRange(tAction.Creature);
					foreach (var cr in visibleCreatures)
						Send.StabilityMeterUpdate(cr, tAction.Creature);
				}
				// If attacker action
				else if (action.Category == CombatActionCategory.Attack)
				{
					var aAction = action as AttackerAction;

					if (action.Creature.IsPlayer && action.SkillId >= SkillId.RangedAttack && action.SkillId <= SkillId.UrgentShot && !AuraData.FeaturesDb.IsEnabled("CombatSystemRenewal"))
					{
						// Players don't seem to be stunned from ranging
						// on old officials. While the proper stun is sent
						// to the client, for some reason you didn't need
						// to wait. Since we don't know how officials did
						// that, we'll just cap the stun time.
						action.Stun = 0;
					}

					action.Creature.Stun = action.Stun;

					var npc = action.Creature as NPC;
					if (npc != null && npc.AI != null && action.SkillId != SkillId.CombatMastery)
						npc.AI.OnUsedSkill(aAction);

					ChannelServer.Instance.Events.OnCreatureAttacks(aAction);
				}
			}

			// Send combat action
			Send.CombatAction(this);

			// Skill used
			if (this.SkillId != SkillId.CombatMastery)
				Send.CombatUsedSkill(this.Attacker, this.SkillId);

			// End combat action
			Send.CombatActionEnd(this.Attacker, this.Id);
		}
	}