internal static void AttackMonster(this ClientSession session, Mate attacker, Skill skill, long targetId, short x, short y) { if (skill?.MpCost > attacker.Mp) { return; } attacker.LastSkillUse = DateTime.Now; attacker.Mp -= skill?.MpCost ?? 0; if (skill?.TargetType == 1 && skill.HitType == 1) { if (!session.HasCurrentMapInstance || skill.TargetRange == 0) { return; } //Probably some pvp stuff in here foreach (MapMonster mon in attacker.Owner.MapInstance.GetListMonsterInRange(attacker.PositionX, attacker.PositionY, skill.TargetRange).Where(s => s.CurrentHp > 0)) { mon.HitQueue.Enqueue(new HitRequest(TargetHitType.AoeTargetHit, session, attacker, skill)); session.CurrentMapInstance.Broadcast(StaticPacketHelper.CastOnTarget(UserType.Npc, attacker.MateTransportId, 2, mon.MapMonsterId, skill.CastAnimation, skill.CastEffect, skill.SkillVNum)); session.CurrentMapInstance.Broadcast(StaticPacketHelper.SkillUsed(UserType.Npc, attacker.MateTransportId, 3, mon.MapMonsterId, skill.SkillVNum, skill.Cooldown, skill.CastAnimation, skill.CastEffect, mon.MapX, mon.MapY, mon.CurrentHp > 0, (int)(mon.CurrentHp / (double)mon.MaxHp * 100), 0, 0, skill.SkillType)); } } else if (skill?.TargetType == 2 && skill.HitType == 0) { ClientSession target = attacker.Owner.Session ?? session; session.CurrentMapInstance.Broadcast(StaticPacketHelper.CastOnTarget(UserType.Npc, attacker.MateTransportId, 2, targetId, skill.CastAnimation, skill.CastEffect, skill.SkillVNum)); session.CurrentMapInstance.Broadcast(StaticPacketHelper.SkillUsed(UserType.Npc, attacker.MateTransportId, 3, targetId, skill.SkillVNum, skill.Cooldown, skill.CastAnimation, skill.CastEffect, x, y, true, 100, 0, 0, skill.SkillType)); skill.BCards.ToList().ForEach(s => { // Apply skill bcards to owner and pet s.ApplyBCards(target.Character); s.ApplyBCards(attacker); }); } else if (skill?.TargetType == 1 && skill.HitType != 1) { session.CurrentMapInstance.Broadcast(StaticPacketHelper.CastOnTarget(UserType.Npc, attacker.MateTransportId, 2, targetId, skill.CastAnimation, skill.CastEffect, skill.SkillVNum)); session.CurrentMapInstance.Broadcast(StaticPacketHelper.SkillUsed(UserType.Npc, attacker.MateTransportId, 3, targetId, skill.SkillVNum, skill.Cooldown, skill.CastAnimation, skill.CastEffect, x, y, true, 100, 0, 0, skill.SkillType)); switch (skill.HitType) { case 2: IEnumerable <MapMonster> entityInRange = session.Character.MapInstance?.GetListMonsterInRange(attacker.PositionX, attacker.PositionY, skill.TargetRange); foreach (BCard sb in skill.BCards) { if (sb.Type != (short)BCardType.CardType.Buff) { continue; } Buff bf = new Buff((short)sb.SecondData); if (bf.Card.BuffType != BuffType.Good) { continue; } var bonusBuff = 0; if (attacker.SpInstance != null && attacker.IsUsingSp && sb.BuffCard?.CardId >= 2000) { if (attacker.SpInstance.FirstPartnerSkill == skill.SkillVNum) { bonusBuff = (int)(attacker.SpInstance.FirstPartnerSkillRank - 1); } else if (attacker.SpInstance.SecondPartnerSkill == skill.SkillVNum) { bonusBuff = (int)(attacker.SpInstance.SecondPartnerSkillRank - 1); } else if (attacker.SpInstance.ThirdPartnerSkill == skill.SkillVNum) { bonusBuff = (int)(attacker.SpInstance.ThirdPartnerSkillRank - 1); } } sb.ApplyBCards(attacker, buffLevel: (short)bonusBuff); sb.ApplyBCards(attacker.Owner, buffLevel: (short)bonusBuff); } if (entityInRange != null) { foreach (var target in entityInRange) { foreach (BCard s in skill.BCards) { if (s.Type != (short)BCardType.CardType.Buff) { s.ApplyBCards(target, attacker); continue; } switch (attacker.Owner.MapInstance.MapInstanceType) { default: s.ApplyBCards(target); break; } } } } break; case 4: case 0: foreach (BCard bc in skill.BCards) { var bonusBuff = 0; if (attacker.SpInstance != null && attacker.IsUsingSp && bc.BuffCard?.CardId >= 2000) { if (attacker.SpInstance.FirstPartnerSkill == skill.SkillVNum) { bonusBuff = (int)(attacker.SpInstance.FirstPartnerSkillRank - 1); } else if (attacker.SpInstance.SecondPartnerSkill == skill.SkillVNum) { bonusBuff = (int)(attacker.SpInstance.SecondPartnerSkillRank - 1); } else if (attacker.SpInstance.ThirdPartnerSkill == skill.SkillVNum) { bonusBuff = (int)(attacker.SpInstance.ThirdPartnerSkillRank - 1); } } if (bc.Type == (short)BCardType.CardType.Buff && bc.BuffCard?.BuffType == BuffType.Good) { bc.ApplyBCards(attacker, buffLevel: (short)bonusBuff); bc.ApplyBCards(attacker.Owner, buffLevel: (short)bonusBuff); } else { bc.ApplyBCards(attacker); } } break; } } else if (skill != null && skill.TargetType == 0 && session.HasCurrentMapInstance) { MapMonster monsterToAttack = attacker.Owner.MapInstance.GetMonster(targetId); if (monsterToAttack == null || attacker.Mp <= skill.MpCost) { return; } if (Map.GetDistance(new MapCell { X = monsterToAttack.MapX, Y = monsterToAttack.MapY }, new MapCell { X = monsterToAttack.MapX, Y = monsterToAttack.MapY }) >= skill.Range + 1 + monsterToAttack.Monster.BasicArea) { return; } foreach (BCard bc in skill.BCards) { var bf = new Buff((short)bc.SecondData); if (bf.Card?.BuffType == BuffType.Bad || bf.Card?.BuffType == BuffType.Neutral) { bc.ApplyBCards(monsterToAttack, attacker); } } session.SendPacket(attacker.GenerateStatInfo()); if (skill.HitType == 3) { monsterToAttack.HitQueue.Enqueue(new HitRequest(TargetHitType.SingleAoeTargetHit, session, attacker, skill)); } else { if (skill.TargetRange != 0) { IEnumerable <MapMonster> monstersInAorRange = attacker.Owner.MapInstance?.GetListMonsterInRange(monsterToAttack.MapX, monsterToAttack.MapY, skill.TargetRange); monsterToAttack.HitQueue.Enqueue(new HitRequest(TargetHitType.SingleAoeTargetHit, session, attacker, skill)); if (monstersInAorRange != null) { foreach (MapMonster mon in monstersInAorRange) { mon.HitQueue.Enqueue(new HitRequest(TargetHitType.SingleAoeTargetHit, session, attacker, skill)); } } } else { if (!monsterToAttack.IsAlive) { session.SendPacket("cancel 2 0"); return; } monsterToAttack.HitQueue.Enqueue(new HitRequest(TargetHitType.SingleAoeTargetHit, session, attacker, skill)); } } } }
private void ExecuteHandler(ClientSession session) { switch (Type) { // characters case 1: session.SendPacket(ServerManager.Instance.GetSessionByCharacterId(TargetId)?.Character ?.GenerateStatInfo()); break; // npcs/mates case 2: if (session.HasCurrentMapInstance) { session.CurrentMapInstance.Npcs.Where(n => n.MapNpcId == (int)TargetId).ToList() .ForEach(npc => { NpcMonster npcinfo = ServerManager.GetNpcMonster(npc.NpcVNum); if (npcinfo == null) { return; } session.Character.LastNpcMonsterId = npc.MapNpcId; session.SendPacket( $"st 2 {TargetId} {npcinfo.Level} {npcinfo.HeroLevel} 100 100 50000 50000"); }); Parallel.ForEach(session.CurrentMapInstance.Sessions, sess => { Mate mate = sess.Character.Mates.Find( s => s.MateTransportId == (int)TargetId); if (mate != null) { session.SendPacket(mate.GenerateStatInfo()); } }); } break; // monsters case 3: if (session.HasCurrentMapInstance) { session.CurrentMapInstance.Monsters.Where(m => m.MapMonsterId == (int)TargetId) .ToList().ForEach(monster => { NpcMonster monsterinfo = ServerManager.GetNpcMonster(monster.MonsterVNum); if (monsterinfo == null) { return; } session.Character.LastNpcMonsterId = monster.MapMonsterId; session.SendPacket( $"st 3 {TargetId} {monsterinfo.Level} {monsterinfo.HeroLevel} {(int)(monster.CurrentHp / (float)monster.MaxHp * 100)} {(int)(monster.CurrentMp / (float)monster.MaxMp * 100)} {monster.CurrentHp} {monster.CurrentMp}{monster.Buff.GetAllItems().Aggregate(string.Empty, (current, buff) => current + $" {buff.Card.CardId}")}"); }); } break; } }