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