private void ZoneHit(int Castingid, short x, short y) { List <CharacterSkill> skills = Session.Character.UseSp ? Session.Character.SkillsSp.GetAllItems() : Session.Character.Skills.GetAllItems(); CharacterSkill characterSkill = skills.FirstOrDefault(s => s.Skill.CastId == Castingid); if (!Session.Character.WeaponLoaded(characterSkill) || !Session.HasCurrentMap) { Session.SendPacket("cancel 2 0"); return; } if (characterSkill != null && characterSkill.CanBeUsed()) { if (Session.Character.Mp >= characterSkill.Skill.MpCost) { Session.CurrentMap?.Broadcast($"ct_n 1 {Session.Character.CharacterId} 3 -1 {characterSkill.Skill.CastAnimation} {characterSkill.Skill.CastEffect} {characterSkill.Skill.SkillVNum}"); characterSkill.LastUse = DateTime.Now; if (!Session.Character.HasGodMode) { Session.Character.Mp -= characterSkill.Skill.MpCost; } Session.SendPacket(Session.Character.GenerateStat()); characterSkill.LastUse = DateTime.Now; Observable.Timer(TimeSpan.FromMilliseconds(characterSkill.Skill.CastTime * 100)) .Subscribe( o => { Session.Character.LastSkillUse = DateTime.Now; Session.CurrentMap?.Broadcast($"bs 1 {Session.Character.CharacterId} {x} {y} {characterSkill.Skill.SkillVNum} {characterSkill.Skill.Cooldown} {characterSkill.Skill.AttackAnimation} {characterSkill.Skill.Effect} 0 0 1 1 0 0 0"); IEnumerable <MapMonster> monstersInRange = Session.CurrentMap?.GetListMonsterInRange(x, y, characterSkill.Skill.TargetRange).ToList(); if (monstersInRange != null) { foreach (MapMonster mon in monstersInRange.Where(s => s.CurrentHp > 0)) { mon.HitQueue.Enqueue(new GameObject.Networking.HitRequest(TargetHitType.ZoneHit, Session, characterSkill.Skill, x, y)); } } }); Observable.Timer(TimeSpan.FromMilliseconds(characterSkill.Skill.CastTime * 100)) .Subscribe( o => { Session.SendPacket($"sr {Castingid}"); }); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MP"), 10)); Session.SendPacket("cancel 2 0"); } } else { Session.SendPacket("cancel 2 0"); } }
/// <summary> /// mtlist /// </summary> /// <param name="packet"></param> public void MultiTargetListHit(MultiTargetListPacket mutliTargetListPacket) { PenaltyLogDTO penalty = Session.Account.PenaltyLogs.OrderByDescending(s => s.DateEnd).FirstOrDefault(); if (Session.Character.IsMuted()) { Session.SendPacket("cancel 0 0"); Session.CurrentMap?.Broadcast(Session.Character.Gender == GenderType.Female ? Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("MUTED_FEMALE"), 1) : Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("MUTED_MALE"), 1)); Session.SendPacket(Session.Character.GenerateSay(String.Format(Language.Instance.GetMessageFromKey("MUTE_TIME"), (penalty.DateEnd - DateTime.Now).ToString("hh\\:mm\\:ss")), 11)); Session.SendPacket(Session.Character.GenerateSay(String.Format(Language.Instance.GetMessageFromKey("MUTE_TIME"), (penalty.DateEnd - DateTime.Now).ToString("hh\\:mm\\:ss")), 12)); return; } if ((DateTime.Now - Session.Character.LastTransform).TotalSeconds < 3) { Session.SendPacket("cancel 0 0"); Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("CANT_ATTACKNOW"), 0)); return; } if (Session.Character.IsVehicled) { Session.SendPacket("cancel 0 0"); return; } Logger.Debug(mutliTargetListPacket.ToString(), Session.SessionId); if (mutliTargetListPacket != null && mutliTargetListPacket.TargetsAmount > 0 && mutliTargetListPacket.TargetsAmount == mutliTargetListPacket.Targets.Count()) { foreach (MultiTargetListSubPacket subpacket in mutliTargetListPacket.Targets) { List <CharacterSkill> skills = Session.Character.UseSp ? Session.Character.SkillsSp.GetAllItems() : Session.Character.Skills.GetAllItems(); if (skills != null) { CharacterSkill ski = skills.FirstOrDefault(s => s.Skill.CastId == subpacket.SkillCastId - 1); if (ski.CanBeUsed()) { MapMonster mon = Session.CurrentMap.GetMonster(subpacket.TargetId); if (mon != null && mon.IsInRange(Session.Character.MapX, Session.Character.MapY, ski.Skill.Range) && ski != null && mon.CurrentHp > 0) { Session.Character.LastSkillUse = DateTime.Now; mon.HitQueue.Enqueue(new GameObject.Networking.HitRequest(TargetHitType.SpecialZoneHit, Session, ski.Skill)); } Observable.Timer(TimeSpan.FromMilliseconds(ski.Skill.CastTime * 100)) .Subscribe( o => { Session.SendPacket($"sr {subpacket.SkillCastId - 1}"); } ); } } } } }
private void ZoneHit(int Castingid, short x, short y) { List <CharacterSkill> skills = Session.Character.UseSp ? Session.Character.SkillsSp.GetAllItems() : Session.Character.Skills.GetAllItems(); ushort damage = 0; int hitmode = 0; CharacterSkill ski = skills.FirstOrDefault(s => s.Skill.CastId == Castingid); if (!Session.Character.WeaponLoaded(ski)) { Session.SendPacket("cancel 2 0"); return; } if (ski != null && ski.CanBeUsed()) { if (Session.Character.Mp >= ski.Skill.MpCost) { Task t = Task.Factory.StartNew((Func <Task>)(async() => { Session.CurrentMap?.Broadcast($"ct_n 1 {Session.Character.CharacterId} 3 -1 {ski.Skill.CastAnimation} {ski.Skill.CastEffect} {ski.Skill.SkillVNum}"); ski.LastUse = DateTime.Now; if (!Session.Character.HasGodMode) { Session.Character.Mp -= ski.Skill.MpCost; } Session.SendPacket(Session.Character.GenerateStat()); ski.LastUse = DateTime.Now; await Task.Delay(ski.Skill.CastTime * 100); Session.Character.LastSkillUse = DateTime.Now; Session.CurrentMap?.Broadcast($"bs 1 {Session.Character.CharacterId} {x} {y} {ski.Skill.SkillVNum} {ski.Skill.Cooldown} {ski.Skill.AttackAnimation} {ski.Skill.Effect} 0 0 1 1 0 0 0"); IEnumerable <MapMonster> monstersInRange = Session.CurrentMap.GetListMonsterInRange(x, y, ski.Skill.TargetRange).ToList(); foreach (MapMonster mon in monstersInRange.Where(s => s.CurrentHp > 0)) { damage = GenerateDamage(mon.MapMonsterId, ski.Skill, ref hitmode); Session.CurrentMap?.Broadcast($"su 1 {Session.Character.CharacterId} 3 {mon.MapMonsterId} {ski.Skill.SkillVNum} {ski.Skill.Cooldown} {ski.Skill.AttackAnimation} {ski.Skill.Effect} {x} {y} {(mon.IsAlive ? 1 : 0)} {(int)(((float)mon.CurrentHp / (float)ServerManager.GetNpc(mon.MonsterVNum).MaxHP) * 100)} {damage} 5 {ski.Skill.SkillType - 1}"); Task.Factory.StartNew(() => { GenerateKillBonus(mon.MapMonsterId); }); } await Task.Delay((ski.Skill.Cooldown) * 100); Session.SendPacket($"sr {Castingid}"); })); } else { Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MP"), 10)); Session.SendPacket("cancel 2 0"); } } else { Session.SendPacket("cancel 2 0"); } }
private void ExecuteHandler(ClientSession session) { CharacterSkill ski = (session.Character.UseSp ? session.Character.SkillsSp?.GetAllItems() : session.Character.Skills?.GetAllItems())?.Find(s => s.Skill?.CastId == CastId && (s.Skill?.UpgradeSkill == 0 || s.Skill?.UpgradeSkill == 3)); if (session.Character.NoAttack > 0 || ski?.CanBeUsed() != true) { session.SendPacket(StaticPacketHelper.Cancel(2)); return; } if (session.Character.CanFight) { bool isMuted = session.Character.MuteMessage(); if (isMuted || session.Character.IsVehicled || session.Character.InvisibleGm) { session.SendPacket(StaticPacketHelper.Cancel()); return; } bool sendCoordinates = false; if (MapX.HasValue && MapY.HasValue) { session.Character.PositionX = MapX.Value; session.Character.PositionY = MapY.Value; sendCoordinates = true; } if (session.Character.IsSitting) { session.Character.Rest(); } switch (UserType) { case UserType.Monster: if (session.Character.Hp > 0) { session.TargetHit(CastId, MapMonsterId, sendCoordinates: sendCoordinates); int[] fairyWings = session.Character.GetBuff(BCardType.CardType.EffectSummon, 11); int random = ServerManager.RandomNumber(); if (fairyWings[0] > random) { Observable.Timer(TimeSpan.FromSeconds(1)).Subscribe(o => { ski.LastUse = DateTime.UtcNow.AddMilliseconds(ski.Skill.Cooldown * 100 * -1); session.SendPacket(StaticPacketHelper.SkillReset(CastId)); }); } } break; case UserType.Player: if (session.Character.Hp > 0) { if (MapMonsterId != session.Character.CharacterId) { session.TargetHit(CastId, MapMonsterId, true, sendCoordinates); } else { session.TargetHit(CastId, MapMonsterId, sendCoordinates: sendCoordinates); } int[] fairyWings = session.Character.GetBuff(BCardType.CardType.EffectSummon, 11); int random = ServerManager.RandomNumber(); if (fairyWings[0] > random) { Observable.Timer(TimeSpan.FromSeconds(1)).Subscribe(o => { ski.LastUse = DateTime.UtcNow.AddMilliseconds(ski.Skill.Cooldown * 100 * -1); session.SendPacket(StaticPacketHelper.SkillReset(CastId)); }); } } else { session.SendPacket(StaticPacketHelper.Cancel(2)); } break; default: session.SendPacket(StaticPacketHelper.Cancel(2)); return; } Observable.Timer(TimeSpan.FromMilliseconds(200)).Subscribe(observer => { session.Character.RemoveBuff(614); session.Character.RemoveBuff(615); session.Character.RemoveBuff(616); }); } else { session.SendPacket(StaticPacketHelper.Cancel(2)); } }
public void TargetHit(int castingId, int targetId) { if ((DateTime.Now - Session.Character.LastTransform).TotalSeconds < 3) { Session.SendPacket("cancel 0 0"); Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("CANT_ATTACK"), 0)); return; } bool doNotCancel = false; List <CharacterSkill> skills = Session.Character.UseSp ? Session.Character.SkillsSp.GetAllItems() : Session.Character.Skills.GetAllItems(); if (skills != null) { CharacterSkill ski = skills.FirstOrDefault(s => s.Skill?.CastId == castingId && s.Skill?.UpgradeSkill == 0); Session.SendPacket("ms_c 0"); if (!Session.Character.WeaponLoaded(ski) || !ski.CanBeUsed()) { Session.SendPacket("cancel 2 0"); return; } if (ski != null && Session.Character.Mp >= ski.Skill.MpCost) { // AOE Target hit if (ski.Skill.TargetType == 1 && ski.Skill.HitType == 1) { Session.Character.LastSkillUse = DateTime.Now; if (!Session.Character.HasGodMode) { Session.Character.Mp -= ski.Skill.MpCost; } if (Session.Character.UseSp && ski.Skill.CastEffect != -1) { Session.SendPackets(Session.Character.GenerateQuicklist()); } Session.SendPacket(Session.Character.GenerateStat()); CharacterSkill skillinfo = Session.Character.Skills.GetAllItems().OrderBy(o => o.SkillVNum).FirstOrDefault(s => s.Skill.UpgradeSkill == ski.Skill.SkillVNum && s.Skill.Effect > 0 && s.Skill.SkillType == 2); Session.CurrentMap?.Broadcast($"ct 1 {Session.Character.CharacterId} 1 {Session.Character.CharacterId} {ski.Skill.CastAnimation} {(skillinfo != null ? skillinfo.Skill.CastEffect : ski.Skill.CastEffect)} {ski.Skill.SkillVNum}"); // Generate scp ski.LastUse = DateTime.Now; if (ski.Skill.CastEffect != 0) { Thread.Sleep(ski.Skill.CastTime * 100); } doNotCancel = true; Session.CurrentMap.Broadcast($"su 1 {Session.Character.CharacterId} 1 {Session.Character.CharacterId} {ski.Skill.SkillVNum} {ski.Skill.Cooldown} {ski.Skill.AttackAnimation} {(skillinfo != null ? skillinfo.Skill.Effect : ski.Skill.Effect)} {Session.Character.MapX} {Session.Character.MapY} 1 {((int)((double)Session.Character.Hp / Session.Character.HPLoad()) * 100)} 0 -2 {ski.Skill.SkillType - 1}"); if (ski.Skill.TargetRange != 0) { foreach (MapMonster mon in Session.CurrentMap.GetListMonsterInRange(Session.Character.MapX, Session.Character.MapY, ski.Skill.TargetRange).Where(s => s.CurrentHp > 0)) { mon.HitQueue.Enqueue(new GameObject.Networking.HitRequest(TargetHitType.AOETargetHit, Session, ski.Skill, skillEffect: (skillinfo != null ? skillinfo.Skill.Effect : ski.Skill.Effect))); } } } else if (ski.Skill.TargetType == 0) // monster target { MapMonster monsterToAttack = Session.CurrentMap.GetMonster(targetId); if (monsterToAttack != null && monsterToAttack.IsAlive) { if (monsterToAttack != null && ski != null && ski.CanBeUsed()) { if (Session.Character.Mp >= ski.Skill.MpCost) { short distanceX = (short)(Session.Character.MapX - monsterToAttack.MapX); short distanceY = (short)(Session.Character.MapY - monsterToAttack.MapY); if (Map.GetDistance(new MapCell() { X = Session.Character.MapX, Y = Session.Character.MapY }, new MapCell() { X = monsterToAttack.MapX, Y = monsterToAttack.MapY }) <= (ski.Skill.Range) + monsterToAttack.Monster.BasicArea) { Session.Character.LastSkillUse = DateTime.Now; ski.LastUse = DateTime.Now; doNotCancel = true; if (!Session.Character.HasGodMode) { Session.Character.Mp -= ski.Skill.MpCost; } if (Session.Character.UseSp && ski.Skill.CastEffect != -1) { Session.SendPackets(Session.Character.GenerateQuicklist()); } Session.SendPacket(Session.Character.GenerateStat()); CharacterSkill characterSkillInfo = Session.Character.Skills.GetAllItems().OrderBy(o => o.SkillVNum) .FirstOrDefault(s => s.Skill.UpgradeSkill == ski.Skill.SkillVNum && s.Skill.Effect > 0 && s.Skill.SkillType == 2); Session.CurrentMap?.Broadcast($"ct 1 {Session.Character.CharacterId} 3 {monsterToAttack.MapMonsterId} {ski.Skill.CastAnimation} {(characterSkillInfo != null ? characterSkillInfo.Skill.CastEffect : ski.Skill.CastEffect)} {ski.Skill.SkillVNum}"); Session.Character.Skills.GetAllItems().Where(s => s.Id != ski.Id).ToList().ForEach(i => i.Hit = 0); // Generate scp ski.LastUse = DateTime.Now; if ((DateTime.Now - ski.LastUse).TotalSeconds > 3) { ski.Hit = 0; } else { ski.Hit++; } if (ski.Skill.CastEffect != 0) { Thread.Sleep(ski.Skill.CastTime * 100); } // check if we will hit mutltiple targets if (ski.Skill.TargetRange != 0) { ComboDTO skillCombo = ski.Skill.Combos.FirstOrDefault(s => ski.Hit == s.Hit); if (skillCombo != null) { if (ski.Skill.Combos.OrderByDescending(s => s.Hit).First().Hit == ski.Hit) { ski.Hit = 0; } IEnumerable <MapMonster> monstersInAOERange = Session.CurrentMap?.GetListMonsterInRange(monsterToAttack.MapX, monsterToAttack.MapY, ski.Skill.TargetRange).ToList(); foreach (MapMonster mon in monstersInAOERange.Where(s => s.CurrentHp > 0)) { mon.HitQueue.Enqueue(new GameObject.Networking.HitRequest(TargetHitType.SingleTargetHitCombo, Session, ski.Skill , skillCombo: skillCombo)); } } else { IEnumerable <MapMonster> monstersInAOERange = Session.CurrentMap?.GetListMonsterInRange(monsterToAttack.MapX, monsterToAttack.MapY, ski.Skill.TargetRange).ToList(); Session.CurrentMap.Broadcast($"su 1 {Session.Character.CharacterId} 3 {targetId} {ski.Skill.SkillVNum} {ski.Skill.Cooldown} {ski.Skill.AttackAnimation} {(characterSkillInfo != null ? characterSkillInfo.Skill.Effect : ski.Skill.Effect)} 0 0 {(monsterToAttack.IsAlive ? 1 : 0)} {((int)((double)Session.Character.Hp / Session.Character.HPLoad()) * 100)} 0 0 {ski.Skill.SkillType - 1}"); foreach (MapMonster mon in monstersInAOERange.Where(s => s.CurrentHp > 0)) { mon.HitQueue.Enqueue(new GameObject.Networking.HitRequest(TargetHitType.SingleAOETargetHit, Session, ski.Skill , skillEffect: (characterSkillInfo != null ? characterSkillInfo.Skill.Effect : ski.Skill.Effect))); } } } else { ComboDTO skillCombo = ski.Skill.Combos.FirstOrDefault(s => ski.Hit == s.Hit); if (skillCombo != null) { if (ski.Skill.Combos.OrderByDescending(s => s.Hit).First().Hit == ski.Hit) { ski.Hit = 0; } monsterToAttack.HitQueue.Enqueue(new GameObject.Networking.HitRequest(TargetHitType.SingleTargetHitCombo, Session, ski.Skill, skillCombo: skillCombo)); } else { monsterToAttack.HitQueue.Enqueue(new GameObject.Networking.HitRequest(TargetHitType.SingleTargetHit, Session, ski.Skill)); } } } } } } } Session.SendPacketAfterWait($"sr {castingId}", ski.Skill.Cooldown * 100); } else { doNotCancel = false; Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MP"), 10)); } } if (!doNotCancel) { Session.SendPacket($"cancel 2 {targetId}"); } }
public void SpecialZoneHit(string packet) { PenaltyLogDTO penalty = Session.Account.PenaltyLogs.OrderByDescending(s => s.DateEnd).FirstOrDefault(); if (Session.Character.IsMuted()) { Session.SendPacket("cancel 0 0"); Session.CurrentMap?.Broadcast(Session.Character.Gender == GenderType.Female ? Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("MUTED_FEMALE"), 1) : Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("MUTED_MALE"), 1)); Session.SendPacket(Session.Character.GenerateSay(String.Format(Language.Instance.GetMessageFromKey("MUTE_TIME"), (penalty.DateEnd - DateTime.Now).ToString("hh\\:mm\\:ss")), 11)); Session.SendPacket(Session.Character.GenerateSay(String.Format(Language.Instance.GetMessageFromKey("MUTE_TIME"), (penalty.DateEnd - DateTime.Now).ToString("hh\\:mm\\:ss")), 12)); return; } if ((DateTime.Now - Session.Character.LastTransform).TotalSeconds < 3) { Session.SendPacket("cancel 0 0"); Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("CANT_ATTACKNOW"), 0)); return; } if (Session.Character.IsVehicled) { Session.SendPacket("cancel 0 0"); return; } Logger.Debug(packet, Session.SessionId); string[] packetsplit = packet.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); ushort damage = 0; int hitmode = 0; if (packetsplit.Length > 3) { // get amount of mobs which are targeted short mobAmount = 0; short.TryParse(packetsplit[2], out mobAmount); if ((packetsplit.Length - 3) / 2 != mobAmount) { return; } for (int i = 3; i < packetsplit.Length - 2; i += 2) { List <CharacterSkill> skills = Session.Character.UseSp ? Session.Character.SkillsSp.GetAllItems() : Session.Character.Skills.GetAllItems(); if (skills != null) { short mapMonsterTargetId = -1; short skillCastId = -1; if (short.TryParse(packetsplit[i], out skillCastId) && short.TryParse(packetsplit[i + 1], out mapMonsterTargetId)) { Task t = Task.Factory.StartNew((Func <Task>)(async() => { CharacterSkill ski = skills.FirstOrDefault(s => s.Skill.CastId == skillCastId - 1); if (ski.CanBeUsed()) { MapMonster mon = Session.CurrentMap.GetMonster(mapMonsterTargetId); if (mon != null && mon.IsInRange(Session.Character.MapX, Session.Character.MapY, ski.Skill.Range) && ski != null && mon.CurrentHp > 0) { Session.Character.LastSkillUse = DateTime.Now; damage = GenerateDamage(mon.MapMonsterId, ski.Skill, ref hitmode); Session.CurrentMap?.Broadcast($"su 1 {Session.Character.CharacterId} 3 {mon.MapMonsterId} {ski.Skill.SkillVNum} {ski.Skill.Cooldown} {ski.Skill.AttackAnimation} {ski.Skill.Effect} {Session.Character.MapX} {Session.Character.MapY} {(mon.IsAlive ? 1 : 0)} {(int)(((float)mon.CurrentHp / (float)ServerManager.GetNpc(mon.MonsterVNum).MaxHP) * 100)} {damage} 0 {ski.Skill.SkillType - 1}"); Task.Factory.StartNew(() => { GenerateKillBonus(mon.MapMonsterId); }); } await Task.Delay((ski.Skill.Cooldown) * 100); Session.SendPacket($"sr {skillCastId - 1}"); } })); } } } } }
public void TargetHit(int castingId, int targetId) { IList <string> broadcastPackets = new List <string>(); List <CharacterSkill> skills = Session.Character.UseSp ? Session.Character.SkillsSp.GetAllItems() : Session.Character.Skills.GetAllItems(); bool notcancel = false; if ((DateTime.Now - Session.Character.LastTransform).TotalSeconds < 3) { Session.SendPacket("cancel 0 0"); Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("CANT_ATTACK"), 0)); return; } if (skills != null) { ushort damage = 0; int hitmode = 0; CharacterSkill ski = skills.FirstOrDefault(s => s.Skill?.CastId == castingId && s.Skill?.UpgradeSkill == 0); Session.SendPacket("ms_c 0"); if (!Session.Character.WeaponLoaded(ski)) { Session.SendPacket("cancel 2 0"); return; } for (int i = 0; i < 10 && !ski.CanBeUsed(); i++) { Thread.Sleep(100); if (i == 10) { Session.SendPacket("cancel 2 0"); return; } } if (ski != null && Session.Character.Mp >= ski.Skill.MpCost) { if (ski.Skill.TargetType == 1 && ski.Skill.HitType == 1) { Session.Character.LastSkillUse = DateTime.Now; if (!Session.Character.HasGodMode) { Session.Character.Mp -= ski.Skill.MpCost; } if (Session.Character.UseSp && ski.Skill.CastEffect != -1) { Session.SendPackets(Session.Character.GenerateQuicklist()); } Session.SendPacket(Session.Character.GenerateStat()); CharacterSkill skillinfo = Session.Character.Skills.GetAllItems().OrderBy(o => o.SkillVNum).FirstOrDefault(s => s.Skill.UpgradeSkill == ski.Skill.SkillVNum && s.Skill.Effect > 0 && s.Skill.SkillType == 2); Session.CurrentMap?.Broadcast($"ct 1 {Session.Character.CharacterId} 1 {Session.Character.CharacterId} {ski.Skill.CastAnimation} {(skillinfo != null ? skillinfo.Skill.CastEffect : ski.Skill.CastEffect)} {ski.Skill.SkillVNum}"); // Generate scp ski.LastUse = DateTime.Now; if (ski.Skill.CastEffect != 0) { Thread.Sleep(ski.Skill.CastTime * 100); } notcancel = true; MapMonster mmon; broadcastPackets.Add($"su 1 {Session.Character.CharacterId} 1 {Session.Character.CharacterId} {ski.Skill.SkillVNum} {ski.Skill.Cooldown} {ski.Skill.AttackAnimation} {(skillinfo != null ? skillinfo.Skill.Effect : ski.Skill.Effect)} {Session.Character.MapX} {Session.Character.MapY} 1 {((int)((double)Session.Character.Hp / Session.Character.HPLoad()) * 100)} 0 -2 {ski.Skill.SkillType - 1}"); if (ski.Skill.TargetRange != 0) { foreach (MapMonster mon in Session.CurrentMap.GetListMonsterInRange(Session.Character.MapX, Session.Character.MapY, ski.Skill.TargetRange).Where(s => s.CurrentHp > 0)) { mmon = Session.CurrentMap.GetMonster(mon.MapMonsterId); if (mmon != null) { damage = GenerateDamage(mon.MapMonsterId, ski.Skill, ref hitmode); broadcastPackets.Add($"su 1 {Session.Character.CharacterId} 3 {mmon.MapMonsterId} {ski.Skill.SkillVNum} {ski.Skill.Cooldown} {ski.Skill.AttackAnimation} {(skillinfo != null ? skillinfo.Skill.Effect : ski.Skill.Effect)} {Session.Character.MapX} {Session.Character.MapY} {(mmon.IsAlive ? 1 : 0)} {(int)(((float)mmon.CurrentHp / (float)mon.Monster.MaxHP) * 100)} {damage} 5 {ski.Skill.SkillType - 1}"); Task.Factory.StartNew(() => { GenerateKillBonus(mon.MapMonsterId); }); } } } } else if (ski.Skill.TargetType == 0) { // if monster target MapMonster monsterToAttack = Session.CurrentMap.GetMonster(targetId); if (monsterToAttack != null && monsterToAttack.IsAlive) { NpcMonster monsterToAttackInfo = ServerManager.GetNpc(monsterToAttack.MonsterVNum); if (monsterToAttack != null && ski != null && ski.CanBeUsed()) { if (Session.Character.Mp >= ski.Skill.MpCost) { short distanceX = (short)(Session.Character.MapX - monsterToAttack.MapX); short distanceY = (short)(Session.Character.MapY - monsterToAttack.MapY); if (Map.GetDistance(new MapCell() { X = Session.Character.MapX, Y = Session.Character.MapY }, new MapCell() { X = monsterToAttack.MapX, Y = monsterToAttack.MapY }) <= ski.Skill.Range + (DateTime.Now - monsterToAttack.LastMove).TotalSeconds * 2 * (monsterToAttackInfo.Speed == 0 ? 1 : monsterToAttackInfo.Speed) || ski.Skill.TargetRange != 0) { Session.Character.LastSkillUse = DateTime.Now; damage = GenerateDamage(monsterToAttack.MapMonsterId, ski.Skill, ref hitmode); ski.LastUse = DateTime.Now; Task.Factory.StartNew(() => { GenerateKillBonus(monsterToAttack.MapMonsterId); }); notcancel = true; if (!Session.Character.HasGodMode) { Session.Character.Mp -= ski.Skill.MpCost; } if (Session.Character.UseSp && ski.Skill.CastEffect != -1) { Session.SendPackets(Session.Character.GenerateQuicklist()); } Session.SendPacket(Session.Character.GenerateStat()); CharacterSkill characterSkillInfo = Session.Character.Skills.GetAllItems().OrderBy(o => o.SkillVNum).FirstOrDefault(s => s.Skill.UpgradeSkill == ski.Skill.SkillVNum && s.Skill.Effect > 0 && s.Skill.SkillType == 2); Session.CurrentMap?.Broadcast($"ct 1 {Session.Character.CharacterId} 3 {monsterToAttack.MapMonsterId} {ski.Skill.CastAnimation} {(characterSkillInfo != null ? characterSkillInfo.Skill.CastEffect : ski.Skill.CastEffect)} {ski.Skill.SkillVNum}"); Session.Character.Skills.GetAllItems().Where(s => s.Id != ski.Id).ToList().ForEach(i => i.Hit = 0); // Generate scp ski.LastUse = DateTime.Now; if (damage == 0 || (DateTime.Now - ski.LastUse).TotalSeconds > 3) { ski.Hit = 0; } else { ski.Hit++; } if (ski.Skill.CastEffect != 0) { Thread.Sleep(ski.Skill.CastTime * 100); } ComboDTO skillCombo = ski.Skill.Combos.FirstOrDefault(s => ski.Hit == s.Hit); if (skillCombo != null) { if (ski.Skill.Combos.OrderByDescending(s => s.Hit).ElementAt(0).Hit == ski.Hit) { ski.Hit = 0; } broadcastPackets.Add($"su 1 {Session.Character.CharacterId} 3 {monsterToAttack.MapMonsterId} {ski.Skill.SkillVNum} {ski.Skill.Cooldown} {skillCombo.Animation} {skillCombo.Effect} {Session.Character.MapX} {Session.Character.MapY} {(monsterToAttack.IsAlive ? 1 : 0)} {(int)(((float)monsterToAttack.CurrentHp / (float)monsterToAttackInfo.MaxHP) * 100)} {damage} {hitmode} {ski.Skill.SkillType - 1}"); } else { broadcastPackets.Add($"su 1 {Session.Character.CharacterId} 3 {monsterToAttack.MapMonsterId} {ski.Skill.SkillVNum} {ski.Skill.Cooldown} {ski.Skill.AttackAnimation} {(characterSkillInfo != null ? characterSkillInfo.Skill.Effect : ski.Skill.Effect)} {Session.Character.MapX} {Session.Character.MapY} {(monsterToAttack.IsAlive ? 1 : 0)} {(int)(((float)monsterToAttack.CurrentHp / (float)monsterToAttackInfo.MaxHP) * 100)} {damage} {hitmode} {ski.Skill.SkillType - 1}"); } if (ski.Skill.TargetRange != 0) { IEnumerable <MapMonster> monstersInAOERange = Session.CurrentMap?.GetListMonsterInRange(monsterToAttack.MapX, monsterToAttack.MapY, ski.Skill.TargetRange).ToList(); foreach (MapMonster mon in monstersInAOERange.Where(s => s.CurrentHp > 0)) { damage = GenerateDamage(mon.MapMonsterId, ski.Skill, ref hitmode); broadcastPackets.Add($"su 1 {Session.Character.CharacterId} 3 {mon.MapMonsterId} {ski.Skill.SkillVNum} {ski.Skill.Cooldown} {ski.Skill.AttackAnimation} {(characterSkillInfo != null ? characterSkillInfo.Skill.Effect : ski.Skill.Effect)} {Session.Character.MapX} {Session.Character.MapY} {(mon.IsAlive ? 1 : 0)} {(int)(((float)mon.CurrentHp / (float)ServerManager.GetNpc(mon.MonsterVNum).MaxHP) * 100)} {damage} 5 {ski.Skill.SkillType - 1}"); Task.Factory.StartNew(() => { GenerateKillBonus(mon.MapMonsterId); }); } } } } } } } // send su packets Session.CurrentMap.Broadcast(broadcastPackets.ToArray()); Task t = Task.Factory.StartNew((Func <Task>)(async() => { await Task.Delay((ski.Skill.Cooldown) * 100); Session.SendPacket($"sr {castingId}"); })); } else { notcancel = false; Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MP"), 10)); } } if (!notcancel) { Session.SendPacket($"cancel 2 {targetId}"); } }