public Attack(Creature.Creature creature, UseSkillArgs args, Action onStageEnd, Action onFinish) { if (creature.Attack != null) creature.Attack.Release(); Args = args; Creature = creature; OnStageEnd = onStageEnd; OnFinish = onFinish; }
public override void Release() { base.Release(); if (Creature == null) return; if (Args != null) Args.Release(); Args = null; Creature = null; OnStageEnd = null; OnFinish = null; }
private void ProcessSkill(Creature creature, UseSkillArgs args, Skill skill, Projectile projectile = null) { bool isProjectileSkill = skill.Type == SkillType.Projectile || skill.Type == SkillType.Userslug; if (!isProjectileSkill) { if (skill.ChargingStageList == null || skill.ChargingStageList.ChargeStageList.Count == 0) { if (skill.Precondition.Cost.Hp > 0) CreatureLogic.HpChanged(creature, creature.LifeStats.MinusHp(skill.Precondition.Cost.Hp)); if (skill.Precondition.Cost.Mp > 0) CreatureLogic.MpChanged(creature, creature.LifeStats.MinusMp(skill.Precondition.Cost.Mp)); } if (!args.IsDelaySkill || args.IsDelayStart) { if (args.TargetPosition.IsNull()) { double angle = args.StartPosition.Heading*Math.PI/32768; args.StartPosition.CopyTo(args.TargetPosition); args.TargetPosition.X += 100*(float) Math.Cos(angle); args.TargetPosition.Y += 100*(float) Math.Sin(angle); } // ReSharper disable ImplicitlyCapturedClosure creature.Attack = new Attack(creature, args, () => GlobalLogic.AttackStageEnd(creature), () => GlobalLogic.AttackFinished(creature)); // ReSharper restore ImplicitlyCapturedClosure VisibleService.Send(creature, new SpAttack(creature, creature.Attack)); VisibleService.Send(creature, new SpAttackDestination(creature, creature.Attack)); if (!args.IsDelaySkill) ProcessStages(creature, skill); else { Player player = creature as Player; if (player != null && skill.BaseId == 20100 && (player.PlayerData.Class == PlayerClass.Berserker || player.PlayerData.Class == PlayerClass.Lancer)) { player.EffectsImpact.ResetChanges(player); //Set IsBlockFrontAttacks } } ProcessMove(creature, skill); } } else { creature.Attack.Args.IsTargetAttack = args.IsTargetAttack; creature.Attack.Args.Targets = args.Targets; ProcessProjectileTargets(creature, skill, projectile); } AiLogic.OnUseSkill(creature, skill); if (skill.ChargingStageList != null) { if (args.IsDelayStart) { int uid = creature.Attack.UID; ThreadPool.QueueUserWorkItem( o => { Thread.Sleep(750); for (int i = 1; i < skill.ChargingStageList.ChargeStageList.Count; i++) { if (creature.Attack.UID != uid) return; creature.Attack.NextStage(); if (i != 3) Thread.Sleep(750); } }); } } else ProcessTargets(creature, skill); }
public void UseSkill(IConnection connection, UseSkillArgs args) { Player player = connection.Player; Skill skill = args.GetSkill(player); if (skill == null) return; if (skill.ChargingStageList != null) args.IsChargeSkill = true; if (skill.Type == SkillType.Mount) { MountService.ProcessMount(player, skill.Id); new SpSkillCooldown(skill.Id, skill.Precondition.CoolTime).Send(player.Connection); return; } if (player.Attack != null && !player.Attack.IsFinished) { if (player.Attack.Args.IsDelaySkill) { int stage = player.Attack.Stage; if (player.Attack.Args.IsChargeSkill) { skill = player.Attack.Args.GetSkill(player); if (skill.ChargingStageList != null && skill.ChargingStageList.ChargeStageList.Count > stage) { int useHp = (int) (skill.ChargingStageList.CostTotalHp* skill.ChargingStageList.ChargeStageList[stage].CostHpRate); int useMp = (int) (skill.ChargingStageList.CostTotalMp* skill.ChargingStageList.ChargeStageList[stage].CostMpRate); if (player.LifeStats.Hp <= useHp) { SystemMessages.YouCannotUseThatSkillAtTheMoment.Send(player.Connection); stage = -1; } else if (player.LifeStats.Mp < useMp) { SystemMessages.NotEnoughMp.Send(player.Connection); stage = -1; } else { if (useHp > 0) CreatureLogic.HpChanged(player, player.LifeStats.MinusHp(useHp)); if (useMp > 0) CreatureLogic.MpChanged(player, player.LifeStats.MinusMp(useMp)); args = new UseSkillArgs { SkillId = player.Attack.Args.SkillId + 10 + stage, StartPosition = player.Position.Clone(), TargetPosition = player.Attack.Args.TargetPosition, }; } } else stage = -1; } player.Attack.Finish(); if (skill.BaseId == 20100 && (player.PlayerData.Class == PlayerClass.Berserker || player.PlayerData.Class == PlayerClass.Lancer)) { player.EffectsImpact.ResetChanges(player); //Set IsBlockFrontAttacks } if (player.Attack.Args.IsChargeSkill && stage != -1) UseSkill(connection, args); return; } if (args.SkillId / 10000 == player.Attack.Args.SkillId / 10000) { player.Attack.Finish(); if (player.Attack.Args.Targets.Count == 0) return; args.Targets = new List<Creature>(player.Attack.Args.Targets); ProcessSkill(player, args, skill); } return; } if (!CheckRequirements(player, skill)) return; args.StartPosition.CopyTo(player.Position); ProcessSkill(player, args, skill); }
public static void UseSkill(IConnection connection, UseSkillArgs args) { SkillEngine.UseSkill(connection, args); }