Пример #1
0
        public static bool HandleMarry(Models.Entities.Player player, Models.Packets.Entities.InteractionPacket packet)
        {
            if (packet.TargetClientId == player.ClientId)
            {
                return(false);
            }

            if (player.Spouse != "None")
            {
                return(true);
            }

            Models.Maps.IMapObject obj;
            if (player.GetFromScreen(packet.TargetClientId, out obj))
            {
                var marriageTarget = obj as Models.Entities.Player;
                if (marriageTarget != null)
                {
                    if (marriageTarget.Spouse != "None")
                    {
                        return(true);
                    }

                    if (marriageTarget.PendingSpouse != player.ClientId)
                    {
                        return(true);
                    }

                    player.AddActionLog("Marriage", player.Name + " : " + marriageTarget.Name);

                    marriageTarget.Spouse = player.Name;
                    player.Spouse         = marriageTarget.Name;

                    player.ClientSocket.Send(new Models.Packets.Misc.StringPacket
                    {
                        Action = Enums.StringAction.Mate,
                        Data   = player.ClientId,
                        String = marriageTarget.Name
                    });

                    marriageTarget.ClientSocket.Send(new Models.Packets.Misc.StringPacket
                    {
                        Action = Enums.StringAction.Mate,
                        Data   = marriageTarget.ClientId,
                        String = player.Name
                    });

                    var fireworks = new Models.Packets.Misc.StringPacket
                    {
                        Action    = Enums.StringAction.MapEffect,
                        PositionX = player.X,
                        PositionY = player.Y,
                        String    = "firework-2love"
                    };

                    player.ClientSocket.Send(fireworks);

                    fireworks.PositionX = marriageTarget.X;
                    fireworks.PositionY = marriageTarget.Y;
                    marriageTarget.ClientSocket.Send(fireworks);

                    Collections.PlayerCollection.BroadcastFormattedMessage("MARRIAGE_CONGRATZ", player.Name, marriageTarget.Name);
                }
            }

            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 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);
        }
        /// <summary>
        /// Handles the thread.
        /// </summary>
        public static void Handle()
        {
            Collections.PlayerCollection
            .ForEach(player =>
            {
                try
                {
                    #region Stamina
                    player.UpdateStamina();
                    #endregion
                    #region Poison
                    if (player.ContainsStatusFlag(Enums.StatusFlag.Poisoned))
                    {
                        if (DateTime.UtcNow >= player.NextPoison)
                        {
                            player.NextPoison = DateTime.UtcNow.AddMilliseconds(3000);

                            if (player.PoisonEffect > 0)
                            {
                                uint damage = (uint)Math.Max(1, (player.HP / 100) * player.PoisonEffect);

                                if (player.HP > damage)
                                {
                                    Helpers.Packets.Interaction.Battle.Damage.Hit(null, player, damage);

                                    var poisonPacket = new Models.Packets.Entities.InteractionPacket
                                    {
                                        Action         = Enums.InteractionAction.Attack,
                                        ClientId       = player.ClientId,
                                        TargetClientId = player.ClientId,
                                        X    = player.X,
                                        Y    = player.Y,
                                        Data = damage
                                    };

                                    player.UpdateScreen(false, poisonPacket);
                                    player.ClientSocket.Send(poisonPacket);
                                }
                                else
                                {
                                    player.PoisonEffect = 0;
                                    player.RemoveStatusFlag(Enums.StatusFlag.Poisoned);
                                }
                            }
                            else
                            {
                                player.RemoveStatusFlag(Enums.StatusFlag.Poisoned);
                            }
                        }
                    }
                    #endregion
                    #region PKPoints
                    if (player.PKPoints > 0)
                    {
                        if (DateTime.UtcNow > player.NextPKPointRemoval)
                        {
                            player.NextPKPointRemoval = DateTime.UtcNow.AddMilliseconds(Data.Constants.Time.PKPointsRemovalTime);

                            player.PKPoints--;
                        }
                    }
                    #endregion
                }
                catch { player.ClientSocket.Disconnect("Thread Failure."); }
            });
        }
Пример #5
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);
        }
Пример #6
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);
        }
Пример #7
0
        /// <summary>
        /// Validates a magic attack.
        /// </summary>
        /// <param name="attacker">The attacker.</param>
        /// <param name="packet">The packet.</param>
        /// <param name="target">The target.</param>
        /// <returns>The status of the validation. (0 = success.)</returns>
        private static int ValidateMagicAttack(AttackableEntityController attacker, Models.Packets.Entities.InteractionPacket packet, out AttackableEntityController target)
        {
            target = null;
            if (packet == null)
            {
                return(1);
            }

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

            if (!Tools.RangeTools.ValidDistance(attacker.MapObject.X, attacker.MapObject.Y, packet.X, packet.Y))
            {
                return(3);
            }

            Models.Maps.IMapObject targetMapObject = null;
            bool requiresTarget = false;

            if (packet.TargetClientId > 0)
            {
                if (!attacker.GetFromScreen(packet.TargetClientId, out targetMapObject) &&
                    packet.TargetClientId != attacker.AttackableEntity.ClientId)
                {
                    return(4);
                }
                else
                {
                    requiresTarget = packet.TargetClientId != attacker.AttackableEntity.ClientId;
                }
            }

            target = targetMapObject as AttackableEntityController;
            if (target != null)
            {
                var targetPlayer = target as Player;
                if (targetPlayer != null)
                {
                    if (!targetPlayer.LoggedIn)
                    {
                        return(5);
                    }

                    if (DateTime.UtcNow < targetPlayer.LoginProtectionEndTime)
                    {
                        return(5);
                    }

                    if (DateTime.UtcNow < targetPlayer.ReviveProtectionEndTime)
                    {
                        return(6);
                    }
                }

                if (!Tools.RangeTools.ValidDistance(attacker.MapObject.X, attacker.MapObject.Y, target.MapObject.X, target.MapObject.Y))
                {
                    return(7);
                }

                if (!target.AttackableEntity.Alive &&
                    packet.MagicType != 1100 && packet.MagicType != 1050)
                {
                    return(8);
                }
            }
            else if (requiresTarget)
            {
                return(10);
            }

            return(0);
        }
Пример #8
0
 /// <summary>
 /// Checks whether the player can use auto attack or not.
 /// </summary>
 /// <param name="packet">The packet.</param>
 /// <returns>True if the player can use auto attack.</returns>
 public bool CanUseAutoAttack(Models.Packets.Entities.InteractionPacket packet)
 {
     return(Player.AttackPacket != null &&
            Player.AttackPacket.Packetstamp == packet.Packetstamp);
 }
Пример #9
0
        /// <summary>
        /// Handling a base magic attack.
        /// </summary>
        /// <param name="attacker">The attacker.</param>
        /// <param name="packet">The packet.</param>
        public static void Handle(Controllers.Entities.AttackableEntityController attacker, Models.Packets.Entities.InteractionPacket packet)
        {
            if (packet == null)
            {
                return;
            }

            Controllers.Entities.AttackableEntityController target;
            var canAttack = ValidateMagicAttack(attacker, packet, out target);

            if (canAttack == 0)
            {
                var spellPacket = new Models.Packets.Spells.SpellPacket
                {
                    ClientId   = attacker.AttackableEntity.ClientId,
                    SpellId    = packet.MagicType,
                    SpellX     = packet.X,
                    SpellY     = packet.Y,
                    SpellLevel = 0
                };

                Models.Spells.SpellInfo spellInfo = null;
                var player  = attacker as Player;
                var monster = attacker as Monster;

                if (player != null)
                {
                    if (!ProcessPlayer(player, packet, spellPacket, out spellInfo))
                    {
                        return;
                    }
                    // TODO: AI BOT ...
                }
                else if (monster != null)
                {
                    if (Collections.SpellInfoCollection.ContainsSpell(packet.MagicType))
                    {
                        spellInfo = Collections.SpellInfoCollection.GetHighestSpell(packet.MagicType);
                    }
                }

                if (spellInfo != null)
                {
                    if (packet.ClientId != attacker.AttackableEntity.ClientId && target != null)
                    {
                        spellPacket.SpellX = target.MapObject.X;
                        spellPacket.SpellY = target.MapObject.Y;
                    }

                    if (spellInfo.DbSpellInfo.UseEP > 0)
                    {
                        if (player != null)
                        {
                            // TODO: IF NOT AI BOT
                            if (spellInfo.Id != 7001 && player.Stamina < spellInfo.DbSpellInfo.UseEP ||
                                spellInfo.Id == 7001 &&
                                player.ContainsStatusFlag(Enums.StatusFlag.Riding) &&
                                player.Stamina < spellInfo.DbSpellInfo.UseEP)
                            {
                                return;
                            }
                        }
                    }

                    if (spellInfo.DbSpellInfo.UseMP > 0)
                    {
                        if (monster != null)
                        {
                            if (monster.MP < spellInfo.DbSpellInfo.UseMP && !monster.IsGuard)
                            {
                                return;
                            }
                        }
                        else if (attacker.AttackableEntity.MP < spellInfo.DbSpellInfo.UseMP)
                        {
                            return;
                        }
                    }

                    if (attacker.MapObject.Map == null)
                    {
                        return;
                    }

                    bool success = false;

                    switch (packet.MagicType)
                    {
                        #region Line Skills
                    case 1045:
                    case 1046:
                    case 11005:
                    case 11000:
                        success = Skills.LineSkills.Handle(attacker, packet, spellPacket, spellInfo);
                        break;
                        #endregion

                        #region SectorSkills

                        #region Magic
                    case 1165:
                    case 7014:
                        success = Skills.SectorSkills.Handle(attacker, packet, spellPacket, spellInfo, true);
                        break;
                        #endregion

                        #region Physical
                    case 1250:
                    case 5050:
                    case 5020:
                    case 1300:
                        success = Skills.SectorSkills.Handle(attacker, packet, spellPacket, spellInfo, false);
                        break;
                        #endregion

                        #endregion

                        #region Single

                        #region Magic
                    case 10310:
                    case 1000:
                    case 1001:
                    case 1002:
                    case 1150:
                    case 1160:
                    case 1180:
                        success = Skills.SingleSkills.Handle(attacker, target, packet, spellPacket, spellInfo, true);
                        break;
                        #endregion

                        #region Physical
                    case 1290:
                    case 5030:
                    case 5040:
                    case 7000:
                    case 7010:
                    case 7030:
                    case 7040:
                        success = Skills.SingleSkills.Handle(attacker, target, packet, spellPacket, spellInfo, false);
                        break;
                        #endregion

                        #endregion

                        #region Circle

                        #region Magic
                    case 1010:                            //lightning tao
                    case 1120:                            //fc
                    case 1125:                            //volc
                    case 3090:                            //pervade
                    case 5001:                            //speed
                    case 8030:                            //arrows
                    case 7013:                            //flame shower
                    case 30011:                           //small ice circle
                    case 30012:                           //large ice circle
                    case 10360:
                    case 10361:
                    case 10392:
                    case 10308:
                        success = Skills.CircleSkills.Handle(attacker, packet, spellPacket, spellInfo, true);
                        break;
                        #endregion

                        #region Physical
                    case 5010:
                    case 7020:
                    case 1115:                            //herc
                        success = Skills.CircleSkills.Handle(attacker, packet, spellPacket, spellInfo, false);
                        break;
                        #endregion

                        #endregion

                        #region MountSkill
                    case 7001:
                        if (player != null)
                        {
                            success = Skills.MountSkill.Handle(player, spellPacket);
                        }
                        else
                        {
                            success = false;
                        }
                        break;
                        #endregion

                        #region Buff
                    case 1075:
                    case 1085:
                    case 1090:
                    case 1095:
                        success = Skills.BuffCurseSkills.Handle(attacker, target, packet, spellPacket, spellInfo);
                        break;
                        #endregion

                        #region Revive
                    case 1050:
                    case 1100:
                        success = Skills.ReviveSkills.Handle(attacker, target, packet, spellPacket);
                        break;
                        #endregion

                        #region Fly
                    case 8002:
                    case 8003:
                        success = Skills.FlySkills.Handle(attacker);
                        break;
                        #endregion

                        #region Scatter
                    case 8001:
                        success = Skills.ScatterSkill.Handle(attacker, packet, spellPacket, spellInfo);
                        break;
                        #endregion

                        #region Cure

                        #region Self
                    case 1190:
                    case 1195:
                    case 7016:
                        success = Skills.CureSkills.HandleSelf(attacker, target, packet, spellPacket, spellInfo);
                        break;
                        #endregion

                        #region Surroundings
                    case 1005:
                    case 1055:
                    case 1170:
                    case 1175:
                        success = Skills.CureSkills.HandleSurroundings(attacker, target, packet, spellPacket, spellInfo);
                        break;
                        #endregion

                        #endregion

                        #region Archer
                    case 10313:
                    case 8000:
                    case 9991:
                    case 7012:
                    case 7015:
                    case 7017:
                    case 1320:
                        success = Skills.SingleSkills.Handle(attacker, target, packet, spellPacket, spellInfo, false, true);
                        break;
                        #endregion

                        #region Ninja

                        #region Toxic Fog
                    case 6001:
                        success = Skills.SectorSkills.Handle(attacker, packet, spellPacket, spellInfo, false, true);
                        break;
                        #endregion

                        #region TwoFold
                    case 6000:
                        success = Skills.SingleSkills.Handle(attacker, target, packet, spellPacket, spellInfo, false, false);
                        break;
                        #endregion

                        #region PoisonStar
                    case 6002:
                        success = Skills.BuffCurseSkills.Handle(attacker, target, packet, spellPacket, spellInfo, true);
                        break;
                        #endregion

                        #region ArcherBane
                    case 6004:
                        success = Skills.BuffCurseSkills.Handle(attacker, target, packet, spellPacket, spellInfo, false, true);
                        break;
                        #endregion

                        #endregion

                    default:
                    {
                        if (player != null)
                        {
                            player.SendFormattedSystemMessage("INVALID_SKILL", true, spellInfo.Id);
                        }
                        success = false;
                        break;
                    }
                    }

                    if (success)
                    {
                        if (spellInfo.DbSpellInfo.UseEP > 0)
                        {
                            if (player != null)
                            {
                                player.Stamina = (byte)Math.Max(0, (((int)player.Stamina) - spellInfo.DbSpellInfo.UseEP));
                            }
                        }

                        if (spellInfo.DbSpellInfo.UseMP > 0)
                        {
                            attacker.AttackableEntity.MP -= spellInfo.DbSpellInfo.UseMP;
                        }

                        attacker.UpdateScreen(false, spellPacket);

                        // Not a single skill and skill is not safe, do damage here ...
                        if (spellPacket.Targets.Count > 0 && !spellPacket.Safe && spellPacket.Process)
                        {
                            foreach (var spellTarget in spellPacket.Targets)
                            {
                                if (spellTarget.AssociatedEntity != null)
                                {
                                    Damage.Hit(attacker, spellTarget.AssociatedEntity, spellTarget.Damage);
                                }
                            }
                        }

                        if (player != null)
                        {
                            player.ClientSocket.Send(spellPacket);

                            if (spellPacket.SpellId >= 1000 && spellPacket.SpellId <= 1002)
                            {
                                packet.ActivationType  = 0;
                                packet.ActivationValue = 0;
                                player.AttackPacket    = packet;
                                player.UseAutoAttack(packet);
                            }
                        }
                    }
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Validates an attack.
        /// </summary>
        /// <param name="packet">The packet.</param>
        /// <param name="target">The target.</param>
        /// <returns>The status of the validation. (0 = success)</returns>
        public int ValidateAttack(Models.Packets.Entities.InteractionPacket packet, out AttackableEntityController target)
        {
            target = null;

            if (packet == null)
            {
                return(1);
            }

            Models.Maps.IMapObject targetMapObject;
            if (!GetFromScreen(packet.TargetClientId, out targetMapObject))
            {
                return(2);
            }

            target = targetMapObject as AttackableEntityController;

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

            if (AttackableEntity.ClientId != target.AttackableEntity.ClientId)
            {
                var player = target as Player;
                if (player != null)
                {
                    if (!player.LoggedIn)
                    {
                        return(4);
                    }

                    if (DateTime.UtcNow < player.LoginProtectionEndTime)
                    {
                        return(5);
                    }

                    if (DateTime.UtcNow < player.ReviveProtectionEndTime)
                    {
                        return(6);
                    }

                    // Can't attack flying players if not ranged
                    if (packet.Action != Enums.InteractionAction.Shoot &&
                        target.ContainsStatusFlag(Enums.StatusFlag.Fly))
                    {
                        return(7);
                    }

                    var attackerPlayer = AttackableEntity as Player;
                    if (attackerPlayer != null)
                    {
                        var pkStatus = attackerPlayer.ValidPkTarget(player);
                        if (pkStatus != 0)
                        {
                            return(8);
                        }
                    }
                }
            }

            if (!Tools.RangeTools.ValidDistance(MapObject.X, MapObject.Y, target.MapObject.X, target.MapObject.Y))
            {
                return(9);
            }

            if (!AttackableEntity.Alive)
            {
                return(10);
            }

            if (!target.AttackableEntity.Alive)
            {
                return(11);
            }

            return(0);
        }
Пример #11
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);
        }
        /// <summary>
        /// Handles attack for a monster.
        /// </summary>
        /// <param name="monster">The monster to handle attack for.</param>
        private static void HandleAttack(Models.Entities.Monster monster)
        {
            if (!monster.Alive)
            {
                return;
            }

            #region Poison
            if (monster.ContainsStatusFlag(Enums.StatusFlag.Poisoned))
            {
                if (DateTime.UtcNow >= monster.NextPoison)
                {
                    monster.NextPoison = DateTime.UtcNow.AddMilliseconds(3000);

                    if (monster.PoisonEffect > 0)
                    {
                        uint damage = (uint)Math.Max(1, (monster.HP / 100) * monster.PoisonEffect);

                        if (monster.HP > damage)
                        {
                            Helpers.Packets.Interaction.Battle.Damage.Hit(null, monster, damage);

                            var poisonPacket = new Models.Packets.Entities.InteractionPacket
                            {
                                Action         = Enums.InteractionAction.Attack,
                                ClientId       = monster.ClientId,
                                TargetClientId = monster.ClientId,
                                X    = monster.X,
                                Y    = monster.Y,
                                Data = damage
                            };

                            monster.UpdateScreen(false, poisonPacket);
                        }
                        else
                        {
                            monster.PoisonEffect = 0;
                            monster.RemoveStatusFlag(Enums.StatusFlag.Poisoned);
                        }
                    }
                    else
                    {
                        monster.RemoveStatusFlag(Enums.StatusFlag.Poisoned);
                    }
                }
            }
            #endregion

            var target = monster.Target as Models.Maps.IMapObject;

            if (target != null && target.Alive)
            {
                if (Tools.RangeTools.GetDistance(monster.X, monster.Y, target.X, target.Y) <= monster.AttackRange &&
                    monster.ContainsInScreen(target.ClientId) && DateTime.UtcNow >= monster.NextAttackTime)
                {
                    monster.NextAttackTime = DateTime.UtcNow.AddMilliseconds(
                        Drivers.Repositories.Safe.Random.Next(monster.AttackSpeed, monster.AttackSpeed * 3));

                    Helpers.Packets.Interaction.Battle.Physical.Handle(monster, new Models.Packets.Entities.InteractionPacket
                    {
                        Action         = Enums.InteractionAction.Attack,
                        ClientId       = monster.ClientId,
                        TargetClientId = target.ClientId,
                        X = target.X,
                        Y = target.Y
                    });
                    return;
                }
            }

            var possibleTarget = monster.FindClosest <Models.Entities.Player>();
            if (possibleTarget != null &&
                possibleTarget.Alive &&
                !possibleTarget.ContainsStatusFlag(Enums.StatusFlag.PartiallyInvisible))
            {
                if (monster.Behaviour == Enums.MonsterBehaviour.Peaceful &&
                    (possibleTarget.Target == null || possibleTarget.Target.ClientId != monster.ClientId))
                {
                    monster.Target = null;
                }
                else
                {
                    monster.Target = possibleTarget;
                }
            }
            else
            {
                monster.Target = null;
            }

            monster.Idle = possibleTarget == null;
        }
Пример #13
0
        /// <summary>
        /// Handling a base ranged attack.
        /// </summary>
        /// <param name="attacker">The attacker.</param>
        /// <param name="packet">The packet.</param>
        public static void Handle(Controllers.Entities.AttackableEntityController attacker, Models.Packets.Entities.InteractionPacket packet)
        {
            Controllers.Entities.AttackableEntityController target;
            var canAttack = attacker.ValidateAttack(packet, out target);

            if (canAttack == 0 && target != null)
            {
                var player = attacker as Player;

                if (player != null)
                {
                    if (!ProcessPlayer(player, packet, 1))
                    {
                        return;
                    }
                }

                uint damage = Calculations.RangedCalculations.GetDamage(attacker as IAttackableEntity, target as IAttackableEntity);
                Damage.Process(attacker, target, ref damage, true);

                if (damage > 0 && player != null)
                {
                    var targetMonster = target as Monster;

                    if (targetMonster != null)
                    {
                        uint newExperience = Calculations.Experience.GetProficiencyExperience(player, targetMonster, damage);

                        if (packet.WeaponTypeRight > 0)
                        {
                            var prof = player.Spells.GetOrCreateProficiency(packet.WeaponTypeRight);
                            if (prof != null)
                            {
                                prof.Raise(newExperience);
                            }
                        }
                    }

                    DecreaseArrows(player, 1);
                }

                packet.Data = damage;
                attacker.UpdateScreen(false, packet);
                if (player != null)
                {
                    player.ClientSocket.Send(packet);

                    packet.ActivationType  = 0;
                    packet.ActivationValue = 0;
                    player.AttackPacket    = packet;
                    player.UseAutoAttack(packet);
                }
            }
        }