public void Initialize()
        {
            _random         = new Random(MapNpcId);
            Npc             = ServerManager.GetNpcMonster(NpcVNum);
            LastEffect      = DateTime.UtcNow;
            LastMove        = DateTime.UtcNow;
            IsHostile       = Npc.IsHostile;
            FirstX          = MapX;
            FirstY          = MapY;
            EffectActivated = true;
            EffectDelay     = 4000;
            _movetime       = ServerManager.RandomNumber(400, 1600);

            //Observable.Timer(TimeSpan.FromMilliseconds(_movetime)).Subscribe(observer => RegisterNpcLife());
            Path        = new List <Node>();
            Recipes     = ServerManager.Instance.GetRecipesByMapNpcId(MapNpcId);
            Target      = -1;
            Teleporters = ServerManager.Instance.GetTeleportersByNpcVNum((short)MapNpcId);
            Shop shop = ServerManager.Instance.GetShopByMapNpcId(MapNpcId);

            if (shop != null)
            {
                shop.Initialize();
                Shop = shop;
            }
        }
Beispiel #2
0
        public void ThrowItems(Tuple <int, short, byte, int, int, short> parameter)
        {
            MapMonster mon = Monsters.Find(s => s.MapMonsterId == parameter.Item1) ?? Monsters.Find(s => s.MonsterVNum == parameter.Item1);

            if (mon == null)
            {
                return;
            }
            short originX = mon.MapX;
            short originY = mon.MapY;
            short destX;
            short destY;
            int   amount = 1;

            Observable.Timer(TimeSpan.FromSeconds(parameter.Item6)).Subscribe(s =>
            {
                for (int i = 0; i < parameter.Item3; i++)
                {
                    amount = ServerManager.RandomNumber(parameter.Item4, parameter.Item5);
                    destX  = (short)(originX + ServerManager.RandomNumber(-10, 10));
                    destY  = (short)(originY + ServerManager.RandomNumber(-10, 10));
                    if (Map.IsBlockedZone(destX, destY))
                    {
                        destX = originX;
                        destY = originY;
                    }
                    MonsterMapItem droppedItem           = new MonsterMapItem(destX, destY, parameter.Item2, amount);
                    DroppedList[droppedItem.TransportId] = droppedItem;
                    Broadcast($"throw {droppedItem.ItemVNum} {droppedItem.TransportId} {originX} {originY} {droppedItem.PositionX} {droppedItem.PositionY} {(droppedItem.GoldAmount > 1 ? droppedItem.GoldAmount : droppedItem.Amount)}");
                }
            });
        }
        public void Sum(ClientSession session, WearableInstance itemToSum)
        {
            if (!session.HasCurrentMap)
            {
                return;
            }

            // cannot sum higher than 5
            if (Upgrade < 6)
            {
                short[] upsuccess = { 100, 100, 85, 70, 50, 20 };
                int[]   goldprice = { 1500, 3000, 6000, 12000, 24000, 48000 };
                short[] sand      = { 5, 10, 15, 20, 25, 30 };
                int     sandVnum  = 1027;
                if (Upgrade + itemToSum.Upgrade < 6 && (((itemToSum.Item.EquipmentSlot == EquipmentType.Gloves) && (Item.EquipmentSlot == EquipmentType.Gloves)) || ((Item.EquipmentSlot == EquipmentType.Boots) && (itemToSum.Item.EquipmentSlot == EquipmentType.Boots))))
                {
                    if (session.Character.Gold < goldprice[Upgrade])
                    {
                        return;
                    }
                    if (session.Character.Inventory.CountItem(sandVnum) < sand[Upgrade])
                    {
                        return;
                    }
                    session.Character.Inventory.RemoveItemAmount(sandVnum, (byte)sand[Upgrade]);
                    session.Character.Gold -= goldprice[Upgrade];

                    int rnd = ServerManager.RandomNumber();
                    if (rnd <= upsuccess[Upgrade + itemToSum.Upgrade])
                    {
                        Upgrade         += (byte)(itemToSum.Upgrade + 1);
                        DarkResistance  += (short)(itemToSum.DarkResistance + itemToSum.Item.DarkResistance);
                        LightResistance += (short)(itemToSum.LightResistance + itemToSum.Item.LightResistance);
                        WaterResistance += (short)(itemToSum.WaterResistance + itemToSum.Item.WaterResistance);
                        FireResistance  += (short)(itemToSum.FireResistance + itemToSum.Item.FireResistance);
                        session.Character.DeleteItemByItemInstanceId(itemToSum.Id);
                        session.SendPacket($"pdti 10 {ItemVNum} 1 27 {Upgrade} 0");
                        session.SendPacket(session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("SUM_SUCCESS"), 0));
                        session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("SUM_SUCCESS"), 12));
                        session.SendPacket(session.Character.GenerateGuri(19, 1, 1324));
                        ItemInstance itemInstnace = session.Character.Inventory.GetItemInstanceById(Id);
                        session.SendPacket(session.Character.GenerateInventoryAdd(itemInstnace.ItemVNum, 1, itemInstnace.Type, itemInstnace.Slot, 0, 0, Upgrade, 0));
                    }
                    else
                    {
                        session.SendPacket(session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("SUM_FAILED"), 0));
                        session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("SUM_FAILED"), 11));
                        session.SendPacket(session.Character.GenerateGuri(19, 1, 1332));
                        session.Character.DeleteItemByItemInstanceId(itemToSum.Id);
                        session.Character.DeleteItemByItemInstanceId(Id);
                    }
                    session.CurrentMap?.Broadcast(session.Character.GenerateGuri(6, 1), session.Character.MapX, session.Character.MapY);
                    session.SendPacket(session.Character.GenerateGold());
                    session.SendPacket("shop_end 1");
                }
            }
        }
Beispiel #4
0
 private void guardiaOfNosville()
 {
     if (LastSpeakNoville.AddSeconds(45) <= DateTime.Now)
     {
         if (MapNpcId == 14832 || MapNpcId == 14831)
         {
             int rnd = ServerManager.RandomNumber(0, 3);
             if (rnd == 1)
             {
                 MapInstance.Broadcast($"say 2 {MapNpcId} 0 They destroyed my field.. Help me!");
                 LastSpeakNoville = DateTime.Now;
             }
             if (rnd == 2)
             {
                 MapInstance.Broadcast($"say 2 {MapNpcId} 0 Help me and kill them!");
                 LastSpeakNoville = DateTime.Now;
             }
         }
         if (MapNpcId == 14837 || MapNpcId == 14838)
         {
             int rnd = ServerManager.RandomNumber(0, 2);
             if (rnd == 1)
             {
                 MapInstance.Broadcast($"say 2 {MapNpcId} 0 ....");
                 LastSpeakNoville = DateTime.Now;
             }
         }
         if (MapNpcId == 14826 || MapNpcId == 14820)
         {
             int rnd = ServerManager.RandomNumber(0, 3);
             if (rnd == 1)
             {
                 MapInstance.Broadcast($"say 2 {MapNpcId} 0 Becarefully..");
                 LastSpeakNoville = DateTime.Now;
             }
             if (rnd == 2)
             {
                 MapInstance.Broadcast($"say 2 {MapNpcId} 0 You are our hero!");
                 LastSpeakNoville = DateTime.Now;
             }
         }
         if (MapNpcId == 14817 || MapNpcId == 14818)
         {
             int rnd = ServerManager.RandomNumber(0, 3);
             if (rnd == 1)
             {
                 MapInstance.Broadcast($"say 2 {MapNpcId} 0 Becarefully..");
                 LastSpeakNoville = DateTime.Now;
             }
             if (rnd == 2)
             {
                 MapInstance.Broadcast($"say 2 {MapNpcId} 0 You are our hero!");
                 LastSpeakNoville = DateTime.Now;
             }
         }
     }
 }
        public static int RarityPoint(short rarity, short lvl)
        {
            Random random = new Random();
            int    p;

            switch (rarity)
            {
            default:
                p = 0;
                break;

            case -2:
                p = -2;
                break;

            case -1:
                p = -1;
                break;

            case 0:
                p = 0;
                break;

            case 1:
                p = 1;
                break;

            case 2:
                p = 2;
                break;

            case 3:
                p = 3;
                break;

            case 4:
                p = 4;
                break;

            case 5:
                p = 5;
                break;

            case 6:
                p = 7;
                break;

            case 7:
                p = 10;
                break;

            case 8:
                p = ServerManager.RandomNumber(11, 16);
                break;
            }
            return(p * (lvl / 5) + 1);
        }
Beispiel #6
0
        public Buff(short id, byte level, Character sender = null)
        {
            Card   = ServerManager.GetCard(id);
            Level  = level;
            Sender = sender;

            if (Card?.BCards != null &&
                Card.Duration == 0 &&
                Card.BCards.Any(s => s.Type == (byte)CardType.SpecialActions && s.SubType == (byte)AdditionalTypes.SpecialActions.Hide / 10))
            {
                Card.Duration = ServerManager.RandomNumber(1, 31) * 10;
            }
        }
 public override void Initialize()
 {
     FirstX        = MapX;
     FirstY        = MapY;
     LastEffect    = LastMove = DateTime.Now;
     Target        = -1;
     Path          = new List <GridPos>();
     IsAlive       = true;
     ShouldRespawn = ShouldRespawn ?? true;
     Monster       = ServerManager.GetNpc(MonsterVNum);
     CurrentHp     = Monster.MaxHP;
     CurrentMp     = Monster.MaxMP;
     Skills        = Monster.Skills.ToList();
     DamageList    = new Dictionary <long, long>();
     _random       = new Random(MapMonsterId);
     _movetime     = ServerManager.RandomNumber(400, 3200);
 }
Beispiel #8
0
        public void DropItemByMonster(long?owner, DropDTO drop, short mapX, short mapY)
        {
            try
            {
                short          localMapX     = mapX;
                short          localMapY     = mapY;
                List <MapCell> possibilities = new List <MapCell>();

                for (short x = -1; x < 2; x++)
                {
                    for (short y = -1; y < 2; y++)
                    {
                        possibilities.Add(new MapCell {
                            X = x, Y = y
                        });
                    }
                }

                foreach (MapCell possibility in possibilities.OrderBy(s => ServerManager.RandomNumber()))
                {
                    localMapX = (short)(mapX + possibility.X);
                    localMapY = (short)(mapY + possibility.Y);
                    if (!Map.IsBlockedZone(localMapX, localMapY))
                    {
                        break;
                    }
                }

                MonsterMapItem droppedItem = new MonsterMapItem(localMapX, localMapY, drop.ItemVNum, drop.Amount, owner ?? -1);
                DroppedList[droppedItem.TransportId] = droppedItem;

                if (drop.Amount == 99)
                {
                    return;
                }
                if (droppedItem == null)
                {
                    return;
                }
                Broadcast($"drop {droppedItem.ItemVNum} {droppedItem.TransportId} {droppedItem.PositionX} {droppedItem.PositionY} {(droppedItem.GoldAmount > 1 ? droppedItem.GoldAmount : droppedItem.Amount)} 0 0 -1");
            }
            catch (Exception e)
            {
                Logger.Error(e);
            }
        }
Beispiel #9
0
        public MapCell GetRandomPosition()
        {
            List <MapCell> cells = new List <MapCell>();

            for (short y = 0; y < YLength; y++)
            {
                for (short x = 0; x < XLength; x++)
                {
                    if (!IsBlockedZone(x, y))
                    {
                        cells.Add(new MapCell {
                            X = x, Y = y
                        });
                    }
                }
            }
            return(cells.OrderBy(s => ServerManager.RandomNumber(0, int.MaxValue)).FirstOrDefault());
        }
Beispiel #10
0
        public bool OpenBoxItem(ClientSession session, ItemInstance box)
        {
            if (box != null)
            {
                List <RollGeneratedItemDTO> roll = box.Item.RollGeneratedItems.Where(s =>
                                                                                     s.MinimumOriginalItemRare <= box.Rare &&
                                                                                     s.MaximumOriginalItemRare >= box.Rare &&
                                                                                     s.OriginalItemDesign == box.Design).ToList();
                int probabilities = roll.Sum(s => s.Probability);
                int rnd           = ServerManager.RandomNumber(0, probabilities);
                int currentrnd    = 0;
                foreach (RollGeneratedItemDTO rollitem in roll)
                {
                    currentrnd += rollitem.Probability;
                    if (currentrnd >= rnd)
                    {
                        Item  i       = ServerManager.GetItem(rollitem.ItemGeneratedVNum);
                        sbyte rare    = 0;
                        byte  upgrade = 0;
                        if (i.ItemType == ItemType.Armor || i.ItemType == ItemType.Weapon ||
                            i.ItemType == ItemType.Shell)
                        {
                            rare = box.Rare;
                        }

                        if (i.ItemType == ItemType.Shell)
                        {
                            upgrade = (byte)ServerManager.RandomNumber(75, 91);
                        }

                        session.Character.GiftAdd(rollitem.ItemGeneratedVNum, rollitem.ItemGeneratedAmount, rare,
                                                  upgrade);
                        session.SendPacket($"rdi {rollitem.ItemGeneratedVNum} {rollitem.ItemGeneratedAmount}");
                        session.Character.Inventory.RemoveItemFromInventory(box.Id);
                        return(true);
                    }
                }
            }

            return(false);
        }
Beispiel #11
0
        public override void Initialize()
        {
            _random     = new Random(MapNpcId);
            Npc         = ServerManager.GetNpc(NpcVNum);
            LastEffect  = DateTime.Now;
            LastMove    = DateTime.Now;
            FirstX      = MapX;
            FirstY      = MapY;
            _movetime   = ServerManager.RandomNumber(500, 3000);
            Path        = new List <GridPos>();
            Recipes     = ServerManager.Instance.GetReceipesByMapNpcId(MapNpcId);
            Target      = -1;
            Teleporters = ServerManager.Instance.GetTeleportersByNpcVNum((short)MapNpcId);
            Shop shop = ServerManager.Instance.GetShopByMapNpcId(MapNpcId);

            if (shop != null)
            {
                shop.Initialize();
                Shop = shop;
            }
        }
Beispiel #12
0
        public void DropItemByMonster(long?owner, DropDTO drop, short mapX, short mapY, bool hideOwnerId = false, bool isQuestItem = false)
        {
            try
            {
                short          localMapX     = mapX;
                short          localMapY     = mapY;
                List <MapCell> possibilities = new List <MapCell>();

                for (short x = -1; x < 2; x++)
                {
                    for (short y = -1; y < 2; y++)
                    {
                        possibilities.Add(new MapCell {
                            X = x, Y = y
                        });
                    }
                }

                foreach (MapCell possibility in possibilities.OrderBy(s => ServerManager.RandomNumber()))
                {
                    localMapX = (short)(mapX + possibility.X);
                    localMapY = (short)(mapY + possibility.Y);
                    if (!Map.IsBlockedZone(localMapX, localMapY))
                    {
                        break;
                    }
                }

                MonsterMapItem droppedItem = new MonsterMapItem(localMapX, localMapY, drop.ItemVNum, drop.Amount, owner ?? -1, isQuestItem)
                {
                    IsDroppedByMonster = true
                };
                DroppedList[droppedItem.TransportId] = droppedItem;
                Broadcast($"drop {droppedItem.ItemVNum} {droppedItem.TransportId} {droppedItem.PositionX} {droppedItem.PositionY} {(droppedItem.GoldAmount > 1 ? droppedItem.GoldAmount : droppedItem.Amount)} {(droppedItem.IsQuestItem ? 1 : 0)} {(droppedItem.OwnerId != -1 ? (!hideOwnerId ? droppedItem.OwnerId : -1) : -1)}");
            }
            catch (Exception e)
            {
                Logger.Error(e);
            }
        }
Beispiel #13
0
        public void ThrowItems(Tuple <int, short, byte, int, int> parameter)
        {
            MapMonster mon = Monsters.Find(s => s.MapMonsterId == parameter.Item1) ?? Monsters.Find(s => s.MonsterVNum == parameter.Item1);

            if (mon == null)
            {
                return;
            }
            short originX = mon.MapX;
            short originY = mon.MapY;
            short destX;
            short destY;
            int   amount = ServerManager.RandomNumber(parameter.Item4, parameter.Item5);

            for (int i = 0; i < parameter.Item3; i++)
            {
                destX = (short)(originX + ServerManager.RandomNumber(-10, 10));
                destY = (short)(originY + ServerManager.RandomNumber(-10, 10));
                MonsterMapItem droppedItem = new MonsterMapItem(destX, destY, parameter.Item2, amount);
                if (parameter.Item2 == 99)
                {
                    return;
                }
                if (amount == 99)
                {
                    return;
                }
                if (parameter == null)
                {
                    return;
                }
                if (droppedItem == null)
                {
                    return;
                }
                DroppedList[droppedItem.TransportId] = droppedItem;

                Broadcast($"throw {droppedItem.ItemVNum} {droppedItem.TransportId} {originX} {originY} {droppedItem.PositionX} {droppedItem.PositionY} {(droppedItem.GoldAmount > 1 ? droppedItem.GoldAmount : droppedItem.Amount)}");
            }
        }
Beispiel #14
0
        public void DropItemByMonster(long?Owner, DropDTO drop, short mapX, short mapY, int gold = 0)
        {
            try
            {
                short          localMapX     = (short)ServerManager.RandomNumber(mapX - 1, mapX + 1);
                short          localMapY     = (short)ServerManager.RandomNumber(mapY - 1, mapY + 1);
                List <MapCell> Possibilities = new List <MapCell>();

                for (short x = -1; x < 2; x++)
                {
                    for (short y = -1; y < 2; y++)
                    {
                        Possibilities.Add(new MapCell()
                        {
                            X = x, Y = y
                        });
                    }
                }

                foreach (MapCell possibilitie in Possibilities.OrderBy(s => _random.Next()))
                {
                    localMapX = (short)(mapX + possibilitie.X);
                    localMapY = (short)(mapY + possibilitie.Y);
                    if (!IsBlockedZone(localMapX, localMapY))
                    {
                        break;
                    }
                }

                MonsterMapItem droppedItem = new MonsterMapItem(localMapX, localMapY, drop.ItemVNum, drop.Amount, Owner ?? -1);

                DroppedList[droppedItem.TransportId] = droppedItem;

                Broadcast($"drop {droppedItem.ItemVNum} {droppedItem.TransportId} {droppedItem.PositionX} {droppedItem.PositionY} {(droppedItem.GoldAmount > 1 ? droppedItem.GoldAmount : droppedItem.Amount)} 0 0 -1");
            }
            catch (Exception e)
            {
                Logger.Error(e);
            }
        }
Beispiel #15
0
        public void Initialize()
        {
            _random         = new Random(MapNpcId);
            Npc             = ServerManager.GetNpc(NpcVNum);
            LastEffect      = DateTime.Now;
            LastMove        = DateTime.Now;
            IsHostile       = Npc.IsHostile;
            FirstX          = MapX;
            FirstY          = MapY;
            EffectActivated = true;
            EffectDelay     = 4000;
            _movetime       = ServerManager.RandomNumber(500, 3000);
            Path            = new List <Node>();
            Recipes         = ServerManager.Instance.GetRecipesByMapNpcId(MapNpcId);
            Target          = -1;
            Teleporters     = ServerManager.Instance.GetTeleportersByNpcVNum((short)MapNpcId);
            Shop shop = ServerManager.Instance.GetShopByMapNpcId(MapNpcId);

            if (shop != null)
            {
                shop.Initialize();
                Shop = shop;
            }
        }
Beispiel #16
0
        private void npcLife()
        {
            // Respawn
            if (CurrentHp <= 0 && ShouldRespawn != null && !ShouldRespawn.Value)
            {
                MapInstance.RemoveNpc(this);
                MapInstance.Broadcast(GenerateOut());
            }

            if (!IsAlive && ShouldRespawn != null && ShouldRespawn.Value)
            {
                double timeDeath = (DateTime.Now - Death).TotalSeconds;
                if (timeDeath >= Npc.RespawnTime / 10d)
                {
                    Respawn();
                }
            }

            if (LastProtectedEffect.AddMilliseconds(6000) <= DateTime.Now)
            {
                LastProtectedEffect = DateTime.Now;
                if (IsMate || IsProtected)
                {
                    MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, 825), MapX, MapY);
                }
            }

            double time = (DateTime.Now - LastEffect).TotalMilliseconds;

            if (EffectDelay > 0)
            {
                if (time > EffectDelay)
                {
                    if (Effect > 0 && EffectActivated)
                    {
                        MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, Effect), MapX, MapY);
                    }

                    LastEffect = DateTime.Now;
                }
            }

            time = (DateTime.Now - LastMove).TotalMilliseconds;
            if (Target == -1 && IsMoving && Npc.Speed > 0 && time > _movetime && !HasBuff(CardType.Move, (byte)AdditionalTypes.Move.MovementImpossible))
            {
                _movetime = ServerManager.RandomNumber(500, 3000);
                int maxindex = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                if (maxindex < 1)
                {
                    maxindex = 1;
                }
                if (Path.Count == 0 || Path.Count >= maxindex && maxindex > 0 && Path[maxindex - 1] == null)
                {
                    short xoffset = (short)ServerManager.RandomNumber(-1, 1);
                    short yoffset = (short)ServerManager.RandomNumber(-1, 1);

                    MapCell moveToPosition = new MapCell {
                        X = FirstX, Y = FirstY
                    };
                    if (RunToX != 0 || RunToY != 0)
                    {
                        moveToPosition = new MapCell {
                            X = RunToX, Y = RunToY
                        };
                        _movetime = ServerManager.RandomNumber(300, 1200);
                    }
                    Path = BestFirstSearch.FindPathJagged(new GridPos {
                        X = MapX, Y = MapY
                    }, new GridPos {
                        X = (short)ServerManager.RandomNumber(moveToPosition.X - 3, moveToPosition.X + 3), Y = (short)ServerManager.RandomNumber(moveToPosition.Y - 3, moveToPosition.Y + 3)
                    }, MapInstance.Map.JaggedGrid);
                    maxindex = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                }
                if (DateTime.Now > LastMove && Npc.Speed > 0 && Path.Count > 0)
                {
                    byte speedIndex = (byte)(Npc.Speed / 2.5 < 1 ? 1 : Npc.Speed / 2.5);
                    maxindex = Path.Count > speedIndex ? speedIndex : Path.Count;
                    short mapX = (short)ServerManager.RandomNumber(Path[maxindex - 1].X - 1, Path[maxindex - 1].X + 1);
                    short mapY = (short)_random.Next(Path[maxindex - 1].Y - 1, Path[maxindex - 1].Y + 1);

                    //short mapX = Path[maxindex - 1].X;
                    //short mapY = Path[maxindex - 1].Y;
                    double waitingtime = Map.GetDistance(new MapCell {
                        X = mapX, Y = mapY
                    }, new MapCell {
                        X = MapX, Y = MapY
                    }) / (double)Npc.Speed;
                    MapInstance.Broadcast(new BroadcastPacket(null, PacketFactory.Serialize(StaticPacketHelper.Move(UserType.Npc, MapNpcId, mapX, mapY, Npc.Speed)), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                    LastMove = DateTime.Now.AddSeconds(waitingtime > 1 ? 1 : waitingtime);

                    Observable.Timer(TimeSpan.FromMilliseconds((int)((waitingtime > 1 ? 1 : waitingtime) * 1000))).Subscribe(x =>
                    {
                        MapX = mapX;
                        MapY = mapY;
                    });

                    Path.RemoveRange(0, maxindex);
                }
            }
            if (Target == -1)
            {
                if (IsHostile && Shop == null)
                {
                    MapMonster    monster = MapInstance.GetMonsterInRangeList(MapX, MapY, (byte)(Npc.NoticeRange > 5 ? Npc.NoticeRange / 2 : Npc.NoticeRange)).Where(s => BattleEntity.CanAttackEntity(s.BattleEntity)).FirstOrDefault();
                    ClientSession session = MapInstance.Sessions.FirstOrDefault(s => BattleEntity.CanAttackEntity(s.Character.BattleEntity) && MapInstance == s.Character.MapInstance && Map.GetDistance(new MapCell {
                        X = MapX, Y = MapY
                    }, new MapCell {
                        X = s.Character.PositionX, Y = s.Character.PositionY
                    }) < Npc.NoticeRange);

                    if (monster != null)
                    {
                        Target = monster.MapMonsterId;
                    }
                    if (session?.Character != null)
                    {
                        Target = session.Character.CharacterId;
                    }
                }
            }
            else if (Target != -1)
            {
                MapMonster monster = MapInstance.Monsters.Find(s => s.MapMonsterId == Target);
                if (monster == null || monster.CurrentHp < 1)
                {
                    Target = -1;
                    return;
                }
                NpcMonsterSkill npcMonsterSkill = null;
                if (ServerManager.RandomNumber(0, 10) > 8)
                {
                    npcMonsterSkill = Skills.Where(s => (DateTime.Now - s.LastSkillUse).TotalMilliseconds >= 100 * s.Skill.Cooldown).OrderBy(rnd => _random.Next()).FirstOrDefault();
                }
                int  hitmode   = 0;
                bool onyxWings = false;
                int  damage    = DamageHelper.Instance.CalculateDamage(new BattleEntity(this), new BattleEntity(monster), npcMonsterSkill?.Skill, ref hitmode, ref onyxWings);
                if (monster.Monster.BCards.Find(s => s.Type == (byte)CardType.LightAndShadow && s.SubType == (byte)AdditionalTypes.LightAndShadow.InflictDamageToMP) is BCard card)
                {
                    int reduce = damage / 100 * card.FirstData;
                    if (monster.CurrentMp < reduce)
                    {
                        reduce            = (int)monster.CurrentMp;
                        monster.CurrentMp = 0;
                    }
                    else
                    {
                        monster.DecreaseMp(reduce);
                    }
                    damage -= reduce;
                }
                int distance = Map.GetDistance(new MapCell {
                    X = MapX, Y = MapY
                }, new MapCell {
                    X = monster.MapX, Y = monster.MapY
                });
                if (monster.CurrentHp > 0 && ((npcMonsterSkill != null && distance < npcMonsterSkill.Skill.Range) || distance <= Npc.BasicRange) && !HasBuff(CardType.SpecialAttack, (byte)AdditionalTypes.SpecialAttack.NoAttack))
                {
                    if (((DateTime.Now - LastSkill).TotalMilliseconds >= 1000 + (Npc.BasicCooldown * 200) /* && Skills.Count == 0*/) || npcMonsterSkill != null)
                    {
                        if (npcMonsterSkill != null)
                        {
                            npcMonsterSkill.LastSkillUse = DateTime.Now;
                            MapInstance.Broadcast(StaticPacketHelper.CastOnTarget(UserType.Npc, MapNpcId, UserType.Monster, Target, npcMonsterSkill.Skill.CastAnimation, npcMonsterSkill.Skill.CastEffect, npcMonsterSkill.Skill.SkillVNum));
                        }

                        if (npcMonsterSkill != null && npcMonsterSkill.Skill.CastEffect != 0)
                        {
                            MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, Effect));
                        }
                        monster.BattleEntity.GetDamage(damage, BattleEntity);
                        lock (monster.DamageList)
                        {
                            if (!monster.DamageList.Any(s => s.Key.MapEntityId == MapNpcId))
                            {
                                monster.AddToAggroList(BattleEntity);
                            }
                        }
                        MapInstance.Broadcast(npcMonsterSkill != null
                            ? StaticPacketHelper.SkillUsed(UserType.Npc, MapNpcId, 3, Target, npcMonsterSkill.SkillVNum, npcMonsterSkill.Skill.Cooldown, npcMonsterSkill.Skill.AttackAnimation, npcMonsterSkill.Skill.Effect, 0, 0, monster.CurrentHp > 0, (int)((float)monster.CurrentHp / (float)monster.MaxHp * 100), damage, hitmode, 0)
                            : StaticPacketHelper.SkillUsed(UserType.Npc, MapNpcId, 3, Target, 0, Npc.BasicCooldown, 11, Npc.BasicSkill, 0, 0, monster.CurrentHp > 0, (int)((float)monster.CurrentHp / (float)monster.MaxHp * 100), damage, hitmode, 0));
                        LastSkill = DateTime.Now;

                        if (npcMonsterSkill?.Skill.TargetType == 1 && npcMonsterSkill?.Skill.HitType == 2)
                        {
                            IEnumerable <ClientSession> clientSessions =
                                MapInstance.Sessions?.Where(s =>
                                                            s.Character.IsInRange(MapX,
                                                                                  MapY, npcMonsterSkill.Skill.TargetRange));
                            IEnumerable <Mate> mates = MapInstance.GetListMateInRange(MapX, MapY, npcMonsterSkill.Skill.TargetRange);

                            foreach (BCard skillBcard in npcMonsterSkill.Skill.BCards)
                            {
                                if (skillBcard.Type == 25 && skillBcard.SubType == 1 && new Buff((short)skillBcard.SecondData, Npc.Level)?.Card?.BuffType == BuffType.Good)
                                {
                                    if (clientSessions != null)
                                    {
                                        foreach (ClientSession clientSession in clientSessions)
                                        {
                                            if (clientSession.Character != null)
                                            {
                                                if (!BattleEntity.CanAttackEntity(clientSession.Character.BattleEntity))
                                                {
                                                    skillBcard.ApplyBCards(clientSession.Character.BattleEntity, BattleEntity);
                                                }
                                            }
                                        }
                                    }
                                    if (mates != null)
                                    {
                                        foreach (Mate mate in mates)
                                        {
                                            if (!BattleEntity.CanAttackEntity(mate.BattleEntity))
                                            {
                                                skillBcard.ApplyBCards(mate.BattleEntity, BattleEntity);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (monster.CurrentHp < 1 && monster.SetDeathStatement())
                        {
                            monster.RunDeathEvent();
                            RemoveTarget();
                        }
                    }
                }
                else
                {
                    int maxdistance = Npc.NoticeRange > 5 ? Npc.NoticeRange / 2 : Npc.NoticeRange;
                    if (IsMoving && !HasBuff(CardType.Move, (byte)AdditionalTypes.Move.MovementImpossible))
                    {
                        const short maxDistance = 5;
                        int         maxindex    = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                        if (maxindex < 1)
                        {
                            maxindex = 1;
                        }
                        if ((Path.Count == 0 && distance >= 1 && distance < maxDistance) || (Path.Count >= maxindex && maxindex > 0 && Path[maxindex - 1] == null))
                        {
                            short xoffset = (short)ServerManager.RandomNumber(-1, 1);
                            short yoffset = (short)ServerManager.RandomNumber(-1, 1);

                            //go to monster
                            Path = BestFirstSearch.FindPathJagged(new GridPos {
                                X = MapX, Y = MapY
                            }, new GridPos {
                                X = (short)(monster.MapX + xoffset), Y = (short)(monster.MapY + yoffset)
                            }, MapInstance.Map.JaggedGrid);
                            maxindex = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                        }
                        if (DateTime.Now > LastMove && Npc.Speed > 0 && Path.Count > 0)
                        {
                            byte speedIndex = (byte)(Npc.Speed / 2.5 < 1 ? 1 : Npc.Speed / 2.5);
                            maxindex = Path.Count > speedIndex ? speedIndex : Path.Count;
                            //short mapX = (short)ServerManager.RandomNumber(Path[maxindex - 1].X - 1, Path[maxindex - 1].X + 1);
                            //short mapY = (short)_random.Next(Path[maxindex - 1].Y - 1, Path[maxindex - 1].Y + 1);

                            short  mapX        = Path[maxindex - 1].X;
                            short  mapY        = Path[maxindex - 1].Y;
                            double waitingtime = Map.GetDistance(new MapCell {
                                X = mapX, Y = mapY
                            }, new MapCell {
                                X = MapX, Y = MapY
                            }) / (double)Npc.Speed;
                            MapInstance.Broadcast(new BroadcastPacket(null, PacketFactory.Serialize(StaticPacketHelper.Move(UserType.Npc, MapNpcId, mapX, mapY, Npc.Speed)), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                            LastMove = DateTime.Now.AddSeconds(waitingtime > 1 ? 1 : waitingtime);

                            Observable.Timer(TimeSpan.FromMilliseconds((int)((waitingtime > 1 ? 1 : waitingtime) * 1000))).Subscribe(x =>
                            {
                                MapX = mapX;
                                MapY = mapY;
                            });

                            Path.RemoveRange(0, maxindex);
                        }
                        if (Target != -1 && (MapId != monster.MapId || distance > maxDistance))
                        {
                            RemoveTarget();
                        }
                    }
                }
            }
        }
Beispiel #17
0
        public override void Use(ClientSession session, ref ItemInstance inv, byte Option = 0, string[] packetsplit = null)
        {
            if (session.Character.IsVehicled)
            {
                session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("CANT_DO_VEHICLED"), 10));
                return;
            }

            if (session.CurrentMapInstance.MapInstanceType == MapInstanceType.TalentArenaMapInstance)
            {
                return;
            }

            if (inv.ItemVNum == 2539 || inv.ItemVNum == 10066)//Cuarry Bank Money Card
            {
                if (session.Character.MapInstance.MapInstanceType != MapInstanceType.NormalInstance || session.Character.MapInstance.MapInstanceType != MapInstanceType.BaseMapInstance)
                {
                    return;
                }

                session.Character.OpenBank();
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
            }

            switch (Effect)
            {
            // airwaves - eventitems
            case 0:
                if (inv.Item.ItemType == ItemType.Shell)
                {
                    if (!(inv).ShellEffects.Any())
                    {
                        session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("SHELL_MUST_BE_IDENTIFIED"), 0));
                        return;
                    }

                    if (packetsplit?.Length < 9)
                    {
                        return;
                    }

                    if (!int.TryParse(packetsplit[6], out int requestType))
                    {
                        return;
                    }
                    if (!Enum.TryParse(packetsplit[8], out InventoryType eqType))
                    {
                        return;
                    }

                    if (inv.ShellEffects.Count != 0 && packetsplit?.Length > 9 && byte.TryParse(packetsplit[9], out byte islot))
                    {
                        ItemInstance wearable = session.Character.Inventory.LoadBySlotAndType(islot, InventoryType.Equipment);
                        if (wearable != null && (wearable.Item.ItemType == ItemType.Weapon || wearable.Item.ItemType == ItemType.Armor) && wearable.Item.LevelMinimum >= inv.Upgrade && wearable.Rare >= inv.Rare && !wearable.Item.IsHeroic)
                        {
                            switch (requestType)
                            {
                            case 0:
                                session.SendPacket(wearable.ShellEffects.Any()
                                            ? $"qna #u_i^1^{session.Character.CharacterId}^{(short)inv.Type}^{inv.Slot}^1^1^{(short)eqType}^{islot} {Language.Instance.GetMessageFromKey("ADD_OPTION_ON_STUFF_NOT_EMPTY")}"
                                            : $"qna #u_i^1^{session.Character.CharacterId}^{(short)inv.Type}^{inv.Slot}^1^1^{(short)eqType}^{islot} {Language.Instance.GetMessageFromKey("ADD_OPTION_ON_STUFF")}");
                                break;

                            case 1:

                                if (inv.ShellEffects == null)
                                {
                                    return;
                                }
                                if (wearable.BoundCharacterId != session.Character.CharacterId && wearable.BoundCharacterId != null)
                                {
                                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("NEED_FRAGANCE"), 0));
                                    return;
                                }
                                if (wearable.Rare < inv.Rare)
                                {
                                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("SHELL_RARITY_TOO_HIGH"), 0));
                                    return;
                                }
                                if (wearable.Item.LevelMinimum < inv.Upgrade)
                                {
                                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("SHELL_LEVEL_TOO_HIGH"), 0));
                                    return;
                                }

                                bool weapon = false;
                                if ((inv.ItemVNum >= 565 && inv.ItemVNum <= 576) || (inv.ItemVNum >= 589 && inv.ItemVNum <= 598))
                                {
                                    weapon = true;
                                }
                                else if ((inv.ItemVNum >= 577 && inv.ItemVNum <= 588) || (inv.ItemVNum >= 656 && inv.ItemVNum <= 664) || inv.ItemVNum == 599)
                                {
                                    weapon = false;
                                }
                                else
                                {
                                    return;
                                }
                                if ((wearable.Item.ItemType == ItemType.Weapon && weapon) || (wearable.Item.ItemType == ItemType.Armor && !weapon))
                                {
                                    if (wearable.ShellEffects.Count > 0 && ServerManager.RandomNumber() < 50)
                                    {
                                        session.Character.DeleteItemByItemInstanceId(inv.Id);
                                        session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("OPTION_FAIL"), 0));
                                        return;
                                    }
                                    wearable.BoundCharacterId = session.Character.CharacterId;
                                    wearable.ShellRarity      = inv.Rare;
                                    wearable.ShellEffects.Clear();
                                    DAOFactory.ShellEffectDAO.DeleteByEquipmentSerialId(wearable.EquipmentSerialId);
                                    wearable.ShellEffects.AddRange(inv.ShellEffects);
                                    if (wearable.EquipmentSerialId == Guid.Empty)
                                    {
                                        wearable.EquipmentSerialId = Guid.NewGuid();
                                    }
                                    DAOFactory.ShellEffectDAO.InsertOrUpdateFromList(wearable.ShellEffects, wearable.EquipmentSerialId);
                                    session.Character.DeleteItemByItemInstanceId(inv.Id);
                                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("OPTION_SUCCESS"), 0));
                                }
                                if (ItemType == ItemType.Magical)
                                {
                                    switch (VNum)
                                    {
                                    // Bank Card
                                    case 2539:
                                    case 10066:
                                        if (session.Character.MapInstance.MapInstanceType != MapInstanceType.BaseMapInstance)
                                        {
                                            return;
                                        }

                                        session.Character.OpenBank();
                                        session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                                        return;
                                    }
                                }
                                break;
                            }
                        }
                    }
                    return;
                }

                if (ItemType == ItemType.Event)
                {
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, EffectValue));
                    if (MappingHelper.GuriItemEffects.ContainsKey(EffectValue))
                    {
                        session.CurrentMapInstance?.Broadcast(UserInterfaceHelper.GenerateGuri(19, 1, session.Character.CharacterId, MappingHelper.GuriItemEffects[EffectValue]), session.Character.PositionX, session.Character.PositionY);
                    }
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            //respawn objects
            case 1:
                if (session.Character.MapInstance.MapInstanceType != MapInstanceType.BaseMapInstance || session.Character.IsSeal)
                {
                    session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("CANT_USE_THAT"), 10));
                    return;
                }
                int type, secondaryType, inventoryType, slot;
                if (packetsplit?.Length > 6 && int.TryParse(packetsplit[2], out type) && int.TryParse(packetsplit[3], out secondaryType) && int.TryParse(packetsplit[4], out inventoryType) && int.TryParse(packetsplit[5], out slot))
                {
                    int packetType;
                    switch (EffectValue)
                    {
                    case 0:
                        if (inv.ItemVNum != 2070 && inv.ItemVNum != 10010 || (session.CurrentMapInstance.Map.MapTypes.Any(m => m.MapTypeId == (short)MapTypeEnum.Act51 || m.MapTypeId == (short)MapTypeEnum.Act52)))
                        {
                            return;
                        }
                        if (Option == 0)
                        {
                            if (ServerManager.Instance.ChannelId == 51)
                            {
                                session.SendPacket(UserInterfaceHelper.GenerateDialog($"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^2 #u_i^{type}^{secondaryType}^{inventoryType}^{slot}^0 {Language.Instance.GetMessageFromKey("WANT_TO_GO_BASE")}"));
                            }
                            else
                            {
                                session.SendPacket(UserInterfaceHelper.GenerateDialog($"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^1 #u_i^{type}^{secondaryType}^{inventoryType}^{slot}^2 {Language.Instance.GetMessageFromKey("WANT_TO_SAVE_POSITION")}"));
                            }
                        }
                        else if (int.TryParse(packetsplit[6], out packetType))
                        {
                            switch (packetType)
                            {
                            case 1:
                                session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^3"));
                                break;

                            case 2:
                                session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^4"));
                                break;

                            case 3:
                                session.Character.SetReturnPoint(session.Character.MapId, session.Character.MapX, session.Character.MapY);
                                RespawnMapTypeDTO respawn = session.Character.Respawn;
                                if (respawn.DefaultX != 0 && respawn.DefaultY != 0 && respawn.DefaultMapId != 0)
                                {
                                    MapCell mapCell = new MapCell();
                                    for (int i = 0; i < 5; i++)
                                    {
                                        mapCell.X = (short)(respawn.DefaultX + ServerManager.RandomNumber(-3, 3));
                                        mapCell.Y = (short)(respawn.DefaultY + ServerManager.RandomNumber(-3, 3));
                                        if (ServerManager.GetMapInstanceByMapId(respawn.DefaultMapId) is MapInstance GoToMap)
                                        {
                                            if (!GoToMap.Map.IsBlockedZone(mapCell.X, mapCell.Y))
                                            {
                                                break;
                                            }
                                        }
                                    }
                                    ServerManager.Instance.ChangeMap(session.Character.CharacterId, respawn.DefaultMapId, mapCell.X, mapCell.Y);
                                }
                                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                                break;

                            case 4:
                                RespawnMapTypeDTO respawnObj = session.Character.Respawn;
                                if (ServerManager.Instance.ChannelId == 51)
                                {
                                    respawnObj.DefaultMapId = (short)(129 + session.Character.Faction);
                                    respawnObj.DefaultX     = 41;
                                    respawnObj.DefaultY     = 42;
                                }
                                if (respawnObj.DefaultX != 0 && respawnObj.DefaultY != 0 && respawnObj.DefaultMapId != 0)
                                {
                                    MapCell mapCell = new MapCell();
                                    for (int i = 0; i < 5; i++)
                                    {
                                        mapCell.X = (short)(respawnObj.DefaultX + ServerManager.RandomNumber(-3, 3));
                                        mapCell.Y = (short)(respawnObj.DefaultY + ServerManager.RandomNumber(-3, 3));
                                        if (ServerManager.GetMapInstanceByMapId(respawnObj.DefaultMapId) is MapInstance GoToMap)
                                        {
                                            if (!GoToMap.Map.IsBlockedZone(mapCell.X, mapCell.Y))
                                            {
                                                break;
                                            }
                                        }
                                    }
                                    ServerManager.Instance.ChangeMap(session.Character.CharacterId, respawnObj.DefaultMapId, mapCell.X, mapCell.Y);
                                }
                                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                                break;
                            }
                        }
                        break;

                    case 1:
                        if (inv.ItemVNum != 2071 && inv.ItemVNum != 10011)
                        {
                            return;
                        }
                        if (int.TryParse(packetsplit[6], out packetType))
                        {
                            if (ServerManager.Instance.ChannelId == 51)
                            {
                                session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("CANNOT_USE"), 10));
                                return;
                            }
                            RespawnMapTypeDTO respawn = session.Character.Return;
                            switch (packetType)
                            {
                            case 0:
                                if (respawn.DefaultX != 0 && respawn.DefaultY != 0 && respawn.DefaultMapId != 0)
                                {
                                    session.SendPacket(UserInterfaceHelper.GenerateRp(respawn.DefaultMapId, respawn.DefaultX, respawn.DefaultY, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^1"));
                                }
                                break;

                            case 1:
                                session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^2"));
                                break;

                            case 2:
                                if (respawn.DefaultX != 0 && respawn.DefaultY != 0 && respawn.DefaultMapId != 0)
                                {
                                    ServerManager.Instance.ChangeMap(session.Character.CharacterId, respawn.DefaultMapId, respawn.DefaultX, respawn.DefaultY);
                                }
                                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                                break;
                            }
                        }
                        break;

                    case 2:
                        if (inv.ItemVNum != 2072 && inv.ItemVNum != 10012)
                        {
                            return;
                        }
                        if (Option == 0)
                        {
                            session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^1"));
                        }
                        else
                        {
                            ServerManager.Instance.JoinMiniland(session, session);
                            session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                        }
                        break;

                    case 4:
                        if (inv.ItemVNum != 2188 || session.Character.MapInstance.Map.MapTypes.Any(s => s.MapTypeId == (short)MapTypeEnum.Act4))
                        {
                            return;
                        }
                        if (Option == 0)
                        {
                            session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^1"));
                        }
                        else
                        {
                            ServerManager.Instance.ChangeMap(session.Character.CharacterId, 98, 28, 34);
                            session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                        }
                        break;

                    case 5:
                        if (inv.ItemVNum != 2311 || ServerManager.Instance.ChannelId != 51)
                        {
                            return;
                        }
                        if (ServerManager.GetAllMapInstances().SelectMany(s => s.Monsters.ToList()).LastOrDefault(s => s.MonsterVNum == (short)session.Character.Faction + 964) is MapMonster flag)
                        {
                            if (Option == 0)
                            {
                                session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^1"));
                            }
                            else
                            {
                                ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId, flag.MapInstance.MapInstanceId, flag.MapX, flag.MapY);
                                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                            }
                        }
                        break;

                    case 6:
                        if (inv.ItemVNum != 2384 || ServerManager.Instance.ChannelId == 51 || session.CurrentMapInstance.MapInstanceType != MapInstanceType.BaseMapInstance)
                        {
                            return;
                        }
                        if (Option == 0)
                        {
                            session.SendPacket(UserInterfaceHelper.GenerateDialog($"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^1 #u_i^{type}^{secondaryType}^{inventoryType}^{slot}^2 {Language.Instance.GetMessageFromKey("WANT_TO_SAVE_POSITION")}"));
                        }
                        else if (int.TryParse(packetsplit[6], out packetType))
                        {
                            switch (packetType)
                            {
                            case 1:
                                session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^3"));
                                break;

                            case 2:
                                session.SendPacket(UserInterfaceHelper.GenerateDelay(5000, 7, $"#u_i^{type}^{secondaryType}^{inventoryType}^{slot}^4"));
                                break;

                            case 3:
                                if (session.CurrentMapInstance.Map.MapTypes.Any(s => s.MapTypeId == (short)MapTypeEnum.Act51 || s.MapTypeId == (short)MapTypeEnum.Act52))
                                {
                                    session.Character.SetReturnPoint(session.Character.MapId, session.Character.MapX, session.Character.MapY);
                                    RespawnMapTypeDTO respawn = session.Character.Respawn;
                                    if (respawn.DefaultX != 0 && respawn.DefaultY != 0 && respawn.DefaultMapId != 0)
                                    {
                                        MapCell mapCell = new MapCell();
                                        for (int i = 0; i < 5; i++)
                                        {
                                            mapCell.X = (short)(respawn.DefaultX + ServerManager.RandomNumber(-3, 3));
                                            mapCell.Y = (short)(respawn.DefaultY + ServerManager.RandomNumber(-3, 3));
                                            if (ServerManager.GetMapInstanceByMapId(respawn.DefaultMapId) is MapInstance GoToMap)
                                            {
                                                if (!GoToMap.Map.IsBlockedZone(mapCell.X, mapCell.Y))
                                                {
                                                    break;
                                                }
                                            }
                                        }
                                        ServerManager.Instance.ChangeMap(session.Character.CharacterId, respawn.DefaultMapId, mapCell.X, mapCell.Y);
                                    }
                                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                                }
                                else
                                {
                                    goto case 4;
                                }
                                break;

                            case 4:
                                MapInstance mapInstanceBackup = session.CurrentMapInstance;
                                session.CurrentMapInstance = ServerManager.GetMapInstanceByMapId(170);
                                RespawnMapTypeDTO respawnObj = session.Character.Respawn;
                                session.CurrentMapInstance = mapInstanceBackup;
                                if (ServerManager.Instance.ChannelId == 51)
                                {
                                    respawnObj.DefaultMapId = (short)(129 + session.Character.Faction);
                                    respawnObj.DefaultX     = 41;
                                    respawnObj.DefaultY     = 42;
                                }
                                if (respawnObj.DefaultX != 0 && respawnObj.DefaultY != 0 && respawnObj.DefaultMapId != 0)
                                {
                                    MapCell mapCell = new MapCell();
                                    for (int i = 0; i < 5; i++)
                                    {
                                        mapCell.X = (short)(respawnObj.DefaultX + ServerManager.RandomNumber(-3, 3));
                                        mapCell.Y = (short)(respawnObj.DefaultY + ServerManager.RandomNumber(-3, 3));
                                        if (ServerManager.GetMapInstanceByMapId(respawnObj.DefaultMapId) is MapInstance GoToMap)
                                        {
                                            if (!GoToMap.Map.IsBlockedZone(mapCell.X, mapCell.Y))
                                            {
                                                break;
                                            }
                                        }
                                    }
                                    ServerManager.Instance.ChangeMap(session.Character.CharacterId, respawnObj.DefaultMapId, mapCell.X, mapCell.Y);
                                }
                                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                                break;
                            }
                        }
                        break;
                    }
                }
                break;

            // dyes or waxes
            case 10:
            case 11:
                if (!session.Character.IsVehicled)
                {
                    if (Effect == 10)
                    {
                        if (EffectValue == 99)
                        {
                            byte nextValue = (byte)ServerManager.RandomNumber(0, 127);
                            session.Character.HairColor = Enum.IsDefined(typeof(HairColorType), nextValue) ? (HairColorType)nextValue : 0;
                        }
                        else
                        {
                            session.Character.HairColor = Enum.IsDefined(typeof(HairColorType), (byte)EffectValue) ? (HairColorType)EffectValue : 0;
                        }
                    }
                    else if (Effect == 11)
                    {
                        if (session.Character.Class == (byte)ClassType.Adventurer && EffectValue > 1)
                        {
                            session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ADVENTURERS_CANT_USE"), 10));
                            return;
                        }
                        if (session.Character.Gender != (GenderType)Sex && (VNum < 2130 || VNum > 2162) && (VNum < 10025 || VNum > 10026))
                        {
                            session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("CANNOT_USE"), 10));
                            return;
                        }
                        session.Character.HairStyle = Enum.IsDefined(typeof(HairStyleType), (byte)EffectValue) ? (HairStyleType)EffectValue : 0;
                    }
                    else
                    {
                        if (session.Character.Class == (byte)ClassType.Adventurer && EffectValue > 1)
                        {
                            session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ADVENTURERS_CANT_USE"), 10));
                            return;
                        }
                        session.Character.HairStyle = Enum.IsDefined(typeof(HairStyleType), (byte)EffectValue) ? (HairStyleType)EffectValue : 0;
                    }
                    session.SendPacket(session.Character.GenerateEq());
                    session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateIn());
                    session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateGidx());
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            // TS npcs health
            case 12:
                if (EffectValue > 0)
                {
                    if (session.Character.Timespace != null)
                    {
                        session.Character.MapInstance.GetBattleEntitiesInRange(new MapCell {
                            X = session.Character.PositionX, Y = session.Character.PositionY
                        }, 6)
                        .Where(s => (s.MapNpc != null || (s.Mate != null && s.Mate.IsTemporalMate)) && !session.Character.BattleEntity.CanAttackEntity(s)).ToList()
                        .ForEach(s =>
                        {
                            int health = EffectValue;
                            if (s.Hp + EffectValue > s.HpMax)
                            {
                                health = s.HpMax - s.Hp;
                            }
                            s.Hp += health;
                            session.Character.MapInstance.Broadcast(s.GenerateRc(health));
                            s.Mate?.Owner.Session.SendPacket(s.Mate.GenerateStatInfo());
                        });
                        session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                        session.SendPacket(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 48));
                    }
                }
                break;

            // dignity restoration
            case 14:
                if ((EffectValue == 100 || EffectValue == 200) && session.Character.Dignity < 100 && !session.Character.IsVehicled)
                {
                    session.Character.Dignity += EffectValue;
                    if (session.Character.Dignity > 100)
                    {
                        session.Character.Dignity = 100;
                    }
                    session.SendPacket(session.Character.GenerateFd());
                    session.SendPacket(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 49 - (byte)session.Character.Faction));
                    session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateIn(InEffect: 1), ReceiverType.AllExceptMe);
                    session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateGidx(), ReceiverType.AllExceptMe);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else if (EffectValue == 2000 && session.Character.Dignity < 100 && !session.Character.IsVehicled)
                {
                    session.Character.Dignity = 100;
                    session.SendPacket(session.Character.GenerateFd());
                    session.SendPacket(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 49 - (byte)session.Character.Faction));
                    session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateIn(InEffect: 1), ReceiverType.AllExceptMe);
                    session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateGidx(), ReceiverType.AllExceptMe);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            // speakers
            case 15:
                if (!session.Character.IsVehicled && Option == 0)
                {
                    session.SendPacket(UserInterfaceHelper.GenerateGuri(10, 3, session.Character.CharacterId, 1));
                }
                break;

            // bubbles
            case 16:
                if (!session.Character.IsVehicled && Option == 0)
                {
                    session.SendPacket(UserInterfaceHelper.GenerateGuri(10, 4, session.Character.CharacterId, 1));
                }
                break;

            // wigs
            case 30:
                if (!session.Character.IsVehicled)
                {
                    ItemInstance wig = session.Character.Inventory.LoadBySlotAndType((byte)EquipmentType.Hat, InventoryType.Wear);
                    if (wig != null)
                    {
                        wig.Design = (byte)ServerManager.RandomNumber(0, 15);
                        session.SendPacket(session.Character.GenerateEq());
                        session.SendPacket(session.Character.GenerateEquipment());
                        session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateIn());
                        session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateGidx());
                        session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    }
                    else
                    {
                        session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("NO_WIG"), 0));
                    }
                }
                break;

            case 31:
                if (!session.Character.IsVehicled && session.Character.HairStyle == HairStyleType.Hair7)
                {
                    session.Character.HairStyle = HairStyleType.Hair8;
                    session.SendPacket(session.Character.GenerateEq());
                    session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateIn());
                    session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateGidx());
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    // idk how it works yet but seems like all characters with this hairstyle have DarkPurple hair
                    //session.Character.HairColor = HairColorType.DarkPurple;
                }
                break;

            // Passive skills books
            case 99:
                if (session.Character.HeroLevel >= EffectValue)
                {
                    if (session.Character.AddSkill((short)(Sex + 1)))
                    {
                        session.SendPacket(session.Character.GenerateSki());
                        session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    }
                }
                else
                {
                    session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("LOW_HERO_LVL"), 10));
                }
                break;

            case 300:
                if (session.Character.Group != null && session.Character.Group.GroupType != GroupType.Group && session.Character.Group.IsLeader(session) && session.CurrentMapInstance.Portals.Any(s => s.Type == (short)PortalType.Raid))
                {
                    int delay = 0;
                    foreach (ClientSession sess in session.Character.Group.Sessions.GetAllItems())
                    {
                        Observable.Timer(TimeSpan.FromMilliseconds(delay)).Subscribe(o =>
                        {
                            if (sess?.Character != null && session?.CurrentMapInstance != null && session?.Character != null && sess.Character != session.Character)
                            {
                                ServerManager.Instance.TeleportOnRandomPlaceInMap(sess, session.CurrentMapInstance.MapInstanceId);
                            }
                        });
                        delay += 100;
                    }
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            default:
                Logger.Warn(string.Format(Language.Instance.GetMessageFromKey("NO_HANDLER_ITEM"), GetType(), VNum, Effect, EffectValue));
                break;
            }
        }
        public override void Use(ClientSession session, ref ItemInstance inv, bool delay = false, string[] packetsplit = null)
        {
            Random random = new Random();

            switch (Effect)
            {
            // airwaves - eventitems
            case 0:
                if (ItemType == ItemType.Event)
                {
                    session.CurrentMap?.Broadcast(session.Character.GenerateEff(EffectValue));
                    if (MappingHelper.GuriItemEffects.ContainsKey(EffectValue))
                    {
                        session.CurrentMap?.Broadcast(session.Character.GenerateGuri(19, 1, MappingHelper.GuriItemEffects[EffectValue]), session.Character.MapX, session.Character.MapY);
                    }
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                }
                break;

            //respawn objects
            case 1:
                int x1;
                int x2;
                int x3;
                int x4;
                if (packetsplit != null && int.TryParse(packetsplit[2], out x1) && int.TryParse(packetsplit[3], out x2) && int.TryParse(packetsplit[4], out x3) && int.TryParse(packetsplit[5], out x4))
                {
                    int x5;
                    switch (EffectValue)
                    {
                    case 0:
                        if (!delay)
                        {
                            session.SendPacket(session.Character.GenerateDialog($"#u_i^{x1}^{x2}^{x3}^{x4}^1 #u_i^{x1}^{x2}^{x3}^{x4}^2 {Language.Instance.GetMessageFromKey("WANT_TO_SAVE_POSITION")}"));
                        }
                        else
                        {
                            if (int.TryParse(packetsplit[6], out x5))
                            {
                                switch (x5)
                                {
                                case 1:
                                    session.SendPacket(session.Character.GenerateDelay(5000, 7, $"#u_i^{x1}^{x2}^{x3}^{x4}^3"));
                                    break;

                                case 2:
                                    session.SendPacket(session.Character.GenerateDelay(5000, 7, $"#u_i^{x1}^{x2}^{x3}^{x4}^4"));
                                    break;

                                case 3:
                                    session.Character.SetReturnPoint(session.Character.MapId, session.Character.MapX, session.Character.MapY);
                                    RespawnMapTypeDTO resp = session.Character.Respawn;
                                    if (resp.DefaultX != 0 && resp.DefaultY != 0 && resp.DefaultMapId != 0)
                                    {
                                        ServerManager.Instance.LeaveMap(session.Character.CharacterId);
                                        ServerManager.Instance.ChangeMap(session.Character.CharacterId, resp.DefaultMapId, (short)(resp.DefaultX + ServerManager.RandomNumber(-5, 5)), (short)(resp.DefaultY + ServerManager.RandomNumber(-5, 5)));
                                    }
                                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                                    break;

                                case 4:
                                    RespawnMapTypeDTO respa = session.Character.Respawn;
                                    if (respa.DefaultX != 0 && respa.DefaultY != 0 && respa.DefaultMapId != 0)
                                    {
                                        ServerManager.Instance.LeaveMap(session.Character.CharacterId);
                                        ServerManager.Instance.ChangeMap(session.Character.CharacterId, respa.DefaultMapId, (short)(respa.DefaultX + ServerManager.RandomNumber(-5, 5)), (short)(respa.DefaultY + ServerManager.RandomNumber(-5, 5)));
                                    }
                                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                                    break;
                                }
                            }
                        }
                        break;

                    case 1:
                        if (int.TryParse(packetsplit[6], out x5))
                        {
                            RespawnMapTypeDTO resp = session.Character.Return;
                            switch (x5)
                            {
                            case 0:
                                if (resp.DefaultX != 0 && resp.DefaultY != 0 && resp.DefaultMapId != 0)
                                {
                                    session.SendPacket(session.Character.GenerateRp(resp.DefaultMapId, resp.DefaultX, resp.DefaultY, $"#u_i^{x1}^{x2}^{x3}^{x4}^1"));
                                }
                                break;

                            case 1:
                                session.SendPacket(session.Character.GenerateDelay(5000, 7, $"#u_i^{x1}^{x2}^{x3}^{x4}^2"));
                                break;

                            case 2:
                                if (resp.DefaultX != 0 && resp.DefaultY != 0 && resp.DefaultMapId != 0)
                                {
                                    ServerManager.Instance.LeaveMap(session.Character.CharacterId);
                                    ServerManager.Instance.ChangeMap(session.Character.CharacterId, resp.DefaultMapId, resp.DefaultX, resp.DefaultY);
                                }
                                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                                break;
                            }
                        }
                        break;
                    }
                }
                break;

            // dyes or waxes
            case 10:
            case 11:
                if (!session.Character.IsVehicled)
                {
                    if (Effect == 10)
                    {
                        if (EffectValue == 99)
                        {
                            byte nextValue = (byte)ServerManager.RandomNumber(0, 127);
                            session.Character.HairColor = Enum.IsDefined(typeof(HairColorType), nextValue) ? (HairColorType)nextValue : 0;
                        }
                        else
                        {
                            session.Character.HairColor = Enum.IsDefined(typeof(HairColorType), (byte)EffectValue) ? (HairColorType)EffectValue : 0;
                        }
                    }
                    else
                    {
                        if (session.Character.Class == (byte)ClassType.Adventurer && EffectValue > 1)
                        {
                            session.SendPacket(session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("ADVENTURERS_CANT_USE"), 10));
                            return;
                        }
                        session.Character.HairStyle = Enum.IsDefined(typeof(HairStyleType), (byte)EffectValue) ? (HairStyleType)EffectValue : 0;
                    }
                    session.SendPacket(session.Character.GenerateEq());
                    session.CurrentMap?.Broadcast(session, session.Character.GenerateIn());
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                }
                break;

            // dignity restoration
            case 14:
                if ((EffectValue == 100 || EffectValue == 200) && session.Character.Dignity < 100 && !session.Character.IsVehicled)
                {
                    session.Character.Dignity += EffectValue;
                    if (session.Character.Dignity > 100)
                    {
                        session.Character.Dignity = 100;
                    }
                    session.SendPacket(session.Character.GenerateFd());
                    session.SendPacket(session.Character.GenerateEff(49 - session.Character.Faction));
                    session.CurrentMap?.Broadcast(session, session.Character.GenerateIn(), ReceiverType.AllExceptMe);
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                }
                else if (EffectValue == 2000 && session.Character.Dignity < 100 && !session.Character.IsVehicled)
                {
                    session.Character.Dignity = 100;
                    session.SendPacket(session.Character.GenerateFd());
                    session.SendPacket(session.Character.GenerateEff(49 - session.Character.Faction));
                    session.CurrentMap?.Broadcast(session, session.Character.GenerateIn(), ReceiverType.AllExceptMe);
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                }
                break;

            // speakers
            case 15:
                if (!session.Character.IsVehicled)
                {
                    if (!delay)
                    {
                        session.SendPacket(session.Character.GenerateGuri(10, 3, 1));
                    }
                }
                break;

            // bubbles
            case 16:
                if (!session.Character.IsVehicled)
                {
                    if (!delay)
                    {
                        session.SendPacket(session.Character.GenerateGuri(10, 4, 1));
                    }
                }
                break;

            // wigs
            case 30:
                if (!session.Character.IsVehicled)
                {
                    WearableInstance wig = session.Character.Inventory.LoadBySlotAndType <WearableInstance>((byte)EquipmentType.Hat, InventoryType.Wear);
                    if (wig != null)
                    {
                        wig.Design = (byte)ServerManager.RandomNumber(0, 15);
                        session.SendPacket(session.Character.GenerateEq());
                        session.SendPacket(session.Character.GenerateEquipment());
                        session.CurrentMap?.Broadcast(session, session.Character.GenerateIn());
                        session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    }
                    else
                    {
                        session.SendPacket(session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("NO_WIG"), 0));
                    }
                }
                break;

            default:
                Logger.Log.Warn(string.Format(Language.Instance.GetMessageFromKey("NO_HANDLER_ITEM"), GetType()));
                break;
            }
        }
        private void Move()
        {
            // Normal Move Mode
            if (Monster == null || !IsAlive)
            {
                return;
            }

            if (IsMoving && Monster.Speed > 0)
            {
                double time = (DateTime.Now - LastMove).TotalMilliseconds;

                if (Path.Any(s => s != null)) // move back to initial position after following target
                {
                    int timetowalk = 2000 / Monster.Speed;
                    if (time > timetowalk)
                    {
                        int mapX = Path.ElementAt(0).x;
                        int mapY = Path.ElementAt(0).y;
                        Path.RemoveAt(0);
                        Observable.Timer(TimeSpan.FromMilliseconds(timetowalk))
                        .Subscribe(
                            x =>
                        {
                            MapX = (short)mapX;
                            MapY = (short)mapY;
                        });

                        LastMove = DateTime.Now;
                        Map.Broadcast(new BroadcastPacket(null, GenerateMv3(), ReceiverType.AllInRange, xCoordinate: mapX, yCoordinate: mapY));
                        return;
                    }
                }
                else if (time > _movetime)
                {
                    short mapX = FirstX, mapY = FirstY;
                    if (Map?.GetFreePosition(ref mapX, ref mapY, (byte)ServerManager.RandomNumber(0, 2), (byte)_random.Next(0, 2)) ?? false)
                    {
                        int distance = Map.GetDistance(new MapCell {
                            X = mapX, Y = mapY
                        }, new MapCell {
                            X = MapX, Y = MapY
                        });
                        Observable.Timer(TimeSpan.FromMilliseconds(1000 * distance / (2 * Monster.Speed)))
                        .Subscribe(
                            x =>
                        {
                            MapX = mapX;
                            MapY = mapY;
                        });

                        LastMove = DateTime.Now.AddMilliseconds(1000 * distance / (2 * Monster.Speed));
                        Map.Broadcast(new BroadcastPacket(null, GenerateMv3(), ReceiverType.All));
                    }
                }
            }

            if (Monster.IsHostile)
            {
                Character character = ServerManager.Instance.Sessions.FirstOrDefault(s => s?.Character != null && s.Character.Hp > 0 && !s.Character.InvisibleGm && !s.Character.Invisible && s.Character.MapId == MapId && Map.GetDistance(new MapCell {
                    X = MapX, Y = MapY
                }, new MapCell {
                    X = s.Character.MapX, Y = s.Character.MapY
                }) < Monster.NoticeRange)?.Character;
                if (character != null)
                {
                    Target = character.CharacterId;
                    if (!Monster.NoAggresiveIcon)
                    {
                        character.Session.SendPacket(GenerateEff(5000));
                    }
                }
            }
        }
        /// <summary>
        /// Follow the Monsters target to it's position.
        /// </summary>
        /// <param name="targetSession">The TargetSession to follow</param>
        private void FollowTarget(ClientSession targetSession)
        {
            int distance = 0;

            if (targetSession != null)
            {
                distance = Map.GetDistance(new MapCell {
                    X = MapX, Y = MapY
                }, new MapCell {
                    X = targetSession.Character.MapX, Y = targetSession.Character.MapY
                });
            }
            if (IsMoving)
            {
                short maxDistance = 22;
                if (!Path.Any() && targetSession != null && distance > 1 && distance < maxDistance)
                {
                    short xoffset = (short)ServerManager.RandomNumber(-1, 1);
                    short yoffset = (short)ServerManager.RandomNumber(-1, 1);

                    Path = Map.StraightPath(new GridPos {
                        x = MapX, y = MapY
                    }, new GridPos {
                        x = (short)(targetSession.Character.MapX + xoffset), y = (short)(targetSession.Character.MapY + yoffset)
                    });
                    if (!Path.Any())
                    {
                        try
                        {
                            Path = Map.JPSPlus(JumpPointParameters, new GridPos {
                                x = MapX, y = MapY
                            }, new GridPos {
                                x = (short)(targetSession.Character.MapX + xoffset), y = (short)(targetSession.Character.MapY + yoffset)
                            });
                        }
                        catch (Exception ex)
                        {
                            Logger.Log.Error($"Pathfinding using JPSPlus failed. Map: {MapId} StartX: {MapX} StartY: {MapY} TargetX: {(short)(targetSession.Character.MapX + xoffset)} TargetY: {(short)(targetSession.Character.MapY + yoffset)}", ex);
                            RemoveTarget();
                        }
                    }
                }
                if (Monster != null && DateTime.Now > LastMove && Monster.Speed > 0 && Path.Any())
                {
                    int    maxindex    = Path.Count > Monster.Speed / 2 ? Monster.Speed / 2 : Path.Count;
                    short  mapX        = (short)Path.ElementAt(maxindex - 1).x;
                    short  mapY        = (short)Path.ElementAt(maxindex - 1).y;
                    double waitingtime = Map.GetDistance(new MapCell {
                        X = mapX, Y = mapY, MapId = MapId
                    }, new MapCell {
                        X = MapX, Y = MapY, MapId = MapId
                    }) / (double)Monster.Speed;
                    Map.Broadcast(new BroadcastPacket(null, $"mv 3 {MapMonsterId} {mapX} {mapY} {Monster.Speed}", ReceiverType.AllInRange, xCoordinate: mapX, yCoordinate: mapY));
                    LastMove = DateTime.Now.AddSeconds(waitingtime > 1 ? 1 : waitingtime);

                    Observable.Timer(TimeSpan.FromMilliseconds((int)((waitingtime > 1 ? 1 : waitingtime) * 1000)))
                    .Subscribe(
                        x =>
                    {
                        MapX = mapX;
                        MapY = mapY;
                    });

                    for (int j = maxindex; j > 0; j--)
                    {
                        Path.RemoveAt(0);
                    }
                }

                if (!Path.Any() && (DateTime.Now - LastEffect).Seconds > 20 && (targetSession == null || MapId != targetSession.Character.MapId || distance > maxDistance))
                {
                    RemoveTarget();
                }
            }
        }
        /// <summary>
        /// Handle any kind of Monster interaction
        /// </summary>
        internal void MonsterLife()
        {
            if (Monster == null)
            {
                return;
            }

            // handle hit queue
            HitRequest hitRequest;

            while (HitQueue.TryDequeue(out hitRequest))
            {
                if (IsAlive)
                {
                    int hitmode = 0;

                    // calculate damage
                    int damage = hitRequest.Session.Character.GenerateDamage(this, hitRequest.Skill, ref hitmode);

                    switch (hitRequest.TargetHitType)
                    {
                    case TargetHitType.SingleTargetHit:
                    {
                        // Target Hit
                        Map?.Broadcast($"su 1 {hitRequest.Session.Character.CharacterId} 3 {MapMonsterId} {hitRequest.Skill.SkillVNum} {hitRequest.Skill.Cooldown} {hitRequest.Skill.AttackAnimation} {hitRequest.SkillEffect} {hitRequest.Session.Character.MapX} {hitRequest.Session.Character.MapY} {(IsAlive ? 1 : 0)} {(int)((float)CurrentHp / (float)Monster.MaxHP * 100)} {damage} {hitmode} {hitRequest.Skill.SkillType - 1}");
                        break;
                    }

                    case TargetHitType.SingleTargetHitCombo:
                    {
                        // Taget Hit Combo
                        Map?.Broadcast($"su 1 {hitRequest.Session.Character.CharacterId} 3 {MapMonsterId} {hitRequest.Skill.SkillVNum} {hitRequest.Skill.Cooldown} {hitRequest.SkillCombo.Animation} {hitRequest.SkillCombo.Effect} {hitRequest.Session.Character.MapX} {hitRequest.Session.Character.MapY} {(IsAlive ? 1 : 0)} {(int)((float)CurrentHp / (float)Monster.MaxHP * 100)} {damage} {hitmode} {hitRequest.Skill.SkillType - 1}");
                        break;
                    }

                    case TargetHitType.SingleAOETargetHit:
                    {
                        // Target Hit Single AOE
                        switch (hitmode)
                        {
                        case 1:
                            hitmode = 4;
                            break;

                        case 3:
                            hitmode = 6;
                            break;

                        default:
                            hitmode = 5;
                            break;
                        }
                        if (hitRequest.ShowTargetHitAnimation)
                        {
                            Map?.Broadcast($"su 1 {hitRequest.Session.Character.CharacterId} 3 {MapMonsterId} {hitRequest.Skill.SkillVNum} {hitRequest.Skill.Cooldown} {hitRequest.Skill.AttackAnimation} {hitRequest.SkillEffect} 0 0 {(IsAlive ? 1 : 0)} {((int)((double)hitRequest.Session.Character.Hp / hitRequest.Session.Character.HPLoad()) * 100)} 0 0 {hitRequest.Skill.SkillType - 1}");
                        }
                        Map?.Broadcast($"su 1 {hitRequest.Session.Character.CharacterId} 3 {MapMonsterId} {hitRequest.Skill.SkillVNum} {hitRequest.Skill.Cooldown} {hitRequest.Skill.AttackAnimation} {hitRequest.SkillEffect} {hitRequest.Session.Character.MapX} {hitRequest.Session.Character.MapY} {(IsAlive ? 1 : 0)} {(int)((float)CurrentHp / (float)Monster.MaxHP * 100)} {damage} {hitmode} {hitRequest.Skill.SkillType - 1}");
                        break;
                    }

                    case TargetHitType.AOETargetHit:
                    {
                        // Target Hit AOE
                        switch (hitmode)
                        {
                        case 1:
                            hitmode = 4;
                            break;

                        case 3:
                            hitmode = 6;
                            break;

                        default:
                            hitmode = 5;
                            break;
                        }
                        Map?.Broadcast($"su 1 {hitRequest.Session.Character.CharacterId} 3 {MapMonsterId} {hitRequest.Skill.SkillVNum} {hitRequest.Skill.Cooldown} {hitRequest.Skill.AttackAnimation} {hitRequest.SkillEffect} {hitRequest.Session.Character.MapX} {hitRequest.Session.Character.MapY} {(IsAlive ? 1 : 0)} {(int)((float)CurrentHp / (float)Monster.MaxHP * 100)} {damage} {hitmode} {hitRequest.Skill.SkillType - 1}");
                        break;
                    }

                    case TargetHitType.ZoneHit:
                    {
                        // Zone HIT
                        Map?.Broadcast($"su 1 {hitRequest.Session.Character.CharacterId} 3 {MapMonsterId} {hitRequest.Skill.SkillVNum} {hitRequest.Skill.Cooldown} {hitRequest.Skill.AttackAnimation} {hitRequest.SkillEffect} {hitRequest.MapX} {hitRequest.MapY} {(IsAlive ? 1 : 0)} {(int)((float)CurrentHp / (float)Monster.MaxHP * 100)} {damage} 5 {hitRequest.Skill.SkillType - 1}");
                        break;
                    }

                    case TargetHitType.SpecialZoneHit:
                    {
                        // Special Zone hit
                        Map?.Broadcast($"su 1 {hitRequest.Session.Character.CharacterId} 3 {MapMonsterId} {hitRequest.Skill.SkillVNum} {hitRequest.Skill.Cooldown} {hitRequest.Skill.AttackAnimation} {hitRequest.SkillEffect} {hitRequest.Session.Character.MapX} {hitRequest.Session.Character.MapY} {(IsAlive ? 1 : 0)} {(int)((float)CurrentHp / (float)Monster.MaxHP * 100)} {damage} 0 {hitRequest.Skill.SkillType - 1}");
                        break;
                    }
                    }

                    // generate the kill bonus
                    hitRequest.Session.Character.GenerateKillBonus(this);
                }
                else
                {
                    // monster already has been killed, send cancel
                    hitRequest.Session.SendPacket($"cancel 2 {MapMonsterId}");
                }
            }

            // Respawn
            if (!IsAlive && ShouldRespawn != null && ShouldRespawn.Value)
            {
                double timeDeath = (DateTime.Now - Death).TotalSeconds;
                if (timeDeath >= Monster.RespawnTime / 10)
                {
                    Respawn();
                }
            }

            // normal movement
            else if (Target == -1)
            {
                Move();
            }

            // target following
            else
            {
                if (Map != null)
                {
                    ClientSession targetSession = Map.GetSessionByCharacterId(Target);

                    // remove target in some situations
                    if (targetSession == null || targetSession.Character.Invisible || targetSession.Character.Hp <= 0 || CurrentHp <= 0)
                    {
                        RemoveTarget();
                        return;
                    }

                    NpcMonsterSkill npcMonsterSkill = null;
                    if (ServerManager.RandomNumber(0, 10) > 8 && Skills != null)
                    {
                        npcMonsterSkill = Skills.Where(s => (DateTime.Now - s.LastSkillUse).TotalMilliseconds >= 100 * s.Skill.Cooldown).OrderBy(rnd => _random.Next()).FirstOrDefault();
                    }

                    // check if target is in range
                    if (!targetSession.Character.InvisibleGm && !targetSession.Character.Invisible && targetSession.Character.Hp > 0 &&
                        ((npcMonsterSkill != null && CurrentMp >= npcMonsterSkill.Skill.MpCost &&
                          Map.GetDistance(new MapCell {
                        X = MapX, Y = MapY
                    },
                                          new MapCell {
                        X = targetSession.Character.MapX, Y = targetSession.Character.MapY
                    }) < npcMonsterSkill.Skill.Range) ||
                         (Map.GetDistance(new MapCell {
                        X = MapX, Y = MapY
                    },
                                          new MapCell {
                        X = targetSession.Character.MapX, Y = targetSession.Character.MapY
                    }) <= Monster.BasicRange)))
                    {
                        TargetHit(targetSession, npcMonsterSkill);
                    }
                    else
                    {
                        FollowTarget(targetSession);
                    }
                }
            }
        }
        /// <summary>
        /// Generate the Monster -&gt; Character Damage
        /// </summary>
        /// <param name="targetCharacter"></param>
        /// <param name="skill"></param>
        /// <param name="hitmode"></param>
        /// <returns></returns>
        internal int GenerateDamage(Character targetCharacter, Skill skill, ref int hitmode)
        {
            //Warning: This code contains a huge amount of copypasta!

            #region Definitions

            if (targetCharacter == null)
            {
                return(0);
            }

            Random random = new Random();

            int  playerDefense;
            byte playerDefenseUpgrade = 0;
            int  playerDodge          = 0;

            WearableInstance playerArmor = targetCharacter.Inventory.LoadBySlotAndType <WearableInstance>((byte)EquipmentType.Armor, InventoryType.Wear);
            if (playerArmor != null)
            {
                playerDefenseUpgrade = playerArmor.Upgrade;
            }

            short mainUpgrade    = Monster.AttackUpgrade;
            int   mainCritChance = Monster.CriticalChance;
            int   mainCritHit    = Monster.CriticalRate - 30;
            int   mainMinDmg     = Monster.DamageMinimum;
            int   mainMaxDmg     = Monster.DamageMaximum;
            int   mainHitRate    = Monster.Concentrate; //probably missnamed, check later
            if (mainMaxDmg == 0)
            {
                mainMinDmg     = Monster.Level * 8;
                mainMaxDmg     = Monster.Level * 12;
                mainCritChance = 10;
                mainCritHit    = 120;
                mainHitRate    = Monster.Level / 2 + 1;
            }

            #endregion

            #region Get Player defense

            switch (Monster.AttackClass)
            {
            case 0:
                playerDefense = targetCharacter.Defence;
                playerDodge   = targetCharacter.DefenceRate;
                break;

            case 1:
                playerDefense = targetCharacter.DistanceDefence;
                playerDodge   = targetCharacter.DistanceDefenceRate;
                break;

            case 2:
                playerDefense = targetCharacter.MagicalDefence;
                break;

            default:
                throw new Exception($"Monster.AttackClass {Monster.AttackClass} not implemented");
            }

            #endregion

            #region Basic Damage Data Calculation

            // TODO: Implement BCard damage boosts, see Issue

            mainUpgrade -= playerDefenseUpgrade;
            if (mainUpgrade < -10)
            {
                mainUpgrade = -10;
            }
            else if (mainUpgrade > 10)
            {
                mainUpgrade = 10;
            }

            #endregion

            #region Detailed Calculation

            #region Dodge

            double multiplier = playerDodge / mainHitRate;
            if (multiplier > 5)
            {
                multiplier = 5;
            }
            double chance = -0.25 * Math.Pow(multiplier, 3) - 0.57 * Math.Pow(multiplier, 2) + 25.3 * multiplier - 1.41;
            if (chance <= 1)
            {
                chance = 1;
            }
            if (Monster.AttackClass == 0 || Monster.AttackClass == 1)
            {
                if (ServerManager.RandomNumber(0, 100) <= chance)
                {
                    hitmode = 1;
                    return(0);
                }
            }

            #endregion

            #region Base Damage

            int baseDamage = ServerManager.RandomNumber(mainMinDmg, mainMaxDmg + 1);
            baseDamage += Monster.Level - targetCharacter.Level;
            int elementalDamage = 0; // placeholder for BCard etc...

            if (skill != null)
            {
                baseDamage      += skill.Damage / 4;
                elementalDamage += skill.ElementalDamage / 4;
            }

            switch (mainUpgrade)
            {
            case -10:
                playerDefense += playerDefense * 2;
                break;

            case -9:
                playerDefense += (int)(playerDefense * 1.2);
                break;

            case -8:
                playerDefense += (int)(playerDefense * 0.9);
                break;

            case -7:
                playerDefense += (int)(playerDefense * 0.65);
                break;

            case -6:
                playerDefense += (int)(playerDefense * 0.54);
                break;

            case -5:
                playerDefense += (int)(playerDefense * 0.43);
                break;

            case -4:
                playerDefense += (int)(playerDefense * 0.32);
                break;

            case -3:
                playerDefense += (int)(playerDefense * 0.22);
                break;

            case -2:
                playerDefense += (int)(playerDefense * 0.15);
                break;

            case -1:
                playerDefense += (int)(playerDefense * 0.1);
                break;

            case 0:
                break;

            case 1:
                baseDamage += (int)(baseDamage * 0.1);
                break;

            case 2:
                baseDamage += (int)(baseDamage * 0.15);
                break;

            case 3:
                baseDamage += (int)(baseDamage * 0.22);
                break;

            case 4:
                baseDamage += (int)(baseDamage * 0.32);
                break;

            case 5:
                baseDamage += (int)(baseDamage * 0.43);
                break;

            case 6:
                baseDamage += (int)(baseDamage * 0.54);
                break;

            case 7:
                baseDamage += (int)(baseDamage * 0.65);
                break;

            case 8:
                baseDamage += (int)(baseDamage * 0.9);
                break;

            case 9:
                baseDamage += (int)(baseDamage * 1.2);
                break;

            case 10:
                baseDamage += baseDamage * 2;
                break;
            }

            #endregion

            #region Elementary Damage

            #region Calculate Elemental Boost + Rate

            double elementalBoost    = 0;
            int    playerRessistance = 0;
            switch (Monster.Element)
            {
            case 0:
                break;

            case 1:
                playerRessistance = targetCharacter.FireResistance;
                switch (targetCharacter.Element)
                {
                case 0:
                    elementalBoost = 1.3;         // Damage vs no element
                    break;

                case 1:
                    elementalBoost = 1;         // Damage vs fire
                    break;

                case 2:
                    elementalBoost = 2;         // Damage vs water
                    break;

                case 3:
                    elementalBoost = 1;         // Damage vs light
                    break;

                case 4:
                    elementalBoost = 1.5;         // Damage vs darkness
                    break;
                }
                break;

            case 2:
                playerRessistance = targetCharacter.WaterResistance;
                switch (targetCharacter.Element)
                {
                case 0:
                    elementalBoost = 1.3;
                    break;

                case 1:
                    elementalBoost = 2;
                    break;

                case 2:
                    elementalBoost = 1;
                    break;

                case 3:
                    elementalBoost = 1.5;
                    break;

                case 4:
                    elementalBoost = 1;
                    break;
                }
                break;

            case 3:
                playerRessistance = targetCharacter.LightResistance;
                switch (targetCharacter.Element)
                {
                case 0:
                    elementalBoost = 1.3;
                    break;

                case 1:
                    elementalBoost = 1.5;
                    break;

                case 2:
                    elementalBoost = 1;
                    break;

                case 3:
                    elementalBoost = 1;
                    break;

                case 4:
                    elementalBoost = 3;
                    break;
                }
                break;

            case 4:
                playerRessistance = targetCharacter.DarkResistance;
                switch (targetCharacter.Element)
                {
                case 0:
                    elementalBoost = 1.3;
                    break;

                case 1:
                    elementalBoost = 1;
                    break;

                case 2:
                    elementalBoost = 1.5;
                    break;

                case 3:
                    elementalBoost = 3;
                    break;

                case 4:
                    elementalBoost = 1;
                    break;
                }
                break;
            }

            #endregion ;

            if (Monster.Element == 0)
            {
                if (elementalBoost == 0.5)
                {
                    elementalBoost = 0;
                }
                else if (elementalBoost == 1)
                {
                    elementalBoost = 0.05;
                }
                else if (elementalBoost == 1.3)
                {
                    elementalBoost = 0;
                }
                else if (elementalBoost == 1.5)
                {
                    elementalBoost = 0.15;
                }
                else if (elementalBoost == 2)
                {
                    elementalBoost = 0.2;
                }
                else if (elementalBoost == 3)
                {
                    elementalBoost = 0.2;
                }
            }

            elementalDamage = (int)((elementalDamage + (elementalDamage + baseDamage) * (Monster.ElementRate / 100D)) * elementalBoost);
            elementalDamage = elementalDamage / 100 * (100 - playerRessistance);
            if (elementalDamage < 0)
            {
                elementalDamage = 0;
            }
            #endregion

            #region Critical Damage

            if (ServerManager.RandomNumber() <= mainCritChance)
            {
                if (Monster.AttackClass == 2)
                {
                }
                else
                {
                    baseDamage += (int)(baseDamage * (mainCritHit / 100D));
                    hitmode     = 3;
                }
            }

            #endregion

            #region Total Damage

            int totalDamage = baseDamage + elementalDamage - playerDefense;
            if (totalDamage < 5)
            {
                totalDamage = ServerManager.RandomNumber(1, 6);
            }

            #endregion

            #endregion

            #region Minimum damage

            if (Monster.Level < 45)
            {
                //no minimum damage
            }
            else if (Monster.Level < 55)
            {
                totalDamage += Monster.Level;
            }
            else if (Monster.Level < 60)
            {
                totalDamage += Monster.Level * 2;
            }
            else if (Monster.Level < 65)
            {
                totalDamage += Monster.Level * 3;
            }
            else if (Monster.Level < 70)
            {
                totalDamage += Monster.Level * 4;
            }
            else
            {
                totalDamage += Monster.Level * 5;
            }

            #endregion

            return(totalDamage);
        }
Beispiel #23
0
        public override void Use(ClientSession session, ref ItemInstance inv, byte Option = 0, string[] packetsplit = null)
        {
            if (!session.HasCurrentMapInstance)
            {
                return;
            }

            if (session.Character.IsLaurenaMorph())
            {
                return;
            }

            if ((DateTime.Now - session.Character.LastPotion).TotalMilliseconds < (session.CurrentMapInstance.Map.MapTypes.OrderByDescending(s => s.PotionDelay).FirstOrDefault()?.PotionDelay ?? 750))
            {
                return;
            }

            if ((session.CurrentMapInstance.MapInstanceType.Equals(MapInstanceType.TalentArenaMapInstance) && VNum != 5935) ||
                session.CurrentMapInstance.MapInstanceType.Equals(MapInstanceType.IceBreakerInstance))
            {
                return;
            }

            if (session.CurrentMapInstance.MapInstanceType != MapInstanceType.TalentArenaMapInstance && VNum == 5935)
            {
                return;
            }

            if (ServerManager.Instance.ChannelId == 51 &&
                session.Character.MapId != 130 &&
                session.Character.MapId != 131 &&
                (session.Character.Group?.Raid == null || !session.Character.Group.Raid.InstanceBag.Lock) &&
                session.Character.MapInstance.MapInstanceType != MapInstanceType.Act4Berios &&
                session.Character.MapInstance.MapInstanceType != MapInstanceType.Act4Calvina &&
                session.Character.MapInstance.MapInstanceType != MapInstanceType.Act4Hatus &&
                session.Character.MapInstance.MapInstanceType != MapInstanceType.Act4Morcos &&
                (inv.ItemVNum == 1242 || inv.ItemVNum == 1243 || inv.ItemVNum == 1244 || inv.ItemVNum == 5582 || inv.ItemVNum == 5583 || inv.ItemVNum == 5584))
            {
                return;
            }

            session.Character.LastPotion = DateTime.Now;

            switch (Effect)
            {
            default:
            {
                bool hasPotionBeenUsed = false;

                int hpLoad = (int)session.Character.HPLoad();
                int mpLoad = (int)session.Character.MPLoad();

                if (session.Character.Hp > 0 &&
                    (session.Character.Hp < hpLoad || session.Character.Mp < mpLoad))
                {
                    hasPotionBeenUsed = true;

                    double buffRc = session.Character.GetBuff(BCardType.CardType.LeonaPassiveSkill, (byte)AdditionalTypes.LeonaPassiveSkill.IncreaseRecoveryItems)[0] / 100D;

                    int hpAmount = Hp + (int)(Hp * buffRc);
                    int mpAmount = Mp + (int)(Mp * buffRc);

                    if (session.Character.Hp + hpAmount > hpLoad)
                    {
                        hpAmount = hpLoad - session.Character.Hp;
                    }

                    if (session.Character.Mp + mpAmount > mpLoad)
                    {
                        mpAmount = mpLoad - session.Character.Mp;
                    }

                    bool convertRecoveryToDamage = ServerManager.RandomNumber() < session.Character.GetBuff(BCardType.CardType.DarkCloneSummon, (byte)AdditionalTypes.DarkCloneSummon.ConvertRecoveryToDamage)[0];

                    if (convertRecoveryToDamage)
                    {
                        session.CurrentMapInstance.Broadcast(session.Character.GenerateDm(hpAmount));

                        session.Character.Hp -= hpAmount;

                        if (session.Character.Hp < 1)
                        {
                            session.Character.Hp = 1;
                        }
                    }
                    else
                    {
                        session.CurrentMapInstance.Broadcast(session.Character.GenerateRc(hpAmount));

                        session.Character.Hp += hpAmount;
                    }

                    session.Character.Mp += mpAmount;

                    switch (inv.ItemVNum)
                    {
                    // Full HP Potion
                    case 1242:
                    case 5582:
                    {
                        if (convertRecoveryToDamage)
                        {
                            session.CurrentMapInstance.Broadcast(session.Character.GenerateDm(session.Character.Hp - 1));
                            session.Character.Hp = 1;
                        }
                        else
                        {
                            session.CurrentMapInstance.Broadcast(session.Character.GenerateRc(hpLoad - session.Character.Hp));
                            session.Character.Hp = hpLoad;
                        }
                    }
                    break;

                    // Full MP Potion
                    case 1243:
                    case 5583:
                    {
                        session.Character.Mp = mpLoad;
                    }
                    break;

                    // Full HP & MP Potion
                    case 1244:
                    case 5584:
                    case 9129:
                    {
                        if (convertRecoveryToDamage)
                        {
                            session.CurrentMapInstance.Broadcast(session.Character.GenerateDm(session.Character.Hp - 1));
                            session.Character.Hp = 1;
                        }
                        else
                        {
                            session.CurrentMapInstance.Broadcast(session.Character.GenerateRc(hpLoad - session.Character.Hp));
                            session.Character.Hp = hpLoad;
                        }

                        session.Character.Mp = mpLoad;
                    }
                    break;
                    }

                    session.SendPacket(session.Character.GenerateStat());
                }

                foreach (Mate mate in session.Character.Mates.Where(s => s.IsTeamMember && s.IsAlive))
                {
                    hpLoad = (int)mate.MaxHp;
                    mpLoad = (int)mate.MaxMp;

                    if (mate.Hp <= 0 || (mate.Hp == hpLoad && mate.Mp == mpLoad))
                    {
                        continue;
                    }

                    hasPotionBeenUsed = true;

                    int hpAmount = Hp;
                    int mpAmount = Mp;

                    if (mate.Hp + hpAmount > hpLoad)
                    {
                        hpAmount = hpLoad - (int)mate.Hp;
                    }

                    if (mate.Mp + mpAmount > mpLoad)
                    {
                        mpAmount = mpLoad - (int)mate.Mp;
                    }

                    mate.Hp += hpAmount;
                    mate.Mp += mpAmount;

                    session.CurrentMapInstance.Broadcast(mate.GenerateRc(hpAmount));

                    switch (inv.ItemVNum)
                    {
                    // Full HP Potion
                    case 1242:
                    case 5582:
                        session.CurrentMapInstance.Broadcast(mate.GenerateRc(hpLoad - (int)mate.Hp));
                        mate.Hp = hpLoad;
                        break;

                    // Full MP Potion
                    case 1243:
                    case 5583:
                        mate.Mp = mpLoad;
                        break;

                    // Full HP & MP Potion
                    case 1244:
                    case 5584:
                    case 9129:
                        session.CurrentMapInstance.Broadcast(mate.GenerateRc(hpLoad - (int)mate.Hp));
                        mate.Hp = hpLoad;
                        mate.Mp = mpLoad;
                        break;
                    }

                    session.SendPacket(mate.GenerateStatInfo());
                }

                if (session.Character.Mates.Any(m => m.IsTeamMember && m.IsAlive))
                {
                    session.SendPackets(session.Character.GeneratePst());
                }

                if (hasPotionBeenUsed)
                {
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
            }
            break;
            }
        }
Beispiel #24
0
        private static void Sync(ClientSession session)
        {
            for (session.Character.MaxFood = 0; session.Character.MaxFood < 5; session.Character.MaxFood++)
            {
                if (session.Character.Hp <= 0 || !session.Character.IsSitting)
                {
                    _regenerateDisposable?.Dispose();
                    session.Character.FoodAmount = 0;
                    session.Character.FoodHp     = 0;
                    session.Character.FoodMp     = 0;
                    return;
                }

                int hpLoad = (int)session.Character.HPLoad();
                int mpLoad = (int)session.Character.MPLoad();

                double buffRc = session.Character.GetBuff(BCardType.CardType.LeonaPassiveSkill, (byte)AdditionalTypes.LeonaPassiveSkill.IncreaseRecoveryItems)[0] / 100D;

                int hpAmount = session.Character.FoodHp + (int)(session.Character.FoodHp * buffRc);
                int mpAmount = session.Character.FoodMp + (int)(session.Character.FoodMp * buffRc);

                if (session.Character.Hp + hpAmount > hpLoad)
                {
                    hpAmount = hpLoad - session.Character.Hp;
                }

                if (session.Character.Mp + mpAmount > mpLoad)
                {
                    mpAmount = mpLoad - session.Character.Mp;
                }

                bool convertRecoveryToDamage = ServerManager.RandomNumber() < session.Character.GetBuff(BCardType.CardType.DarkCloneSummon, (byte)AdditionalTypes.DarkCloneSummon.ConvertRecoveryToDamage)[0];

                if (convertRecoveryToDamage)
                {
                    session.Character.Hp -= hpAmount;

                    if (session.Character.Hp < 1)
                    {
                        session.Character.Hp = 1;
                    }

                    if (hpAmount > 0)
                    {
                        session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateDm(hpAmount));
                    }
                }
                else
                {
                    session.Character.Hp += hpAmount;

                    if (hpAmount > 0)
                    {
                        session.CurrentMapInstance?.Broadcast(session, session.Character.GenerateRc(hpAmount));
                    }
                }

                session.Character.Mp += mpAmount;

                foreach (Mate mate in session.Character.Mates.Where(s => s.IsTeamMember && s.IsAlive && s.IsSitting))
                {
                    hpLoad = mate.HpLoad();
                    mpLoad = mate.MpLoad();

                    hpAmount = session.Character.FoodHp;
                    mpAmount = session.Character.FoodMp;

                    if (mate.Hp + hpAmount > hpLoad)
                    {
                        hpAmount = hpLoad - (int)mate.Hp;
                    }

                    if (mate.Mp + mpAmount > mpLoad)
                    {
                        mpAmount = mpLoad - (int)mate.Mp;
                    }

                    mate.Hp += hpAmount;
                    mate.Mp += mpAmount;

                    if (hpAmount > 0)
                    {
                        session.CurrentMapInstance?.Broadcast(session, mate.GenerateRc(hpAmount));
                    }
                }

                if (session.IsConnected)
                {
                    session.SendPacket(session.Character.GenerateStat());

                    if (session.Character.Mates.Any(m => m.IsTeamMember && m.IsAlive && m.IsSitting))
                    {
                        session.SendPackets(session.Character.GeneratePst());
                    }

                    Thread.Sleep(1800);
                }
            }
        }
Beispiel #25
0
        public void PerfectSP(ClientSession Session, UpgradeProtection protect)
        {
            short[] upsuccess = { 50, 40, 30, 20, 10 };

            int[]   goldprice  = { 5000, 10000, 20000, 50000, 100000 };
            short[] stoneprice = { 1, 2, 3, 4, 5 };
            short   stonevnum;
            byte    upmode = 1;

            switch (Item.Morph)
            {
            case 2:
                stonevnum = 2514;
                break;

            case 6:
                stonevnum = 2514;
                break;

            case 9:
                stonevnum = 2514;
                break;

            case 12:
                stonevnum = 2514;
                break;

            case 3:
                stonevnum = 2515;
                break;

            case 4:
                stonevnum = 2515;
                break;

            case 14:
                stonevnum = 2515;
                break;

            case 5:
                stonevnum = 2516;
                break;

            case 11:
                stonevnum = 2516;
                break;

            case 15:
                stonevnum = 2516;
                break;

            case 10:
                stonevnum = 2517;
                break;

            case 13:
                stonevnum = 2517;
                break;

            case 7:
                stonevnum = 2517;
                break;

            case 17:
                stonevnum = 2518;
                break;

            case 18:
                stonevnum = 2518;
                break;

            case 19:
                stonevnum = 2518;
                break;

            case 20:
                stonevnum = 2519;
                break;

            case 21:
                stonevnum = 2519;
                break;

            case 22:
                stonevnum = 2519;
                break;

            case 23:
                stonevnum = 2520;
                break;

            case 24:
                stonevnum = 2520;
                break;

            case 25:
                stonevnum = 2520;
                break;

            case 26:
                stonevnum = 2521;
                break;

            case 27:
                stonevnum = 2521;
                break;

            case 28:
                stonevnum = 2521;
                break;

            default:
                return;
            }
            if (SpStoneUpgrade > 99)
            {
                return;
            }
            else if (SpStoneUpgrade > 80)
            {
                upmode = 5;
            }
            else if (SpStoneUpgrade > 60)
            {
                upmode = 4;
            }
            else if (SpStoneUpgrade > 40)
            {
                upmode = 3;
            }
            else if (SpStoneUpgrade > 20)
            {
                upmode = 2;
            }

            if (IsFixed)
            {
                return;
            }
            if (Session.Character.Gold < goldprice[upmode - 1])
            {
                return;
            }
            if (Session.Character.Inventory.CountItem(stonevnum) < stoneprice[upmode - 1])
            {
                return;
            }

            SpecialistInstance specialist = Session.Character.Inventory.LoadByItemInstance <SpecialistInstance>(Id);

            int rnd = ServerManager.RandomNumber();

            if (rnd <= upsuccess[upmode - 1])
            {
                byte type = (byte)ServerManager.RandomNumber(0, 16), count = 1;
                if (upmode == 4)
                {
                    count = 2;
                }
                if (upmode == 5)
                {
                    count = (byte)ServerManager.RandomNumber(3, 6);
                }

                Session.CurrentMap.Broadcast(Session.Character.GenerateEff(3005), Session.Character.MapX, Session.Character.MapY);

                if (type < 3)
                {
                    specialist.SpDamage += count;
                    Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_ATTACK"), count), 12));
                    Session.SendPacket(Session.Character.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_ATTACK"), count), 0));
                }
                else if (type < 6)
                {
                    specialist.SpDefence += count;
                    Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_DEFENSE"), count), 12));
                    Session.SendPacket(Session.Character.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_DEFENSE"), count), 0));
                }
                else if (type < 9)
                {
                    specialist.SpElement += count;
                    Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_ELEMENT"), count), 12));
                    Session.SendPacket(Session.Character.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_ELEMENT"), count), 0));
                }
                else if (type < 12)
                {
                    specialist.SpHP += count;
                    Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_HPMP"), count), 12));
                    Session.SendPacket(Session.Character.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_HPMP"), count), 0));
                }
                else if (type == 12)
                {
                    specialist.SpFire += count;
                    Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_FIRE"), count), 12));
                    Session.SendPacket(Session.Character.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_FIRE"), count), 0));
                }
                else if (type == 13)
                {
                    specialist.SpWater += count;
                    Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_WATER"), count), 12));
                    Session.SendPacket(Session.Character.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_WATER"), count), 0));
                }
                else if (type == 14)
                {
                    specialist.SpLight += count;
                    Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_LIGHT"), count), 12));
                    Session.SendPacket(Session.Character.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_LIGHT"), count), 0));
                }
                else if (type == 15)
                {
                    specialist.SpDark += count;
                    Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_SHADOW"), count), 12));
                    Session.SendPacket(Session.Character.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("PERFECTSP_SUCCESS"), Language.Instance.GetMessageFromKey("PERFECTSP_SHADOW"), count), 0));
                }
                specialist.SpStoneUpgrade++;
            }
            else
            {
                Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PERFECTSP_FAILURE"), 11));
                Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("PERFECTSP_FAILURE"), 0));
            }
            Session.SendPacket(Session.Character.GenerateInventoryAdd(ItemVNum, Amount, InventoryType.Equipment, Slot, Rare, Design, Upgrade, SpStoneUpgrade));
            Session.Character.Gold -= goldprice[upmode - 1];
            Session.SendPacket(Session.Character.GenerateGold());
            Session.Character.Inventory.RemoveItemAmount(stonevnum, stoneprice[upmode - 1]);
            Session.SendPacket("shop_end 1");
        }
Beispiel #26
0
        public void Initialize()
        {
            if (MapInstance.MapInstanceType == MapInstanceType.BaseMapInstance && ServerManager.Instance.MapBossVNums.Contains(NpcVNum))
            {
                MapCell randomCell = MapInstance.Map.GetRandomPosition();
                if (randomCell != null)
                {
                    if (MapInstance.Portals.Any(s => Map.GetDistance(new MapCell {
                        X = s.SourceX, Y = s.SourceY
                    }, new MapCell {
                        X = randomCell.X, Y = randomCell.Y
                    }) < 5))
                    {
                        randomCell = MapInstance.Map.GetRandomPosition();
                    }
                    MapX = randomCell.X;
                    MapY = randomCell.Y;
                }
            }

            _random = new Random(MapNpcId);
            Npc     = ServerManager.GetNpcMonster(NpcVNum);
            MaxHp   = Npc.MaxHP;
            MaxMp   = Npc.MaxMP;

            if (MapInstance?.MapInstanceType == MapInstanceType.TimeSpaceInstance)
            {
                if (IsProtected)
                {
                    MaxHp *= 8;
                    MaxMp *= 8;
                }
            }
            IsAlive             = true;
            CurrentHp           = MaxHp;
            CurrentMp           = MaxMp;
            LastEffect          = DateTime.Now;
            LastProtectedEffect = DateTime.Now;
            LastMove            = DateTime.Now;
            LastSkill           = DateTime.Now;
            IsHostile           = Npc.IsHostile;
            ShouldRespawn       = ShouldRespawn ?? true;
            FirstX          = MapX;
            FirstY          = MapY;
            EffectActivated = true;
            _movetime       = ServerManager.RandomNumber(500, 3000);
            Path            = new List <Node>();
            Recipes         = ServerManager.Instance.GetRecipesByMapNpcId(MapNpcId);
            Target          = -1;
            Teleporters     = ServerManager.Instance.GetTeleportersByNpcVNum(MapNpcId);
            Shop shop = ServerManager.Instance.GetShopByMapNpcId(MapNpcId);

            if (shop != null)
            {
                shop.Initialize();
                Shop = shop;
            }
            Skills = new List <NpcMonsterSkill>();
            foreach (NpcMonsterSkill ski in Npc.Skills)
            {
                Skills.Add(new NpcMonsterSkill {
                    SkillVNum = ski.SkillVNum, Rate = ski.Rate
                });
            }
            BattleEntity = new BattleEntity(this);

            if (AliveTime > 0)
            {
                Thread AliveTimeThread = new Thread(() => AliveTimeCheck());
                AliveTimeThread.Start();
            }

            if (NpcVNum == 1408)
            {
                OnDeathEvents.Add(new EventContainer(MapInstance, EventActionType.SPAWNMONSTER, new MonsterToSummon(621, new MapCell {
                    X = MapX, Y = MapY
                }, null, move: true)));
            }
            if (NpcVNum == 1409)
            {
                OnDeathEvents.Add(new EventContainer(MapInstance, EventActionType.SPAWNMONSTER, new MonsterToSummon(622, new MapCell {
                    X = MapX, Y = MapY
                }, null, move: true)));
            }
            if (NpcVNum == 1410)
            {
                OnDeathEvents.Add(new EventContainer(MapInstance, EventActionType.SPAWNMONSTER, new MonsterToSummon(623, new MapCell {
                    X = MapX, Y = MapY
                }, null, move: true)));
            }

            if (OnSpawnEvents.Any())
            {
                OnSpawnEvents.ToList().ForEach(e => { EventHelper.Instance.RunEvent(e, npc: this); });
                OnSpawnEvents.Clear();
            }
        }
Beispiel #27
0
        public void UpgradeSp(ClientSession Session, UpgradeProtection protect)
        {
            short[] upsuccess = { 100, 100, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50, 45, 40, 30 };
            short[] upfail    = { 20, 25, 25, 30, 35, 40, 40, 40, 40, 40, 45, 43, 40, 37, 29 };

            int[]   goldprice       = { 200000, 200000, 200000, 200000, 200000, 500000, 500000, 500000, 500000, 500000, 1000000, 1000000, 1000000, 1000000, 1000000 };
            short[] feather         = { 3, 5, 8, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70 };
            short[] fullmoon        = { 1, 3, 5, 7, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 };
            short[] soul            = { 2, 4, 6, 8, 10, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5 };
            short   featherVnum     = 2282;
            short   fullmoonVnum    = 1030;
            short   greenSoulVnum   = 2283;
            short   redSoulVnum     = 2284;
            short   blueSoulVnum    = 2285;
            short   dragonSkinVnum  = 2511;
            short   dragonBloodVnum = 2512;
            short   dragonHeartVnum = 2513;
            short   blueScrollVnum  = 1363;
            short   redScrollVnum   = 1364;

            if (!Session.HasCurrentMap)
            {
                return;
            }
            if (IsFixed)
            {
                Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ITEM_IS_FIXED"), 10));
                return;
            }
            if (Session.Character.Inventory.CountItem(fullmoonVnum) < fullmoon[Upgrade])
            {
                Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey(string.Format(Language.Instance.GetMessageFromKey("NOT_ENOUGH_ITEMS"), ServerManager.GetItem(fullmoonVnum).Name, fullmoon[Upgrade])), 10));
                return;
            }
            if (Session.Character.Inventory.CountItem(featherVnum) < feather[Upgrade])
            {
                Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey(string.Format(Language.Instance.GetMessageFromKey("NOT_ENOUGH_ITEMS"), ServerManager.GetItem(featherVnum).Name, feather[Upgrade])), 10));
                return;
            }
            if (Session.Character.Gold < goldprice[Upgrade])
            {
                Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10));
                return;
            }

            if (Upgrade < 5)
            {
                if (SpLevel > 20)
                {
                    if (Item.Morph <= 16)
                    {
                        if (Session.Character.Inventory.CountItem(greenSoulVnum) < soul[Upgrade])
                        {
                            Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey(string.Format(Language.Instance.GetMessageFromKey("NOT_ENOUGH_ITEMS"), ServerManager.GetItem(greenSoulVnum).Name, soul[Upgrade])), 10));
                            return;
                        }
                        if (protect == UpgradeProtection.Protected)
                        {
                            if (Session.Character.Inventory.CountItem(blueScrollVnum) < 1)
                            {
                                Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey(string.Format(Language.Instance.GetMessageFromKey("NOT_ENOUGH_ITEMS"), ServerManager.GetItem(blueScrollVnum).Name, 1)), 10));
                                return;
                            }
                            Session.Character.Inventory.RemoveItemAmount(blueScrollVnum);
                            Session.SendPacket("shop_end 2");
                        }
                        Session.Character.Inventory.RemoveItemAmount(greenSoulVnum, soul[Upgrade]);
                    }
                    else
                    {
                        if (Session.Character.Inventory.CountItem(dragonSkinVnum) < soul[Upgrade])
                        {
                            Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey(string.Format(Language.Instance.GetMessageFromKey("NOT_ENOUGH_ITEMS"), ServerManager.GetItem(dragonSkinVnum).Name, soul[Upgrade])), 10));
                            return;
                        }
                        if (protect == UpgradeProtection.Protected)
                        {
                            if (Session.Character.Inventory.CountItem(blueScrollVnum) < 1)
                            {
                                Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey(string.Format(Language.Instance.GetMessageFromKey("NOT_ENOUGH_ITEMS"), ServerManager.GetItem(blueScrollVnum).Name, 1)), 10));
                                return;
                            }
                            Session.Character.Inventory.RemoveItemAmount(blueScrollVnum);
                            Session.SendPacket("shop_end 2");
                        }
                        Session.Character.Inventory.RemoveItemAmount(dragonSkinVnum, soul[Upgrade]);
                    }
                }
                else
                {
                    Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("LVL_REQUIRED"), 21), 11));
                    return;
                }
            }
            else if (Upgrade < 10)
            {
                if (SpLevel > 40)
                {
                    if (Item.Morph <= 16)
                    {
                        if (Session.Character.Inventory.CountItem(redSoulVnum) < soul[Upgrade])
                        {
                            Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey(string.Format(Language.Instance.GetMessageFromKey("NOT_ENOUGH_ITEMS"), ServerManager.GetItem(redSoulVnum).Name, soul[Upgrade])), 10));
                            return;
                        }
                        if (protect == UpgradeProtection.Protected)
                        {
                            if (Session.Character.Inventory.CountItem(blueScrollVnum) < 1)
                            {
                                Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey(string.Format(Language.Instance.GetMessageFromKey("NOT_ENOUGH_ITEMS"), ServerManager.GetItem(blueScrollVnum).Name, 1)), 10));
                                return;
                            }
                            Session.Character.Inventory.RemoveItemAmount(blueScrollVnum);
                            Session.SendPacket("shop_end 2");
                        }
                        Session.Character.Inventory.RemoveItemAmount(redSoulVnum, soul[Upgrade]);
                    }
                    else
                    {
                        if (Session.Character.Inventory.CountItem(dragonBloodVnum) < soul[Upgrade])
                        {
                            Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey(string.Format(Language.Instance.GetMessageFromKey("NOT_ENOUGH_ITEMS"), ServerManager.GetItem(dragonBloodVnum).Name, soul[Upgrade])), 10));
                            return;
                        }
                        if (protect == UpgradeProtection.Protected)
                        {
                            if (Session.Character.Inventory.CountItem(blueScrollVnum) < 1)
                            {
                                Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey(string.Format(Language.Instance.GetMessageFromKey("NOT_ENOUGH_ITEMS"), ServerManager.GetItem(blueScrollVnum).Name, 1)), 10));
                                return;
                            }
                            Session.Character.Inventory.RemoveItemAmount(blueScrollVnum);
                            Session.SendPacket("shop_end 2");
                        }
                        Session.Character.Inventory.RemoveItemAmount(dragonBloodVnum, soul[Upgrade]);
                    }
                }
                else
                {
                    Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("LVL_REQUIRED"), 41), 11));
                    return;
                }
            }
            else if (Upgrade < 15)
            {
                if (SpLevel > 50)
                {
                    if (Item.Morph <= 16)
                    {
                        if (Session.Character.Inventory.CountItem(blueSoulVnum) < soul[Upgrade])
                        {
                            Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey(string.Format(Language.Instance.GetMessageFromKey("NOT_ENOUGH_ITEMS"), ServerManager.GetItem(blueSoulVnum).Name, soul[Upgrade])), 10));
                            return;
                        }
                        if (protect == UpgradeProtection.Protected && Upgrade > 9)
                        {
                            if (Session.Character.Inventory.CountItem(redScrollVnum) < 1)
                            {
                                return;
                            }
                            Session.Character.Inventory.RemoveItemAmount(redScrollVnum);
                            Session.SendPacket("shop_end 2");
                        }
                        Session.Character.Inventory.RemoveItemAmount(blueSoulVnum, soul[Upgrade]);
                    }
                    else
                    {
                        if (Session.Character.Inventory.CountItem(dragonHeartVnum) < soul[Upgrade])
                        {
                            return;
                        }
                        if (protect == UpgradeProtection.Protected && Upgrade > 9)
                        {
                            if (Session.Character.Inventory.CountItem(redScrollVnum) < 1)
                            {
                                Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey(string.Format(Language.Instance.GetMessageFromKey("NOT_ENOUGH_ITEMS"), ServerManager.GetItem(redScrollVnum).Name, 1)), 10));
                                return;
                            }
                            Session.Character.Inventory.RemoveItemAmount(redScrollVnum);
                            Session.SendPacket("shop_end 2");
                        }
                        Session.Character.Inventory.RemoveItemAmount(dragonHeartVnum, soul[Upgrade]);
                    }
                }
                else
                {
                    Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("LVL_REQUIRED"), 51), 11));
                    return;
                }
            }

            Session.Character.Gold -= goldprice[Upgrade];

            // remove feather and fullmoon before upgrading
            Session.Character.Inventory.RemoveItemAmount(featherVnum, feather[Upgrade]);
            Session.Character.Inventory.RemoveItemAmount(fullmoonVnum, fullmoon[Upgrade]);

            WearableInstance wearable  = Session.Character.Inventory.LoadByItemInstance <WearableInstance>(Id);
            ItemInstance     inventory = Session.Character.Inventory.GetItemInstanceById(Id);
            int rnd = ServerManager.RandomNumber();

            if (rnd <= upfail[Upgrade])
            {
                if (protect == UpgradeProtection.Protected)
                {
                    Session.CurrentMap.Broadcast(Session.Character.GenerateEff(3004), Session.Character.MapX, Session.Character.MapY);
                }
                Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("UPGRADESP_FAILED"), 11));
                Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("UPGRADESP_FAILED"), 0));
            }
            else if (rnd <= upsuccess[Upgrade])
            {
                if (protect == UpgradeProtection.Protected)
                {
                    Session.CurrentMap.Broadcast(Session.Character.GenerateEff(3004), Session.Character.MapX, Session.Character.MapY);
                }
                Session.CurrentMap.Broadcast(Session.Character.GenerateEff(3005), Session.Character.MapX, Session.Character.MapY);
                Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("UPGRADESP_SUCCESS"), 12));
                Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("UPGRADESP_SUCCESS"), 0));
                wearable.Upgrade++;
                Session.SendPacket(Session.Character.GenerateInventoryAdd(ItemVNum, 1, inventory.Type, inventory.Slot, wearable.Rare, wearable.Design, wearable.Upgrade, SpStoneUpgrade));
            }
            else
            {
                if (protect == UpgradeProtection.Protected)
                {
                    Session.CurrentMap.Broadcast(Session.Character.GenerateEff(3004), Session.Character.MapX, Session.Character.MapY);
                    Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("UPGRADESP_FAILED_SAVED"), 11));
                    Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("UPGRADESP_FAILED_SAVED"), 0));
                }
                else
                {
                    wearable.Rare = -2;
                    Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("UPGRADESP_DESTROYED"), 11));
                    Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("UPGRADESP_DESTROYED"), 0));
                    Session.SendPacket(Session.Character.GenerateInventoryAdd(ItemVNum, 1, inventory.Type, inventory.Slot, wearable.Rare, wearable.Design, wearable.Upgrade, SpStoneUpgrade));
                }
            }
            Session.SendPacket(Session.Character.GenerateGold());
            Session.SendPacket(Session.Character.GenerateEq());
            Session.SendPacket("shop_end 1");
        }
Beispiel #28
0
        public override void Use(ClientSession session, ref ItemInstance inv, byte Option = 0, string[] packetsplit = null)
        {
            if (session.Character.IsVehicled)
            {
                session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("CANT_DO_VEHICLED"), 10));
                return;
            }

            if (session.CurrentMapInstance.MapInstanceType == MapInstanceType.TalentArenaMapInstance)
            {
                return;
            }

            if (packetsplit == null)
            {
                return;
            }

            void releasePet(MateType mateType, Guid itemToRemoveId)
            {
                if (int.TryParse(packetsplit[3], out int mateTransportId))
                {
                    Mate mate = session.Character.Mates.Find(s => s.MateTransportId == mateTransportId && s.MateType == mateType);
                    if (mate != null)
                    {
                        if (!mate.IsTeamMember)
                        {
                            List <ItemInstance> mateInventory = mate.GetInventory();
                            if (mateInventory.Count > 0)
                            {
                                session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("EQ_NOT_EMPTY"), 0));
                            }
                            else
                            {
                                session.Character.Mates.Remove(mate);
                                byte i = 0;
                                session.Character.Mates.Where(s => s.MateType == MateType.Partner).ToList().ForEach(s =>
                                {
                                    s.GetInventory().ForEach(item => item.Type = (InventoryType)(13 + i));
                                    s.PetId = i;
                                    i++;
                                });
                                session.SendPacket(UserInterfaceHelper.GenerateInfo(Language.Instance.GetMessageFromKey("PET_RELEASED")));
                                session.SendPacket(UserInterfaceHelper.GeneratePClear());
                                session.SendPackets(session.Character.GenerateScP());
                                session.SendPackets(session.Character.GenerateScN());
                                session.CurrentMapInstance?.Broadcast(mate.GenerateOut());
                                session.Character.Inventory.RemoveItemFromInventory(itemToRemoveId);
                            }
                        }
                        else
                        {
                            session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("PET_IN_TEAM_UNRELEASABLE"), 0));
                        }
                    }
                }
            }

            if (BCards.Count > 0 && session.Character.MapInstance == session.Character.Miniland)
            {
                BCards.ForEach(c => c.ApplyBCards(session.Character.BattleEntity, session.Character.BattleEntity));
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                return;
            }

            switch (Effect)
            {
            case 10:
                if (int.TryParse(packetsplit[3], out int mateTransportId))
                {
                    Mate mate = session.Character.Mates.Find(s => s.MateTransportId == mateTransportId);
                    if (mate == null || mate.MateType != MateType.Pet || mate.Loyalty >= 1000)
                    {
                        return;
                    }
                    mate.Loyalty += 100;
                    if (mate.Loyalty > 1000)
                    {
                        mate.Loyalty = 1000;
                    }
                    mate.GenerateXp(EffectValue);
                    session.SendPacket(mate.GenerateCond());
                    session.SendPacket(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            case 11:
                if (int.TryParse(packetsplit[3], out mateTransportId))
                {
                    Mate mate = session.Character.Mates.Find(s => s.MateTransportId == mateTransportId);
                    if (mate == null || mate.MateType != MateType.Pet || mate.Level >= session.Character.Level - 5 || mate.Level + 1 > ServerManager.Instance.Configuration.MaxLevel)
                    {
                        return;
                    }
                    mate.Level++;
                    mate.Hp = mate.MaxHp;
                    mate.Mp = mate.MaxMp;
                    session.SendPacket($"say 2 {mate.MateTransportId} 0 " + Language.Instance.GetMessageFromKey("MATE_POWER_INCREASED"));
                    session.SendPackets(session.Character.GenerateScP());
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 8), mate.PositionX, mate.PositionY);
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 198), mate.PositionX, mate.PositionY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            case 12:
                if (int.TryParse(packetsplit[3], out mateTransportId))
                {
                    Mate mate = session.Character.Mates.Find(s => s.MateTransportId == mateTransportId);
                    if (mate == null || mate.MateType != MateType.Partner || mate.Level >= session.Character.Level - 5 || mate.Level + 1 > ServerManager.Instance.Configuration.MaxLevel)
                    {
                        return;
                    }
                    mate.Level++;
                    mate.Hp = mate.MaxHp;
                    mate.Mp = mate.MaxMp;
                    session.SendPacket($"say 2 {mate.MateTransportId} 0 " + Language.Instance.GetMessageFromKey("MATE_POWER_INCREASED"));
                    session.SendPackets(session.Character.GenerateScN());
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 8), mate.PositionX, mate.PositionY);
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 198), mate.PositionX, mate.PositionY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            case 13:
                if (int.TryParse(packetsplit[3], out mateTransportId) && session.Character.Mates.FirstOrDefault(s => s.MateTransportId == mateTransportId) is Mate pet)
                {
                    if (pet.MateType == MateType.Pet)
                    {
                        session.SendPacket(UserInterfaceHelper.GenerateGuri(10, 1, mateTransportId, 2));
                    }
                    else
                    {
                        session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("CANT_CHANGE_PARTNER_NAME"), 0));
                    }
                }
                break;

            case 14:
                if (int.TryParse(packetsplit[3], out mateTransportId))
                {
                    if (session.Character.MapInstance == session.Character.Miniland)
                    {
                        Mate mate = session.Character.Mates.Find(s => s.MateTransportId == mateTransportId && s.MateType == MateType.Pet);
                        if (mate?.CanPickUp == false)
                        {
                            session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5));
                            session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                            session.SendPacket($"say 2 {mate.MateTransportId} 0 " + Language.Instance.GetMessageFromKey("PET_SMART"));
                            mate.CanPickUp = true;
                            session.SendPackets(session.Character.GenerateScP());
                            session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_CAN_PICK_UP"), 10));
                            session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                        }
                    }
                    else
                    {
                        session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_IN_MINILAND"), 12));
                    }
                }
                break;

            case 16:
                if (int.TryParse(packetsplit[3], out mateTransportId))
                {
                    Mate mate = session.Character.Mates.Find(s => s.MateTransportId == mateTransportId);
                    if (mate == null || mate.MateType != MateType.Pet || mate.Level == 1)
                    {
                        return;
                    }
                    mate.Level--;
                    mate.Hp = mate.MaxHp;
                    mate.Mp = mate.MaxMp;
                    session.SendPacket($"say 2 {mate.MateTransportId} 0 " + Language.Instance.GetMessageFromKey("MATE_POWER_DECREASED"));
                    session.SendPackets(session.Character.GenerateScP());
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 198), mate.PositionX, mate.PositionY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            case 17:
                if (int.TryParse(packetsplit[3], out mateTransportId))
                {
                    Mate mate = session.Character.Mates.Find(s => s.MateTransportId == mateTransportId);
                    if (mate?.IsSummonable == false)
                    {
                        mate.IsSummonable = true;
                        session.SendPackets(session.Character.GenerateScP());
                        session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("PET_SUMMONABLE"), mate.Name), 10));
                        session.SendPacket(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("PET_SUMMONABLE"), mate.Name), 0));
                        session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    }
                }
                break;

            case 18:
                if (int.TryParse(packetsplit[3], out mateTransportId))
                {
                    Mate mate = session.Character.Mates.Find(s => s.MateTransportId == mateTransportId);
                    if (mate == null || mate.MateType != MateType.Partner || mate.Level == 1)
                    {
                        return;
                    }
                    mate.Level--;
                    mate.Hp = mate.MaxHp;
                    mate.Mp = mate.MaxMp;
                    session.SendPacket($"say 2 {mate.MateTransportId} 0 " + Language.Instance.GetMessageFromKey("MATE_POWER_DECREASED"));
                    session.SendPackets(session.Character.GenerateScN());
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 198), mate.PositionX, mate.PositionY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            case 1000:
                releasePet(MateType.Pet, inv.Id);
                break;

            case 1001:
                releasePet(MateType.Partner, inv.Id);
                break;

            case 1339:
                int rndevolve = ServerManager.RandomNumber(0, 1000);
                if (rndevolve > 900)
                {
                    if (int.TryParse(packetsplit[3], out mateTransportId))
                    {
                        Mate mate = session.Character.Mates.Find(s => s.MateTransportId == mateTransportId);
                        if (mate == null)
                        {
                            session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PICK_PET"), 10));
                            return;
                        }
                        if (mate.Level >= 30 && mate.NpcMonsterVNum == 649 && mate.IsTeamMember == true && mate.MateType == MateType.Pet)
                        {
                            mate.Level          = 1;
                            mate.NpcMonsterVNum = 650;
                            session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5));
                            session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                            session.SendPackets(session.Character.GenerateScP());
                            session.SendPackets(session.Character.GenerateScN());
                            session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_EVOLED"), 10));
                            if (session?.Character != null)
                            {
                                if (session.Character.Miniland == session.Character.MapInstance)
                                {
                                    ServerManager.Instance.JoinMiniland(session, session);
                                }
                                else
                                {
                                    ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId,
                                                                             session.Character.MapInstanceId, session.Character.PositionX, session.Character.PositionY,
                                                                             true);
                                    session.SendPacket(StaticPacketHelper.Cancel(2));
                                }
                            }
                        }
                        else
                        {
                            if (mate.Level >= 30 && mate.NpcMonsterVNum == 648 && mate.IsTeamMember == true && mate.MateType == MateType.Pet)
                            {
                                mate.Level          = 1;
                                mate.NpcMonsterVNum = 649;
                                session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5));
                                session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                                session.SendPackets(session.Character.GenerateScP());
                                session.SendPackets(session.Character.GenerateScN());
                                session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_EVOLED"), 10));
                                if (session?.Character != null)
                                {
                                    if (session.Character.Miniland == session.Character.MapInstance)
                                    {
                                        ServerManager.Instance.JoinMiniland(session, session);
                                    }
                                    else
                                    {
                                        ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId,
                                                                                 session.Character.MapInstanceId, session.Character.PositionX, session.Character.PositionY,
                                                                                 true);
                                        session.SendPacket(StaticPacketHelper.Cancel(2));
                                    }
                                }
                            }
                            else
                            {
                                if (mate.Level >= 30 && mate.NpcMonsterVNum == 651 && mate.IsTeamMember == true && mate.MateType == MateType.Pet)
                                {
                                    mate.Level          = 1;
                                    mate.NpcMonsterVNum = 652;
                                    session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5));
                                    session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                                    session.SendPackets(session.Character.GenerateScP());
                                    session.SendPackets(session.Character.GenerateScN());
                                    session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_EVOLED"), 10));
                                    if (session?.Character != null)
                                    {
                                        if (session.Character.Miniland == session.Character.MapInstance)
                                        {
                                            ServerManager.Instance.JoinMiniland(session, session);
                                        }
                                        else
                                        {
                                            ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId,
                                                                                     session.Character.MapInstanceId, session.Character.PositionX, session.Character.PositionY,
                                                                                     true);
                                            session.SendPacket(StaticPacketHelper.Cancel(2));
                                        }
                                    }
                                }
                                else
                                {
                                    if (mate.Level >= 30 && mate.NpcMonsterVNum == 652 && mate.IsTeamMember == true && mate.MateType == MateType.Pet)
                                    {
                                        mate.Level          = 1;
                                        mate.NpcMonsterVNum = 653;
                                        session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5));
                                        session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                                        session.SendPackets(session.Character.GenerateScP());
                                        session.SendPackets(session.Character.GenerateScN());
                                        session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_EVOLED"), 10));
                                        if (session?.Character != null)
                                        {
                                            if (session.Character.Miniland == session.Character.MapInstance)
                                            {
                                                ServerManager.Instance.JoinMiniland(session, session);
                                            }
                                            else
                                            {
                                                ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId,
                                                                                         session.Character.MapInstanceId, session.Character.PositionX, session.Character.PositionY,
                                                                                         true);
                                                session.SendPacket(StaticPacketHelper.Cancel(2));
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (mate.Level >= 30 && mate.NpcMonsterVNum == 660 && mate.IsTeamMember == true && mate.MateType == MateType.Pet)
                                        {
                                            mate.Level          = 1;
                                            mate.NpcMonsterVNum = 661;
                                            session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5));
                                            session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                                            session.SendPackets(session.Character.GenerateScP());
                                            session.SendPackets(session.Character.GenerateScN());
                                            session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_EVOLED"), 10));
                                            if (session?.Character != null)
                                            {
                                                if (session.Character.Miniland == session.Character.MapInstance)
                                                {
                                                    ServerManager.Instance.JoinMiniland(session, session);
                                                }
                                                else
                                                {
                                                    ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId,
                                                                                             session.Character.MapInstanceId, session.Character.PositionX, session.Character.PositionY,
                                                                                             true);
                                                    session.SendPacket(StaticPacketHelper.Cancel(2));
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (mate.Level >= 30 && mate.NpcMonsterVNum == 661 && mate.IsTeamMember == true && mate.MateType == MateType.Pet)
                                            {
                                                mate.Level          = 1;
                                                mate.NpcMonsterVNum = 662;
                                                session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5));
                                                session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                                                session.SendPackets(session.Character.GenerateScP());
                                                session.SendPackets(session.Character.GenerateScN());
                                                session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_EVOLED"), 10));
                                                if (session?.Character != null)
                                                {
                                                    if (session.Character.Miniland == session.Character.MapInstance)
                                                    {
                                                        ServerManager.Instance.JoinMiniland(session, session);
                                                    }
                                                    else
                                                    {
                                                        ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId,
                                                                                                 session.Character.MapInstanceId, session.Character.PositionX, session.Character.PositionY,
                                                                                                 true);
                                                        session.SendPacket(StaticPacketHelper.Cancel(2));
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                if (mate.Level >= 30 && mate.NpcMonsterVNum == 657 && mate.IsTeamMember == true && mate.MateType == MateType.Pet)
                                                {
                                                    mate.Level          = 1;
                                                    mate.NpcMonsterVNum = 658;
                                                    session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5));
                                                    session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                                                    session.SendPackets(session.Character.GenerateScP());
                                                    session.SendPackets(session.Character.GenerateScN());
                                                    session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_EVOLED"), 10));
                                                    if (session?.Character != null)
                                                    {
                                                        if (session.Character.Miniland == session.Character.MapInstance)
                                                        {
                                                            ServerManager.Instance.JoinMiniland(session, session);
                                                        }
                                                        else
                                                        {
                                                            ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId,
                                                                                                     session.Character.MapInstanceId, session.Character.PositionX, session.Character.PositionY,
                                                                                                     true);
                                                            session.SendPacket(StaticPacketHelper.Cancel(2));
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    if (mate.Level >= 30 && mate.NpcMonsterVNum == 658 && mate.IsTeamMember == true && mate.MateType == MateType.Pet)
                                                    {
                                                        mate.Level          = 1;
                                                        mate.NpcMonsterVNum = 659;
                                                        session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5));
                                                        session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                                                        session.SendPackets(session.Character.GenerateScP());
                                                        session.SendPackets(session.Character.GenerateScN());
                                                        session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_EVOLED"), 10));
                                                        if (session?.Character != null)
                                                        {
                                                            if (session.Character.Miniland == session.Character.MapInstance)
                                                            {
                                                                ServerManager.Instance.JoinMiniland(session, session);
                                                            }
                                                            else
                                                            {
                                                                ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId,
                                                                                                         session.Character.MapInstanceId, session.Character.PositionX, session.Character.PositionY,
                                                                                                         true);
                                                                session.SendPacket(StaticPacketHelper.Cancel(2));
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        if (mate.Level >= 30 && mate.NpcMonsterVNum == 660 && mate.IsTeamMember == true && mate.MateType == MateType.Pet)
                                                        {
                                                            mate.Level          = 1;
                                                            mate.NpcMonsterVNum = 661;
                                                            session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5));
                                                            session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                                                            session.SendPackets(session.Character.GenerateScP());
                                                            session.SendPackets(session.Character.GenerateScN());
                                                            session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_EVOLED"), 10));
                                                            if (session?.Character != null)
                                                            {
                                                                if (session.Character.Miniland == session.Character.MapInstance)
                                                                {
                                                                    ServerManager.Instance.JoinMiniland(session, session);
                                                                }
                                                                else
                                                                {
                                                                    ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId,
                                                                                                             session.Character.MapInstanceId, session.Character.PositionX, session.Character.PositionY,
                                                                                                             true);
                                                                    session.SendPacket(StaticPacketHelper.Cancel(2));
                                                                }
                                                            }
                                                        }
                                                        else
                                                        {
                                                            if (mate.Level >= 30 && mate.NpcMonsterVNum == 988 && mate.IsTeamMember == true && mate.MateType == MateType.Pet)
                                                            {
                                                                mate.Level          = 1;
                                                                mate.NpcMonsterVNum = 416;
                                                                session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5));
                                                                session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                                                                session.SendPackets(session.Character.GenerateScP());
                                                                session.SendPackets(session.Character.GenerateScN());
                                                                session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_EVOLED"), 10));
                                                                if (session?.Character != null)
                                                                {
                                                                    if (session.Character.Miniland == session.Character.MapInstance)
                                                                    {
                                                                        ServerManager.Instance.JoinMiniland(session, session);
                                                                    }
                                                                    else
                                                                    {
                                                                        ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId,
                                                                                                                 session.Character.MapInstanceId, session.Character.PositionX, session.Character.PositionY,
                                                                                                                 true);
                                                                        session.SendPacket(StaticPacketHelper.Cancel(2));
                                                                    }
                                                                }
                                                            }
                                                            else
                                                            {
                                                                if (mate.Level >= 30 && mate.NpcMonsterVNum == 416 && mate.IsTeamMember == true && mate.MateType == MateType.Pet)
                                                                {
                                                                    mate.Level          = 1;
                                                                    mate.NpcMonsterVNum = 412;
                                                                    session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5));
                                                                    session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                                                                    session.SendPackets(session.Character.GenerateScP());
                                                                    session.SendPackets(session.Character.GenerateScN());
                                                                    session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_EVOLED"), 10));
                                                                    if (session?.Character != null)
                                                                    {
                                                                        if (session.Character.Miniland == session.Character.MapInstance)
                                                                        {
                                                                            ServerManager.Instance.JoinMiniland(session, session);
                                                                        }
                                                                        else
                                                                        {
                                                                            ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId,
                                                                                                                     session.Character.MapInstanceId, session.Character.PositionX, session.Character.PositionY,
                                                                                                                     true);
                                                                            session.SendPacket(StaticPacketHelper.Cancel(2));
                                                                        }
                                                                    }
                                                                }
                                                                else
                                                                {
                                                                    if (mate.Level >= 30 && mate.NpcMonsterVNum == 412 && mate.IsTeamMember == true && mate.MateType == MateType.Pet)
                                                                    {
                                                                        mate.Level          = 1;
                                                                        mate.NpcMonsterVNum = 414;
                                                                        session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5));
                                                                        session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                                                                        session.SendPackets(session.Character.GenerateScP());
                                                                        session.SendPackets(session.Character.GenerateScN());
                                                                        session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_EVOLED"), 10));
                                                                        if (session?.Character != null)
                                                                        {
                                                                            if (session.Character.Miniland == session.Character.MapInstance)
                                                                            {
                                                                                ServerManager.Instance.JoinMiniland(session, session);
                                                                            }
                                                                            else
                                                                            {
                                                                                ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId,
                                                                                                                         session.Character.MapInstanceId, session.Character.PositionX, session.Character.PositionY,
                                                                                                                         true);
                                                                                session.SendPacket(StaticPacketHelper.Cancel(2));
                                                                            }
                                                                        }
                                                                    }
                                                                    else
                                                                    {
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        break;
                                                    }
                                                    break;
                                                }
                                                break;
                                            }
                                            break;
                                        }
                                        break;
                                    }
                                    break;
                                }
                                break;
                            }
                            break;
                        }
                        break;
                    }
                    else
                    {
                        session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_NOT_EVOLED"), 10));
                    }
                    break;
                }
                else
                {
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_NOT_EVOLED"), 10));
                }
                break;

            case 2137:
                int rnd = ServerManager.RandomNumber(0, 1000);
                {
                    if (int.TryParse(packetsplit[3], out mateTransportId))
                    {
                        Mate mate = session.Character.Mates.Find(s => s.MateTransportId == mateTransportId);
                        if (mate == null)
                        {
                            session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("PICK_PET"), 10));
                        }
                        else
                        if (mate.Defence <= 9 || mate.Attack <= 9)
                        {
                            if (rnd >= 600 && rnd <= 800)
                            {
                                mate.Attack++;
                                session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ATTACK_PLUS"), 10));
                                session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 3004), session.Character.MapX, session.Character.MapY);
                            }
                            else if (rnd >= 801 && rnd <= 1000)
                            {
                                mate.Defence++;
                                session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("DEF_PLUS"), 10));
                                session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 3004), session.Character.MapX, session.Character.MapY);
                            }
                            else if (rnd <= 800 && rnd >= 400)
                            {
                                if (mate.Defence == 0)
                                {
                                    return;
                                }
                                else
                                {
                                    mate.Defence--;
                                    session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("DEF_MINUS"), 10));
                                    session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 3005), session.Character.MapX, session.Character.MapY);
                                }
                            }
                            else if (rnd <= 399 && rnd >= 0)
                            {
                                if (mate.Attack == 0)
                                {
                                    return;
                                }
                                else
                                {
                                    mate.Attack--;
                                    session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ATTACK_MINUS"), 10));
                                    session.CurrentMapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 3005), session.Character.MapX, session.Character.MapY);
                                }
                            }
                            else
                            {
                                return;
                            }
                        }
                        else
                        {
                            return;
                        }
                    }
                    else
                    {
                        return;
                    }
                    session.Character.Inventory.RemoveItemAmount(2079, 1);
                }
                break;

            default:
                Logger.Warn(string.Format(Language.Instance.GetMessageFromKey("NO_HANDLER_ITEM"), GetType(), VNum, Effect, EffectValue));
                break;
            }
        }
Beispiel #29
0
        private void npcLife()
        {
            double time = (DateTime.Now - LastEffect).TotalMilliseconds;

            if (time > EffectDelay)
            {
                if (IsMate || IsProtected)
                {
                    MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, 825), MapX, MapY);
                }
                if (Effect > 0 && EffectActivated)
                {
                    MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, Effect), MapX, MapY);
                }
                LastEffect = DateTime.Now;
            }

            time = (DateTime.Now - LastMove).TotalMilliseconds;
            if (IsMoving && Npc.Speed > 0 && time > _movetime)
            {
                _movetime = ServerManager.RandomNumber(500, 3000);
                byte point  = (byte)ServerManager.RandomNumber(2, 4);
                byte fpoint = (byte)ServerManager.RandomNumber(0, 2);

                byte xpoint = (byte)ServerManager.RandomNumber(fpoint, point);
                byte ypoint = (byte)(point - xpoint);

                short mapX = FirstX;
                short mapY = FirstY;

                if (MapInstance.Map.GetFreePosition(ref mapX, ref mapY, xpoint, ypoint))
                {
                    double value = (xpoint + ypoint) / (double)(2 * Npc.Speed);
                    Observable.Timer(TimeSpan.FromMilliseconds(1000 * value)).Subscribe(x =>
                    {
                        MapX = mapX;
                        MapY = mapY;
                    });
                    LastMove = DateTime.Now.AddSeconds(value);
                    MapInstance.Broadcast(new BroadcastPacket(null, PacketFactory.Serialize(StaticPacketHelper.Move(UserType.Npc, MapNpcId, MapX, MapY, Npc.Speed)), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                }
            }
            if (Target == -1)
            {
                if (IsHostile && Shop == null)
                {
                    MapMonster monster = MapInstance.Monsters.Find(s => MapInstance == s.MapInstance && Map.GetDistance(new MapCell {
                        X = MapX, Y = MapY
                    }, new MapCell {
                        X = s.MapX, Y = s.MapY
                    }) < (Npc.NoticeRange > 5 ? Npc.NoticeRange / 2 : Npc.NoticeRange));
                    ClientSession session = MapInstance.Sessions.FirstOrDefault(s => MapInstance == s.Character.MapInstance && Map.GetDistance(new MapCell {
                        X = MapX, Y = MapY
                    }, new MapCell {
                        X = s.Character.PositionX, Y = s.Character.PositionY
                    }) < Npc.NoticeRange);

                    if (monster != null && session != null)
                    {
                        Target = monster.MapMonsterId;
                    }
                }
            }
            else if (Target != -1)
            {
                MapMonster monster = MapInstance.Monsters.Find(s => s.MapMonsterId == Target);
                if (monster == null || monster.CurrentHp < 1)
                {
                    Target = -1;
                    return;
                }
                NpcMonsterSkill npcMonsterSkill = null;
                if (ServerManager.RandomNumber(0, 10) > 8)
                {
                    npcMonsterSkill = Npc.Skills.Where(s => (DateTime.Now - s.LastSkillUse).TotalMilliseconds >= 100 * s.Skill.Cooldown).OrderBy(rnd => _random.Next()).FirstOrDefault();
                }
                int  hitmode   = 0;
                bool onyxWings = false;
                int  damage    = DamageHelper.Instance.CalculateDamage(new BattleEntity(this), new BattleEntity(monster), npcMonsterSkill?.Skill, ref hitmode, ref onyxWings);
                if (monster.Monster.BCards.Find(s => s.Type == (byte)CardType.LightAndShadow && s.SubType == (byte)AdditionalTypes.LightAndShadow.InflictDamageToMP) is BCard card)
                {
                    int reduce = damage / 100 * card.FirstData;
                    if (monster.CurrentMp < reduce)
                    {
                        monster.CurrentMp = 0;
                    }
                    else
                    {
                        monster.CurrentMp -= reduce;
                    }
                }
                int distance = Map.GetDistance(new MapCell {
                    X = MapX, Y = MapY
                }, new MapCell {
                    X = monster.MapX, Y = monster.MapY
                });
                if (monster.CurrentHp > 0 && ((npcMonsterSkill != null && distance < npcMonsterSkill.Skill.Range) || distance <= Npc.BasicRange))
                {
                    if (((DateTime.Now - LastEffect).TotalMilliseconds >= 1000 + (Npc.BasicCooldown * 200) && Npc.Skills.Count == 0) || npcMonsterSkill != null)
                    {
                        if (npcMonsterSkill != null)
                        {
                            npcMonsterSkill.LastSkillUse = DateTime.Now;
                            MapInstance.Broadcast(StaticPacketHelper.CastOnTarget(UserType.Npc, MapNpcId, 3, Target, npcMonsterSkill.Skill.CastAnimation, npcMonsterSkill.Skill.CastEffect, npcMonsterSkill.Skill.SkillVNum));
                        }

                        if (npcMonsterSkill != null && npcMonsterSkill.Skill.CastEffect != 0)
                        {
                            MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Npc, MapNpcId, Effect));
                        }
                        monster.CurrentHp -= damage;
                        MapInstance.Broadcast(npcMonsterSkill != null
                            ? StaticPacketHelper.SkillUsed(UserType.Npc, MapNpcId, 3, Target, npcMonsterSkill.SkillVNum, npcMonsterSkill.Skill.Cooldown, npcMonsterSkill.Skill.AttackAnimation, npcMonsterSkill.Skill.Effect, 0, 0, monster.CurrentHp > 0, (int)((float)monster.CurrentHp / (float)monster.Monster.MaxHP * 100), damage, hitmode, 0)
                            : StaticPacketHelper.SkillUsed(UserType.Npc, MapNpcId, 3, Target, 0, Npc.BasicCooldown, 11, Npc.BasicSkill, 0, 0, monster.CurrentHp > 0, (int)((float)monster.CurrentHp / (float)monster.Monster.MaxHP * 100), damage, hitmode, 0));
                        LastEffect = DateTime.Now;
                        if (monster.CurrentHp < 1)
                        {
                            RemoveTarget();
                            monster.IsAlive   = false;
                            monster.LastMove  = DateTime.Now;
                            monster.CurrentHp = 0;
                            monster.CurrentMp = 0;
                            monster.Death     = DateTime.Now;
                            Target            = -1;
                        }
                    }
                }
                else
                {
                    int maxdistance = Npc.NoticeRange > 5 ? Npc.NoticeRange / 2 : Npc.NoticeRange;
                    if (IsMoving)
                    {
                        const short maxDistance = 5;
                        int         maxindex    = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                        if (maxindex < 1)
                        {
                            maxindex = 1;
                        }
                        if ((Path.Count == 0 && distance >= 1 && distance < maxDistance) || (Path.Count >= maxindex && maxindex > 0 && Path[maxindex - 1] == null))
                        {
                            short xoffset = (short)ServerManager.RandomNumber(-1, 1);
                            short yoffset = (short)ServerManager.RandomNumber(-1, 1);

                            //go to monster
                            Path = BestFirstSearch.FindPathJagged(new GridPos {
                                X = MapX, Y = MapY
                            }, new GridPos {
                                X = (short)(monster.MapX + xoffset), Y = (short)(monster.MapY + yoffset)
                            }, MapInstance.Map.JaggedGrid);
                            maxindex = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                        }
                        if (DateTime.Now > LastMove && Npc.Speed > 0 && Path.Count > 0)
                        {
                            short  mapX        = Path[maxindex - 1].X;
                            short  mapY        = Path[maxindex - 1].Y;
                            double waitingtime = Map.GetDistance(new MapCell {
                                X = mapX, Y = mapY
                            }, new MapCell {
                                X = MapX, Y = MapY
                            }) / (double)Npc.Speed;
                            MapInstance.Broadcast(new BroadcastPacket(null, PacketFactory.Serialize(StaticPacketHelper.Move(UserType.Npc, MapNpcId, MapX, MapY, Npc.Speed)), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                            LastMove = DateTime.Now.AddSeconds(waitingtime > 1 ? 1 : waitingtime);

                            Observable.Timer(TimeSpan.FromMilliseconds((int)((waitingtime > 1 ? 1 : waitingtime) * 1000))).Subscribe(x =>
                            {
                                MapX = mapX;
                                MapY = mapY;
                            });

                            Path.RemoveRange(0, maxindex);
                        }
                        if (Target != -1 && (MapId != monster.MapId || distance > maxDistance))
                        {
                            RemoveTarget();
                        }
                    }
                }
            }
        }
Beispiel #30
0
        public void ApplyBCards(object session, object sender = null)
        {
            Type type = session.GetType();

            // int counterBuff = 0;
            if (type == null)
            {
                return;
            }
            switch ((BCardType.CardType)Type)
            {
            case BCardType.CardType.Buff:
            {
                if (type == typeof(Character) && session is Character character)
                {
                    Buff buff = null;
                    if (sender != null)
                    {
                        Type sType = sender.GetType();
                        if (sType != null)
                        {
                            if (sType == typeof(Character) && sender is Character sendingCharacter)
                            {
                                buff = new Buff((short)SecondData, sendingCharacter.Level);

                                //Todo: Get anti stats from BCard
                            }
                        }
                    }
                    else
                    {
                        buff = new Buff((short)SecondData, character.Level);
                    }
                    if (ServerManager.RandomNumber() < FirstData)
                    {
                        character.AddBuff(buff);
                    }
                }
                else if (type == typeof(MapMonster))
                {
                    if (ServerManager.RandomNumber() < FirstData && session is MapMonster mapMonster)
                    {
                        mapMonster.AddBuff(new Buff((short)SecondData, mapMonster.Monster.Level));
                    }
                }
                else if (type == typeof(MapNpc))
                {
                }
                else if (type == typeof(Mate))
                {
                }
                break;
            }

            case BCardType.CardType.Move:
            {
                if (type == typeof(Character) && session is Character character)
                {
                    character.LastSpeedChange = DateTime.Now;
                    character.Session.SendPacket(character.GenerateCond());
                }
            }
            break;

            case BCardType.CardType.Summons:
                if (type == typeof(Character))
                {
                }
                else if (type == typeof(MapMonster))
                {
                    if (session is MapMonster mapMonster)
                    {
                        List <MonsterToSummon> summonParameters = new List <MonsterToSummon>();
                        for (int i = 0; i < FirstData; i++)
                        {
                            short x = (short)(ServerManager.RandomNumber(-3, 3) + mapMonster.MapX);
                            short y = (short)(ServerManager.RandomNumber(-3, 3) + mapMonster.MapY);
                            summonParameters.Add(new MonsterToSummon((short)SecondData, new MapCell {
                                X = x, Y = y
                            }, -1, true));
                        }
                        if (ServerManager.RandomNumber() <= Math.Abs(ThirdData) || ThirdData == 0)
                        {
                            switch (SubType)
                            {
                            case 2:
                                EventHelper.Instance.RunEvent(new EventContainer(mapMonster.MapInstance, EventActionType.SPAWNMONSTERS, summonParameters));
                                break;

                            default:
                                if (!mapMonster.OnDeathEvents.Any(s => s.EventActionType == EventActionType.SPAWNMONSTERS))
                                {
                                    mapMonster.OnDeathEvents.Add(new EventContainer(mapMonster.MapInstance, EventActionType.SPAWNMONSTERS, summonParameters));
                                }
                                break;
                            }
                        }
                    }
                }
                else if (type == typeof(MapNpc))
                {
                }
                else if (type == typeof(Mate))
                {
                }
                break;

            case BCardType.CardType.SpecialAttack:
                break;

            case BCardType.CardType.SpecialDefence:
                break;

            case BCardType.CardType.AttackPower:
                break;

            case BCardType.CardType.Target:
                break;

            case BCardType.CardType.Critical:
                break;

            case BCardType.CardType.SpecialCritical:
                break;

            case BCardType.CardType.Element:
                break;

            case BCardType.CardType.IncreaseDamage:
                break;

            case BCardType.CardType.Defence:
                break;

            case BCardType.CardType.DodgeAndDefencePercent:
                break;

            case BCardType.CardType.Block:
                break;

            case BCardType.CardType.Absorption:
                break;

            case BCardType.CardType.ElementResistance:
                break;

            case BCardType.CardType.EnemyElementResistance:
                break;

            case BCardType.CardType.Damage:
                break;

            case BCardType.CardType.GuarantedDodgeRangedAttack:
                break;

            case BCardType.CardType.Morale:
                break;

            case BCardType.CardType.Casting:
                break;

            case BCardType.CardType.Reflection:
                break;

            case BCardType.CardType.DrainAndSteal:
                break;

            case BCardType.CardType.HealingBurningAndCasting:
                if (type == typeof(Character))
                {
                    if (session is Character character && character.Hp > 0)
                    {
                        int bonus = 0;
                        if (SubType == (byte)AdditionalTypes.HealingBurningAndCasting.RestoreHP / 10)
                        {
                            if (IsLevelScaled)
                            {
                                bonus = character.Level * FirstData;
                            }
                            else
                            {
                                bonus = FirstData;
                            }
                            if (character.Hp + bonus <= character.HPLoad())
                            {
                                character.Hp += bonus;
                            }
                            else
                            {
                                bonus        = (int)character.HPLoad() - character.Hp;
                                character.Hp = (int)character.HPLoad();
                            }
                            character.Session.CurrentMapInstance?.Broadcast(character.Session, character.GenerateRc(bonus));
                        }
                        if (SubType == (byte)AdditionalTypes.HealingBurningAndCasting.RestoreMP / 10)
                        {
                            if (IsLevelScaled)
                            {
                                bonus = character.Level * FirstData;
                            }
                            else
                            {
                                bonus = FirstData;
                            }
                            if (character.Mp + bonus <= character.MPLoad())
                            {
                                character.Mp += bonus;
                            }
                            else
                            {
                                bonus        = (int)character.MPLoad() - character.Mp;
                                character.Mp = (int)character.MPLoad();
                            }
                        }
                        character.Session.SendPacket(character.GenerateStat());
                    }
                }
                else if (type == typeof(MapMonster))
                {
                    if (ServerManager.RandomNumber() < FirstData && session is MapMonster mapMonster)
                    {
                        mapMonster.AddBuff(new Buff((short)SecondData, mapMonster.Monster.Level));
                    }
                }
                else if (type == typeof(MapNpc))
                {
                }
                else if (type == typeof(Mate))
                {
                }
                break;

            case BCardType.CardType.HPMP:
                break;

            case BCardType.CardType.SpecialisationBuffResistance:
                break;

            case BCardType.CardType.SpecialEffects:
                break;

            case BCardType.CardType.Capture:
                if (type == typeof(MapMonster))
                {
                    if (session is MapMonster mapMonster && sender is ClientSession senderSession)
                    {
                        NpcMonster mateNpc = ServerManager.GetNpc(mapMonster.MonsterVNum);
                        if (mateNpc != null)
                        {
                            if (mapMonster.Monster.Catch)
                            {
                                if (mapMonster.IsAlive && mapMonster.CurrentHp <= (int)((double)mapMonster.MaxHp / 2))
                                {
                                    if (mapMonster.Monster.Level < senderSession.Character.Level)
                                    {
#warning find a new algorithm
                                        int[] chance = { 100, 80, 60, 40, 20, 0 };
                                        if (ServerManager.RandomNumber() < chance[ServerManager.RandomNumber(0, 5)])
                                        {
                                            Mate mate = new Mate(senderSession.Character, mateNpc, (byte)(mapMonster.Monster.Level - 15 > 0 ? mapMonster.Monster.Level - 15 : 1), MateType.Pet);
                                            if (senderSession.Character.CanAddMate(mate))
                                            {
                                                senderSession.Character.AddPetWithSkill(mate);
                                                senderSession.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("CATCH_SUCCESS"), 0));
                                                senderSession.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, senderSession.Character.CharacterId, 197));
                                                senderSession.CurrentMapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, senderSession.Character.CharacterId, 3, mapMonster.MapMonsterId, -1, 0, 15, -1, -1, -1, true, (int)((float)mapMonster.CurrentHp / (float)mapMonster.MaxHp * 100), 0, -1, 0));
                                                mapMonster.SetDeathStatement();
                                                senderSession.CurrentMapInstance?.Broadcast(StaticPacketHelper.Out(UserType.Monster, mapMonster.MapMonsterId));
                                            }
                                            else
                                            {
                                                senderSession.SendPacket(senderSession.Character.GenerateSay(Language.Instance.GetMessageFromKey("PET_SLOT_FULL"), 10));
                                                senderSession.SendPacket(StaticPacketHelper.Cancel(2, mapMonster.MapMonsterId));
                                            }
                                        }
                                        else
                                        {
                                            senderSession.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("CATCH_FAIL"), 0));
                                            senderSession.CurrentMapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, senderSession.Character.CharacterId, 3, mapMonster.MapMonsterId, -1, 0, 15, -1, -1, -1, true, (int)((float)mapMonster.CurrentHp / (float)mapMonster.MaxHp * 100), 0, -1, 0));
                                        }
                                    }
                                    else
                                    {
                                        senderSession.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("LEVEL_LOWER_THAN_MONSTER"), 0));
                                        senderSession.SendPacket(StaticPacketHelper.Cancel(2, mapMonster.MapMonsterId));
                                    }
                                }
                                else
                                {
                                    senderSession.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("CURRENT_HP_TOO_HIGH"), 0));
                                    senderSession.SendPacket(StaticPacketHelper.Cancel(2, mapMonster.MapMonsterId));
                                }
                            }
                            else
                            {
                                senderSession.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("MONSTER_CANT_BE_CAPTURED"), 0));
                                senderSession.SendPacket(StaticPacketHelper.Cancel(2, mapMonster.MapMonsterId));
                            }
                        }
                    }
                }
                break;

            case BCardType.CardType.SpecialDamageAndExplosions:
                break;

            case BCardType.CardType.SpecialEffects2:
                break;

            case BCardType.CardType.CalculatingLevel:
                break;

            case BCardType.CardType.Recovery:
                break;

            case BCardType.CardType.MaxHPMP:
                break;

            case BCardType.CardType.MultAttack:
                break;

            case BCardType.CardType.MultDefence:
                break;

            case BCardType.CardType.TimeCircleSkills:
                break;

            case BCardType.CardType.RecoveryAndDamagePercent:
                break;

            case BCardType.CardType.Count:
                break;

            case BCardType.CardType.NoDefeatAndNoDamage:
                break;

            case BCardType.CardType.SpecialActions:
                break;

            case BCardType.CardType.Mode:
                break;

            case BCardType.CardType.NoCharacteristicValue:
                break;

            case BCardType.CardType.LightAndShadow:
                break;

            case BCardType.CardType.Item:
                break;

            case BCardType.CardType.DebuffResistance:
                break;

            case BCardType.CardType.SpecialBehaviour:
                break;

            case BCardType.CardType.Quest:
                break;

            case BCardType.CardType.SecondSPCard:
                break;

            case BCardType.CardType.SPCardUpgrade:
                break;

            case BCardType.CardType.HugeSnowman:
                break;

            case BCardType.CardType.Drain:
                break;

            case BCardType.CardType.BossMonstersSkill:
                break;

            case BCardType.CardType.LordHatus:
                break;

            case BCardType.CardType.LordCalvinas:
                break;

            case BCardType.CardType.SESpecialist:
                break;

            case BCardType.CardType.FourthGlacernonFamilyRaid:
                break;

            case BCardType.CardType.SummonedMonsterAttack:
                break;

            case BCardType.CardType.BearSpirit:
                break;

            case BCardType.CardType.SummonSkill:
                break;

            case BCardType.CardType.InflictSkill:
                break;

            case BCardType.CardType.HideBarrelSkill:
                break;

            case BCardType.CardType.FocusEnemyAttentionSkill:
                break;

            case BCardType.CardType.TauntSkill:
                break;

            case BCardType.CardType.FireCannoneerRangeBuff:
                break;

            case BCardType.CardType.VulcanoElementBuff:
                break;

            case BCardType.CardType.DamageConvertingSkill:
                break;

            case BCardType.CardType.MeditationSkill:
            {
                if (type == typeof(Character) && session is Character character)
                {
                    if (SkillVNum.HasValue && SubType.Equals((byte)AdditionalTypes.MeditationSkill.CausingChance / 10) && ServerManager.RandomNumber() < FirstData)
                    {
                        Skill skill    = ServerManager.GetSkill(SkillVNum.Value);
                        Skill newSkill = ServerManager.GetSkill((short)SecondData);
                        Observable.Timer(TimeSpan.FromMilliseconds(100)).Subscribe(observer =>
                            {
                                foreach (QuicklistEntryDTO quicklistEntry in character.QuicklistEntries.Where(s => s.Pos.Equals(skill.CastId)))
                                {
                                    character.Session.SendPacket($"qset {quicklistEntry.Q1} {quicklistEntry.Q2} {quicklistEntry.Type}.{quicklistEntry.Slot}.{newSkill.CastId}.0");
                                }
                                character.Session.SendPacket($"mslot {newSkill.CastId} -1");
                            });
                        character.SkillComboCount++;
                        character.LastSkillComboUse = DateTime.Now;
                        if (skill.CastId > 10)
                        {
                            // HACK this way
                            Observable.Timer(TimeSpan.FromMilliseconds((skill.Cooldown * 100) + 500)).Subscribe(observer => character.Session.SendPacket(StaticPacketHelper.SkillReset(skill.CastId)));
                        }
                    }
                    switch (SubType)
                    {
                    case 2:
                        character.MeditationDictionary[(short)SecondData] = DateTime.Now.AddSeconds(4);
                        break;

                    case 3:
                        character.MeditationDictionary[(short)SecondData] = DateTime.Now.AddSeconds(8);
                        break;

                    case 4:
                        character.MeditationDictionary[(short)SecondData] = DateTime.Now.AddSeconds(12);
                        break;
                    }
                }
            }
            break;

            case BCardType.CardType.FalconSkill:
                break;

            case BCardType.CardType.AbsorptionAndPowerSkill:
                break;

            case BCardType.CardType.LeonaPassiveSkill:
                break;

            case BCardType.CardType.FearSkill:
                break;

            case BCardType.CardType.SniperAttack:
                break;

            case BCardType.CardType.FrozenDebuff:
                break;

            case BCardType.CardType.JumpBackPush:
                break;

            case BCardType.CardType.FairyXPIncrease:
                break;

            case BCardType.CardType.SummonAndRecoverHP:
                break;

            case BCardType.CardType.TeamArenaBuff:
                break;

            case BCardType.CardType.ArenaCamera:
                break;

            case BCardType.CardType.DarkCloneSummon:
                break;

            case BCardType.CardType.AbsorbedSpirit:
                break;

            case BCardType.CardType.AngerSkill:
                break;

            case BCardType.CardType.MeteoriteTeleport:
                break;

            case BCardType.CardType.StealBuff:
                break;

            case BCardType.CardType.Unknown:
                break;

            case BCardType.CardType.EffectSummon:
                break;

            default:
                Logger.Warn($"Card Type {Type} not defined!");
                break;
            }
        }