/// <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); }
/// <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); }
/// <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); }
/// <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 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); }
/// <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); }