예제 #1
0
        public void Cast(SkillCast skillCast)
        {
            int spiritCost  = skillCast.GetSpCost();
            int staminaCost = skillCast.GetStaCost();

            if (Stats[PlayerStatId.Spirit].Current >= spiritCost && Stats[PlayerStatId.Stamina].Current >= staminaCost)
            {
                ConsumeSp(spiritCost);
                ConsumeStamina(staminaCost);
                SkillCast = skillCast;
                Session.SendNotice(skillCast.SkillId.ToString());

                // TODO: Move this and all others combat cases like recover sp to its own class.
                // Since the cast is always sent by the skill, we have to check buffs even when not doing damage.
                if (skillCast.IsBuffToOwner() || skillCast.IsBuffToEntity() || skillCast.IsBuffShield() || skillCast.IsDebuffToOwner())
                {
                    Status status = new Status(skillCast, Session.FieldPlayer.ObjectId, Session.FieldPlayer.ObjectId, 1);
                    StatusHandler.Handle(Session, status);
                }

                // Refresh out-of-combat timer
                if (CombatCTS != null)
                {
                    CombatCTS.Cancel();
                }
                CombatCTS = new CancellationTokenSource();
                CombatCTS.Token.Register(() => CombatCTS.Dispose());
                StartCombatStance(CombatCTS);
            }
        }
예제 #2
0
        public double GetDamage()
        {
            SkillCast skillCast = this;

            SkillDamage = DamageHandler.CalculateSkillDamage(skillCast).GetDamage();
            return(SkillDamage);
        }
예제 #3
0
        public SkillCast Cast(int skillId, short skillLevel, long skillSN, int unkValue)
        {
            SkillCast skillCast   = new SkillCast(skillId, skillLevel, skillSN, unkValue);
            int       spiritCost  = skillCast.GetSpCost();
            int       staminaCost = skillCast.GetStaCost();

            if (Stats[PlayerStatId.Spirit].Current >= spiritCost && Stats[PlayerStatId.Stamina].Current >= staminaCost)
            {
                ConsumeSp(spiritCost);
                ConsumeStamina(staminaCost);
                SkillCast = skillCast;

                if (skillCast.IsBuff())
                {
                    // TODO: Add buff timer
                }

                // Refresh out-of-combat timer
                if (CombatCTS != null)
                {
                    CombatCTS.Cancel();
                }
                CombatCTS = new CancellationTokenSource();
                CombatCTS.Token.Register(() => CombatCTS.Dispose());
                StartCombatEnd(CombatCTS);

                return(skillCast);
            }
            return(null);
        }
예제 #4
0
 private static void Remove(GameSession session, SkillCast skillCast, int sourceId)
 {
     Task.Run(async() =>
     {
         // TODO: Get the correct Region Skill Duration when calling chain Skills
         await Task.Delay(skillCast.DurationTick() + 5000);
         session.FieldManager.BroadcastPacket(RegionSkillPacket.Remove(sourceId));
     });
 }
예제 #5
0
 public Status(SkillCast skillCast, int owner, int source, int duration, int stacks)
 {
     SkillId   = skillCast.SkillId;
     UniqueId  = GuidGenerator.Int();
     Owner     = owner;
     Source    = source;
     Level     = skillCast.SkillLevel;
     Stacks    = stacks;
     SkillCast = skillCast;
     Start     = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds() + Environment.TickCount;
     End       = Start + duration;
 }
예제 #6
0
 public Status(SkillCast skillCast, int target, int source, int stacks)
 {
     SkillId   = skillCast.SkillId;
     UniqueId  = GuidGenerator.Int();
     Target    = target;
     Source    = source;
     Level     = skillCast.SkillLevel;
     Stacks    = stacks > 0 && stacks <= skillCast.MaxStack() ? stacks : skillCast.MaxStack();
     SkillCast = skillCast;
     Start     = Environment.TickCount;
     Duration  = skillCast.DurationTick();
     End       = Start + Duration;
 }
        public static DamageHandler CalculateDamage(SkillCast skill, Player player, Mob mob, bool isCrit = false)
        {
            if (player.GmFlags.Contains("oneshot"))
            {
                return(new DamageHandler(mob.Stats.Hp.Total, true));
            }
            // TODO: Calculate attack damage w/ stats
            double attackDamage    = 300;
            double skillDamageRate = isCrit ? skill.GetCriticalDamage() : skill.GetDamageRate();
            double skillDamage     = skillDamageRate * attackDamage;
            double enemyRes        = skill.GetSkillDamageType() == DamageType.Physical ? mob.Stats.PhysRes.Total : mob.Stats.MagRes.Total;
            double resPierce       = skill.GetSkillDamageType() == DamageType.Physical ? player.Stats[PlayerStatId.PhysAtk].Current : player.Stats[PlayerStatId.MagAtk].Current;
            // TODO: Fix damage multiplier (add pet?)
            double numerator = skillDamage * (1 + player.Stats[PlayerStatId.BonusAtk].Current) * (1500 - (enemyRes - (resPierce * 15)));

            double pierceCoeff = 1 - player.Stats[PlayerStatId.Pierce].Current;
            // TODO: Find correct enemy defense stats
            double denominator = mob.Stats.Cad.Total * pierceCoeff * 15;

            return(new DamageHandler(numerator / denominator, isCrit));
        }
예제 #8
0
 public static void Handle(GameSession session, int sourceId, CoordF coords, SkillCast skillCast)
 {
     session.FieldManager.BroadcastPacket(RegionSkillPacket.Send(sourceId, coords.ToShort(), skillCast));
     Remove(session, skillCast, sourceId);
 }
 public static DamageHandler CalculateSkillDamage(SkillCast skillCast) => new DamageHandler(skillCast.GetDamageRate(), false);
예제 #10
0
 public SkillCast(int id, short level, long skillSN, int serverTick, SkillCast parentSkill) : this(id, level, skillSN, serverTick)
 {
     ParentSkill = parentSkill;
 }