Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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
                }
            }
        }