Пример #1
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);
        }
Пример #2
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);
        }
Пример #3
0
        /// <summary>
        /// Handles the circle skills.
        /// </summary>
        /// <param name="attacker">The attacker.</param>
        /// <param name="targets">The targets. [not set yet]</param>
        /// <param name="interaction">The interaction packet.</param>
        /// <param name="usespell">The usespell packet.</param>
        /// <param name="spell">The spell.</param>
        /// <param name="damage">The damage.</param>
        /// <returns>Returns true if the skill was used successfully.</returns>
        public static bool HandleMag(Entities.IEntity attacker, ConcurrentBag <Entities.IEntity> targets, InteractionPacket interaction, UseSpellPacket usespell, Data.Spell spell, out uint damage)
        {
            damage = 0;

            if (attacker is Entities.GameClient)
            {
                if (spell.SpellID == 8030 || spell.SpellID == 10308 || spell.SpellID == 7013 || spell.SpellID > 10360)
                {
                    if (!Ranged.ProcessClient(attacker as Entities.GameClient, interaction, true, 3))
                    {
                        return(false);
                    }
                }
            }

            /*Calculations.InLineAlgorithm ila = new ProjectX_V3_Game.Calculations.InLineAlgorithm(
             *      attacker.X, interaction.X, attacker.Y, interaction.Y,
             *      (byte)spell.Range, Calculations.InLineAlgorithm.Algorithm.DDA);*/

            //	Calculations.Sector sector = new ProjectX_V3_Game.Calculations.Sector(attacker.X, attacker.Y, interaction.X, interaction.Y);
            //	sector.Arrange(spell.Sector, spell.Range);

            byte count    = 0;
            bool bluename = false;

            foreach (Maps.IMapObject obj in attacker.Screen.MapObjects.Values)
            {
                if (count > 28)
                {
                    return(true);
                }

                if (!(obj as Entities.IEntity).Alive)
                {
                    continue;
                }

                if (obj is Entities.NPC)
                {
                    continue;
                }

                if (obj.EntityUID == attacker.EntityUID)
                {
                    continue;
                }

                if (obj is Entities.BossMonster)
                {
                    if (!(obj as Entities.BossMonster).CanBeAttacked)
                    {
                        continue;
                    }
                }

                if (obj is Entities.Monster)
                {
                    if (((byte)(obj as Entities.Monster).Behaviour) >= 3)
                    {
                        continue;
                    }
                }

                if (!Core.Screen.ValidDistance(obj.X, obj.Y, attacker.X, attacker.Y))
                {
                    continue;
                }

                if (obj is Entities.GameClient)
                {
                    if (!(obj as Entities.GameClient).LoggedIn)
                    {
                        continue;
                    }

                    if (obj.Map.MapType == Enums.MapType.NoPK && (attacker is Entities.GameClient))
                    {
                        continue;
                    }

                    if (attacker is Entities.GameClient)
                    {
                        if ((attacker as Entities.GameClient).PKMode != Enums.PKMode.PK)
                        {
                            continue;
                        }

                        if (!Combat.FixTarget(attacker, obj as Entities.IEntity))
                        {
                            continue;
                        }
                    }
                    if ((obj as Entities.GameClient).ContainsFlag1(Enums.Effect1.Fly))
                    {
                        continue;
                    }

                    if (!(DateTime.Now >= (obj as Entities.GameClient).LoginProtection.AddSeconds(10)))
                    {
                        continue;
                    }

                    if (!(DateTime.Now >= (obj as Entities.GameClient).ReviveProtection.AddSeconds(5)))
                    {
                        continue;
                    }

                    if (!Combat.FixTarget(attacker, (obj as Entities.GameClient)))
                    {
                        continue;
                    }


                    if ((obj as Entities.GameClient).ContainsFlag1(Enums.Effect1.BlueName))
                    {
                        bluename = true;
                    }
                }

                //if (!ila.InLine(obj.X, obj.Y))
                //	continue;

                //if (!sector.Inside(obj.X, obj.Y))
                //	continue;

                Entities.IEntity targetentity = obj as Entities.IEntity;
                if (spell.SpellID == 8030 || spell.SpellID == 10308 || spell.SpellID == 7013 || spell.SpellID > 10360)
                {
                    damage = Calculations.Battle.GetRangedDamage(attacker, targetentity);
                }
                else
                {
                    damage = Calculations.Battle.GetMagicDamage(attacker, targetentity, spell);
                }
                Combat.ProcessDamage(attacker, targetentity, ref damage, false);
                if (damage > 0)
                {
                    if (!(targetentity is Entities.GameClient))
                    {
                        uint exp = (uint)ProjectX_V3_Lib.ThreadSafe.RandomGenerator.Generator.Next((int)(damage / 2), (int)damage);
                        if (targetentity.Level > (attacker.Level + 10))
                        {
                            exp *= 2;
                        }
                        else if (attacker.Level > (targetentity.Level + 10))
                        {
                            exp = (uint)ProjectX_V3_Lib.ThreadSafe.RandomGenerator.Generator.Next(1, (int)targetentity.Level);
                        }
                        if ((attacker is Entities.GameClient))
                        {
                            (attacker as Entities.GameClient).AddSpellExp(spell.SpellID, exp);
                        }
                    }
                    usespell.AddTarget(targetentity.EntityUID, damage);
                    targets.Add(targetentity);
                }
                count++;
            }
            if (spell.SpellID == 8030 || spell.SpellID == 10308 || spell.SpellID == 7013 || spell.SpellID > 10360)
            {
                if (attacker is Entities.GameClient)
                {
                    Ranged.DecreaseArrows(attacker as Entities.GameClient, 3);
                }
            }
            if (attacker is Entities.GameClient && bluename)
            {
                (attacker as Entities.GameClient).AddStatusEffect1(Enums.Effect1.BlueName, 10000);
            }
            return(true);
        }
Пример #4
0
        /// <summary>
        /// Handles the single attack skills.
        /// </summary>
        /// <param name="attacker">The attacker.</param>
        /// <param name="target">The target.</param>
        /// <param name="interaction">The interaction packet.</param>
        /// <param name="usespell">The usespell packet.</param>
        /// <param name="spell">The spell.</param>
        /// <param name="damage">The damage.</param>
        /// <returns>Returns true if the skill was used successfully.</returns>
        public static bool Handle(Entities.IEntity attacker, Entities.IEntity target, InteractionPacket interaction, UseSpellPacket usespell, Data.Spell spell, out uint damage)
        {
            damage = 0;
            if (attacker is Entities.GameClient)
            {
                if (!Ranged.ProcessClient(attacker as Entities.GameClient, interaction, true))
                {
                    return(false);
                }
            }
            if (attacker.EntityUID == target.EntityUID)
            {
                return(false);
            }
            if (target is Entities.NPC)
            {
                return(false);
            }

            if (target is Entities.BossMonster)
            {
                if (!(target as Entities.BossMonster).CanBeAttacked)
                {
                    return(false);
                }
            }

            if (target is Entities.Monster)
            {
                if (((byte)(target as Entities.Monster).Behaviour) >= 3)
                {
                    return(false);
                }
            }

            if (target is Entities.GameClient)
            {
                if (!(target as Entities.GameClient).LoggedIn)
                {
                    return(false);
                }

                if (target.Map.MapType == Enums.MapType.NoPK && (attacker is Entities.GameClient))
                {
                    return(false);
                }

                if (!(DateTime.Now >= (target as Entities.GameClient).LoginProtection.AddSeconds(10)))
                {
                    return(false);
                }

                if (!(DateTime.Now >= (target as Entities.GameClient).ReviveProtection.AddSeconds(5)))
                {
                    return(false);
                }

                if (!Combat.FixTarget(attacker, target))
                {
                    return(false);
                }
            }

            if (attacker is Entities.GameClient)
            {
                Ranged.DecreaseArrows(attacker as Entities.GameClient, 1);
            }
            damage = Calculations.Battle.GetRangedDamage(attacker, target);
            damage = (uint)(damage * 1.5);
            Combat.ProcessDamage(attacker, target, ref damage, false);
            if (damage > 0)
            {
                if (!(target is Entities.GameClient))
                {
                    uint exp = (uint)ProjectX_V3_Lib.ThreadSafe.RandomGenerator.Generator.Next((int)(damage / 2), (int)damage);
                    if (target.Level > (attacker.Level + 10))
                    {
                        exp *= 2;
                    }
                    if ((attacker is Entities.GameClient))
                    {
                        (attacker as Entities.GameClient).AddSpellExp(spell.SpellID, exp);
                    }
                }
                usespell.AddTarget(target.EntityUID, damage);
            }
            return(true);
        }
Пример #5
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);
        }