예제 #1
0
        /// <summary>
        /// Handles the mount skill.
        /// </summary>
        /// <param name="player">The player.</param>
        /// <param name="spellPacket">The spell packet.</param>
        /// <returns>True if the skill was handled correctly.</returns>
        public static bool Handle(Models.Entities.Player player, Models.Packets.Spells.SpellPacket spellPacket)
        {
            if (player.Equipments.Get(Enums.ItemPosition.Steed, false) == null)
            {
                return(false);
            }

            if (player.ContainsStatusFlag(Enums.StatusFlag.Riding))
            {
                player.RemoveStatusFlag(Enums.StatusFlag.Riding);
            }
            else if (player.Stamina < 100)
            {
                return(false);
            }
            else
            {
                player.AddStatusFlag(Enums.StatusFlag.Riding);
            }

            player.ClientSocket.Send(new Models.Packets.Entities.SteedVigorPacket
            {
                Type   = 2,
                Amount = 9001
            });

            TargetFinalization.SkillFinalize(player, null, spellPacket, 0);

            return(true);
        }
예제 #2
0
        /// <summary>
        /// Handling the revive skills.
        /// </summary>
        /// <param name="attacker">The attacker.</param>
        /// <param name="target">The target.</param>
        /// <param name="packet">The packet.</param>
        /// <param name="spellPacket">The spell packet.</param>
        /// <returns>True if the skill was handled correctly.</returns>
        public static bool Handle(AttackableEntityController attacker, AttackableEntityController target,
                                  Models.Packets.Entities.InteractionPacket packet,
                                  Models.Packets.Spells.SpellPacket spellPacket)
        {
            if (target == null)
            {
                return(false);
            }

            var targetPlayer = target as Models.Entities.Player;

            if (targetPlayer == null)
            {
                return(false);
            }

            if (targetPlayer.Alive)
            {
                return(false);
            }

            if (targetPlayer.ClientId == attacker.AttackableEntity.ClientId)
            {
                return(false);
            }

            targetPlayer.Revive(true);

            TargetFinalization.SkillFinalize(attacker, target, spellPacket, 0);

            return(true);
        }
예제 #3
0
        /// <summary>
        /// Handles line skills.
        /// </summary>
        /// <param name="attacker">The attacker.</param>
        /// <param name="packet">The packet.</param>
        /// <param name="spellPacket">The spell packet.</param>
        /// <param name="spellInfo">The spell info.</param>
        /// <returns>True if the skill was handled.</returns>
        public static bool Handle(AttackableEntityController attacker,
                                  Models.Packets.Entities.InteractionPacket packet,
                                  Models.Packets.Spells.SpellPacket spellPacket,
                                  Models.Spells.SpellInfo spellInfo)
        {
            spellPacket.Process = true;

            if (packet.TargetClientId == attacker.AttackableEntity.ClientId)
            {
                return(false);
            }

            var ila = new Tools.ILA(
                attacker.MapObject.X, packet.X,
                attacker.MapObject.Y, packet.Y,
                (byte)spellInfo.DbSpellInfo.Range);

            foreach (var possibleTarget in attacker.GetAllInScreen())
            {
                if (spellPacket.Targets.Count > 8)
                {
                    return(true);
                }

                var target = possibleTarget as AttackableEntityController;

                if (target != null)
                {
                    if (!TargetValidation.Validate(attacker, target))
                    {
                        continue;
                    }

                    if (target.ContainsStatusFlag(Enums.StatusFlag.Fly))
                    {
                        continue;
                    }

                    if (!ila.InLine(target.MapObject.X, target.MapObject.Y))
                    {
                        continue;
                    }

                    uint damage = Calculations.PhysicalCalculations.GetDamage(attacker.AttackableEntity, target.AttackableEntity);
                    Damage.Process(attacker, target, ref damage, false);

                    if (damage > 0)
                    {
                        TargetFinalization.SkillFinalize(attacker, target, spellPacket, damage);
                    }
                }
            }

            return(true);
        }
예제 #4
0
        /// <summary>
        /// Handles a self curing skill.
        /// </summary>
        /// <param name="attacker">The attack.</param>
        /// <param name="target">The target.</param>
        /// <param name="packet">The packet.</param>
        /// <param name="spellPacket">The spell packet.</param>
        /// <param name="spellInfo">The spell info.</param>
        /// <returns>True if the skill was handled correct.</returns>
        public static bool HandleSelf(AttackableEntityController attacker, AttackableEntityController target,
                                      Models.Packets.Entities.InteractionPacket packet,
                                      Models.Packets.Spells.SpellPacket spellPacket, Models.Spells.SpellInfo spellInfo)
        {
            if (target == null)
            {
                target = attacker;
            }

            if (target.AttackableEntity.ClientId != attacker.AttackableEntity.ClientId)
            {
                return(false);
            }

            var attackerPlayer = attacker as Models.Entities.Player;

            if (attackerPlayer != null)
            {
                if (DateTime.UtcNow < attackerPlayer.NextSmallLongSkill)
                {
                    attackerPlayer.SendSystemMessage("REST");
                    return(false);
                }

                attackerPlayer.NextSmallLongSkill = DateTime.UtcNow.AddMilliseconds(Data.Constants.Time.SmallLongSkillTime);
            }

            if (spellInfo.Id == 1190 || spellInfo.Id == 7016)
            {
                attacker.AttackableEntity.HP += spellInfo.DbSpellInfo.Power;
            }
            else
            {
                attacker.AttackableEntity.MP += spellInfo.DbSpellInfo.Power;
            }

            if (attackerPlayer != null)
            {
                uint newExperience = (uint)Drivers.Repositories.Safe.Random.Next((int)spellInfo.DbSpellInfo.Power, ((int)spellInfo.DbSpellInfo.Power * 2));
                var  skill         = attackerPlayer.Spells.GetOrCreateSkill(spellInfo.Id);
                if (skill != null)
                {
                    skill.Raise(newExperience);
                }
            }

            TargetFinalization.SkillFinalize(attacker, null, spellPacket, spellInfo.DbSpellInfo.Power);

            return(true);
        }
예제 #5
0
        /// <summary>
        /// Handles the scatter skill.
        /// </summary>
        /// <param name="attacker">The attacker.</param>
        /// <param name="packet">The packet.</param>
        /// <param name="spellPacket">The spell packet.</param>
        /// <param name="spellInfo">The spell info.</param>
        /// <returns>True if the skill was handled correctly.</returns>
        public static bool Handle(AttackableEntityController attacker,
                                  Models.Packets.Entities.InteractionPacket packet,
                                  Models.Packets.Spells.SpellPacket spellPacket,
                                  Models.Spells.SpellInfo spellInfo)
        {
            spellPacket.Process = true;

            var attackerPlayer = attacker as Models.Entities.Player;

            if (attackerPlayer != null)
            {
                if (!Ranged.ProcessPlayer(attackerPlayer, packet, 3))
                {
                    return(false);
                }
            }

            var sector = new Tools.Sector(attacker.MapObject.X, attacker.MapObject.Y,
                                          packet.X, packet.Y);

            sector.Arrange(spellInfo.Sector, spellInfo.DbSpellInfo.Range);

            foreach (var possibleTarget in attacker.GetAllInScreen())
            {
                if (spellPacket.Targets.Count > 8)
                {
                    return(true);
                }

                var target = possibleTarget as AttackableEntityController;

                if (target != null)
                {
                    if (!TargetValidation.Validate(attacker, target))
                    {
                        continue;
                    }

                    if (target.ContainsStatusFlag(Enums.StatusFlag.Fly))
                    {
                        continue;
                    }

                    if (!sector.Inside(target.MapObject.X, target.MapObject.Y))
                    {
                        continue;
                    }

                    uint damage = Calculations.RangedCalculations.GetDamage(attacker.AttackableEntity, target.AttackableEntity);
                    Damage.Process(attacker, target, ref damage, false);

                    if (damage > 0)
                    {
                        TargetFinalization.SkillFinalize(attacker, target, spellPacket, damage);
                    }
                }
            }

            if (attackerPlayer != null && spellPacket.Targets.Count > 0)
            {
                Ranged.DecreaseArrows(attackerPlayer, 3);
            }

            return(true);
        }
예제 #6
0
        /// <summary>
        /// Handles a circular skill.
        /// </summary>
        /// <param name="attacker">The attacker.</param>
        /// <param name="packet">The packet.</param>
        /// <param name="spellPacket">The spell packet.</param>
        /// <param name="spellInfo">The spell info.</param>
        /// <param name="isMagic">Boolean determining whether the circular skill is a magic skill or not.</param>
        /// <returns>True if the skill was handled correct.</returns>
        /// <remarks>This handles all types of circular skills (Physical, Magic, Ranged.) however ranged and physical is determined from either the skill id or whether isMagic is set.</remarks>
        public static bool Handle(AttackableEntityController attacker,
                                  Models.Packets.Entities.InteractionPacket packet,
                                  Models.Packets.Spells.SpellPacket spellPacket,
                                  Models.Spells.SpellInfo spellInfo,
                                  bool isMagic)
        {
            spellPacket.Process = true;

            if (!isMagic && spellInfo.Id < 8000 &&
                packet.TargetClientId == attacker.AttackableEntity.ClientId)
            {
                return(false);
            }

            var attackerPlayer = attacker as Models.Entities.Player;

            if (attackerPlayer != null)
            {
                if (DateTime.UtcNow < attackerPlayer.NextLongSkill)
                {
                    attackerPlayer.SendSystemMessage("REST");
                    return(false);
                }

                attackerPlayer.NextLongSkill = DateTime.UtcNow.AddMilliseconds(Data.Constants.Time.LongSkillTime);
            }

            foreach (var possibleTarget in attacker.GetAllInScreen())
            {
                if (spellPacket.Targets.Count > 8)
                {
                    return(true);
                }

                var target = possibleTarget as AttackableEntityController;

                if (target != null)
                {
                    if (!TargetValidation.Validate(attacker, target))
                    {
                        continue;
                    }

                    if (target.ContainsStatusFlag(Enums.StatusFlag.Fly))
                    {
                        continue;
                    }

                    if (Tools.RangeTools.GetDistanceU(attacker.MapObject.X, attacker.MapObject.Y, target.MapObject.X, target.MapObject.Y) >= 8)
                    {
                        continue;
                    }

                    bool isRanged = (spellInfo.Id == 8030 || spellInfo.Id == 10308 || spellInfo.Id == 7013 || spellInfo.Id > 10360);

                    uint damage = isRanged ?
                                  Calculations.RangedCalculations.GetDamage(attacker.AttackableEntity, target.AttackableEntity) :
                                  isMagic?
                                  Calculations.MagicCalculations.GetDamage(attacker.AttackableEntity, target.AttackableEntity, spellInfo) :
                                      Calculations.PhysicalCalculations.GetDamage(attacker.AttackableEntity, target.AttackableEntity);

                    Damage.Process(attacker, target, ref damage, false);

                    if (isRanged && attackerPlayer != null)
                    {
                        Ranged.DecreaseArrows(attackerPlayer, 3);
                    }

                    if (damage > 0)
                    {
                        TargetFinalization.SkillFinalize(attacker, target, spellPacket, damage);
                    }
                }
            }

            return(true);
        }
예제 #7
0
        /// <summary>
        /// Handles the sector skills.
        /// </summary>
        /// <param name="attacker">The attacker.</param>
        /// <param name="packet">The packet.</param>
        /// <param name="spellPacket">The spell packet.</param>
        /// <param name="spellInfo">The spell info.</param>
        /// <param name="isMagic">Boolean determining whether the attack is magic or not.</param>
        /// <param name="isPoison">Booealning determining whether the attack is poisonous (Toxic fog.)</param>
        /// <returns>True if the skill was handled correctly.</returns>
        public static bool Handle(AttackableEntityController attacker,
                                  Models.Packets.Entities.InteractionPacket packet,
                                  Models.Packets.Spells.SpellPacket spellPacket,
                                  Models.Spells.SpellInfo spellInfo,
                                  bool isMagic, bool isPoison = false)
        {
            spellPacket.Process = true;

            if (packet.TargetClientId == attacker.AttackableEntity.ClientId)
            {
                return(false);
            }

            if (isPoison && Tools.RangeTools.GetDistanceU(attacker.MapObject.X, attacker.MapObject.Y, packet.X, packet.Y) >= 9)
            {
                return(false);
            }

            var attackerPlayer = attacker as Models.Entities.Player;

            if (attackerPlayer != null)
            {
                if (DateTime.UtcNow < attackerPlayer.NextLongSkill)
                {
                    attackerPlayer.SendSystemMessage("REST");
                    return(false);
                }

                attackerPlayer.NextLongSkill = DateTime.UtcNow.AddMilliseconds(Data.Constants.Time.LongSkillTime);
            }

            ushort x = attacker.MapObject.X;
            ushort y = attacker.MapObject.Y;

            if (spellInfo.Id == 6001)
            {
                if (Tools.RangeTools.GetDistanceU(x, y, packet.X, packet.Y) > spellInfo.DbSpellInfo.Distance)
                {
                    return(false);
                }

                x = packet.X;
                y = packet.Y;
            }

            var sector = new Tools.Sector(x, y,
                                          packet.X, packet.Y);

            sector.Arrange(spellInfo.Sector, spellInfo.DbSpellInfo.Range);

            foreach (var possibleTarget in attacker.GetAllInScreen())
            {
                if (spellPacket.Targets.Count > 8)
                {
                    return(true);
                }

                var target = possibleTarget as AttackableEntityController;

                if (target != null)
                {
                    if (!TargetValidation.Validate(attacker, target))
                    {
                        continue;
                    }

                    if (target.ContainsStatusFlag(Enums.StatusFlag.Fly))
                    {
                        continue;
                    }

                    if (!sector.Inside(target.MapObject.X, target.MapObject.Y))
                    {
                        continue;
                    }

                    if (isPoison && target.ContainsStatusFlag(Enums.StatusFlag.Poisoned))
                    {
                        continue;
                    }

                    uint damage = isPoison ?
                                  (uint)target.AttackableEntity.HP / 10 :
                                  isMagic?
                                  Calculations.MagicCalculations.GetDamage(attacker.AttackableEntity, target.AttackableEntity, spellInfo) :
                                      Calculations.PhysicalCalculations.GetDamage(attacker.AttackableEntity, target.AttackableEntity);

                    if (isPoison)
                    {
                        target.AttackableEntity.PoisonEffect = (spellInfo.DbSpellInfo.Power - 30000);
                        target.AddStatusFlag(Enums.StatusFlag.Poisoned, 60000);
                    }

                    Damage.Process(attacker, target, ref damage, false);

                    if (damage > 0)
                    {
                        TargetFinalization.SkillFinalize(attacker, target, spellPacket, damage);
                    }
                }
            }

            return(true);
        }
예제 #8
0
        /// <summary>
        /// Handles single skills.
        /// </summary>
        /// <param name="attacker">The attacker.</param>
        /// <param name="target">The target.</param>
        /// <param name="packet">The packet.</param>
        /// <param name="spellPacket">The spell packet.</param>
        /// <param name="spellInfo">The spell info.</param>
        /// <param name="isMagic">Boolean determining whether the single attack is magic.</param>
        /// <param name="isRanged">Boolean determining whether the single attack is ranged.</param>
        /// <returns>True if the skill was handled correctly.</returns>
        /// <remarks>If both isMagic and isRanged is set to false then it's assumed as a physical skill.</remarks>
        public static bool Handle(AttackableEntityController attacker, AttackableEntityController target,
                                  Models.Packets.Entities.InteractionPacket packet,
                                  Models.Packets.Spells.SpellPacket spellPacket, Models.Spells.SpellInfo spellInfo,
                                  bool isMagic, bool isRanged = false)
        {
            if (target == null)
            {
                return(false);
            }

            if (attacker.AttackableEntity.ClientId == target.AttackableEntity.ClientId)
            {
                return(false);
            }

            if (!TargetValidation.Validate(attacker, target))
            {
                return(false);
            }

            var attackerPlayer = attacker as Models.Entities.Player;

            if (isRanged)
            {
                if (attackerPlayer != null)
                {
                    if (!Ranged.ProcessPlayer(attackerPlayer, packet, 1))
                    {
                        return(false);
                    }
                }

                Ranged.DecreaseArrows(attackerPlayer, 1);
            }

            uint damage = isRanged ?
                          Calculations.RangedCalculations.GetDamage(attacker.AttackableEntity, target.AttackableEntity) :
                          isMagic?
                          Calculations.MagicCalculations.GetDamage(attacker.AttackableEntity, target.AttackableEntity, spellInfo) :
                              Calculations.PhysicalCalculations.GetDamage(attacker.AttackableEntity, target.AttackableEntity);

            if (!isMagic)
            {
                damage = (uint)Math.Max(1, (int)(((double)damage) * (1.1 + (0.1 * spellInfo.Level))));

                if (spellInfo.Id == 1290 && damage > 0 && !isRanged)
                {
                    double damagePercentage = (double)((damage / 100) * 26.6);
                    damage += (uint)(damagePercentage * spellInfo.Level);
                }

                if (spellInfo.Id == 6000 && damage > 0 && !isRanged)
                {
                    damage = (uint)((damage / 100) * (spellInfo.DbSpellInfo.Power - 30000));
                }
            }

            Damage.Process(attacker, target, ref damage, true);

            if (damage > 0)
            {
                TargetFinalization.SkillFinalize(attacker, target, spellPacket, damage);

                return(true);
            }

            return(false);
        }
예제 #9
0
        /// <summary>
        /// Handling buffs and curse skills
        /// </summary>
        /// <param name="attacker">The attacker.</param>
        /// <param name="target">The target.</param>
        /// <param name="packet">The packet.</param>
        /// <param name="spellPacket">The spell packet.</param>
        /// <param name="spellInfo">The spell info.</param>
        /// <param name="curse">Boolean determining whether it should handle the skill as a curse.</param>
        /// <param name="disspell">Boolean determining whether it should handle the skill as a disspelling skill.</param>
        /// <returns>True if the skill was handled correct.</returns>
        public static bool Handle(AttackableEntityController attacker, AttackableEntityController target,
                                  Models.Packets.Entities.InteractionPacket packet,
                                  Models.Packets.Spells.SpellPacket spellPacket, Models.Spells.SpellInfo spellInfo,
                                  bool curse = false, bool disspell = false)
        {
            if (target == null)
            {
                return(false);
            }

            var targetPlayer = target as Models.Entities.Player;

            if (targetPlayer == null)
            {
                return(false);
            }

            if (!attacker.AttackableEntity.Alive)
            {
                return(false);
            }

            var attackerPlayer = attacker as Models.Entities.Player;

            if (attackerPlayer != null)
            {
                if (DateTime.UtcNow < attackerPlayer.NextSmallLongSkill)
                {
                    attackerPlayer.SendSystemMessage("REST");
                    return(false);
                }

                attackerPlayer.NextSmallLongSkill = DateTime.UtcNow.AddMilliseconds(Data.Constants.Time.SmallLongSkillTime);
            }


            if (!targetPlayer.LoggedIn)
            {
                return(false);
            }

            uint damage = 0;

            if (curse)
            {
                if (!TargetValidation.Validate(attacker, target))
                {
                    return(false);
                }

                targetPlayer.AddStatusFlag(Enums.StatusFlag.NoPotion, (5000 * (spellInfo.Level + 1)));
            }
            else if (disspell)
            {
                targetPlayer.RemoveStatusFlag(Enums.StatusFlag.Fly);

                damage = (uint)Math.Max(1, (targetPlayer.HP / 10));

                if (damage > 0)
                {
                    Damage.Process(attacker, target, ref damage, false);
                }
            }
            else
            {
                var duration = spellInfo.DbSpellInfo.StepSecs * 1000;

                switch (spellInfo.Id)
                {
                case 1075: targetPlayer.AddStatusFlag(Enums.StatusFlag.PartiallyInvisible, duration); break;

                case 1085: targetPlayer.AddStatusFlag(Enums.StatusFlag.StarOfAccuracy, duration); break;

                case 1090: targetPlayer.AddStatusFlag(Enums.StatusFlag.Shield, duration); break;

                case 1095: targetPlayer.AddStatusFlag(Enums.StatusFlag.Stigma, duration); break;
                }
            }

            var maxExp = (int)(Math.Max(25, (int)targetPlayer.Level) / 2);

            uint newExperience = (uint)Drivers.Repositories.Safe.Random.Next(maxExp / 2, maxExp);
            var  skill         = targetPlayer.Spells.GetOrCreateSkill(spellInfo.Id);

            if (skill != null)
            {
                skill.Raise(newExperience);
            }

            TargetFinalization.SkillFinalize(attackerPlayer, targetPlayer, spellPacket, damage);

            return(true);
        }
예제 #10
0
        /// <summary>
        /// Handles cure skills for surroundings.
        /// </summary>
        /// <param name="attacker">The attacker.</param>
        /// <param name="target">The target.</param>
        /// <param name="packet">The packet.</param>
        /// <param name="spellPacket">The spell packet.</param>
        /// <param name="spellInfo">The spell info.</param>
        /// <returns>True if the skill was handled correct.</returns>
        public static bool HandleSurroundings(AttackableEntityController attacker, AttackableEntityController target,
                                              Models.Packets.Entities.InteractionPacket packet,
                                              Models.Packets.Spells.SpellPacket spellPacket, Models.Spells.SpellInfo spellInfo)
        {
            spellPacket.Safe = true;

            if (target == null)
            {
                return(false);
            }

            var attackerPlayer = attacker as Models.Entities.Player;

            if (attackerPlayer != null)
            {
                if (DateTime.UtcNow < attackerPlayer.NextSmallLongSkill)
                {
                    attackerPlayer.SendSystemMessage("REST");
                    return(false);
                }

                attackerPlayer.NextSmallLongSkill = DateTime.UtcNow.AddMilliseconds(Data.Constants.Time.SmallLongSkillTime);
            }

            var targetMonster = target as Models.Entities.Monster;

            if (targetMonster != null)
            {
                if (targetMonster.IsGuard)
                {
                    return(false);
                }
            }

            target.AttackableEntity.HP += spellInfo.DbSpellInfo.Power;
            TargetFinalization.SkillFinalize(attacker, target, spellPacket, spellInfo.DbSpellInfo.Power);

            if (spellInfo.Id == 1055)
            {
                foreach (var possibleTarget in attacker.GetAllInScreen())
                {
                    if (possibleTarget.ClientId == target.AttackableEntity.ClientId)
                    {
                        continue;
                    }

                    if (Tools.RangeTools.GetDistanceU(possibleTarget.X, possibleTarget.Y, target.MapObject.X, target.MapObject.Y) > spellInfo.DbSpellInfo.Distance)
                    {
                        continue;
                    }

                    target = possibleTarget as AttackableEntityController;
                    if (target == null)
                    {
                        continue;
                    }

                    targetMonster = possibleTarget as Models.Entities.Monster;
                    if (targetMonster != null)
                    {
                        if (targetMonster.IsGuard)
                        {
                            continue;
                        }
                    }

                    var targetPlayer = possibleTarget as Models.Entities.Player;
                    if (targetPlayer != null)
                    {
                        if (!targetPlayer.LoggedIn)
                        {
                            continue;
                        }
                    }

                    TargetFinalization.SkillFinalize(attacker, target, spellPacket, spellInfo.DbSpellInfo.Power);
                }
            }

            if (attackerPlayer != null)
            {
                uint newExperience = (uint)Drivers.Repositories.Safe.Random.Next((int)spellInfo.DbSpellInfo.Power, (int)(spellInfo.DbSpellInfo.Power * 2));
                newExperience *= (uint)spellPacket.Targets.Count;

                var skill = attackerPlayer.Spells.GetOrCreateSkill(spellInfo.Id);
                if (skill != null)
                {
                    skill.Raise(newExperience);
                }
            }

            return(true);
        }