public bool SkillCast(SkillArg arg) { ActorExt sActor = arg.Caster; ActorExt dActor = arg.Target; Skill skill = arg.Skill; ushort dir = arg.Dir; DateTime now = DateTime.Now; if (skill.BaseData.Effect != 0) { skill.BaseData.Duration = (int)Effect.EffectManager.Instance[skill.BaseData.Effect].Duration; } if (!sActor.Status.CastingSkill || arg.CastFinished) { if (arg.CastFinished || CheckSkillCast(sActor, dActor, dir, skill)) { if (arg.Skill.BaseData.ManaCost > 0 && !arg.CastFinished && arg.Caster.ActorType == SmartEngine.Network.Map.ActorType.PC) { System.Threading.Interlocked.Add(ref arg.Caster.MP, -arg.Skill.BaseData.ManaCost); ((ActorPC)arg.Caster).Client().SendPlayerMP(); } if (arg.Caster.Tasks.TryGetValue("SwordBlocking", out Task duration)) { duration.Deactivate(); } if (arg.Caster.Tasks.TryGetValue("Teleport", out duration)) { duration.Deactivate(); } if (arg.Caster.Tasks.TryGetValue("FoodRecovery", out duration)) { duration.Deactivate(); } if (arg.Caster.Tasks.TryGetValue("Stealth", out duration)) { duration.Deactivate(); } if (skill.BaseData.CastTime == 0 || (skill.BaseData.ShouldApproach && arg.CastFinished) || (skill.BaseData.ActionTime != 0 && skill.BaseData.CastTime == 0) || arg.CastFinished) { sActor.Status.CastingSkill = true; if (skill.BaseData.ShouldApproach || skill.BaseData.ActionTime != 0) { int castTime = 0; if (skill.BaseData.ShouldApproach) { castTime = 500; if (arg.Target != null && arg.Target != arg.Caster) { castTime = arg.Caster.DistanceToActor(arg.Target) * arg.Skill.BaseData.ApproachTimeRate; } arg.ApproachTime = castTime; BroadcastSkillCast(arg, SkillMode.CastActionDelay); } else if (skill.BaseData.ActionTime > 0) { castTime = skill.BaseData.ActionTime; arg.ApproachTime = castTime; BroadcastSkillCast(arg, SkillMode.CastActionDelay); } if ((arg.Caster is ActorPC pc) && arg.Skill.BaseData.MovementLockOnCasting > 0) { SkillHandlers.Common.Additions.MovementLock mLock = new SkillHandlers.Common.Additions.MovementLock(pc.Client(), arg.Skill.BaseData.MovementLockOnCasting); mLock.Activate(); } HandleSkillCasting(arg); SkillCastTask task = new SkillCastTask(castTime, sActor, arg); sActor.Tasks["SkillCast"] = task; task.Activate(); } else { SkillActivate(arg); } } else { sActor.Status.CastingSkill = true; int castTime = 0; BroadcastSkillCast(arg, SkillMode.Cast); castTime = skill.BaseData.CastTime; if ((arg.Caster is ActorPC pc) && arg.Skill.BaseData.MovementLockOnCasting > 0) { SkillHandlers.Common.Additions.MovementLock mLock = new SkillHandlers.Common.Additions.MovementLock(pc.Client(), arg.Skill.BaseData.MovementLockOnCasting); mLock.Activate(); } HandleSkillCasting(arg); SkillCastTask task = new SkillCastTask(castTime, sActor, arg); sActor.Tasks["SkillCast"] = task; task.Activate(); } return(true); } return(false); } else { return(false); } }
public void SkillActivate(SkillArg arg) { ActorPC pc = arg.Caster as ActorPC; arg.Caster.Status.CastingSkill = false; if (pc != null && arg.Skill.BaseData.MovementLockOnAction > 0) { SkillHandlers.Common.Additions.MovementLock mLock = new SkillHandlers.Common.Additions.MovementLock(pc.Client(), arg.Skill.BaseData.MovementLockOnAction); mLock.Activate(); } if (arg.Caster.Status.Dead) { return; } arg.Caster.Status.LastSkillID = arg.Skill.ID; if (!arg.Caster.Status.Dead && !arg.Caster.Status.Down) { HandleSkillCastFinish(arg); BroadcastSkillCast(arg, SkillMode.Activate); HandleSkillActivate(arg); } if (pc != null) { int duration = arg.AffectedActors.Count > 0 ? 30000 : 5000; if (pc.Tasks.TryGetValue("CombatStatusTask", out Task task)) { if (task.DueTime < duration) { task.DueTime = duration; } task.Activate(); } else { Tasks.Player.CombatStatusTask ct = new Tasks.Player.CombatStatusTask(duration, pc); pc.Tasks["CombatStatusTask"] = ct; ct.Activate(); } } arg.ActivationIndex++; if (arg.Skill.BaseData.Duration <= 0) { BroadcastSkillCast(arg, SkillMode.End); } if (arg.ActivationIndex < arg.Skill.BaseData.ActivationTimes.Count) { arg.Caster.Status.CastingSkill = true; SkillCastTask task = new SkillCastTask(arg.Skill.BaseData.ActivationTimes[arg.ActivationIndex - 1], arg.Caster, arg); arg.Caster.Tasks["SkillCast"] = task; task.Activate(); } else { if (arg.Skill.BaseData.CoolDown != 0) { arg.Skill.CoolDownEndTime = DateTime.Now.AddMilliseconds(arg.Skill.BaseData.CoolDown); } //if (arg.Skill.BaseData.ActivationTimes.Count < arg.ActivationIndex) //{ // Logger.Log.Debug($"ActivationTimes for skill:{arg.Skill.ID} is smaller than index:{arg.ActivationIndex}"); //} if (arg.Caster.ActorType == ActorType.NPC) { arg.Caster.Status.SkillCooldownEnd = DateTime.Now.AddMilliseconds(arg.Skill.BaseData.ActivationTimes.Count > 0 && arg.Skill.BaseData.ActivationTimes.Count > (arg.ActivationIndex - 1) ? arg.Skill.BaseData.ActivationTimes[arg.ActivationIndex - 1] : 500); } else { arg.Caster.Status.SkillCooldownEnd = DateTime.Now.AddMilliseconds(100);//TODO: Use real data } } }