Inheritance: OpenNos.Data.MapMonsterDTO
Ejemplo n.º 1
0
        internal int SummonMonster(MonsterToSummon summon)
        {
            NpcMonster npcmonster = ServerManager.GetNpcMonster(summon.VNum);

            if (npcmonster != null)
            {
                MapMonster mapMonster = new MapMonster
                {
                    MonsterVNum    = npcmonster.NpcMonsterVNum,
                    MapY           = summon.SpawnCell.Y,
                    MapX           = summon.SpawnCell.X,
                    MapId          = Map.MapId,
                    IsMoving       = summon.IsMoving,
                    MapMonsterId   = GetNextMonsterId(),
                    ShouldRespawn  = false,
                    Target         = summon.Target,
                    OnDeathEvents  = summon.DeathEvents,
                    OnNoticeEvents = summon.NoticingEvents,
                    IsTarget       = summon.IsTarget,
                    IsBonus        = summon.IsBonus,
                    IsBoss         = summon.IsBoss,
                    IsHostile      = summon.IsHostile
                };
                mapMonster.Initialize(this);
                AddMonster(mapMonster);
                Broadcast(mapMonster.GenerateIn());
                return(mapMonster.MapMonsterId);
            }
            return(default);
Ejemplo n.º 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)}");
                }
            });
        }
Ejemplo n.º 3
0
 public void LoadMonsters()
 {
     foreach (MapMonsterDTO monster in DAOFactory.MapMonsterDAO.LoadFromMap(Map.MapId).ToList())
     {
         MapMonster mo = monster as MapMonster;
         mo.Initialize(this);
         _monsters[mo.MapMonsterId] = mo;
         _mapMonsterIds.Add(mo.MapMonsterId);
     }
 }
Ejemplo n.º 4
0
 public void LoadMonsters()
 {
     Parallel.ForEach(DAOFactory.MapMonsterDAO.LoadFromMap(Map.MapId).ToList(), monster =>
     {
         MapMonster mapMonster = new MapMonster(monster);
         mapMonster.Initialize(this);
         int mapMonsterId             = mapMonster.MapMonsterId;
         _monsters[mapMonsterId]      = mapMonster;
         _mapMonsterIds[mapMonsterId] = mapMonsterId;
     });
 }
Ejemplo n.º 5
0
        public void LoadMonsters()
        {
            var partitioner = Partitioner.Create(DAOFactory.MapMonsterDAO.LoadFromMap(Map.MapId), EnumerablePartitionerOptions.None);

            Parallel.ForEach(partitioner, monster =>
            {
                MapMonster mapMonster = monster as MapMonster;
                mapMonster.Initialize(this);
                int mapMonsterId        = mapMonster.MapMonsterId;
                _monsters[mapMonsterId] = mapMonster;
                _mapMonsterIds.Add(mapMonsterId);
            });
        }
Ejemplo n.º 6
0
        public void DespawnMonster(MapMonster monster)
        {
            if (monster == null)
            {
                return;
            }

            monster.IsAlive   = false;
            monster.LastMove  = DateTime.UtcNow;
            monster.CurrentHp = 0;
            monster.CurrentMp = 0;
            monster.Death     = DateTime.UtcNow;
            Broadcast(StaticPacketHelper.Out(UserType.Monster, monster.MapMonsterId));
        }
Ejemplo n.º 7
0
        public void ThrowItems(Tuple <int, short, byte, int, int> parameter)
        {
            MapMonster mon     = Monsters.FirstOrDefault(s => s.MapMonsterId == parameter.Item1);
            short      originX = mon.MapX;
            short      originY = mon.MapY;
            short      destX;
            short      destY;
            int        amount = ServerManager.Instance.RandomNumber(parameter.Item4, parameter.Item5);

            for (int i = 0; i < parameter.Item3; i++)
            {
                destX = (short)(originX + ServerManager.Instance.RandomNumber(-10, 10));
                destY = (short)(originY + ServerManager.Instance.RandomNumber(-10, 10));
                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)}");
            }
        }
Ejemplo n.º 8
0
        public void AddBuff(short buffId, BattleEntity sender = null)
        {
            if (sender?.EntityType == EntityType.Player &&
                sender.Session?.Character is Character senderCharacter)
            {
                Buff buff = new Buff(buffId, senderCharacter.Level, senderCharacter);

                switch (EntityType)
                {
                case EntityType.Player:
                    Session.Character.AddBuff(buff);
                    break;

                case EntityType.Monster:
                    MapMonster?.AddBuff(buff);
                    break;
                }
            }
        }
Ejemplo n.º 9
0
        internal List <int> SummonMonsters(List <MonsterToSummon> summonParameters)
        {
            List <int> ids = new List <int>();

            foreach (MonsterToSummon mon in summonParameters)
            {
                NpcMonster npcmonster = ServerManager.Instance.GetNpc(mon.VNum);
                if (npcmonster != null)
                {
                    MapMonster monster = new MapMonster {
                        MonsterVNum = npcmonster.NpcMonsterVNum, MapY = mon.SpawnCell.X, MapX = mon.SpawnCell.Y, MapId = Map.MapId, IsMoving = mon.IsMoving, MapMonsterId = GetNextMonsterId(), ShouldRespawn = false, Target = mon.Target, OnDeathEvents = mon.DeathEvents, IsTarget = mon.IsTarget, IsBonus = mon.IsBonus
                    };
                    monster.Initialize(this);
                    monster.IsHostile = mon.IsHostile;
                    AddMonster(monster);
                    Broadcast(monster.GenerateIn());
                    ids.Add(monster.MapMonsterId);
                }
            }

            return(ids);
        }
Ejemplo n.º 10
0
        internal int SummonMonster(MonsterToSummon monsterToSummon)
        {
            NpcMonster npcMonster = ServerManager.GetNpc(monsterToSummon.VNum);

            if (npcMonster != null)
            {
                MapMonster mapMonster = new MapMonster
                {
                    Owner          = monsterToSummon.Owner,
                    AliveTime      = monsterToSummon.AliveTime,
                    IsKamikaze     = monsterToSummon.IsKamikaze,
                    MonsterVNum    = npcMonster.NpcMonsterVNum,
                    MapX           = monsterToSummon.SpawnCell.X,
                    MapY           = monsterToSummon.SpawnCell.Y,
                    MapId          = Map.MapId,
                    IsMoving       = monsterToSummon.IsMoving,
                    MapMonsterId   = GetNextMonsterId(),
                    ShouldRespawn  = false,
                    Target         = monsterToSummon.Target,
                    OnDeathEvents  = monsterToSummon.DeathEvents,
                    OnNoticeEvents = monsterToSummon.NoticingEvents,
                    IsTarget       = monsterToSummon.IsTarget,
                    IsBonus        = monsterToSummon.IsBonus,
                    IsBoss         = monsterToSummon.IsBoss,
                    NoticeRange    = monsterToSummon.NoticeRange
                };

                mapMonster.Initialize(this);
                mapMonster.IsHostile = monsterToSummon.IsHostile;
                mapMonster.Faction   = monsterToSummon.Faction;
                AddMonster(mapMonster);
                Broadcast(mapMonster.GenerateIn());

                return(mapMonster.MapMonsterId);
            }

            return(0);
        }
Ejemplo n.º 11
0
        public BattleEntity(MapMonster monster)
        {
            HpMax = monster.Monster.MaxHP;
            MpMax = monster.Monster.MaxMP;

            Buffs               = monster.Buff.GetAllItems();
            BCards              = monster.Monster.BCards.ToList();
            Level               = monster.Monster.Level;
            EntityType          = EntityType.Monster;
            MapMonster          = monster;
            DamageMinimum       = 0;
            DamageMaximum       = 0;
            WeaponDamageMinimum = monster.Monster.DamageMinimum;
            WeaponDamageMaximum = monster.Monster.DamageMaximum;
            Hitrate             = monster.Monster.Concentrate;
            CritChance          = monster.Monster.CriticalChance;
            CritRate            = monster.Monster.CriticalRate;
            Morale              = monster.Monster.Level;
            AttackUpgrade       = monster.Monster.AttackUpgrade;
            FireResistance      = monster.Monster.FireResistance;
            WaterResistance     = monster.Monster.WaterResistance;
            LightResistance     = monster.Monster.LightResistance;
            ShadowResistance    = monster.Monster.DarkResistance;
            PositionX           = monster.MapX;
            PositionY           = monster.MapY;
            AttackType          = (AttackType)monster.Monster.AttackClass;
            DefenseUpgrade      = monster.Monster.DefenceUpgrade;
            MeleeDefense        = monster.Monster.CloseDefence;
            MeleeDefenseDodge   = monster.Monster.DefenceDodge;
            RangeDefense        = monster.Monster.DistanceDefence;
            RangeDefenseDodge   = monster.Monster.DistanceDefenceDodge;
            MagicalDefense      = monster.Monster.MagicDefence;
            ArmorMeleeDefense   = monster.Monster.CloseDefence;
            ArmorRangeDefense   = monster.Monster.DistanceDefence;
            ArmorMagicalDefense = monster.Monster.MagicDefence;
            Element             = monster.Monster.Element;
            ElementRate         = monster.Monster.ElementRate;
        }
Ejemplo n.º 12
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();
                        }
                    }
                }
            }
        }
Ejemplo n.º 13
0
        public override void Use(ClientSession session, ref ItemInstance inv, byte option = 0, string[] packetsplit = null)
        {
            inv.Item.BCards.ForEach(c => c.ApplyBCards(session.Character));

            switch (Effect)
            {
            case 0:
                switch (VNum)
                {
                case 1428:
                    session.SendPacket("guri 18 1");
                    break;

                case 1429:
                    session.SendPacket("guri 18 0");
                    break;

                case 1430:
                    if (packetsplit == null)
                    {
                        return;
                    }

                    if (packetsplit.Length < 9)
                    {
                        // MODIFIED PACKET
                        return;
                    }

                    if (!short.TryParse(packetsplit[9], out short eqSlot) || !Enum.TryParse(packetsplit[8], out InventoryType eqType))
                    {
                        return;
                    }
                    WearableInstance eq = session.Character.Inventory.LoadBySlotAndType <WearableInstance>(eqSlot, eqType);
                    if (eq == null)
                    {
                        // PACKET MODIFIED
                        return;
                    }
                    if (eq.Item.ItemType != ItemType.Armor && eq.Item.ItemType != ItemType.Weapon)
                    {
                        return;
                    }
                    eq.EquipmentOptions.Clear();
                    eq.ShellRarity = null;
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("SHELL_ERASED"), 0));
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateGuri(17, 1, session.Character.CharacterId));
                    break;

                case 1904:
                    short[] items = { 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1972, 1973 };
                    for (int i = 0; i < 5; i++)
                    {
                        session.Character.GiftAdd(items[ServerManager.Instance.RandomNumber(0, items.Length)], 1);
                    }
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    break;

                case 5916:
                    session.Character.AddStaticBuff(new StaticBuffDTO
                    {
                        CardId        = 340,
                        CharacterId   = session.Character.CharacterId,
                        RemainingTime = 7200
                    });
                    session.Character.RemoveBuff(339);
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    break;

                case 5929:
                    session.Character.AddStaticBuff(new StaticBuffDTO
                    {
                        CardId        = 340,
                        CharacterId   = session.Character.CharacterId,
                        RemainingTime = 600
                    });
                    session.Character.RemoveBuff(339);
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    break;

                default:
                    IEnumerable <RollGeneratedItemDTO> roll = DAOFactory.RollGeneratedItemDAO.Where(s => s.OriginalItemVNum == VNum);
                    IEnumerable <RollGeneratedItemDTO> rollGeneratedItemDtos = roll as IList <RollGeneratedItemDTO> ?? roll.ToList();
                    if (!rollGeneratedItemDtos.Any())
                    {
                        return;
                    }
                    int probabilities = rollGeneratedItemDtos.Sum(s => s.Probability);
                    int rnd           = ServerManager.Instance.RandomNumber(0, probabilities);
                    int currentrnd    = 0;
                    foreach (RollGeneratedItemDTO rollitem in rollGeneratedItemDtos)
                    {
                        if (rollitem.Probability == 10000)
                        {
                            session.Character.GiftAdd(rollitem.ItemGeneratedVNum, rollitem.ItemGeneratedAmount);
                            continue;
                        }
                        currentrnd += rollitem.Probability;
                        if (currentrnd < rnd)
                        {
                            continue;
                        }
                        if (rollitem.IsSuperReward)
                        {
                            CommunicationServiceClient.Instance.SendMessageToCharacter(new SCSCharacterMessage
                            {
                                DestinationCharacterId = null,
                                SourceCharacterId      = session.Character.CharacterId,
                                SourceWorldId          = ServerManager.Instance.WorldId,
                                Message = Language.Instance.GetMessageFromKey("SUPER_REWARD"),
                                Type    = MessageType.Shout
                            });
                        }
                        session.Character.GiftAdd(rollitem.ItemGeneratedVNum, rollitem.ItemGeneratedAmount, 0, rollitem.ItemGeneratedUpgrade);
                        break;
                    }
                    session.Character.Inventory.RemoveItemAmount(VNum);
                    break;
                }
                break;

            // sp point potions
            case 150:
            case 151:
                session.Character.SpAdditionPoint += EffectValue;
                if (session.Character.SpAdditionPoint > 1000000)
                {
                    session.Character.SpAdditionPoint = 1000000;
                }
                session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("SP_POINTSADDED"), EffectValue), 0));
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                session.SendPacket(session.Character.GenerateSpPoint());
                break;

            case 204:
                session.Character.SpPoint         += EffectValue;
                session.Character.SpAdditionPoint += EffectValue * 3;
                if (session.Character.SpAdditionPoint > 1000000)
                {
                    session.Character.SpAdditionPoint = 1000000;
                }
                if (session.Character.SpPoint > 10000)
                {
                    session.Character.SpPoint = 10000;
                }
                session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("SP_POINTSADDEDBOTH"), EffectValue, EffectValue * 3), 0));
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                session.SendPacket(session.Character.GenerateSpPoint());
                break;

            case 250:
                if (session.Character.Buff.Any(s => s.Card.CardId == 131))
                {
                    //TODO ADD MESSAGE ALREADY GOT BUFF
                    return;
                }
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                session.Character.AddStaticBuff(new StaticBuffDTO {
                    CardId = 131
                });
                session.CurrentMapInstance.Broadcast(session.Character.GeneratePairy());
                session.SendPacket(session.Character.GeneratePairy());
                break;

            case 208:
                if (session.Character.Buff.Any(s => s.Card.CardId == 121))
                {
                    //TODO ADD MESSAGE ALREADY GOT BUFF
                    return;
                }
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                session.Character.AddStaticBuff(new StaticBuffDTO {
                    CardId = 121, CharacterId = session.Character.CharacterId, RemainingTime = 3600
                });
                break;

            case 301:
                if (ServerManager.Instance.IsCharacterMemberOfGroup(session.Character.CharacterId))
                {
                    //TODO you are in group
                    return;
                }
                ItemInstance raidSeal = session.Character.Inventory.LoadBySlotAndType <ItemInstance>(inv.Slot, InventoryType.Main);

                ScriptedInstance raid = ServerManager.Instance.Raids.FirstOrDefault(s => s.RequieredItems.Any(obj => obj.VNum == raidSeal.ItemVNum))?.GetClone();
                if (raid != null)
                {
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, raidSeal.Id);
                    Group group = new Group(GroupType.Team);
                    group.Raid = raid;
                    group.JoinGroup(session.Character.CharacterId);
                    ServerManager.Instance.AddGroup(group);
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("YOU_ARE_RAID_CHIEF"), session.Character.Name), 0));
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("YOU_ARE_RAID_CHIEF"), session.Character.Name), 10));
                    if (session.Character.Level > raid.LevelMaximum || session.Character.Level < raid.LevelMinimum)
                    {
                        session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("RAID_LEVEL_INCORRECT"), 10));
                    }
                    session.SendPacket(session.Character.GenerateRaid(2, false));
                    session.SendPacket(session.Character.GenerateRaid(0, false));
                    session.SendPacket(session.Character.GenerateRaid(1, false));
                    session.SendPacket(group.GenerateRdlst());
                }
                break;

            case 305:
                if (packetsplit == null || packetsplit.Length < 3)
                {
                    return;
                }
                Mate mate = session.Character.Mates.FirstOrDefault(s => s.MateTransportId == int.Parse(packetsplit[3]));
                if (mate != null && EffectValue == mate.NpcMonsterVNum && mate.Skin == 0)
                {
                    mate.Skin = Morph;
                    session.SendPacket(mate.GenerateCMode(mate.Skin));
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                }
                break;

            //Atk/Def/HP/Exp potions
            case 6600:
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                break;

            // Divorce letter
            case 6969:     // this is imaginary number I = √(-1)
                CharacterRelationDTO rel = session.Character.CharacterRelations.FirstOrDefault(s => s.RelationType == CharacterRelationType.Spouse);
                if (rel != null)
                {
                    session.Character.DeleteRelation(rel.CharacterId == session.Character.CharacterId ? rel.RelatedCharacterId : rel.CharacterId);
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateInfo(Language.Instance.GetMessageFromKey("DIVORCED")));
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                }
                break;

            // Cupid's arrow
            case 34:     // this is imaginary number I = √(-1)
                if (packetsplit != null && packetsplit.Length > 3)
                {
                    if (long.TryParse(packetsplit[3], out long characterId))
                    {
                        if (session.Character.CharacterRelations.Any(s => s.RelationType == CharacterRelationType.Spouse))
                        {
                            session.SendPacket($"info {Language.Instance.GetMessageFromKey("ALREADY_MARRIED")}");
                            return;
                        }
                        if (session.Character.IsFriendOfCharacter(characterId))
                        {
                            ClientSession otherSession = ServerManager.Instance.GetSessionByCharacterId(characterId);
                            if (otherSession != null)
                            {
                                otherSession.SendPacket(UserInterfaceHelper.Instance.GenerateDialog(
                                                            $"#fins^-34^{session.Character.CharacterId} #fins^-69^{session.Character.CharacterId} {string.Format(Language.Instance.GetMessageFromKey("MARRY_REQUEST"), session.Character.Name)}"));
                                session.Character.FriendRequestCharacters.Add(characterId);
                                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                            }
                        }
                        else
                        {
                            session.SendPacket($"info {Language.Instance.GetMessageFromKey("NOT_FRIEND")}");
                        }
                    }
                }
                break;

            case 570:
                if (session.Character.Faction == (FactionType)EffectValue)
                {
                    return;
                }
                session.SendPacket(session.Character.Family == null
                        ? $"qna #guri^750^{EffectValue} {Language.Instance.GetMessageFromKey($"ASK_CHANGE_FACTION{EffectValue}")}"
                        : UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("IN_FAMILY"), 0));
                break;

            // wings
            case 650:
                if (session.Character.UseSp && session.Character.SpInstance != null)
                {
                    if (option == 0)
                    {
                        session.SendPacket($"qna #u_i^1^{session.Character.CharacterId}^{(byte) inv.Type}^{inv.Slot}^3 {Language.Instance.GetMessageFromKey("ASK_WINGS_CHANGE")}");
                    }
                    else
                    {
                        session.Character.SpInstance.Design = (byte)EffectValue;
                        session.Character.MorphUpgrade2     = EffectValue;
                        session.CurrentMapInstance?.Broadcast(session.Character.GenerateCMode());
                        session.SendPacket(session.Character.GenerateStat());
                        session.SendPacket(session.Character.GenerateStatChar());
                        session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    }
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("NO_SP"), 0));
                }
                break;

            // presentation messages
            case 203:
                if (!session.Character.IsVehicled)
                {
                    if (option == 0)
                    {
                        session.SendPacket(UserInterfaceHelper.Instance.GenerateGuri(10, 2, session.Character.CharacterId, 1));
                    }
                }
                break;

            // magic lamps
            case 651:
                if (session.Character.Inventory.All(i => i.Value.Type != InventoryType.Wear))
                {
                    if (option == 0)
                    {
                        session.SendPacket($"qna #u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^3 {Language.Instance.GetMessageFromKey("ASK_USE")}");
                    }
                    else
                    {
                        session.Character.ChangeSex();
                        session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    }
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("EQ_NOT_EMPTY"), 0));
                }
                break;

            // vehicles
            case 1000:
                if (session.Character.HasShopOpened)
                {
                    return;
                }
                if (Morph > 0)
                {
                    if (option == 0 && !session.Character.IsVehicled)
                    {
                        if (session.Character.IsSitting)
                        {
                            session.Character.IsSitting = false;
                            session.CurrentMapInstance?.Broadcast(session.Character.GenerateRest());
                        }
                        session.Character.LastDelay = DateTime.Now;
                        session.SendPacket(UserInterfaceHelper.Instance.GenerateDelay(3000, 3, $"#u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^2"));
                    }
                    else
                    {
                        if (!session.Character.IsVehicled && option != 0)
                        {
                            DateTime delay = DateTime.Now.AddSeconds(-4);
                            if (session.Character.LastDelay > delay && session.Character.LastDelay < delay.AddSeconds(2))
                            {
                                session.Character.Speed         = Speed;
                                session.Character.IsVehicled    = true;
                                session.Character.VehicleSpeed  = Speed;
                                session.Character.MorphUpgrade  = 0;
                                session.Character.MorphUpgrade2 = 0;
                                session.Character.Morph         = Morph + (byte)session.Character.Gender;
                                session.Character.Mates?.ForEach(x => session.CurrentMapInstance?.Broadcast(x.GenerateOut()));
                                session.CurrentMapInstance?.Broadcast(session.Character.GenerateEff(196), session.Character.MapX, session.Character.MapY);
                                session.CurrentMapInstance?.Broadcast(session.Character.GenerateCMode());
                                session.SendPacket(session.Character.GenerateCond());
                                session.Character.LastSpeedChange = DateTime.Now;
                            }
                        }
                        else if (session.Character.IsVehicled)
                        {
                            session.Character.Mates?.ForEach(x =>
                            {
                                x.PositionX = session.Character.PositionX;
                                x.PositionY = session.Character.PositionY;
                                session.CurrentMapInstance?.Broadcast(x.GenerateIn());
                            });
                            session.Character.RemoveVehicle();
                        }
                    }
                }
                break;

            case 1002:
                // TODO REVIEW THIS

                /*
                 * if (EffectValue == 69)
                 * {
                 *  int rnd = ServerManager.Instance.RandomNumber(0, 1000);
                 *  if (rnd < 5)
                 *  {
                 *      short[] vnums =
                 *      {
                 *          5560, 5591, 4099, 907, 1160, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714,
                 *          4715, 4716
                 *      };
                 *      byte[] counts = {1, 1, 1, 1, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
                 *      int item = ServerManager.Instance.RandomNumber(0, 17);
                 *
                 *      session.Character.GiftAdd(vnums[item], counts[item]);
                 *  }
                 *  else if (rnd < 30)
                 *  {
                 *      short[] vnums = {361, 362, 363, 366, 367, 368, 371, 372, 373};
                 *      session.Character.GiftAdd(vnums[ServerManager.Instance.RandomNumber(0, 9)], 1);
                 *  }
                 *  else
                 *  {
                 *      short[] vnums =
                 *      {
                 *          1161, 2282, 1030, 1244, 1218, 5369, 1012, 1363, 1364, 2160, 2173, 5959, 5983, 2514,
                 *          2515, 2516, 2517, 2518, 2519, 2520, 2521, 1685, 1686, 5087, 5203, 2418, 2310, 2303,
                 *          2169, 2280, 5892, 5893, 5894, 5895, 5896, 5897, 5898, 5899, 5332, 5105, 2161, 2162
                 *      };
                 *      byte[] counts =
                 *      {
                 *          10, 10, 20, 5, 1, 1, 99, 1, 1, 5, 5, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 5, 20,
                 *          20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
                 *      };
                 *      int item = ServerManager.Instance.RandomNumber(0, 42);
                 *      session.Character.GiftAdd(vnums[item], counts[item]);
                 *  }
                 *  session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                 * }
                 */
                if (session.HasCurrentMapInstance)
                {
                    if (session.CurrentMapInstance.Map.MapTypes.All(m => m.MapTypeId != (short)MapTypeEnum.Act4))
                    {
                        short[] vnums =
                        {
                            1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399,
                            1400, 1401, 1402, 1403, 1404, 1405
                        };
                        short vnum = vnums[ServerManager.Instance.RandomNumber(0, 20)];

                        NpcMonster npcmonster = ServerManager.Instance.GetNpc(vnum);
                        if (npcmonster == null)
                        {
                            return;
                        }
                        MapMonster monster = new MapMonster
                        {
                            MonsterVNum   = vnum,
                            MapY          = session.Character.MapY,
                            MapX          = session.Character.MapX,
                            MapId         = session.Character.MapInstance.Map.MapId,
                            Position      = (byte)session.Character.Direction,
                            IsMoving      = true,
                            MapMonsterId  = session.CurrentMapInstance.GetNextMonsterId(),
                            ShouldRespawn = false
                        };
                        monster.Initialize(session.CurrentMapInstance);
                        session.CurrentMapInstance.AddMonster(monster);
                        session.CurrentMapInstance.Broadcast(monster.GenerateIn());
                        session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    }
                }
                break;

            case 69:
                session.Character.GetReput(ReputPrice);
                session.SendPacket(session.Character.GenerateFd());
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                break;

            case 789:
                session.Character.GiftAdd((short)inv.Item.EffectValue, 1);
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                break;

            case 790:
                break;

            case 1003:
                if (!session.Character.StaticBonusList.Any(s => s.StaticBonusType == StaticBonusType.BazaarMedalGold || s.StaticBonusType == StaticBonusType.BazaarMedalSilver))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.BazaarMedalGold
                    });
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            case 1004:
                if (!session.Character.StaticBonusList.Any(s => s.StaticBonusType == StaticBonusType.BazaarMedalGold || s.StaticBonusType == StaticBonusType.BazaarMedalGold))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.BazaarMedalSilver
                    });
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            case 1005:
                if (session.Character.StaticBonusList.All(s => s.StaticBonusType != StaticBonusType.BackPack))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.BackPack
                    });
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    session.SendPacket(session.Character.GenerateExts());
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            case 1006:
                if (option == 0)
                {
                    session.SendPacket($"qna #u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^2 {Language.Instance.GetMessageFromKey("ASK_PET_MAX")}");
                }
                else
                {
                    if (session.Character.MaxMateCount < 30)
                    {
                        session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("GET_PET_PLACES"), 10));
                        session.SendPacket(session.Character.GenerateScpStc());
                        session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    }
                }
                break;

            case 1007:
                if (session.Character.StaticBonusList.All(s => s.StaticBonusType != StaticBonusType.PetBasket))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.PetBasket
                    });
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    session.SendPacket(session.Character.GenerateExts());
                    session.SendPacket("ib 1278 1");
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            case 1008:
                if (session.Character.StaticBonusList.All(s => s.StaticBonusType != StaticBonusType.PetBackPack))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.PetBackPack
                    });
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    session.SendPacket(session.Character.GenerateExts());
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            default:
                Logger.Log.Warn(string.Format(Language.Instance.GetMessageFromKey("NO_HANDLER_ITEM"), GetType()));
                break;
            }
        }
Ejemplo n.º 14
0
        internal int SummonMonster(MonsterToSummon summon)
        {
            NpcMonster npcMonster = ServerManager.GetNpcMonster(summon.VNum);

            if (npcMonster != null)
            {
                short mapX = summon.SpawnCell.X;
                short mapY = summon.SpawnCell.Y;

                if (mapX == 0 && mapY == 0)
                {
                    MapCell cell = Map.GetRandomPosition();

                    if (cell != null)
                    {
                        mapX = cell.X;
                        mapY = cell.Y;
                    }
                }

                MapMonster mapMonster = new MapMonster
                {
                    MonsterVNum      = npcMonster.NpcMonsterVNum,
                    MapX             = mapX,
                    MapY             = mapY,
                    Position         = 2,
                    MapId            = Map.MapId,
                    IsMoving         = summon.IsMoving,
                    MapMonsterId     = GetNextMonsterId(),
                    ShouldRespawn    = false,
                    OnNoticeEvents   = summon.NoticingEvents,
                    UseSkillOnDamage = summon.UseSkillOnDamage,
                    OnSpawnEvents    = summon.SpawnEvents,
                    IsTarget         = summon.IsTarget,
                    Target           = summon.Target,
                    IsBonus          = summon.IsBonus,
                    IsBoss           = summon.IsBoss,
                    NoticeRange      = summon.NoticeRange,
                    Owner            = summon.Owner,
                    AliveTime        = summon.AliveTime,
                    AliveTimeMp      = summon.AliveTimeMp,
                    BaseMaxHp        = summon.MaxHp,
                    BaseMaxMp        = summon.MaxMp
                };

                if (summon.HasDelay > 0)
                {
                    AddDelayedMonster(mapMonster);
                }

                Observable.Timer(TimeSpan.FromSeconds(summon.HasDelay))
                .Subscribe(o =>
                {
                    mapMonster.Initialize(this);
                    mapMonster.BattleEntity.OnDeathEvents.AddRange(summon.DeathEvents);
                    mapMonster.IsHostile = summon.IsHostile;

                    AddMonster(mapMonster);
                    Broadcast(mapMonster.GenerateIn());
                    RemoveDelayedMonster(mapMonster);

                    if (summon.AfterSpawnEvents.Any())
                    {
                        summon.AfterSpawnEvents.ForEach(e => EventHelper.Instance.RunEvent(e, monster: mapMonster));
                    }

                    if (summon.IsMeteorite)
                    {
                        OnMeteoriteEvents(summon, mapMonster);
                    }
                });

                return(mapMonster.MapMonsterId);
            }

            return(default);
Ejemplo n.º 15
0
 public void DespawnMonster(MapMonster monster)
 {
     monster.SetDeathStatement();
     Broadcast(StaticPacketHelper.Out(UserType.Monster, monster.MapMonsterId));
 }
Ejemplo n.º 16
0
        /// <summary>
        /// $Summon Command
        /// </summary>
        /// <param name="summonPacket"></param>
        public void Summon(SummonPacket summonPacket)
        {
            Logger.Debug("Summon Command", Session.SessionId);
            if (summonPacket != null)
            {
                if (Session.IsOnMap && Session.HasCurrentMap)
                {
                    Random random = new Random();

                    short vnum = summonPacket.NpcMonsterVNum;
                    byte amount = summonPacket.Amount;
                    bool isMoving = summonPacket.IsMoving;

                    NpcMonster npcmonster = ServerManager.GetNpc(vnum);
                    if (npcmonster == null)
                    {
                        return;
                    }
                    for (int i = 0; i < amount; i++)
                    {
                        List<MapCell> Possibilities = new List<MapCell>();
                        for (short x = -4; x < 5; x++)
                        {
                            for (short y = -4; y < 5; y++)
                            {
                                Possibilities.Add(new MapCell() { X = x, Y = y });
                            }
                        }
                        foreach (MapCell possibilitie in Possibilities.OrderBy(s => random.Next()))
                        {
                            short mapx = (short)(Session.Character.MapX + possibilitie.X);
                            short mapy = (short)(Session.Character.MapY + possibilitie.Y);
                            if (!Session.CurrentMap?.IsBlockedZone(mapx, mapy) ?? false)
                            {
                                break;
                            }
                        }

                        if (Session.HasCurrentMap)
                        {
                            // ReSharper disable once PossibleNullReferenceException HasCurrentMap NullCheck
                            MapMonster monster = new MapMonster { MonsterVNum = vnum, MapY = Session.Character.MapY, MapX = Session.Character.MapX, MapId = Session.Character.MapId, Position = (byte)Session.Character.Direction, IsMoving = isMoving, MapMonsterId = Session.CurrentMap.GetNextMonsterId(), ShouldRespawn = false };
                            monster.Initialize(Session.CurrentMap);
                            monster.StartLife();
                            Session.CurrentMap.AddMonster(monster);
                            Session.CurrentMap.Broadcast(monster.GenerateIn3());
                        }
                    }
                }
            }
            else
            {
                Session.SendPacket(Session.Character.GenerateSay("$Summon VNUM AMOUNT MOVE", 10));
            }
        }
Ejemplo n.º 17
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();
                        }
                    }
                }
            }
        }
Ejemplo n.º 18
0
        public override void Use(ClientSession session, ref ItemInstance inv, byte option = 0, string[] packetsplit = null)
        {
            if (packetsplit == null)
            {
                return;
            }

            void ReleasePet(MateType mateType, Guid itemToRemoveId)
            {
                if (!int.TryParse(packetsplit[3], out int mateTransportId))
                {
                    return;
                }

                Mate mate = session.Character.Mates.Find(s => s.MateTransportId == mateTransportId && s.MateType == mateType);

                if (mate == null)
                {
                    return;
                }

                if (mate.MateType == MateType.Partner)
                {
                    if (mate.SpInstance != null || mate.GlovesInstance != null || mate.BootsInstance != null || mate.WeaponInstance != null || mate.ArmorInstance != null)
                    {
                        session.SendPacket(UserInterfaceHelper.GenerateInfo(Language.Instance.GetMessageFromKey("MUST_REMOVE_PARTNER_EQUIPMENT")));
                        return;
                    }
                }

                if (!mate.IsTeamMember)
                {
                    session.Character.Mates.Remove(mate);
                    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));
                }
            }

            switch (Effect)
            {
            // loyalty & xp petfood
            case 10:
                if (int.TryParse(packetsplit[3], out var mateTransportId))
                {
                    Mate mate = session.Character.Mates.Find(s => s.MateTransportId == mateTransportId && s.MateType == MateType.Pet);

                    if (mate == null || mate.Loyalty >= 1000 || mate.MateType == MateType.Partner)
                    {
                        return;
                    }

                    mate.Loyalty = (short)(mate.Loyalty + 100 > 1000 ? 1000 : mate.Loyalty + 100);
                    mate.GenerateXp(EffectValue);
                    session.SendPacket(mate.GenerateScPacket());
                    mate.Owner?.Session.SendPacket(mate.GenerateCond());
                    mate.Owner?.Session.SendPacket(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5));
                    mate.Owner?.Session.SendPacket(StaticPacketHelper.GenerateEff(UserType.Npc, mate.MateTransportId, 5002));
                    mate.Owner?.Session.SendPacket(mate.Owner.GenerateSay(Language.Instance.GetMessageFromKey("MATE_EATS_FOOD"), 10));
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            case 11:
            case 12:
                if (int.TryParse(packetsplit[3], out mateTransportId))
                {
                    Mate mate = session.Character.Mates.Find(s => s.MateTransportId == mateTransportId && s.MateType == (Effect == 11 ? MateType.Pet : MateType.Partner));
                    AddPetLevel(ref mate, inv.Id);
                }
                break;

            case 13:
                if (int.TryParse(packetsplit[3], out mateTransportId) && session.Character.Mates.Any(s => s.MateTransportId == mateTransportId))
                {
                    session.SendPacket(UserInterfaceHelper.GenerateGuri(10, 1, mateTransportId, 2));
                }
                break;

            case 14:
                if (int.TryParse(packetsplit[3], out mateTransportId))
                {
                    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));
                        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);
                    }
                }
                break;

            case 16:
                if (int.TryParse(packetsplit[3], out mateTransportId))
                {
                    Mate mate = session.Character.Mates.Find(s => s.MateTransportId == mateTransportId && s.MateType == MateType.Pet);
                    RemovePetLevel(ref mate, 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 && s.MateType == MateType.Partner);
                    RemovePetLevel(ref mate, inv.Id);
                }
                break;

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

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

            // Pet trainer
            case 10000:
                if (session.Character.MapInstance != session.Character.Miniland)
                {
                    session.SendPacket(UserInterfaceHelper.GenerateModal(Language.Instance.GetMessageFromKey("NOT_IN_MINILAND"), 1));
                    return;
                }

                var monster = new MapMonster
                {
                    MonsterVNum   = (short)EffectValue,
                    MapY          = session.Character.PositionY,
                    MapX          = session.Character.PositionX,
                    MapId         = session.Character.MapInstance.Map.MapId,
                    Position      = session.Character.Direction,
                    IsMoving      = true,
                    IsHostile     = true,
                    MapMonsterId  = session.CurrentMapInstance.GetNextMonsterId(),
                    IsMateTrainer = true,
                    ShouldRespawn = false
                };

                monster.Initialize(session.CurrentMapInstance);
                session.CurrentMapInstance.AddMonster(monster);
                session.CurrentMapInstance.Broadcast(monster.GenerateIn());
                session.Character.Inventory.RemoveItemAmount(inv.ItemVNum);
                monster.GetNearestOponent();
                break;

            default:
                Logger.Warn(string.Format(Language.Instance.GetMessageFromKey("NO_HANDLER_ITEM"), GetType(), VNum, Effect, EffectValue));
                break;
            }
        }
Ejemplo n.º 19
0
        public ushort GenerateDamage(MapMonster monsterToAttack, Skill skill, ref int hitmode)
        {
            #region Definitions

            if (monsterToAttack == null)
            {
                return 0;
            }
            if (Inventory == null)
            {
                return 0;
            }

            Random random = new Random();

            // int miss_chance = 20;
            int monsterDefence = 0;
            int monsterDodge = 0;

            short mainUpgrade = 0;
            int mainCritChance = 0;
            int mainCritHit = 0;
            int mainMinDmg = 0;
            int mainMaxDmg = 0;
            int mainHitRate = 0;

            short secUpgrade = 0;
            int secCritChance = 0;
            int secCritHit = 0;
            int secMinDmg = 0;
            int secMaxDmg = 0;
            int secHitRate = 0;

            // int CritChance = 4; int CritHit = 70; int MinDmg = 0; int MaxDmg = 0; int HitRate = 0;
            // sbyte Upgrade = 0;
            #endregion

            #region Get Weapon Stats

            WearableInstance weapon = Inventory.LoadBySlotAndType<WearableInstance>((byte)EquipmentType.MainWeapon, InventoryType.Wear);
            if (weapon != null)
            {
                mainUpgrade = weapon.Upgrade;
            }

            mainMinDmg += MinHit;
            mainMaxDmg += MaxHit;
            mainHitRate += HitRate;
            mainCritChance += HitCriticalRate;
            mainCritHit += HitCritical;

            WearableInstance weapon2 = Inventory.LoadBySlotAndType<WearableInstance>((byte)EquipmentType.SecondaryWeapon, InventoryType.Wear);
            if (weapon2 != null)
            {
                secUpgrade = weapon2.Upgrade;
            }

            secMinDmg += MinDistance;
            secMaxDmg += MaxDistance;
            secHitRate += DistanceRate;
            secCritChance += DistanceCriticalRate;
            secCritHit += DistanceCritical;

            #endregion

            #region Switch skill.Type

            switch (skill.Type)
            {
                case 0:
                    monsterDefence = monsterToAttack.Monster.CloseDefence;
                    monsterDodge = monsterToAttack.Monster.DefenceDodge;
                    if (Class == ClassType.Archer)
                    {
                        mainCritHit = secCritHit;
                        mainCritChance = secCritChance;
                        mainHitRate = secHitRate;
                        mainMaxDmg = secMaxDmg;
                        mainMinDmg = secMinDmg;
                        mainUpgrade = secUpgrade;
                    }
                    break;

                case 1:
                    monsterDefence = monsterToAttack.Monster.DistanceDefence;
                    monsterDodge = monsterToAttack.Monster.DistanceDefenceDodge;
                    if (Class == ClassType.Swordman || Class == ClassType.Adventurer || Class == ClassType.Magician)
                    {
                        mainCritHit = secCritHit;
                        mainCritChance = secCritChance;
                        mainHitRate = secHitRate;
                        mainMaxDmg = secMaxDmg;
                        mainMinDmg = secMinDmg;
                        mainUpgrade = secUpgrade;
                    }
                    break;

                case 2:
                    monsterDefence = monsterToAttack.Monster.MagicDefence;
                    break;

                case 3:
                    switch (Class)
                    {
                        case ClassType.Swordman:
                            monsterDefence = monsterToAttack.Monster.CloseDefence;
                            break;

                        case ClassType.Archer:
                            monsterDefence = monsterToAttack.Monster.DistanceDefence;
                            break;

                        case ClassType.Magician:
                            monsterDefence = monsterToAttack.Monster.MagicDefence;
                            break;

                        case ClassType.Adventurer:
                            monsterDefence = monsterToAttack.Monster.CloseDefence;
                            break;
                    }
                    break;

                case 5:
                    monsterDefence = monsterToAttack.Monster.CloseDefence;
                    monsterDodge = monsterToAttack.Monster.DefenceDodge;
                    if (Class == ClassType.Archer)
                    {
                        mainCritHit = secCritHit;
                        mainCritChance = secCritChance;
                        mainHitRate = secHitRate;
                        mainMaxDmg = secMaxDmg;
                        mainMinDmg = secMinDmg;
                        mainUpgrade = secUpgrade;
                    }
                    break;
            }

            #endregion

            #region Basic Damage Data Calculation

            #warning TODO: Implement BCard damage boosts, see Issue

            mainUpgrade -= monsterToAttack.Monster.DefenceUpgrade;
            if (mainUpgrade < -10)
            {
                mainUpgrade = -10;
            }
            else if (mainUpgrade > 10)
            {
                mainUpgrade = 10;
            }

            #endregion

            #region Detailed Calculation

            #region Dodge

            if (Class != ClassType.Magician)
            {
                double multiplier = monsterDodge / (mainHitRate + 1);
                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 ((skill.Type == 0 || skill.Type == 1) && !HasGodMode)
                {
                    if (random.Next(0, 100) <= chance)
                    {
                        hitmode = 1;
                        return 0;
                    }
                }
            }

            #endregion

            #region Base Damage

            int baseDamage = new Random().Next(mainMinDmg, mainMaxDmg + 1);
            baseDamage += (skill.Damage / 4);
            baseDamage += Level - monsterToAttack.Monster.Level; //Morale
            if (Class == ClassType.Adventurer)
            {
                //HACK: Damage is ~10 lower in OpenNos than in official. Fix this...
                baseDamage += 20;
            }
            int elementalDamage = 0; // placeholder for BCard etc...
            elementalDamage += (skill.ElementalDamage / 4);
            switch (mainUpgrade)
            {
                case -10:
                    monsterDefence += monsterDefence * 2;
                    break;

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

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

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

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

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

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

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

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

                case -1:
                    monsterDefence += (int)(monsterDefence * 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;
            }
            if (skill.Type == 1)
            {
                if (Math.Abs(monsterToAttack.MapX - MapX) < 4 && Math.Abs(monsterToAttack.MapY - MapY) < 4)
                    baseDamage = (int)(baseDamage * 0.7);
            }

            #endregion

            #region Elementary Damage

            #region Calculate Elemental Boost + Rate

            double elementalBoost = 0;
            short monsterResistance = 0;
            switch (Element)
            {
                case 0:
                    break;

                case 1:
                    monsterResistance = monsterToAttack.Monster.FireResistance;
                    switch (monsterToAttack.Monster.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:
                    monsterResistance = monsterToAttack.Monster.WaterResistance;
                    switch (monsterToAttack.Monster.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:
                    monsterResistance = monsterToAttack.Monster.LightResistance;
                    switch (monsterToAttack.Monster.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:
                    monsterResistance = monsterToAttack.Monster.DarkResistance;
                    switch (monsterToAttack.Monster.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 (skill.Element == 0)
            {
                if (elementalBoost == 0.5)
                {
                    elementalBoost = 0;
                }
                else if (elementalBoost == 1)
                {
                    elementalBoost = 0.05;
                }
                else if (elementalBoost == 1.3)
                {
                    elementalBoost = 0.15;
                }
                else if (elementalBoost == 1.5)
                {
                    elementalBoost = 0.15;
                }
                else if (elementalBoost == 2)
                {
                    elementalBoost = 0.2;
                }
                else if (elementalBoost == 3)
                {
                    elementalBoost = 0.2;
                }
            }
            else if (skill.Element != Element)
            {
                elementalBoost = 0;
            }

            elementalDamage = (int)((elementalDamage + ((elementalDamage + baseDamage) * ((ElementRate + ElementRateSP) / 100D))) * elementalBoost);
            elementalDamage = elementalDamage / 100 * (100 - monsterResistance);

            #endregion

            #region Critical Damage

            baseDamage -= monsterDefence;

            if (random.Next(100) <= mainCritChance)
            {
                if (skill.Type == 2)
                {
                }
                else if (skill.Type == 3 && Class != ClassType.Magician)
                {
                    double multiplier = (mainCritHit / 100D);
                    if (multiplier > 3)
                        multiplier = 3;
                    baseDamage += (int)(baseDamage * multiplier);
                    hitmode = 3;
                }
                else
                {
                    double multiplier = (mainCritHit / 100D);
                    if (multiplier > 3)
                        multiplier = 3;
                    baseDamage += (int)(baseDamage * multiplier);
                    hitmode = 3;
                }
            }

            #endregion

            #region Total Damage

            int totalDamage = baseDamage + elementalDamage;
            if (totalDamage < 5)
            {
                totalDamage = random.Next(1, 6);
            }

            #endregion

            #endregion

            if (monsterToAttack.DamageList.ContainsKey(CharacterId))
            {
                monsterToAttack.DamageList[CharacterId] += totalDamage;
            }
            else
            {
                monsterToAttack.DamageList.Add(CharacterId, totalDamage);
            }
            if (monsterToAttack.CurrentHp <= totalDamage)
            {
                monsterToAttack.IsAlive = false;
                monsterToAttack.CurrentHp = 0;
                monsterToAttack.CurrentMp = 0;
                monsterToAttack.Death = DateTime.Now;
                monsterToAttack.LastMove = DateTime.Now;
            }
            else
            {
                monsterToAttack.CurrentHp -= totalDamage;
            }

            while (totalDamage > ushort.MaxValue)
            {
                totalDamage -= ushort.MaxValue;
            }
            // only set the hit delay if we become the monsters target with this hit
            if (monsterToAttack.Target != CharacterId)
            {
                monsterToAttack.LastEffect = DateTime.Now;
            }
            ushort damage = Convert.ToUInt16(totalDamage);
            if (monsterToAttack.IsMoving)
            {
                monsterToAttack.Target = CharacterId;
            }
            return damage;
        }
Ejemplo n.º 20
0
        public void GenerateKillBonus(MapMonster monsterToAttack)
        {
            if (monsterToAttack == null || monsterToAttack.IsAlive)
            {
                return;
            }

            Random random = new Random(DateTime.Now.Millisecond & monsterToAttack.MapMonsterId);

            // owner set
            long? dropOwner = monsterToAttack.DamageList.Any() ? monsterToAttack.DamageList.First().Key : (long?)null;
            Group group = null;
            if (dropOwner != null)
            {
                group = ServerManager.Instance.Groups.FirstOrDefault(g => g.IsMemberOfGroup((long)dropOwner));
            }

            // end owner set
            int i = 1;
            if (Session.HasCurrentMap)
            {
                List<DropDTO> droplist = monsterToAttack.Monster.Drops.Where(s => Session.CurrentMap.MapTypes.Any(m => m.MapTypeId == s.MapTypeId) || (s.MapTypeId == null)).ToList();
                if (monsterToAttack.Monster.MonsterType != MonsterType.Special)
                {
                    #region item drop

                    int dropRate = ServerManager.DropRate;
                    int x = 0;
                    foreach (DropDTO drop in droplist.OrderBy(s => random.Next()))
                    {
                        if (x < 4)
                        {
                            i++;
                            double rndamount = random.Next(0, 100) * random.NextDouble();
                            if (rndamount <= ((double)drop.DropChance * dropRate) / 5000.000)
                            {
                                x++;
                                if (Session.CurrentMap != null)
                                {
                                    if (Session.CurrentMap.MapTypes.Any(s => s.MapTypeId == (short)MapTypeEnum.Act4) || monsterToAttack.Monster.MonsterType == MonsterType.Elite)
                                    {
                                        List<long> alreadyGifted = new List<long>();
                                        foreach (long charId in monsterToAttack.DamageList.Keys)
                                        {
                                            if (!alreadyGifted.Contains(charId))
                                            {
                                                ClientSession giftsession = ServerManager.Instance.GetSessionByCharacterId(charId);
                                                giftsession?.Character.GiftAdd(drop.ItemVNum, (byte)drop.Amount);
                                                alreadyGifted.Add(charId);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (group != null)
                                        {
                                            if (group.SharingMode == (byte)GroupSharingType.ByOrder)
                                            {
                                                dropOwner = group.GetNextOrderedCharacterId(this);
                                                if (dropOwner.HasValue)
                                                {
                                                    group.Characters.ForEach(s => s.SendPacket(s.Character.GenerateSay(String.Format(Language.Instance.GetMessageFromKey("ITEM_BOUND_TO"), ServerManager.GetItem(drop.ItemVNum).Name, group.Characters.Single(c => c.Character.CharacterId == (long)dropOwner).Character.Name, drop.Amount), 10)));
                                                }
                                            }
                                            else
                                            {
                                                group.Characters.ForEach(s => s.SendPacket(s.Character.GenerateSay(String.Format(Language.Instance.GetMessageFromKey("DROPPED_ITEM"), ServerManager.GetItem(drop.ItemVNum).Name, drop.Amount), 10)));
                                            }
                                        }

                                        long? owner = dropOwner;
                                        Observable.Timer(TimeSpan.FromMilliseconds(500))
                                       .Subscribe(
                                       o =>
                                       {
                                           Session.CurrentMap.DropItemByMonster(owner, drop, monsterToAttack.MapX, monsterToAttack.MapY);
                                       });
                                    }
                                }
                            }
                        }
                    }

                    #endregion

                    #region gold drop

                    // gold calculation
                    int gold = GetGold(monsterToAttack);
                    gold = gold > 1000000000 ? 1000000000 : gold;
                    double randChance = random.Next(0, 100) * random.NextDouble();

                    if (gold > 0 && randChance <= (int)((ServerManager.GoldDropRate * 10) * CharacterHelper.GoldPenalty(Level, monsterToAttack.Monster.Level)))
                    {
                        DropDTO drop2 = new DropDTO()
                        {
                            Amount = gold,
                            ItemVNum = 1046
                        };
                        if (Session.CurrentMap != null)
                        {
                            if (Session.CurrentMap.MapTypes.Any(s => s.MapTypeId == (short)MapTypeEnum.Act4) || monsterToAttack.Monster.MonsterType == MonsterType.Elite)
                            {
                                List<long> alreadyGifted = new List<long>();
                                foreach (long charId in monsterToAttack.DamageList.Keys)
                                {
                                    if (!alreadyGifted.Contains(charId))
                                    {
                                        ClientSession session = ServerManager.Instance.GetSessionByCharacterId(charId);
                                        if (session != null)
                                        {
                                            session.Character.Gold += drop2.Amount;
                                            if (session.Character.Gold > 1000000000)
                                            {
                                                session.Character.Gold = 1000000000;
                                                session.SendPacket(session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("MAX_GOLD"), 0));
                                            }
                                            session.SendPacket(session.Character.GenerateSay($"{Language.Instance.GetMessageFromKey("ITEM_ACQUIRED")}: {ServerManager.GetItem(drop2.ItemVNum).Name} x {drop2.Amount}", 10));
                                            session.SendPacket(session.Character.GenerateGold());
                                        }
                                        alreadyGifted.Add(charId);
                                    }
                                }
                            }
                            else
                            {
                                if (group != null)
                                {
                                    if (group.SharingMode == (byte)GroupSharingType.ByOrder)
                                    {
                                        dropOwner = group.GetNextOrderedCharacterId(this);

                                        if (dropOwner.HasValue)
                                        {
                                            group.Characters.ForEach(s => s.SendPacket(s.Character.GenerateSay(String.Format(Language.Instance.GetMessageFromKey("ITEM_BOUND_TO"), ServerManager.GetItem(drop2.ItemVNum).Name, group.Characters.Single(c => c.Character.CharacterId == (long)dropOwner).Character.Name, drop2.Amount), 10)));
                                        }
                                    }
                                    else
                                    {
                                        group.Characters.ForEach(s => s.SendPacket(s.Character.GenerateSay(String.Format(Language.Instance.GetMessageFromKey("DROPPED_ITEM"), ServerManager.GetItem(drop2.ItemVNum).Name, drop2.Amount), 10)));
                                    }
                                }

                                // delayed Drop
                                Observable.Timer(TimeSpan.FromMilliseconds(500))
                                      .Subscribe(
                                      o =>
                                      {
                                          Session.CurrentMap.DropItemByMonster(dropOwner, drop2, monsterToAttack.MapX, monsterToAttack.MapY);
                                      });
                            }
                        }
                    }

                    #endregion

                    #region exp

                    if (Hp > 0)
                    {
                        Group grp = ServerManager.Instance.Groups.FirstOrDefault(g => g.IsMemberOfGroup(CharacterId));
                        if (grp != null)
                        {
                            foreach (ClientSession targetSession in grp.Characters.Where(g => g.Character.MapId == MapId))
                            {
                                if (grp.IsMemberOfGroup(monsterToAttack.DamageList.FirstOrDefault().Key))
                                {
                                    targetSession.Character.GenerateXp(monsterToAttack.Monster, true);
                                }
                                else
                                {
                                    targetSession.SendPacket(targetSession.Character.GenerateSay(Language.Instance.GetMessageFromKey("XP_NOTFIRSTHIT"), 10));
                                    targetSession.Character.GenerateXp(monsterToAttack.Monster, false);
                                }
                            }
                        }
                        else
                        {
                            if (monsterToAttack.DamageList.FirstOrDefault().Key == CharacterId)
                            {
                                GenerateXp(monsterToAttack.Monster, true);
                            }
                            else
                            {
                                Session.SendPacket(GenerateSay(Language.Instance.GetMessageFromKey("XP_NOTFIRSTHIT"), 10));
                                GenerateXp(monsterToAttack.Monster, false);
                            }
                        }
                        GenerateDignity(monsterToAttack.Monster);
                    }

                    #endregion
                }
            }
        }
Ejemplo n.º 21
0
        public override void Use(ClientSession session, ref ItemInstance inv, byte Option = 0, string[] packetsplit = null)
        {
            inv.Item.BCards.ForEach(c => c.ApplyBCards(session.Character));

            switch (Effect)
            {
            // Honour Medals
            case 69:
                session.Character.Reputation += ReputPrice;
                session.SendPacket(session.Character.GenerateFd());
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                break;

            // SP Potions
            case 150:
            case 151:
                session.Character.SpAdditionPoint += EffectValue;
                if (session.Character.SpAdditionPoint > 1000000)
                {
                    session.Character.SpAdditionPoint = 1000000;
                }
                session.SendPacket(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("SP_POINTSADDED"), EffectValue), 0));
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                session.SendPacket(session.Character.GenerateSpPoint());
                break;

            // Specialist Medal
            case 204:
                session.Character.SpPoint         += EffectValue;
                session.Character.SpAdditionPoint += EffectValue * 3;
                if (session.Character.SpAdditionPoint > 1000000)
                {
                    session.Character.SpAdditionPoint = 1000000;
                }
                if (session.Character.SpPoint > 10000)
                {
                    session.Character.SpPoint = 10000;
                }
                session.SendPacket(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("SP_POINTSADDEDBOTH"), EffectValue, EffectValue * 3), 0));
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                session.SendPacket(session.Character.GenerateSpPoint());
                break;

            // Raid Seals
            case 301:
                if (ServerManager.Instance.IsCharacterMemberOfGroup(session.Character.CharacterId))
                {
                    //TODO you are in group
                    return;
                }
                ItemInstance raidSeal = session.Character.Inventory.LoadBySlotAndType <ItemInstance>(inv.Slot, InventoryType.Main);
                session.Character.Inventory.RemoveItemFromInventory(raidSeal.Id);

                ScriptedInstance raid = ServerManager.Instance.Raids.FirstOrDefault(s => s.RequiredItems?.Any(obj => obj?.VNum == raidSeal.ItemVNum) == true)?.Copy();
                if (raid != null)
                {
                    Group group = new Group()
                    {
                        GroupType = GroupType.BigTeam,
                        Raid      = raid
                    };
                    group.JoinGroup(session.Character.CharacterId);
                    ServerManager.Instance.AddGroup(group);
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("RAID_LEADER"), session.Character.Name), 0));
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("RAID_LEADER"), session.Character.Name), 10));
                    if (session.Character.Level > raid.LevelMaximum || session.Character.Level < raid.LevelMinimum)
                    {
                        session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("RAID_LEVEL_INCORRECT"), 10));
                    }
                    session.SendPacket(session.Character.GenerateRaid(2, false));
                    session.SendPacket(session.Character.GenerateRaid(0, false));
                    session.SendPacket(session.Character.GenerateRaid(1, false));
                    session.SendPacket(group.GenerateRdlst());
                }
                break;

            case 1169:
            {
                if (session?.Character != null)
                {
                    if (session.Character.Miniland == session.Character.MapInstance)
                    {
                        ServerManager.Instance.JoinMiniland(session, session);
                    }
                    else
                    {
                        ServerManager.Shout($"GRACIAS POR USAR SERVICIOS HEAT!");
                        ServerManager.Instance.ChangeMapInstance(session.Character.CharacterId, session.Character.MapInstanceId, session.Character.PositionX, session.Character.PositionY);
                        session.SendPacket(StaticPacketHelper.Cancel(2));
                        session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    }
                }
            }
            break;

            case 1574:
                if (EffectValue == 1574)
                {
                    int rnd = ServerManager.RandomNumber(0, 1);
                    if (rnd < 1)
                    {
                        short[] vnums =
                        {
                            //ID's of the Items, you will get
                            4129, 4130, 4131, 4132
                        };
                        //This Code counts the Items, you inserted
                        byte[] counts = { 1, 1, 1, 1 };
                        int    item   = ServerManager.RandomNumber(0, 4);
                        session.Character.GiftAdd(vnums[item], counts[item]);
                    }
                    //This Code, deltes the Item from the Inventory
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.SendPacket("msg 5 Success! You recieved your Items.");
                }
                break;



            // Partner Suits/Skins
            case 305:
                Mate mate = session.Character.Mates.Find(s => s.MateTransportId == int.Parse(packetsplit[3]));
                if (mate != null && EffectValue == mate.NpcMonsterVNum && mate.Skin == 0)
                {
                    mate.Skin = Morph;
                    session.SendPacket(mate.GenerateCMode(mate.Skin));
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            // Fairy Booster
            case 250:
                if (!session.Character.Buff.ContainsKey(131))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 131
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 3011), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // Fairy booster 2
            case 253:
                if (!session.Character.Buff.ContainsKey(131))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 131
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 3011), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // exp/job booster
            case 251:
                if (!session.Character.Buff.ContainsKey(121))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 121
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 3011), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            //sp job booster
            case 1362:
                if (!session.Character.Buff.ContainsKey(146))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 146
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 3011), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // Ice oil
            case 252:
                if (!session.Character.Buff.ContainsKey(340))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 340
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 16), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // Valentin Buff
            case 254:
                if (!session.Character.Buff.ContainsKey(109))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 109
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 3410), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // Buff exp 20%
            case 256:
                if (!session.Character.Buff.ContainsKey(119))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 119
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 4756), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // Ancella fate
            case 258:
                if (!session.Character.Buff.ContainsKey(393))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 393
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 4756), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // Speedbooster
            case 260:
                if (!session.Character.IsVehicled || session.Character.Buff.Any(s => s.Card.CardId == 336))
                {
                    return;
                }
                session.CurrentMapInstance?.Broadcast(session.Character.GenerateEff(885), session.Character.MapX, session.Character.MapY);

                session.Character.Speed += 5;
                switch (session.Character.Morph)
                {
                case 2517:         // Nossi M
                case 2518:         // Nossi F
                case 2522:         // Roller M
                case 2523:         // Roller F
                                   // Removes <= lv 4 debuffs
                    List <BuffType> bufftodisable = new List <BuffType> {
                        BuffType.Bad
                    };
                    session.Character.DisableBuffs(bufftodisable, 4);
                    break;
                }
                Observable.Timer(TimeSpan.FromSeconds(session.Character.BuffRandomTime * 0.1D)).Subscribe(o =>
                {
                    session.Character.Speed -= 5;
                    session.Character.LoadSpeed();
                    switch (session.Character.Morph)
                    {
                    case 2526:         // White male unicorn
                    case 2527:         // White female unicorn
                    case 2528:         // Pink male unicorn
                    case 2529:         // Pink female unicorn
                    case 2530:         // Black male unicorn
                    case 2531:         // Black Female Unicorn
                    case 2928:         // Male UFO
                    case 2929:         // Female UFO
                    case 3679:         // Male squelettic dragon
                    case 3680:         // Female squelettic dragon
                        ServerManager.Instance.TeleportOnRandomPlaceInMap(session, session.Character.MapInstanceId, true);
                        break;

                    case 2432:         // Magic broom
                    case 2433:         // Magic broom F
                    case 2520:         // VTT M
                    case 2521:         // VTT F
                        switch (session.Character.Direction)
                        {
                        case 0:
                            // -y
                            ServerManager.Instance.TeleportForward(session, session.Character.MapInstanceId, session.Character.PositionX, (short)(session.Character.PositionY - 5));
                            break;

                        case 1:
                            // +x
                            ServerManager.Instance.TeleportForward(session, session.Character.MapInstanceId, (short)(session.Character.PositionX + 5), session.Character.PositionY);
                            break;

                        case 2:
                            // +y
                            ServerManager.Instance.TeleportForward(session, session.Character.MapInstanceId, session.Character.PositionX, (short)(session.Character.PositionY + 5));
                            break;

                        case 3:
                            // -x
                            ServerManager.Instance.TeleportForward(session, session.Character.MapInstanceId, (short)(session.Character.PositionX - 5), session.Character.PositionY);
                            break;

                        case 4:
                            ServerManager.Instance.TeleportForward(session, session.Character.MapInstanceId, (short)(session.Character.PositionX - 5), (short)(session.Character.PositionY - 5));
                            // -x -y
                            break;

                        case 5:
                            // +x +y
                            ServerManager.Instance.TeleportForward(session, session.Character.MapInstanceId, (short)(session.Character.PositionX - 5), (short)(session.Character.PositionY - 5));
                            break;

                        case 6:
                            // +x -y
                            ServerManager.Instance.TeleportForward(session, session.Character.MapInstanceId, (short)(session.Character.PositionX + 5), (short)(session.Character.PositionY + 5));
                            break;

                        case 7:
                            // -x +y
                            ServerManager.Instance.TeleportForward(session, session.Character.MapInstanceId, (short)(session.Character.PositionX - 5), (short)(session.Character.PositionY + 5));
                            break;
                        }
                        break;
                    }
                });
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                break;



            // Rainbow Pearl/Magic Eraser
            case 666:
                if (EffectValue == 1 && byte.TryParse(packetsplit[9], out byte islot))
                {
                    ItemInstance wearInstance = session.Character.Inventory.LoadBySlotAndType(islot, InventoryType.Equipment);

                    if (wearInstance != null && (wearInstance.Item.ItemType == ItemType.Weapon || wearInstance.Item.ItemType == ItemType.Armor) && wearInstance.ShellEffects.Count != 0 && wearInstance.Item.IsHeroic)
                    {
                        wearInstance.ShellEffects.Clear();
                        DAOFactory.ShellEffectDAO.DeleteByEquipmentSerialId(wearInstance.EquipmentSerialId);
                        if (wearInstance.EquipmentSerialId == Guid.Empty)
                        {
                            wearInstance.EquipmentSerialId = Guid.NewGuid();
                        }
                        session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                        session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("OPTION_DELETE"), 0));
                    }
                }
                else
                {
                    session.SendPacket("guri 18 0");
                }
                break;

            // Atk/Def/HP/Exp potions
            case 6600:
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                break;

            // Ancelloan's Blessing
            case 208:
                if (!session.Character.Buff.ContainsKey(121))
                {
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 121
                    });
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // Divorce letter
            case 6969:     // this is imaginary number I = √(-1)
                var rel = session.Character.CharacterRelations.FirstOrDefault(s => s.RelationType == CharacterRelationType.Spouse);
                if (rel != null)
                {
                    session.Character.DeleteRelation(rel.CharacterId == session.Character.CharacterId ? rel.RelatedCharacterId : rel.CharacterId);
                    session.SendPacket(UserInterfaceHelper.GenerateInfo(Language.Instance.GetMessageFromKey("DIVORCED")));

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

                break;

            // Cupid's arrow
            case 34:     // this is imaginary number I = √(-1)
                         // Cupid's arrow
                if (packetsplit != null && packetsplit.Length > 3)
                {
                    if (long.TryParse(packetsplit[3], out long characterId))
                    {
                        if (session.Character.CharacterRelations.Any(s => s.RelationType == CharacterRelationType.Spouse))
                        {
                            session.SendPacket($"info {Language.Instance.GetMessageFromKey("ALREADY_MARRIED")}");
                            return;
                        }
                        ClientSession otherSession = ServerManager.Instance.GetSessionByCharacterId(characterId);
                        if (otherSession != null)
                        {
                            otherSession.SendPacket(UserInterfaceHelper.GenerateDialog(
                                                        $"#fins^-34^{session.Character.CharacterId} #fins^-69^{session.Character.CharacterId} {string.Format(Language.Instance.GetMessageFromKey("MARRY_REQUEST"), session.Character.Name)}"));
                            session.Character.FriendRequestCharacters.Add(characterId);
                            session.Character.Inventory.RemoveItemFromInventory(inv.Id, 1);
                            session.Character.AddStaticBuff(new StaticBuffDTO {
                                CardId = 319
                            });
                        }
                    }
                }
                break;


            case 100:
            {
            }
            break;

            case 5836:
            {
                session.SendPacket($"gb 0 {session.Account.BankGold / 1000} {session.Character.Gold} 0 0");
                session.SendPacket($"s_memo 6 [Account balance]: {session.Account.BankGold} gold; [Owned]: {session.Character.Gold} gold\nWe will do our best. Thank you for using the services of Cuarry Bank.");
            }
            break;

            // Faction Egg
            case 570:
                if (session.Character.Faction == (FactionType)EffectValue)
                {
                    return;
                }
                if (EffectValue < 3)
                {
                    session.SendPacket(session.Character.Family == null
                            ? $"qna #guri^750^{EffectValue} {Language.Instance.GetMessageFromKey($"ASK_CHANGE_FACTION{EffectValue}")}"
                            : UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("IN_FAMILY"),
                                                              0));
                }
                else
                {
                    session.SendPacket(session.Character.Family != null
                            ? $"qna #guri^750^{EffectValue} {Language.Instance.GetMessageFromKey($"ASK_CHANGE_FACTION{EffectValue}")}"
                            : UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("NO_FAMILY"),
                                                              0));
                }

                break;

            // SP Wings
            case 650:
                ItemInstance specialistInstance = session.Character.Inventory.LoadBySlotAndType((byte)EquipmentType.Sp, InventoryType.Wear);
                if (session.Character.UseSp && specialistInstance != null)
                {
                    if (Option == 0)
                    {
                        session.SendPacket($"qna #u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^3 {Language.Instance.GetMessageFromKey("ASK_WINGS_CHANGE")}");
                    }
                    else
                    {
                        void disposeBuff(short vNum)
                        {
                            if (session.Character.BuffObservables.ContainsKey(vNum))
                            {
                                session.Character.BuffObservables[vNum].Dispose();
                                session.Character.BuffObservables.Remove(vNum);
                            }
                            session.Character.RemoveBuff(vNum);
                        }

                        disposeBuff(387);
                        disposeBuff(395);
                        disposeBuff(396);
                        disposeBuff(397);
                        disposeBuff(398);
                        disposeBuff(410);
                        disposeBuff(411);
                        disposeBuff(444);

                        specialistInstance.Design = (byte)EffectValue;

                        session.Character.MorphUpgrade2 = EffectValue;
                        session.CurrentMapInstance?.Broadcast(session.Character.GenerateCMode());
                        session.SendPacket(session.Character.GenerateStat());
                        session.SendPacket(session.Character.GenerateStatChar());
                        session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    }
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("NO_SP"), 0));
                }
                break;

            // Self-Introduction
            case 203:
                if (!session.Character.IsVehicled && Option == 0)
                {
                    session.SendPacket(UserInterfaceHelper.GenerateGuri(10, 2, session.Character.CharacterId, 1));
                }
                break;

            // Magic Lamp
            case 651:
                if (session.Character.Inventory.All(i => i.Type != InventoryType.Wear))
                {
                    if (Option == 0)
                    {
                        session.SendPacket($"qna #u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^3 {Language.Instance.GetMessageFromKey("ASK_USE")}");
                    }
                    else
                    {
                        session.Character.ChangeSex();
                        session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    }
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("EQ_NOT_EMPTY"), 0));
                }
                break;

            // Vehicles
            case 1000:
                if (EffectValue != 0 || ServerManager.Instance.ChannelId == 51 || session.CurrentMapInstance?.MapInstanceType == MapInstanceType.EventGameInstance)
                {
                    return;
                }

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

                if (Morph > 0)
                {
                    if (Option == 0 && !session.Character.IsVehicled)
                    {
                        if (session.Character.IsSitting)
                        {
                            session.Character.IsSitting = false;
                            session.CurrentMapInstance?.Broadcast(session.Character.GenerateRest());
                        }
                        session.Character.LastDelay = DateTime.Now;
                        session.SendPacket(UserInterfaceHelper.GenerateDelay(3000, 3, $"#u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^2"));
                    }
                    else
                    {
                        if (!session.Character.IsVehicled && Option != 0)
                        {
                            DateTime delay = DateTime.Now.AddSeconds(-4);
                            if (session.Character.LastDelay > delay && session.Character.LastDelay < delay.AddSeconds(2))
                            {
                                session.Character.Speed         = Speed;
                                session.Character.IsVehicled    = true;
                                session.Character.VehicleSpeed  = Speed;
                                session.Character.MorphUpgrade  = 0;
                                session.Character.MorphUpgrade2 = 0;
                                session.Character.Morph         = Morph + (byte)session.Character.Gender;
                                session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 4809), session.Character.MapX, session.Character.MapY);
                                session.CurrentMapInstance?.Broadcast(session.Character.GenerateCMode());
                                session.SendPacket(session.Character.GenerateCond());
                                session.Character.LastSpeedChange = DateTime.Now;
                            }
                        }
                        else if (session.Character.IsVehicled)
                        {
                            session.Character.Mates?.Where(s => s.IsTeamMember).ToList().ForEach(x =>
                            {
                                x.PositionX = session.Character.PositionX;
                                x.PositionY = session.Character.PositionY;
                                session.CurrentMapInstance?.Broadcast(x.GenerateIn());
                            });
                            session.Character.RemoveVehicle();
                        }
                    }
                }
                break;

            // Sealed Vessel
            case 1002:
                if (EffectValue == 69)
                {
                    int rnd = ServerManager.RandomNumber(0, 1000);
                    if (rnd < 5)
                    {
                        short[] vnums =
                        {
                            5560, 5591, 4099, 907, 1160, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714,
                            4715, 4716
                        };
                        byte[] counts = { 1, 1, 1, 1, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
                        int    item   = ServerManager.RandomNumber(0, 17);
                        session.Character.GiftAdd(vnums[item], counts[item]);
                    }
                    else if (rnd < 30)
                    {
                        short[] vnums = { 361, 362, 363, 366, 367, 368, 371, 372, 373 };
                        session.Character.GiftAdd(vnums[ServerManager.RandomNumber(0, 9)], 1);
                    }
                    else
                    {
                        short[] vnums =
                        {
                            1161, 2282, 1030, 1244, 1218, 5369, 1012, 1363, 1364, 2160, 2173, 5959, 5983, 2514,
                            2515, 2516, 2517, 2518, 2519, 2520, 2521, 1685, 1686, 5087, 5203, 2418, 2310, 2303,
                            2169, 2280, 5892, 5893, 5894, 5895, 5896, 5897, 5898, 5899, 5332, 5105, 2161, 2162
                        };
                        byte[] counts =
                        {
                            10, 10, 20, 5, 1, 1, 99, 1, 1, 5, 5, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 5, 20,
                            20,  1,  1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1
                        };
                        int item = ServerManager.RandomNumber(0, 42);
                        session.Character.GiftAdd(vnums[item], counts[item]);
                    }
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else if (session.HasCurrentMapInstance && session.CurrentMapInstance.Map.MapTypes.All(m => m.MapTypeId != (short)MapTypeEnum.Act4))
                {
                    short[] vnums = { 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405 };
                    short   vnum  = vnums[ServerManager.RandomNumber(0, 20)];

                    NpcMonster npcmonster = ServerManager.GetNpc(vnum);
                    if (npcmonster == null)
                    {
                        return;
                    }
                    MapMonster monster = new MapMonster
                    {
                        MonsterVNum   = vnum,
                        MapY          = session.Character.MapY,
                        MapX          = session.Character.MapX,
                        MapId         = session.Character.MapInstance.Map.MapId,
                        Position      = session.Character.Direction,
                        IsMoving      = true,
                        MapMonsterId  = session.CurrentMapInstance.GetNextMonsterId(),
                        ShouldRespawn = false
                    };
                    monster.Initialize(session.CurrentMapInstance);
                    session.CurrentMapInstance.AddMonster(monster);
                    session.CurrentMapInstance.Broadcast(monster.GenerateIn());
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            // Golden Bazaar Medal
            case 1003:
                if (!session.Character.StaticBonusList.Any(s => s.StaticBonusType == StaticBonusType.BazaarMedalGold || s.StaticBonusType == StaticBonusType.BazaarMedalSilver))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.BazaarMedalGold
                    });
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            // Silver Bazaar Medal
            case 1004:
                if (!session.Character.StaticBonusList.Any(s => s.StaticBonusType == StaticBonusType.BazaarMedalGold || s.StaticBonusType == StaticBonusType.BazaarMedalGold))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.BazaarMedalSilver
                    });
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            // Pet Slot Expansion
            case 1006:
                if (Option == 0)
                {
                    session.SendPacket($"qna #u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^2 {Language.Instance.GetMessageFromKey("ASK_PET_MAX")}");
                }
                else if (session.Character.MaxMateCount < 30)
                {
                    session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("GET_PET_PLACES"), 10));
                    session.SendPacket(session.Character.GenerateScpStc());
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            // Pet Basket
            case 1007:
                if (session.Character.StaticBonusList.All(s => s.StaticBonusType != StaticBonusType.PetBasket))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.PetBasket
                    });
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.SendPacket(session.Character.GenerateExts());
                    session.SendPacket("ib 1278 1");
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            // Partner's Backpack
            case 1008:
                if (session.Character.StaticBonusList.All(s => s.StaticBonusType != StaticBonusType.PetBackPack))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.PetBackPack
                    });
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.SendPacket(session.Character.GenerateExts());
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            // Backpack Expansion
            case 1009:
                if (session.Character.StaticBonusList.All(s => s.StaticBonusType != StaticBonusType.BackPack))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.BackPack
                    });
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.SendPacket(session.Character.GenerateExts());
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            // Sealed Tarot Card
            case 1005:
                session.Character.GiftAdd((short)(VNum - Effect), 1);
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                break;

            // Tarot Card Game
            case 1894:
                if (EffectValue == 0)
                {
                    for (int i = 0; i < 5; i++)
                    {
                        session.Character.GiftAdd((short)(Effect + ServerManager.RandomNumber(0, 10)), 1);
                    }
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            // Sealed Tarot Card
            case 2152:
                session.Character.GiftAdd((short)(VNum + Effect), 1);
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                break;

            default:
                switch (VNum)
                {
                case 5841:
                    int     rnd   = ServerManager.RandomNumber(0, 1000);
                    short[] vnums = null;
                    if (rnd < 900)
                    {
                        vnums = new short[] { 4356, 4357, 4358, 4359 };
                    }
                    else
                    {
                        vnums = new short[] { 4360, 4361, 4362, 4363 };
                    }
                    session.Character.GiftAdd(vnums[ServerManager.RandomNumber(0, 4)], 1);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    break;

                default:
                    Logger.Warn(string.Format(Language.Instance.GetMessageFromKey("NO_HANDLER_ITEM"), GetType()) + $" ItemVNum: {VNum} Effect: {Effect} EffectValue: {EffectValue}");
                    break;
                }
                break;
            }
        }
Ejemplo n.º 22
0
        public void ApplyBCards(object session, object sender = null)
        {
            //Console.WriteLine($"BCardId: {BCardId} Type: {(BCardType.CardType)Type} SubType: {SubType} CardId: {CardId?.ToString() ?? "null"} ItemVNum: {ItemVNum?.ToString() ?? "null"} SkillVNum: {SkillVNum?.ToString() ?? "null"} SessionType: {session?.GetType().ToString() ?? "null"} SenderType: {sender?.GetType().ToString() ?? "null"}");

            switch ((BCardType.CardType)Type)
            {
            case BCardType.CardType.Buff:
            {
                if (ServerManager.RandomNumber() < FirstData)
                {
                    Character senderCharacter = sender is ClientSession senderSession
                                ? senderSession.Character : sender as Character;

                    if (session is Character character)
                    {
                        short cardId = (short)SecondData;

                        // If either Berserk Spirit or Strong Berserk Spirit is active
                        // then don't add Weak Berserk Spirit

                        if (cardId == 601 &&
                            character.Buff?.Any(s => s?.Card?.CardId == 602 || s?.Card?.CardId == 603) == true)
                        {
                            break;
                        }

                        if (senderCharacter != null)
                        {
                            // TODO: Get anti stats from BCard

                            character.AddBuff(new Buff((short)SecondData, senderCharacter.Level, senderCharacter));
                        }
                        else
                        {
                            character.AddBuff(new Buff((short)SecondData, character.Level));
                        }
                    }
                    else if (session is MapMonster mapMonster)
                    {
                        if (senderCharacter != null)
                        {
                            mapMonster.AddBuff(new Buff((short)SecondData, senderCharacter.Level, senderCharacter));
                        }
                        else
                        {
                            mapMonster.AddBuff(new Buff((short)SecondData, mapMonster.Monster.Level));
                        }
                    }
                }
            }
            break;

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

            case BCardType.CardType.Summons:
            {
                if (session is Character character)
                {
                    if (character.MapInstance != null)
                    {
                        List <MonsterToSummon> monsterList = new List <MonsterToSummon>();

                        if (SubType == (byte)AdditionalTypes.Summons.Summons / 10)
                        {
                            int aliveTime = ServerManager.GetNpc((short)SecondData).RespawnTime;

                            for (int i = 0; i < FirstData; i++)
                            {
                                MapCell mapCell = new MapCell
                                {
                                    X = (short)(ServerManager.RandomNumber(-1, 2) + character.PositionX),
                                    Y = (short)(ServerManager.RandomNumber(-1, 2) + character.PositionY),
                                };

                                monsterList.Add(new MonsterToSummon((short)SecondData, mapCell, -1, true, false, false, true, false, -1, character, aliveTime, false));
                            }
                        }

                        if (monsterList.Any())
                        {
                            EventHelper.Instance.RunEvent(new EventContainer(character.MapInstance,
                                                                             EventActionType.SPAWNMONSTERS, monsterList));
                        }
                    }
                }
            }
            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:
            {
                Character senderCharacter = sender is ClientSession senderSession
                            ? senderSession.Character : sender as Character;

                if (senderCharacter != null)
                {
                    #region Character

                    if (session is Character character)
                    {
                        void HealingBurningAndCastingAction()
                        {
                            if (!character.IsAlive ||
                                character.MapInstance == null ||
                                character.Session == null)
                            {
                                return;
                            }

                            int amount = 0;

                            if (SubType == (byte)AdditionalTypes.HealingBurningAndCasting.RestoreHP / 10 ||
                                SubType == (byte)AdditionalTypes.HealingBurningAndCasting.DecreaseHP / 10)
                            {
                                if (FirstData > 0)
                                {
                                    if (IsLevelScaled)
                                    {
                                        amount = senderCharacter.Level * FirstData;
                                    }
                                    else
                                    {
                                        amount = FirstData;
                                    }

                                    if (character.Hp + amount > character.HPMax)
                                    {
                                        amount = character.HPMax - character.Hp;
                                    }

                                    character.Hp += amount;

                                    character.MapInstance.Broadcast(character.GenerateRc(amount));
                                }
                                else
                                {
                                    if (IsLevelScaled)
                                    {
                                        amount = senderCharacter.Level * (FirstData - 1);
                                    }
                                    else
                                    {
                                        amount = FirstData;
                                    }

                                    amount *= -1;

                                    if (character.Hp - amount < 1)
                                    {
                                        amount = character.Hp - 1;
                                    }

                                    character.GetDamage(amount);

                                    character.MapInstance.Broadcast(character.GenerateDm(amount));
                                }

                                character.Session.SendPacket(character.GenerateStat());
                            }
                            else if (SubType == (byte)AdditionalTypes.HealingBurningAndCasting.RestoreMP / 10 ||
                                     SubType == (byte)AdditionalTypes.HealingBurningAndCasting.DecreaseMP / 10)
                            {
                                if (FirstData > 0)
                                {
                                    if (IsLevelScaled)
                                    {
                                        amount = senderCharacter.Level * FirstData;
                                    }
                                    else
                                    {
                                        amount = FirstData;
                                    }

                                    if (character.Mp + amount > character.MPMax)
                                    {
                                        amount = character.MPMax - character.Mp;
                                    }

                                    character.Mp += amount;
                                }
                                else
                                {
                                    if (IsLevelScaled)
                                    {
                                        amount = senderCharacter.Level * (FirstData - 1);
                                    }
                                    else
                                    {
                                        amount = FirstData;
                                    }

                                    amount *= -1;

                                    if (character.Mp - amount < 1)
                                    {
                                        amount = character.Mp - 1;
                                    }

                                    character.DecreaseMp(amount);
                                }

                                character.Session.SendPacket(character.GenerateStat());
                            }
                        }

                        HealingBurningAndCastingAction();

                        if (ThirdData > 0 &&
                            CardId != null)
                        {
                            IDisposable disposable = Observable.Interval(TimeSpan.FromSeconds(ThirdData * 2))
                                                     .Subscribe(s => HealingBurningAndCastingAction());

                            character.DisposeBCard(BCardId);
                            character.BCardDisposables[BCardId] = disposable;
                        }
                    }

                    #endregion

                    #region MapMonster

                    else if (session is MapMonster mapMonster)
                    {
                        void HealingBurningAndCastingAction()
                        {
                            if (!mapMonster.IsAlive ||
                                mapMonster.MapInstance == null)
                            {
                                return;
                            }

                            int amount = 0;

                            if (SubType == (byte)AdditionalTypes.HealingBurningAndCasting.RestoreHP / 10 ||
                                SubType == (byte)AdditionalTypes.HealingBurningAndCasting.DecreaseHP / 10)
                            {
                                if (FirstData > 0)
                                {
                                    if (IsLevelScaled)
                                    {
                                        amount = senderCharacter.Level * FirstData;
                                    }
                                    else
                                    {
                                        amount = FirstData;
                                    }

                                    if (mapMonster.CurrentHp + amount > mapMonster.MaxHp)
                                    {
                                        amount = mapMonster.MaxHp - mapMonster.CurrentHp;
                                    }

                                    mapMonster.CurrentHp += amount;

                                    mapMonster.MapInstance.Broadcast(mapMonster.GenerateRc(amount));
                                }
                                else
                                {
                                    if (IsLevelScaled)
                                    {
                                        amount = senderCharacter.Level * (FirstData - 1);
                                    }
                                    else
                                    {
                                        amount = FirstData;
                                    }

                                    amount *= -1;

                                    if (mapMonster.CurrentHp - amount < 1)
                                    {
                                        amount = mapMonster.CurrentHp - 1;
                                    }

                                    mapMonster.CurrentHp -= amount;

                                    mapMonster.MapInstance.Broadcast(mapMonster.GenerateDm(amount));
                                }
                            }

                            if (SubType == (byte)AdditionalTypes.HealingBurningAndCasting.RestoreMP / 10 ||
                                SubType == (byte)AdditionalTypes.HealingBurningAndCasting.DecreaseMP / 10)
                            {
                                if (FirstData > 0)
                                {
                                    if (IsLevelScaled)
                                    {
                                        amount = senderCharacter.Level * FirstData;
                                    }
                                    else
                                    {
                                        amount = FirstData;
                                    }

                                    if (mapMonster.CurrentMp + amount > mapMonster.MaxMp)
                                    {
                                        amount = mapMonster.MaxMp - mapMonster.CurrentMp;
                                    }

                                    mapMonster.CurrentMp += amount;
                                }
                                else
                                {
                                    if (IsLevelScaled)
                                    {
                                        amount = senderCharacter.Level * (FirstData - 1);
                                    }
                                    else
                                    {
                                        amount = FirstData;
                                    }

                                    amount *= -1;

                                    if (mapMonster.CurrentMp - amount < 1)
                                    {
                                        amount = mapMonster.CurrentMp - 1;
                                    }

                                    mapMonster.CurrentMp -= amount;
                                }
                            }
                        }

                        HealingBurningAndCastingAction();

                        if (ThirdData > 0 &&
                            CardId != null)
                        {
                            IDisposable disposable = Observable.Interval(TimeSpan.FromSeconds(ThirdData * 2))
                                                     .Subscribe(s => HealingBurningAndCastingAction());

                            mapMonster.DisposeBCard(BCardId);
                            mapMonster.BCardDisposables[BCardId] = disposable;
                        }
                    }

                    #endregion
                }
            }
            break;

            case BCardType.CardType.HPMP:
            {
                if (SubType == (byte)AdditionalTypes.HPMP.DecreaseRemainingMP / 10)
                {
                    if (FirstData < 0)
                    {
                        double multiplier = (FirstData * -1) / 100D;

                        if (session is Character character)
                        {
                            character.DecreaseMp((int)(character.Mp * multiplier));
                            character.Session?.SendPacket(character.GenerateStat());
                        }
                        else if (session is MapMonster mapMonster)
                        {
                            mapMonster.DecreaseMp((int)(mapMonster.CurrentMp * multiplier));
                        }
                    }
                }
            }
            break;

            case BCardType.CardType.SpecializationBuffResistance:
            {
                if (SubType == (byte)AdditionalTypes.SpecializationBuffResistance.RemoveGoodEffects / 10)
                {
                    if (session is Character character)
                    {
                        if (FirstData < 0)
                        {
                            if (ServerManager.RandomNumber() < (FirstData * -1))
                            {
                                character.Buff?.GetAllItems()?.Where(s => s?.Card?.BuffType == BuffType.Bad && s.Card.Level < SecondData)?
                                .ToList()?.ForEach(s => character.RemoveBuff(s.Card.CardId));
                            }
                        }
                        else
                        {
                            if (ServerManager.RandomNumber() < FirstData)
                            {
                                character.Buff?.GetAllItems()?.Where(s => s?.Card?.BuffType == BuffType.Good && s.Card.Level < SecondData)?
                                .ToList()?.ForEach(s => character.RemoveBuff(s.Card.CardId));
                            }
                        }
                    }
                }
            }
            break;

            case BCardType.CardType.SpecialEffects:
            {
                if (SubType == (byte)AdditionalTypes.SpecialEffects.ShadowAppears / 10)
                {
                    if (session is Character character)
                    {
                        character.NumberOfShadows = FirstData;
                        character.ShadowsDistance = SecondData;
                        character.MapInstance?.Broadcast(character.GenerateSpeed());
                    }
                }
            }
            break;

            case BCardType.CardType.Capture:
            {
                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)
                                {
                                    // TODO: 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:
            {
                if (SubType == (byte)AdditionalTypes.SpecialEffects2.TeleportInRadius / 10)
                {
                    if (session is Character character)
                    {
                        character.Teleport((short)FirstData);
                    }
                }
            }
            break;

            case BCardType.CardType.CalculatingLevel:
                break;

            case BCardType.CardType.Recovery:
                break;

            case BCardType.CardType.MaxHPMP:
            {
                if (session is Character character)
                {
                    if (SubType == (byte)AdditionalTypes.MaxHPMP.IncreasesMaximumHP / 10)
                    {
                        character.HPLoad();
                        character.Session?.SendPacket(character.GenerateStat());
                    }
                    else if (SubType == (byte)AdditionalTypes.MaxHPMP.IncreasesMaximumMP / 10)
                    {
                        character.MPLoad();
                        character.Session?.SendPacket(character.GenerateStat());
                    }
                }
            }
            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:
            {
                Character senderCharacter = sender is ClientSession senderSession
                            ? senderSession.Character : sender as Character;

                if (SubType == (byte)AdditionalTypes.SpecialActions.PushBack / 10)
                {
                    if (senderCharacter != null)
                    {
                        if (session is Character character)
                        {
                            if (character.ResistForcedMovementChance <= 0 ||
                                ServerManager.RandomNumber() < character.ResistForcedMovementChance)
                            {
                                character.PushBack((short)FirstData, senderCharacter);
                            }
                        }
                        else if (session is MapMonster mapMonster)
                        {
                            mapMonster.PushBack((short)FirstData, senderCharacter);
                        }
                    }
                }
                else if (SubType == (byte)AdditionalTypes.SpecialActions.FocusEnemies / 10)
                {
                    if (senderCharacter != null)
                    {
                        if (session is Character character)
                        {
                            if (character.ResistForcedMovementChance <= 0 ||
                                ServerManager.RandomNumber() < character.ResistForcedMovementChance)
                            {
                                character.Focus((short)FirstData, senderCharacter);
                            }
                        }
                        else if (session is MapMonster mapMonster)
                        {
                            mapMonster.Focus((short)FirstData, senderCharacter);
                        }
                    }
                }
                else if (SubType == (byte)AdditionalTypes.SpecialActions.Hide / 10)
                {
                    if (session is Character character)
                    {
                        character.SetInvisible(true);
                    }
                }
            }
            break;

            case BCardType.CardType.Transform:
                break;

            case BCardType.CardType.Mode:
                break;

            case BCardType.CardType.NoCharacteristicValue:
                break;

            case BCardType.CardType.LightAndShadow:
            {
                if (SubType == (byte)AdditionalTypes.LightAndShadow.RemoveBadEffects / 10)
                {
                    if (session is Character character)
                    {
                        character.Buff?.GetAllItems()?.Where(s => s?.Card?.BuffType == BuffType.Bad && s.Card.Level < FirstData)?
                        .ToList()?.ForEach(s => character.RemoveBuff(s.Card.CardId));
                    }
                }
            }
            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:
            {
                if (session is Character character)
                {
                    if (character.MapInstance != null)
                    {
                        List <MonsterToSummon> monsterList = new List <MonsterToSummon>();

                        if (SubType == (byte)AdditionalTypes.SecondSPCard.PlantBomb / 10)
                        {
                            MapMonster bomb = character.MapInstance.Monsters.FirstOrDefault(m => m?.Owner?.CharacterId == character.CharacterId &&
                                                                                            m.MonsterVNum == (short)SecondData);

                            if (bomb == null)
                            {
                                for (int i = 0; i < FirstData; i++)
                                {
                                    monsterList.Add(new MonsterToSummon((short)SecondData, new MapCell {
                                            X = character.PositionX, Y = character.PositionY
                                        },
                                                                        -1, false, false, false, false, false, -1, character, 0, false));
                                }
                            }
                            else
                            {
                                bomb.Explode();
                                break;
                            }
                        }
                        else if (SubType == (byte)AdditionalTypes.SecondSPCard.PlantSelfDestructionBomb / 10)
                        {
                            int aliveTime = ServerManager.GetNpc((short)SecondData).RespawnTime;

                            for (int i = 0; i < FirstData; i++)
                            {
                                MapCell mapCell = new MapCell
                                {
                                    X = (short)(ServerManager.RandomNumber(-1, 2) + character.PositionX),
                                    Y = (short)(ServerManager.RandomNumber(-1, 2) + character.PositionY),
                                };

                                monsterList.Add(new MonsterToSummon((short)SecondData, mapCell, -1, true, false, false, true, false, -1, character, aliveTime, true));
                            }
                        }

                        if (monsterList.Any())
                        {
                            EventHelper.Instance.RunEvent(new EventContainer(character.MapInstance,
                                                                             EventActionType.SPAWNMONSTERS, monsterList));
                        }
                    }
                }
            }
            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:
            {
                if (SubType == (byte)AdditionalTypes.SESpecialist.LowerHPStrongerEffect / 10)
                {
                    Character senderCharacter = sender is ClientSession senderSession
                                ? senderSession.Character : sender as Character;

                    if (senderCharacter != null)
                    {
                        if (session is Character character)
                        {
                            double percentage = (character.Hp * 100) / character.HPMax;

                            if (percentage < 35)
                            {
                                character.AddBuff(new Buff(274, senderCharacter.Level, senderCharacter));
                            }
                            else if (percentage < 67)
                            {
                                character.AddBuff(new Buff(273, senderCharacter.Level, senderCharacter));
                            }
                            else
                            {
                                character.AddBuff(new Buff(272, senderCharacter.Level, senderCharacter));
                            }
                        }
                    }
                }
            }
            break;

            case BCardType.CardType.FourthGlacernonFamilyRaid:
                break;

            case BCardType.CardType.SummonedMonsterAttack:
                break;

            case BCardType.CardType.BearSpirit:
            {
                if (session is Character character)
                {
                    if (SubType == (byte)AdditionalTypes.BearSpirit.IncreaseMaximumHP / 10)
                    {
                        character.HPLoad();
                        character.Session?.SendPacket(character.GenerateStat());
                    }
                    else if (SubType == (byte)AdditionalTypes.BearSpirit.IncreaseMaximumMP / 10)
                    {
                        character.MPLoad();
                        character.Session?.SendPacket(character.GenerateStat());
                    }
                }
            }
            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 (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)
                        {
                            Observable.Timer(TimeSpan.FromMilliseconds((skill.GetCooldown(character) * 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 Found!");
                break;
            }
        }
Ejemplo n.º 23
0
        public override void Use(ClientSession session, ref ItemInstance inv, bool delay = false, string[] packetsplit = null)
        {
            switch (Effect)
            {
            // sp point potions
            case 150:
            case 151:
                session.Character.SpAdditionPoint += EffectValue;
                if (session.Character.SpAdditionPoint > 1000000)
                {
                    session.Character.SpAdditionPoint = 1000000;
                }
                session.SendPacket(session.Character.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("SP_POINTSADDED"), EffectValue), 0));
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                session.SendPacket(session.Character.GenerateSpPoint());
                break;

            case 204:
                session.Character.SpPoint         += EffectValue;
                session.Character.SpAdditionPoint += EffectValue * 3;
                if (session.Character.SpAdditionPoint > 1000000)
                {
                    session.Character.SpAdditionPoint = 1000000;
                }
                if (session.Character.SpPoint > 10000)
                {
                    session.Character.SpPoint = 10000;
                }
                session.SendPacket(session.Character.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("SP_POINTSADDEDBOTH"), EffectValue, EffectValue * 3), 0));
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                session.SendPacket(session.Character.GenerateSpPoint());
                break;

            //Atk/Def/HP/Exp potions
            case 6600:
                switch (EffectValue)
                {
                case 1:
                    IndicatorBase buff1 = new Buff.Indicators.Item.AttackPotion(session.Character.Level);
                    session.CurrentMapInstance?.Broadcast(session.Character.GenerateEff(203));
                    session.Character.Buff.Add(buff1);
                    break;

                case 2:
                    IndicatorBase buff2 = new Buff.Indicators.Item.DefensePotion(session.Character.Level);
                    session.CurrentMapInstance?.Broadcast(session.Character.GenerateEff(203));
                    session.Character.Buff.Add(buff2);
                    break;

                case 3:
                    IndicatorBase buff3 = new Buff.Indicators.Item.EnergyPotion(session.Character.Level);
                    session.CurrentMapInstance?.Broadcast(session.Character.GenerateEff(203));
                    session.Character.Buff.Add(buff3);
                    break;

                case 4:
                    IndicatorBase buff4 = new Buff.Indicators.Item.ExperiencePotion(session.Character.Level);
                    session.CurrentMapInstance?.Broadcast(session.Character.GenerateEff(203));
                    session.Character.Buff.Add(buff4);
                    break;
                }
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                break;

            // Divorce letter
            case 6969:     // this is imaginary number I = √(-1)
                break;

            // Cupid's arrow
            case 34:     // this is imaginary number I = √(-1)
                break;

            case 570:
                if (session.Character.Faction == EffectValue)
                {
                    return;
                }
                session.SendPacket(session.Character.Family == null
                        ? $"qna #guri^750^{EffectValue} {Language.Instance.GetMessageFromKey($"ASK_CHANGE_FACTION{EffectValue}")}"
                        : session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("IN_FAMILY"), 0));
                break;

            // wings
            case 650:
                SpecialistInstance specialistInstance = session.Character.Inventory.LoadBySlotAndType <SpecialistInstance>((byte)EquipmentType.Sp, InventoryType.Wear);
                if (session.Character.UseSp && specialistInstance != null)
                {
                    if (!delay)
                    {
                        session.SendPacket($"qna #u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^3 {Language.Instance.GetMessageFromKey("ASK_WINGS_CHANGE")}");
                    }
                    else
                    {
                        specialistInstance.Design       = (byte)EffectValue;
                        session.Character.MorphUpgrade2 = EffectValue;
                        session.CurrentMapInstance?.Broadcast(session.Character.GenerateCMode());
                        session.SendPacket(session.Character.GenerateStat());
                        session.SendPacket(session.Character.GenerateStatChar());
                        session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    }
                }
                else
                {
                    session.SendPacket(session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("NO_SP"), 0));
                }
                break;

            // presentation messages
            case 203:
                if (!session.Character.IsVehicled)
                {
                    if (!delay)
                    {
                        session.SendPacket(session.Character.GenerateGuri(10, 2, 1));
                    }
                }
                break;

            // magic lamps
            case 651:
                if (session.Character.Inventory.GetAllItems().All(i => i.Type != InventoryType.Wear))
                {
                    if (!delay)
                    {
                        session.SendPacket($"qna #u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^3 {Language.Instance.GetMessageFromKey("ASK_USE")}");
                    }
                    else
                    {
                        session.Character.ChangeSex();
                        session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    }
                }
                else
                {
                    session.SendPacket(session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("EQ_NOT_EMPTY"), 0));
                }
                break;

            // vehicles
            case 1000:
                if (Morph > 0)
                {
                    if (!delay && !session.Character.IsVehicled)
                    {
                        if (session.Character.IsSitting)
                        {
                            session.Character.IsSitting = false;
                            session.CurrentMapInstance?.Broadcast(session.Character.GenerateRest());
                        }
                        session.SendPacket(session.Character.GenerateDelay(3000, 3, $"#u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^2"));
                    }
                    else
                    {
                        if (!session.Character.IsVehicled && delay)
                        {
                            session.Character.Speed         = Speed;
                            session.Character.IsVehicled    = true;
                            session.Character.VehicleSpeed  = Speed;
                            session.Character.MorphUpgrade  = 0;
                            session.Character.MorphUpgrade2 = 0;
                            session.Character.Morph         = Morph + (byte)session.Character.Gender;
                            session.CurrentMapInstance?.Broadcast(session.Character.GenerateEff(196), session.Character.MapX, session.Character.MapY);
                            session.CurrentMapInstance?.Broadcast(session.Character.GenerateCMode());
                            session.SendPacket(session.Character.GenerateCond());
                            session.Character.LastSpeedChange = DateTime.Now;
                        }
                        else if (session.Character.IsVehicled)
                        {
                            session.Character.RemoveVehicle();
                        }
                    }
                }
                break;

            case 1002:
                if (EffectValue == 69)
                {
                    int rnd = ServerManager.RandomNumber(0, 1000);
                    if (rnd < 5)
                    {
                        short[] vnums  = { 5560, 5591, 4099, 907, 1160, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716 };
                        byte[]  counts = { 1, 1, 1, 1, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
                        int     item   = ServerManager.RandomNumber(0, 17);

                        session.Character.GiftAdd(vnums[item], counts[item]);
                    }
                    else if (rnd < 30)
                    {
                        short[] vnums = { 361, 362, 363, 366, 367, 368, 371, 372, 373 };
                        session.Character.GiftAdd(vnums[ServerManager.RandomNumber(0, 9)], 1);
                    }
                    else
                    {
                        short[] vnums  = { 1161, 2282, 1030, 1244, 1218, 5369, 1012, 1363, 1364, 2160, 2173, 5959, 5983, 2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 1685, 1686, 5087, 5203, 2418, 2310, 2303, 2169, 2280, 5892, 5893, 5894, 5895, 5896, 5897, 5898, 5899, 5332, 5105, 2161, 2162 };
                        byte[]  counts = { 10, 10, 20, 5, 1, 1, 99, 1, 1, 5, 5, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 5, 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
                        int     item   = ServerManager.RandomNumber(0, 42);
                        session.Character.GiftAdd(vnums[item], counts[item]);
                    }
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                }
                else
                {
                    if (session.HasCurrentMapInstance)
                    {
                        if (session.CurrentMapInstance.Map.MapTypes.All(m => m.MapTypeId != (short)MapTypeEnum.Act4))
                        {
                            short[] vnums = { 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405 };
                            short   vnum  = vnums[ServerManager.RandomNumber(0, 20)];

                            NpcMonster npcmonster = ServerManager.GetNpc(vnum);
                            if (npcmonster == null)
                            {
                                return;
                            }
                            // ReSharper disable once PossibleNullReferenceException HasCurrentMapInstance NullCheck
                            MapMonster monster = new MapMonster {
                                MonsterVNum = vnum, MapY = session.Character.MapY, MapX = session.Character.MapX, MapId = session.Character.MapInstance.Map.MapId, Position = (byte)session.Character.Direction, IsMoving = true, MapMonsterId = session.CurrentMapInstance.GetNextMonsterId(), ShouldRespawn = false
                            };
                            monster.Initialize(session.CurrentMapInstance);
                            monster.StartLife();
                            session.CurrentMapInstance.AddMonster(monster);
                            session.CurrentMapInstance.Broadcast(monster.GenerateIn3());
                            session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                        }
                    }
                }
                break;

            case 69:
                session.Character.Reput += ReputPrice;
                session.SendPacket(session.Character.GenerateFd());
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                break;

            case 1003:
                if (!session.Character.StaticBonusList.Any(s => s.StaticBonusType == StaticBonusType.BazaarMedalGold || s.StaticBonusType == StaticBonusType.BazaarMedalSilver))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO {
                        CharacterId = session.Character.CharacterId, DateEnd = DateTime.Now.AddDays(EffectValue), StaticBonusType = StaticBonusType.BazaarMedalGold
                    });
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            case 1004:
                if (!session.Character.StaticBonusList.Any(s => s.StaticBonusType == StaticBonusType.BazaarMedalGold || s.StaticBonusType == StaticBonusType.BazaarMedalGold))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO {
                        CharacterId = session.Character.CharacterId, DateEnd = DateTime.Now.AddDays(EffectValue), StaticBonusType = StaticBonusType.BazaarMedalSilver
                    });
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            case 1005:
                if (session.Character.StaticBonusList.All(s => s.StaticBonusType != StaticBonusType.BackPack))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO {
                        CharacterId = session.Character.CharacterId, DateEnd = DateTime.Now.AddDays(EffectValue), StaticBonusType = StaticBonusType.BackPack
                    });
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    session.SendPacket(session.Character.GenerateExts());
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            default:
                Logger.Log.Warn(string.Format(Language.Instance.GetMessageFromKey("NO_HANDLER_ITEM"), GetType()));
                break;
            }
        }
Ejemplo n.º 24
0
        private void NpcLife()
        {
            double time = (DateTime.Now - LastEffect).TotalMilliseconds;

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

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

                byte xpoint = (byte)ServerManager.Instance.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, GenerateMv2(), ReceiverType.All, xCoordinate: mapX, yCoordinate: mapY));
                }
            }
            if (Target == -1)
            {
                if (IsHostile && Shop == null)
                {
                    MapMonster monster = MapInstance.Monsters.FirstOrDefault(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.FirstOrDefault(s => s.MapMonsterId == Target);
                if (monster == null || monster.CurrentHp < 1)
                {
                    Target = -1;
                    return;
                }
                NpcMonsterSkill npcMonsterSkill = null;
                if (ServerManager.Instance.RandomNumber(0, 10) > 8)
                {
                    npcMonsterSkill = Npc.Skills.Where(s => (DateTime.Now - s.LastSkillUse).TotalMilliseconds >= 100 * s.Skill.Cooldown).OrderBy(rnd => _random.Next()).FirstOrDefault();
                }

                const short damage   = 100;
                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.Any() || npcMonsterSkill != null)
                    {
                        if (npcMonsterSkill != null)
                        {
                            npcMonsterSkill.LastSkillUse = DateTime.Now;
                            MapInstance.Broadcast($"ct 2 {MapNpcId} 3 {Target} {npcMonsterSkill.Skill.CastAnimation} {npcMonsterSkill.Skill.CastEffect} {npcMonsterSkill.Skill.SkillVNum}");
                        }

                        if (npcMonsterSkill != null && npcMonsterSkill.Skill.CastEffect != 0)
                        {
                            MapInstance.Broadcast(GenerateEff(Effect));
                        }

                        monster.CurrentHp -= damage;

                        MapInstance.Broadcast(npcMonsterSkill != null
                            ? $"su 2 {MapNpcId} 3 {Target} {npcMonsterSkill.SkillVNum} {npcMonsterSkill.Skill.Cooldown} {npcMonsterSkill.Skill.AttackAnimation} {npcMonsterSkill.Skill.Effect} 0 0 {(monster.CurrentHp > 0 ? 1 : 0)} {(int)((double)monster.CurrentHp / monster.Monster.MaxHP * 100)} {damage} 0 0"
                            : $"su 2 {MapNpcId} 3 {Target} 0 {Npc.BasicCooldown} 11 {Npc.BasicSkill} 0 0 {(monster.CurrentHp > 0 ? 1 : 0)} {(int)((double)monster.CurrentHp / monster.Monster.MaxHP * 100)} {damage} 0 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;
                        if (!Path.Any() && distance > 1 && distance < maxDistance)
                        {
                            short xoffset = (short)ServerManager.Instance.RandomNumber(-1, 1);
                            short yoffset = (short)ServerManager.Instance.RandomNumber(-1, 1);
                            //go to monster
                            Path = BestFirstSearch.FindPath(new GridPos {
                                X = MapX, Y = MapY
                            }, new GridPos {
                                X = (short)(monster.MapX + xoffset), Y = (short)(monster.MapY + yoffset)
                            }, MapInstance.Map.Grid);
                        }
                        if (DateTime.Now > LastMove && Npc.Speed > 0 && Path.Any())
                        {
                            int maxindex = Path.Count > Npc.Speed / 2 && Npc.Speed > 1 ? Npc.Speed / 2 : Path.Count;
                            maxindex = maxindex < 1 ? 1 : maxindex;
                            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
                            }, new MapCell {
                                X = MapX, Y = MapY
                            }) / (double)Npc.Speed;
                            MapInstance.Broadcast(new BroadcastPacket(null, $"mv 2 {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 > Path.Count ? Path.Count : maxindex);
                        }
                        if (Target != -1 && (MapId != monster.MapId || distance > maxDistance))
                        {
                            RemoveTarget();
                        }
                    }
                }
            }
        }
Ejemplo n.º 25
0
        public override void Use(ClientSession session, ref ItemInstance inv, byte Option = 0, string[] packetsplit = null)
        {
            inv.Item.BCards.ForEach(c => c.ApplyBCards(session.Character));

            switch (Effect)
            {
            // Honour Medals
            case 69:
                session.Character.Reputation += ReputPrice;
                session.SendPacket(session.Character.GenerateFd());
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                break;

            // SP Potions
            case 150:
            case 151:
                session.Character.SpAdditionPoint += EffectValue;
                if (session.Character.SpAdditionPoint > 1000000)
                {
                    session.Character.SpAdditionPoint = 1000000;
                }
                session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("SP_POINTSADDED"), EffectValue), 0));
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                session.SendPacket(session.Character.GenerateSpPoint());
                break;

            // Specialist Medal
            case 204:
                session.Character.SpPoint         += EffectValue;
                session.Character.SpAdditionPoint += EffectValue * 3;
                if (session.Character.SpAdditionPoint > 1000000)
                {
                    session.Character.SpAdditionPoint = 1000000;
                }
                if (session.Character.SpPoint > 10000)
                {
                    session.Character.SpPoint = 10000;
                }
                session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("SP_POINTSADDEDBOTH"), EffectValue, EffectValue * 3), 0));
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                session.SendPacket(session.Character.GenerateSpPoint());
                break;

            // Raid Seals
            case 301:
                if (ServerManager.Instance.IsCharacterMemberOfGroup(session.Character.CharacterId))
                {
                    //TODO you are in group
                    return;
                }
                ItemInstance raidSeal = session.Character.Inventory.LoadBySlotAndType <ItemInstance>(inv.Slot, InventoryType.Main);
                session.Character.Inventory.RemoveItemFromInventory(raidSeal.Id);

                ScriptedInstance raid = ServerManager.Instance.Raids.FirstOrDefault(s => s.RequiredItems?.Any(obj => obj?.VNum == raidSeal.ItemVNum) == true)?.Copy();
                if (raid != null)
                {
                    Group group = new Group()
                    {
                        GroupType = GroupType.BigTeam,
                        Raid      = raid
                    };
                    group.JoinGroup(session.Character.CharacterId);
                    ServerManager.Instance.AddGroup(group);
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("RAID_LEADER"), session.Character.Name), 0));
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("RAID_LEADER"), session.Character.Name), 10));
                    if (session.Character.Level > raid.LevelMaximum || session.Character.Level < raid.LevelMinimum)
                    {
                        session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("RAID_LEVEL_INCORRECT"), 10));
                    }
                    session.SendPacket(session.Character.GenerateRaid(2, false));
                    session.SendPacket(session.Character.GenerateRaid(0, false));
                    session.SendPacket(session.Character.GenerateRaid(1, false));
                    session.SendPacket(group.GenerateRdlst());
                }
                break;

            // Partner Suits/Skins
            case 305:
                Mate mate = session.Character.Mates.Find(s => s.MateTransportId == int.Parse(packetsplit[3]));
                if (mate != null && EffectValue == mate.NpcMonsterVNum && mate.Skin == 0)
                {
                    mate.Skin = Morph;
                    session.SendPacket(mate.GenerateCMode(mate.Skin));
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            // Fairy Booster
            case 250:
                if (!session.Character.Buff.ContainsKey(131))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 131
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 3014), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // Fairy booster 2
            case 253:
                if (!session.Character.Buff.ContainsKey(131))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 131
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 3014), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // exp/job booster
            case 251:
                if (!session.Character.Buff.ContainsKey(121))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 121
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 3014), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // Ice oil
            case 252:
                if (!session.Character.Buff.ContainsKey(340))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 340
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 1), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // Valentin Buff
            case 254:
                if (!session.Character.Buff.ContainsKey(109))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 109
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 3406), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // Buff exp 20%
            case 256:
                if (!session.Character.Buff.ContainsKey(119))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 119
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 203), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // Ancella fate
            case 258:
                if (!session.Character.Buff.ContainsKey(393))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 393
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 203), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // Speedbooster
            case 260:
                if (!session.Character.Buff.ContainsKey(336))
                {
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 336
                    });
                    session.CurrentMapInstance?.Broadcast(session.Character.GeneratePairy());
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), inv.Item.Name), 0));
                    session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 3014), session.Character.MapX, session.Character.MapY);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;



            // Rainbow Pearl/Magic Eraser
            case 666:
                if (EffectValue == 1 && byte.TryParse(packetsplit[9], out byte islot))
                {
                    ItemInstance wearInstance = session.Character.Inventory.LoadBySlotAndType(islot, InventoryType.Equipment);

                    if (wearInstance != null && (wearInstance.Item.ItemType == ItemType.Weapon || wearInstance.Item.ItemType == ItemType.Armor) && wearInstance.ShellEffects.Count != 0 && !wearInstance.Item.IsHeroic)
                    {
                        wearInstance.ShellEffects.Clear();
                        DAOFactory.ShellEffectDAO.DeleteByEquipmentSerialId(wearInstance.EquipmentSerialId);
                        if (wearInstance.EquipmentSerialId == Guid.Empty)
                        {
                            wearInstance.EquipmentSerialId = Guid.NewGuid();
                        }
                        session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                        session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("OPTION_DELETE"), 0));
                    }
                }
                else
                {
                    session.SendPacket("guri 18 0");
                }
                break;

            // Atk/Def/HP/Exp potions
            case 6600:
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                break;

            // Ancelloan's Blessing
            case 208:
                if (!session.Character.Buff.ContainsKey(121))
                {
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 121
                    });
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            case 2081:
                if (!session.Character.Buff.ContainsKey(146))
                {
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.Character.AddStaticBuff(new StaticBuffDTO()
                    {
                        CardId = 146
                    });
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("ITEM_IN_USE"), 0));
                }
                break;

            // Divorce letter
            case 6969:     // this is imaginary number I = √(-1)
                break;

            // Cupid's arrow
            case 34:     // this is imaginary number I = √(-1)
                break;

            case 100:
            {
            }
            break;

            // Faction Egg
            case 570:
                if (session.Character.Faction == (FactionType)EffectValue)
                {
                    return;
                }
                if (EffectValue < 3)
                {
                    session.SendPacket(session.Character.Family == null
                            ? $"qna #guri^750^{EffectValue} {Language.Instance.GetMessageFromKey($"ASK_CHANGE_FACTION{EffectValue}")}"
                            : UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("IN_FAMILY"),
                                                                       0));
                }
                else
                {
                    session.SendPacket(session.Character.Family != null
                            ? $"qna #guri^750^{EffectValue} {Language.Instance.GetMessageFromKey($"ASK_CHANGE_FACTION{EffectValue}")}"
                            : UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("NO_FAMILY"),
                                                                       0));
                }

                break;

            // SP Wings
            case 650:
                ItemInstance specialistInstance = session.Character.Inventory.LoadBySlotAndType((byte)EquipmentType.Sp, InventoryType.Wear);
                if (session.Character.UseSp && specialistInstance != null)
                {
                    if (Option == 0)
                    {
                        session.SendPacket($"qna #u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^3 {Language.Instance.GetMessageFromKey("ASK_WINGS_CHANGE")}");
                    }
                    else
                    {
                        void disposeBuff(short vNum)
                        {
                            if (session.Character.BuffObservables.ContainsKey(vNum))
                            {
                                session.Character.BuffObservables[vNum].Dispose();
                                session.Character.BuffObservables.Remove(vNum);
                            }
                            session.Character.RemoveBuff(vNum);
                        }

                        disposeBuff(387);
                        disposeBuff(395);
                        disposeBuff(396);
                        disposeBuff(397);
                        disposeBuff(398);
                        disposeBuff(410);
                        disposeBuff(411);
                        disposeBuff(444);

                        specialistInstance.Design = (byte)EffectValue;

                        session.Character.MorphUpgrade2 = EffectValue;
                        session.CurrentMapInstance?.Broadcast(session.Character.GenerateCMode());
                        session.SendPacket(session.Character.GenerateStat());
                        session.SendPacket(session.Character.GenerateStatChar());
                        session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    }
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("NO_SP"), 0));
                }
                break;

            // Self-Introduction
            case 203:
                if (!session.Character.IsVehicled && Option == 0)
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateGuri(10, 2, session.Character.CharacterId, 1));
                }
                break;

            // Magic Lamp
            case 651:
                if (session.Character.Inventory.All(i => i.Type != InventoryType.Wear))
                {
                    if (Option == 0)
                    {
                        session.SendPacket($"qna #u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^3 {Language.Instance.GetMessageFromKey("ASK_USE")}");
                    }
                    else
                    {
                        session.Character.ChangeSex();
                        session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    }
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("EQ_NOT_EMPTY"), 0));
                }
                break;

            // Vehicles
            case 1000:
                if (EffectValue != 0 || ServerManager.Instance.ChannelId == 51 || session.CurrentMapInstance?.MapInstanceType == MapInstanceType.EventGameInstance)
                {
                    return;
                }
                if (Morph > 0)
                {
                    if (Option == 0 && !session.Character.IsVehicled)
                    {
                        if (session.Character.IsSitting)
                        {
                            session.Character.IsSitting = false;
                            session.CurrentMapInstance?.Broadcast(session.Character.GenerateRest());
                        }
                        session.Character.LastDelay = DateTime.Now;
                        session.SendPacket(UserInterfaceHelper.Instance.GenerateDelay(3000, 3, $"#u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^2"));
                    }
                    else
                    {
                        if (!session.Character.IsVehicled && Option != 0)
                        {
                            DateTime delay = DateTime.Now.AddSeconds(-4);
                            if (session.Character.LastDelay > delay && session.Character.LastDelay < delay.AddSeconds(2))
                            {
                                session.Character.Speed         = Speed;
                                session.Character.IsVehicled    = true;
                                session.Character.VehicleSpeed  = Speed;
                                session.Character.MorphUpgrade  = 0;
                                session.Character.MorphUpgrade2 = 0;
                                session.Character.Morph         = Morph + (byte)session.Character.Gender;
                                session.CurrentMapInstance?.Broadcast(StaticPacketHelper.GenerateEff(UserType.Player, session.Character.CharacterId, 196), session.Character.MapX, session.Character.MapY);
                                session.CurrentMapInstance?.Broadcast(session.Character.GenerateCMode());
                                session.SendPacket(session.Character.GenerateCond());
                                session.Character.LastSpeedChange = DateTime.Now;
                            }
                        }
                        else if (session.Character.IsVehicled)
                        {
                            session.Character.RemoveVehicle();
                        }
                    }
                }
                break;

            // Sealed Vessel
            case 1002:
                if (EffectValue == 69)
                {
                    int rnd = ServerManager.Instance.RandomNumber(0, 1000);
                    if (rnd < 5)
                    {
                        short[] vnums =
                        {
                            5560, 5591, 4099, 907, 1160, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714,
                            4715, 4716
                        };
                        byte[] counts = { 1, 1, 1, 1, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
                        int    item   = ServerManager.Instance.RandomNumber(0, 17);
                        session.Character.GiftAdd(vnums[item], counts[item]);
                    }
                    else if (rnd < 30)
                    {
                        short[] vnums = { 361, 362, 363, 366, 367, 368, 371, 372, 373 };
                        session.Character.GiftAdd(vnums[ServerManager.Instance.RandomNumber(0, 9)], 1);
                    }
                    else
                    {
                        short[] vnums =
                        {
                            1161, 2282, 1030, 1244, 1218, 5369, 1012, 1363, 1364, 2160, 2173, 5959, 5983, 2514,
                            2515, 2516, 2517, 2518, 2519, 2520, 2521, 1685, 1686, 5087, 5203, 2418, 2310, 2303,
                            2169, 2280, 5892, 5893, 5894, 5895, 5896, 5897, 5898, 5899, 5332, 5105, 2161, 2162
                        };
                        byte[] counts =
                        {
                            10, 10, 20, 5, 1, 1, 99, 1, 1, 5, 5, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 5, 20,
                            20,  1,  1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1
                        };
                        int item = ServerManager.Instance.RandomNumber(0, 42);
                        session.Character.GiftAdd(vnums[item], counts[item]);
                    }
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                else if (session.HasCurrentMapInstance && session.CurrentMapInstance.Map.MapTypes.All(m => m.MapTypeId != (short)MapTypeEnum.Act4))
                {
                    short[] vnums = { 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405 };
                    short   vnum  = vnums[ServerManager.Instance.RandomNumber(0, 20)];

                    NpcMonster npcmonster = ServerManager.Instance.GetNpc(vnum);
                    if (npcmonster == null)
                    {
                        return;
                    }
                    MapMonster monster = new MapMonster
                    {
                        MonsterVNum   = vnum,
                        MapY          = session.Character.MapY,
                        MapX          = session.Character.MapX,
                        MapId         = session.Character.MapInstance.Map.MapId,
                        Position      = session.Character.Direction,
                        IsMoving      = true,
                        MapMonsterId  = session.CurrentMapInstance.GetNextMonsterId(),
                        ShouldRespawn = false
                    };
                    monster.Initialize(session.CurrentMapInstance);
                    session.CurrentMapInstance.AddMonster(monster);
                    session.CurrentMapInstance.Broadcast(monster.GenerateIn());
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            // Golden Bazaar Medal
            case 1003:
                if (!session.Character.StaticBonusList.Any(s => s.StaticBonusType == StaticBonusType.BazaarMedalGold || s.StaticBonusType == StaticBonusType.BazaarMedalSilver))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.BazaarMedalGold
                    });
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            // Silver Bazaar Medal
            case 1004:
                if (!session.Character.StaticBonusList.Any(s => s.StaticBonusType == StaticBonusType.BazaarMedalGold || s.StaticBonusType == StaticBonusType.BazaarMedalGold))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.BazaarMedalSilver
                    });
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            // Pet Slot Expansion
            case 1006:
                if (Option == 0)
                {
                    session.SendPacket($"qna #u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^2 {Language.Instance.GetMessageFromKey("ASK_PET_MAX")}");
                }
                else if (session.Character.MaxMateCount < 30)
                {
                    session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("GET_PET_PLACES"), 10));
                    session.SendPacket(session.Character.GenerateScpStc());
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            // Pet Basket
            case 1007:
                if (session.Character.StaticBonusList.All(s => s.StaticBonusType != StaticBonusType.PetBasket))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.PetBasket
                    });
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.SendPacket(session.Character.GenerateExts());
                    session.SendPacket("ib 1278 1");
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            // Partner's Backpack
            case 1008:
                if (session.Character.StaticBonusList.All(s => s.StaticBonusType != StaticBonusType.PetBackPack))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.PetBackPack
                    });
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.SendPacket(session.Character.GenerateExts());
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            // Backpack Expansion
            case 1009:
                if (session.Character.StaticBonusList.All(s => s.StaticBonusType != StaticBonusType.BackPack))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.BackPack
                    });
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    session.SendPacket(session.Character.GenerateExts());
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            // Sealed Tarot Card
            case 1005:
                session.Character.GiftAdd((short)(VNum - Effect), 1);
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                break;

            // Tarot Card Game
            case 1894:
                if (EffectValue == 0)
                {
                    for (int i = 0; i < 5; i++)
                    {
                        session.Character.GiftAdd((short)(Effect + ServerManager.Instance.RandomNumber(0, 10)), 1);
                    }
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                }
                break;

            // Sealed Tarot Card
            case 2152:
                session.Character.GiftAdd((short)(VNum + Effect), 1);
                session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                break;

            default:
                switch (VNum)
                {
                case 5841:
                    int     rnd   = ServerManager.Instance.RandomNumber(0, 1000);
                    short[] vnums = null;
                    if (rnd < 900)
                    {
                        vnums = new short[] { 4356, 4357, 4358, 4359 };
                    }
                    else
                    {
                        vnums = new short[] { 4360, 4361, 4362, 4363 };
                    }
                    session.Character.GiftAdd(vnums[ServerManager.Instance.RandomNumber(0, 4)], 1);
                    session.Character.Inventory.RemoveItemFromInventory(inv.Id);
                    break;

                default:
                    Logger.Warn(string.Format(Language.Instance.GetMessageFromKey("NO_HANDLER_ITEM"), GetType()) + $" ItemVNum: {VNum} Effect: {Effect} EffectValue: {EffectValue}");
                    break;
                }
                break;
            }
        }
Ejemplo n.º 26
0
        public override void Use(ClientSession session, ref ItemInstance inv, byte Option = 0, string[] packetsplit = null)
        {
            inv.Item.BCards.ForEach(c => c.ApplyBCards(session.Character));

            switch (Effect)
            {
            // sp point potions
            case 150:
            case 151:
                session.Character.SpAdditionPoint += EffectValue;
                if (session.Character.SpAdditionPoint > 1000000)
                {
                    session.Character.SpAdditionPoint = 1000000;
                }
                session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("SP_POINTSADDED"), EffectValue), 0));
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                session.SendPacket(session.Character.GenerateSpPoint());
                break;

            case 204:
                session.Character.SpPoint         += EffectValue;
                session.Character.SpAdditionPoint += EffectValue * 3;
                if (session.Character.SpAdditionPoint > 1000000)
                {
                    session.Character.SpAdditionPoint = 1000000;
                }
                if (session.Character.SpPoint > 10000)
                {
                    session.Character.SpPoint = 10000;
                }
                session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("SP_POINTSADDEDBOTH"), EffectValue, EffectValue * 3), 0));
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                session.SendPacket(session.Character.GenerateSpPoint());
                break;

            case 301:
                if (ServerManager.Instance.IsCharacterMemberOfGroup(session.Character.CharacterId))
                {
                    //TODO you are in group
                    return;
                }
                ItemInstance raidSeal = session.Character.Inventory.LoadBySlotAndType <ItemInstance>(inv.Slot, InventoryType.Main);
                session.Character.Inventory.RemoveItemAmountFromInventory(1, raidSeal.Id);

                ScriptedInstance raid = ServerManager.Instance.Raids.FirstOrDefault(s => s.RequieredItems.Any(obj => obj.VNum == raidSeal.ItemVNum)).GetClone();
                if (raid != null)
                {
                    Group group = new Group(GroupType.Team);
                    group.Raid = raid;
                    group.JoinGroup(session.Character.CharacterId);
                    ServerManager.Instance.AddGroup(group);
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("YOU_ARE_RAID_CHIEF"), session.Character.Name), 0));
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("YOU_ARE_RAID_CHIEF"), session.Character.Name), 10));
                    if (session.Character.Level > raid.LevelMaximum || session.Character.Level < raid.LevelMinimum)
                    {
                        session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("RAID_LEVEL_INCORRECT"), 10));
                    }
                    session.SendPacket(session.Character.GenerateRaid(2, false));
                    session.SendPacket(session.Character.GenerateRaid(0, false));
                    session.SendPacket(session.Character.GenerateRaid(1, false));
                    session.SendPacket(group.GenerateRdlst());
                }
                break;

            case 305:
                Mate mate = session.Character.Mates.FirstOrDefault(s => s.MateTransportId == int.Parse(packetsplit[3]));
                if (mate != null && EffectValue == mate.NpcMonsterVNum && mate.Skin == 0)
                {
                    mate.Skin = Morph;
                    session.SendPacket(mate.GenerateCMode(mate.Skin));
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                }
                break;

            //Atk/Def/HP/Exp potions
            case 6600:
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                break;

            case 208:
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                session.Character.AddStaticBuff(new StaticBuffDTO()
                {
                    CardId = 121
                });
                break;

            // Divorce letter
            case 6969:     // this is imaginary number I = √(-1)
                break;

            // Cupid's arrow
            case 34:     // this is imaginary number I = √(-1)
                break;

            case 570:
                if (session.Character.Faction == EffectValue)
                {
                    return;
                }
                session.SendPacket(session.Character.Family == null
                        ? $"qna #guri^750^{EffectValue} {Language.Instance.GetMessageFromKey($"ASK_CHANGE_FACTION{EffectValue}")}"
                        : UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("IN_FAMILY"),
                                                                   0));
                break;

            // wings
            case 650:
                SpecialistInstance specialistInstance = session.Character.Inventory.LoadBySlotAndType <SpecialistInstance>((byte)EquipmentType.Sp, InventoryType.Wear);
                if (session.Character.UseSp && specialistInstance != null)
                {
                    if (Option == 0)
                    {
                        session.SendPacket($"qna #u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^3 {Language.Instance.GetMessageFromKey("ASK_WINGS_CHANGE")}");
                    }
                    else
                    {
                        specialistInstance.Design       = (byte)EffectValue;
                        session.Character.MorphUpgrade2 = EffectValue;
                        session.CurrentMapInstance?.Broadcast(session.Character.GenerateCMode());
                        session.SendPacket(session.Character.GenerateStat());
                        session.SendPacket(session.Character.GenerateStatChar());
                        session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    }
                }
                else
                {
                    session.SendPacket(
                        UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("NO_SP"), 0));
                }
                break;

            // presentation messages
            case 203:
                if (!session.Character.IsVehicled)
                {
                    if (Option == 0)
                    {
                        session.SendPacket(UserInterfaceHelper.Instance.GenerateGuri(10, 2, session.Character.CharacterId, 1));
                    }
                }
                break;

            // magic lamps
            case 651:
                if (session.Character.Inventory.GetAllItems().All(i => i.Type != InventoryType.Wear))
                {
                    if (Option == 0)
                    {
                        session.SendPacket($"qna #u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^3 {Language.Instance.GetMessageFromKey("ASK_USE")}");
                    }
                    else
                    {
                        session.Character.ChangeSex();
                        session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    }
                }
                else
                {
                    session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("EQ_NOT_EMPTY"), 0));
                }
                break;

            // vehicles
            case 1000:
                if (Morph > 0)
                {
                    if (Option == 0 && !session.Character.IsVehicled)
                    {
                        if (session.Character.IsSitting)
                        {
                            session.Character.IsSitting = false;
                            session.CurrentMapInstance?.Broadcast(session.Character.GenerateRest());
                        }
                        session.Character.LastDelay = DateTime.Now;
                        session.SendPacket(UserInterfaceHelper.Instance.GenerateDelay(3000, 3, $"#u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^2"));
                    }
                    else
                    {
                        if (!session.Character.IsVehicled && Option != 0)
                        {
                            DateTime delay = DateTime.Now.AddSeconds(-4);
                            if (session.Character.LastDelay > delay && session.Character.LastDelay < delay.AddSeconds(2))
                            {
                                session.Character.Speed         = Speed;
                                session.Character.IsVehicled    = true;
                                session.Character.VehicleSpeed  = Speed;
                                session.Character.MorphUpgrade  = 0;
                                session.Character.MorphUpgrade2 = 0;
                                session.Character.Morph         = Morph + (byte)session.Character.Gender;
                                session.CurrentMapInstance?.Broadcast(session.Character.GenerateEff(196), session.Character.MapX, session.Character.MapY);
                                session.CurrentMapInstance?.Broadcast(session.Character.GenerateCMode());
                                session.SendPacket(session.Character.GenerateCond());
                                session.Character.LastSpeedChange = DateTime.Now;
                            }
                        }
                        else if (session.Character.IsVehicled)
                        {
                            session.Character.RemoveVehicle();
                        }
                    }
                }
                break;

            case 1002:
                if (EffectValue == 69)
                {
                    int rnd = ServerManager.Instance.RandomNumber(0, 1000);
                    if (rnd < 5)
                    {
                        short[] vnums =
                        {
                            5560, 5591, 4099, 907, 1160, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714,
                            4715, 4716
                        };
                        byte[] counts = { 1, 1, 1, 1, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
                        int    item   = ServerManager.Instance.RandomNumber(0, 17);

                        session.Character.GiftAdd(vnums[item], counts[item]);
                    }
                    else if (rnd < 30)
                    {
                        short[] vnums = { 361, 362, 363, 366, 367, 368, 371, 372, 373 };
                        session.Character.GiftAdd(vnums[ServerManager.Instance.RandomNumber(0, 9)], 1);
                    }
                    else
                    {
                        short[] vnums =
                        {
                            1161, 2282, 1030, 1244, 1218, 5369, 1012, 1363, 1364, 2160, 2173, 5959, 5983, 2514,
                            2515, 2516, 2517, 2518, 2519, 2520, 2521, 1685, 1686, 5087, 5203, 2418, 2310, 2303,
                            2169, 2280, 5892, 5893, 5894, 5895, 5896, 5897, 5898, 5899, 5332, 5105, 2161, 2162
                        };
                        byte[] counts =
                        {
                            10, 10, 20, 5, 1, 1, 99, 1, 1, 5, 5, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 5, 20,
                            20,  1,  1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1
                        };
                        int item = ServerManager.Instance.RandomNumber(0, 42);
                        session.Character.GiftAdd(vnums[item], counts[item]);
                    }
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                }
                else
                {
                    if (session.HasCurrentMapInstance)
                    {
                        if (session.CurrentMapInstance.Map.MapTypes.All(m => m.MapTypeId != (short)MapTypeEnum.Act4))
                        {
                            short[] vnums =
                            {
                                1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399,
                                1400, 1401, 1402, 1403, 1404, 1405
                            };
                            short vnum = vnums[ServerManager.Instance.RandomNumber(0, 20)];

                            NpcMonster npcmonster = ServerManager.Instance.GetNpc(vnum);
                            if (npcmonster == null)
                            {
                                return;
                            }
                            MapMonster monster = new MapMonster
                            {
                                MonsterVNum   = vnum,
                                MapY          = session.Character.MapY,
                                MapX          = session.Character.MapX,
                                MapId         = session.Character.MapInstance.Map.MapId,
                                Position      = (byte)session.Character.Direction,
                                IsMoving      = true,
                                MapMonsterId  = session.CurrentMapInstance.GetNextMonsterId(),
                                ShouldRespawn = false
                            };
                            monster.Initialize(session.CurrentMapInstance);
                            session.CurrentMapInstance.AddMonster(monster);
                            session.CurrentMapInstance.Broadcast(monster.GenerateIn());
                            session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                        }
                    }
                }
                break;

            case 69:
                session.Character.Reput += ReputPrice;
                session.SendPacket(session.Character.GenerateFd());
                session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                break;

            case 1003:
                if (!session.Character.StaticBonusList.Any(s => s.StaticBonusType == StaticBonusType.BazaarMedalGold || s.StaticBonusType == StaticBonusType.BazaarMedalSilver))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.BazaarMedalGold
                    });
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            case 1004:
                if (!session.Character.StaticBonusList.Any(s => s.StaticBonusType == StaticBonusType.BazaarMedalGold || s.StaticBonusType == StaticBonusType.BazaarMedalGold))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.BazaarMedalSilver
                    });
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            case 1005:
                if (session.Character.StaticBonusList.All(s => s.StaticBonusType != StaticBonusType.BackPack))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.BackPack
                    });
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    session.SendPacket(session.Character.GenerateExts());
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            case 1006:
                if (Option == 0)
                {
                    session.SendPacket($"qna #u_i^1^{session.Character.CharacterId}^{(byte)inv.Type}^{inv.Slot}^2 {Language.Instance.GetMessageFromKey("ASK_PET_MAX")}");
                }
                else
                {
                    if (session.Character.MaxMateCount < 30)
                    {
                        session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("GET_PET_PLACES"), 10));
                        session.SendPacket(session.Character.GenerateScpStc());
                        session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    }
                }
                break;

            case 1007:
                if (session.Character.StaticBonusList.All(s => s.StaticBonusType != StaticBonusType.PetBasket))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.PetBasket
                    });
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    session.SendPacket(session.Character.GenerateExts());
                    session.SendPacket("ib 1278 1");
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            case 1008:
                if (session.Character.StaticBonusList.All(s => s.StaticBonusType != StaticBonusType.PetBackPack))
                {
                    session.Character.StaticBonusList.Add(new StaticBonusDTO
                    {
                        CharacterId     = session.Character.CharacterId,
                        DateEnd         = DateTime.Now.AddDays(EffectValue),
                        StaticBonusType = StaticBonusType.PetBackPack
                    });
                    session.Character.Inventory.RemoveItemAmountFromInventory(1, inv.Id);
                    session.SendPacket(session.Character.GenerateExts());
                    session.SendPacket(session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("EFFECT_ACTIVATED"), Name), 12));
                }
                break;

            default:
                Logger.Log.Warn(string.Format(Language.Instance.GetMessageFromKey("NO_HANDLER_ITEM"), GetType()));
                break;
            }
        }
Ejemplo n.º 27
0
        internal void NpcLife()
        {
            double time = (DateTime.Now - LastEffect).TotalMilliseconds;

            if (Effect > 0 && time > EffectDelay)
            {
                Map.Broadcast(GenerateEff(), MapX, MapY);
                LastEffect = DateTime.Now;
            }

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

                byte xpoint = (byte)_random.Next(fpoint, point);
                byte ypoint = (byte)(point - xpoint);

                short mapX = FirstX;
                short mapY = FirstY;

                if (Map.GetFreePosition(ref mapX, ref mapY, xpoint, ypoint))
                {
                    Observable.Timer(TimeSpan.FromMilliseconds(1000 * (xpoint + ypoint) / (2 * Npc.Speed)))
                    .Subscribe(
                        x =>
                    {
                        this.MapX = mapX;
                        this.MapY = mapY;
                    });

                    LastMove = DateTime.Now.AddSeconds((xpoint + ypoint) / (2 * Npc.Speed));
                    Map.Broadcast(new BroadcastPacket(null, GenerateMv2(), ReceiverType.AllInRange, xCoordinate: mapX, yCoordinate: mapY));
                }
            }
            if (Target == -1)
            {
                if (this.Npc.IsHostile && this.Shop == null)
                {
                    MapMonster monster = this.Map.Monsters.FirstOrDefault(s => MapId == s.MapId && 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 = this.Map.Sessions.FirstOrDefault(s => MapId == s.Character.MapId && Map.GetDistance(new MapCell()
                    {
                        X = MapX, Y = MapY
                    }, new MapCell()
                    {
                        X = s.Character.MapX, Y = s.Character.MapY
                    }) < Npc.NoticeRange);

                    if (monster != null && session != null)
                    {
                        Target = monster.MapMonsterId;
                    }
                }
            }
            else if (Target != -1)
            {
                MapMonster monster = this.Map.Monsters.FirstOrDefault(s => s.MapMonsterId == Target);
                if (monster == null || monster.CurrentHp < 1)
                {
                    Target = -1;
                    return;
                }
                NpcMonsterSkill npcMonsterSkill = null;
                if (_random.Next(10) > 8)
                {
                    npcMonsterSkill = Npc.Skills.Where(s => (DateTime.Now - s.LastSkillUse).TotalMilliseconds >= 100 * s.Skill.Cooldown).OrderBy(rnd => _random.Next()).FirstOrDefault();
                }

                short damage   = 100;
                int   distance = Map.GetDistance(new MapCell()
                {
                    X = MapX, Y = MapY
                }, new MapCell()
                {
                    X = monster.MapX, Y = monster.MapY
                });
                if (monster != null && monster.CurrentHp > 0 && ((npcMonsterSkill != null && distance < npcMonsterSkill.Skill.Range) || (distance <= Npc.BasicRange)))
                {
                    if (((DateTime.Now - LastEffect).TotalMilliseconds >= 1000 + Npc.BasicCooldown * 200 && !Npc.Skills.Any()) || npcMonsterSkill != null)
                    {
                        if (npcMonsterSkill != null)
                        {
                            npcMonsterSkill.LastSkillUse = DateTime.Now;
                            Map.Broadcast($"ct 2 {MapNpcId} 3 {Target} {npcMonsterSkill.Skill.CastAnimation} {npcMonsterSkill.Skill.CastEffect} {npcMonsterSkill.Skill.SkillVNum}");
                        }

                        if (npcMonsterSkill != null && npcMonsterSkill.Skill.CastEffect != 0)
                        {
                            Map.Broadcast(GenerateEff());
                        }

                        monster.CurrentHp -= damage;

                        if (npcMonsterSkill != null)
                        {
                            Map.Broadcast($"su 2 {MapNpcId} 3 {Target} {npcMonsterSkill.SkillVNum} {npcMonsterSkill.Skill.Cooldown} {npcMonsterSkill.Skill.AttackAnimation} {npcMonsterSkill.Skill.Effect} 0 0 {(monster.CurrentHp > 0 ? 1 : 0)} { (int)(monster.CurrentHp / monster.Monster.MaxHP * 100) } {damage} 0 0");
                        }
                        else
                        {
                            Map.Broadcast($"su 2 {MapNpcId} 3 {Target} 0 {Npc.BasicCooldown} 11 {Npc.BasicSkill} 0 0 {(monster.CurrentHp > 0 ? 1 : 0)} { (int)(monster.CurrentHp / monster.Monster.MaxHP * 100) } {damage} 0 0");
                        }

                        LastEffect = DateTime.Now;
                        if (monster.CurrentHp < 1)
                        {
                            if (IsMoving)
                            {
                                Path = Map.StraightPath(new GridPos()
                                {
                                    x = this.MapX, y = this.MapY
                                }, new GridPos()
                                {
                                    x = FirstX, y = FirstY
                                });
                                if (!Path.Any())
                                {
                                    Path = Map.JPSPlus(JumpPointParameters, new GridPos()
                                    {
                                        x = this.MapX, y = this.MapY
                                    }, new GridPos()
                                    {
                                        x = FirstX, y = FirstY
                                    });
                                }
                            }

                            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)
                    {
                        short maxDistance = 5;
                        if (Path.Count() == 0 && monster != null && distance > 1 && distance < maxDistance)
                        {
                            short xoffset = (short)_random.Next(-1, 1);
                            short yoffset = (short)_random.Next(-1, 1);

                            Path = Map.StraightPath(new GridPos()
                            {
                                x = this.MapX, y = this.MapY
                            }, new GridPos()
                            {
                                x = (short)(monster.MapX + xoffset), y = (short)(monster.MapY + yoffset)
                            });
                            if (!Path.Any())
                            {
                                Path = Map.JPSPlus(JumpPointParameters, new GridPos()
                                {
                                    x = this.MapX, y = this.MapY
                                }, new GridPos()
                                {
                                    x = (short)(monster.MapX + xoffset), y = (short)(monster.MapY + yoffset)
                                });
                            }
                        }
                        if (DateTime.Now > LastMove && Npc.Speed > 0 && Path.Any())
                        {
                            short mapX;
                            short mapY;
                            int   maxindex = (Path.Count > Npc.Speed / 2 && Npc.Speed > 1) ? Npc.Speed / 2 : Path.Count;
                            mapX = (short)Path.ElementAt(maxindex - 1).x;
                            mapY = (short)Path.ElementAt(maxindex - 1).y;
                            double waitingtime = (double)(Map.GetDistance(new MapCell()
                            {
                                X = mapX, Y = mapY, MapId = MapId
                            }, new MapCell()
                            {
                                X = MapX, Y = MapY, MapId = MapId
                            })) / (double)(Npc.Speed);
                            Map.Broadcast(new BroadcastPacket(null, $"mv 2 {this.MapNpcId} {mapX} {mapY} {Npc.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 =>
                            {
                                this.MapX = mapX;
                                this.MapY = mapY;
                            });

                            for (int j = maxindex; j > 0; j--)
                            {
                                Path.RemoveAt(0);
                            }
                        }
                        if (Path.Count() == 0 && (monster == null || MapId != monster.MapId || distance > maxDistance))
                        {
                            Path = Map.StraightPath(new GridPos()
                            {
                                x = this.MapX, y = this.MapY
                            }, new GridPos()
                            {
                                x = FirstX, y = FirstY
                            });
                            if (!Path.Any())
                            {
                                Path = Map.JPSPlus(JumpPointParameters, new GridPos()
                                {
                                    x = this.MapX, y = this.MapY
                                }, new GridPos()
                                {
                                    x = FirstX, y = FirstY
                                });
                            }
                            Target = -1;
                        }
                    }
                    else
                    {
                        if (distance > maxdistance)
                        {
                            Target = -1;
                        }
                    }
                }
            }
        }
Ejemplo n.º 28
0
 public void RemoveMonster(MapMonster monsterToRemove)
 {
     _monsters.Remove(monsterToRemove.MapMonsterId);
 }
Ejemplo n.º 29
0
 public void AddDelayedMonster(MapMonster monster) => _delayedMonsters[monster.MapMonsterId] = monster;
Ejemplo n.º 30
0
        public void ApplyBCards(object session, object caster = null)
        {
            switch ((BCardType.CardType)Type)
            {
            case BCardType.CardType.Buff:
                if (session.GetType() == typeof(Character))
                {
                    if (ServerManager.Instance.RandomNumber() < FirstData)
                    {
                        Character character = session as Character;
                        character?.AddBuff(new Buff(SecondData, character.Level));
                    }
                }
                else if (session.GetType() == typeof(MapMonster))
                {
                    if (ServerManager.Instance.RandomNumber() < FirstData)
                    {
                        if (session is MapMonster monster)
                        {
                            monster.AddBuff(!(caster is Character character) ? new Buff(SecondData, 1) : new Buff(SecondData, character.Level));
                        }
                    }
                }
                else if (session.GetType() == typeof(MapNpc))
                {
                }
                else if (session.GetType() == typeof(Mate))
                {
                }
                break;

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

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

                        default:
                            if (monster.OnDeathEvents.All(s => s.EventActionType != EventActionType.SPAWNMONSTERS))
                            {
                                monster.OnDeathEvents.Add(new EventContainer(monster.MapInstance, EventActionType.SPAWNMONSTERS, summonParameters));
                            }
                            break;
                        }
                    }
                }
                else if (session.GetType() == typeof(MapNpc))
                {
                }
                else if (session.GetType() == 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:
                AdditionalTypes.HealingBurningAndCasting subtype = (AdditionalTypes.HealingBurningAndCasting)SubType;
                switch (subtype)
                {
                case AdditionalTypes.HealingBurningAndCasting.RestoreHP:
                case AdditionalTypes.HealingBurningAndCasting.RestoreHPWhenCasting:
                    if (session is Character sess)
                    {
                        int  heal   = FirstData;
                        bool change = false;
                        if (IsLevelScaled)
                        {
                            if (IsLevelDivided)
                            {
                                heal /= sess.Level;
                            }
                            else
                            {
                                heal *= sess.Level;
                            }
                        }
                        sess.Session?.CurrentMapInstance?.Broadcast(sess.GenerateRc(heal));
                        if (sess.Hp + heal < sess.HPLoad())
                        {
                            sess.Hp += heal;
                            change   = true;
                        }
                        else
                        {
                            if (sess.Hp != (int)sess.HPLoad())
                            {
                                change = true;
                            }
                            sess.Hp = (int)sess.HPLoad();
                        }
                        if (change)
                        {
                            sess.Session?.SendPacket(sess.GenerateStat());
                        }
                    }
                    break;
                }
                break;

            case BCardType.CardType.HPMP:
                break;

            case BCardType.CardType.SpecialisationBuffResistance:
                break;

            case BCardType.CardType.SpecialEffects:
                break;

            case BCardType.CardType.Capture:
                if (session.GetType() == typeof(MapMonster))
                {
                    if (caster is Character)
                    {
                        MapMonster monster   = session as MapMonster;
                        Character  character = caster as Character;
                        if (monster != null && character != null)
                        {
                            if (monster.Monster.RaceType == 1 && (character.MapInstance.MapInstanceType == MapInstanceType.BaseMapInstance || character.MapInstance.MapInstanceType == MapInstanceType.TimeSpaceInstance))
                            {
                                if (monster.Monster.Level < character.Level)
                                {
                                    if (monster.CurrentHp < (monster.Monster.MaxHP / 2))
                                    {
                                        if (character.MaxMateCount == character.Mates.Count())
                                        {
                                            // Algo
                                            int capturerate = ((character.Level / monster.Monster.Level) / (monster.CurrentHp / monster.Monster.MaxHP) * 3);
                                            if (ServerManager.Instance.RandomNumber() <= capturerate)
                                            {
                                                Mate currentmate = character.Mates.FirstOrDefault(m => m.IsTeamMember == true);
                                                if (currentmate != null)
                                                {
                                                    currentmate.IsTeamMember = false;
                                                    character.Session.CurrentMapInstance.Broadcast(currentmate.GenerateOut());
                                                }
                                                monster.MapInstance.DespawnMonster(monster);
                                                NpcMonster mateNpc = ServerManager.Instance.GetNpc(monster.Monster.NpcMonsterVNum);
                                                byte       lvl     = 0;
                                                lvl += monster.Monster.Level;
                                                lvl -= 10;
                                                if (lvl <= 0)
                                                {
                                                    lvl = 1;
                                                }
                                                Mate mate = new Mate(character, mateNpc, lvl, MateType.Pet);
                                                character.Mates.Add(mate);
                                                mate.IsTeamMember = true;
                                                character.Session.SendPacket($"ctl 2 {mate.PetId} 3");
                                                character.MapInstance.Broadcast(mate.GenerateIn());
                                                character.Session.SendPacket(character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("YOU_GET_PET"), mate.Name), 0));
                                                character.Session.SendPacket(UserInterfaceHelper.Instance.GeneratePClear());
                                                character.Session.SendPackets(character.GenerateScP());
                                                character.Session.SendPackets(character.GenerateScN());
                                                character.Session.SendPacket(UserInterfaceHelper.Instance.GeneratePClear());
                                                character.Session.SendPackets(character.GenerateScP());
                                                character.Session.SendPackets(character.GenerateScN());
                                                character.Session.SendPacket(character.GeneratePinit());
                                                character.Session.SendPackets(character.GeneratePst());
                                            }
                                            else
                                            {
                                                character.Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("CAPTURE_FAILED"), 0));
                                            }
                                        }
                                        else
                                        {
                                            character.Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("MAX_MATES_COUNT"), 0));
                                        }
                                    }
                                    else
                                    {
                                        character.Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("MONSTER_MUST_BE_LOW_HP"), 0));
                                    }
                                }
                                else
                                {
                                    character.Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("MONSTER_LVL_MUST_BE_LESS"), 0));
                                }
                            }
                            else
                            {
                                character.Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("MONSTER_CANNOT_BE_CAPTURED"), 0));
                            }
                        }
                    }
                }
                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:

                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;

            default:
                Logger.Error(new ArgumentOutOfRangeException($"Card Type {Type} not defined!"));
                //throw new ArgumentOutOfRangeException();
                break;
            }
        }
Ejemplo n.º 31
0
 public void RemoveDelayedMonster(MapMonster monsterToRemove) => _delayedMonsters.Remove(monsterToRemove.MapMonsterId);
Ejemplo n.º 32
0
        /// <summary>
        /// Handle any kind of Monster interaction
        /// </summary>
        private void monsterLife()
        {
            if (Monster == null)
            {
                return;
            }
            if ((DateTime.Now - LastEffect).TotalSeconds >= 5)
            {
                LastEffect = DateTime.Now;
                if (IsTarget)
                {
                    MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Monster, MapMonsterId, 824));
                }
                if (IsBonus)
                {
                    MapInstance.Broadcast(StaticPacketHelper.GenerateEff(UserType.Monster, MapMonsterId, 826));
                }
            }

            if (IsBoss && IsAlive)
            {
                MapInstance.Broadcast(GenerateBoss());
            }

            // handle hit queue
            while (HitQueue.TryDequeue(out HitRequest hitRequest))
            {
                if (IsAlive && hitRequest.Session.Character.Hp > 0 && (ServerManager.Instance.ChannelId != 51 || MonsterVNum - (byte)hitRequest.Session.Character.Faction != 678))
                {
                    int  hitmode        = 0;
                    bool isCaptureSkill = hitRequest.Skill.BCards.Any(s => s.Type.Equals((byte)CardType.Capture));

                    // calculate damage
                    bool         onyxWings    = false;
                    BattleEntity battleEntity = new BattleEntity(hitRequest.Session.Character, hitRequest.Skill);
                    int          damage       = DamageHelper.Instance.CalculateDamage(battleEntity, new BattleEntity(this), hitRequest.Skill, ref hitmode, ref onyxWings);
                    if (onyxWings)
                    {
                        short      onyxX  = (short)(hitRequest.Session.Character.PositionX + 2);
                        short      onyxY  = (short)(hitRequest.Session.Character.PositionY + 2);
                        int        onyxId = MapInstance.GetNextMonsterId();
                        MapMonster onyx   = new MapMonster()
                        {
                            MonsterVNum = 2371, MapX = onyxX, MapY = onyxY, MapMonsterId = onyxId, IsHostile = false, IsMoving = false, ShouldRespawn = false
                        };
                        MapInstance.Broadcast(UserInterfaceHelper.Instance.GenerateGuri(31, 1, hitRequest.Session.Character.CharacterId, onyxX, onyxY));
                        onyx.Initialize(MapInstance);
                        MapInstance.AddMonster(onyx);
                        MapInstance.Broadcast(onyx.GenerateIn());
                        CurrentHp -= damage / 2;
                        Observable.Timer(TimeSpan.FromMilliseconds(350)).Subscribe(o =>
                        {
                            MapInstance.Broadcast(StaticPacketHelper.SkillUsed(UserType.Monster, onyxId, 3, MapMonsterId, -1, 0, -1, hitRequest.Skill.Effect, -1, -1, true, 92, damage / 2, 0, 0));
                            MapInstance.RemoveMonster(onyx);
                            MapInstance.Broadcast(StaticPacketHelper.Out(UserType.Monster, onyx.MapMonsterId));
                        });
                    }
                    if (hitmode != 1)
                    {
                        hitRequest.Skill.BCards.Where(s => s.Type.Equals((byte)CardType.Buff)).ToList().ForEach(s => s.ApplyBCards(this, hitRequest.Session));
                        hitRequest.Skill.BCards.Where(s => s.Type.Equals((byte)CardType.Capture)).ToList().ForEach(s => s.ApplyBCards(this, hitRequest.Session));
                        if (battleEntity?.ShellWeaponEffects != null)
                        {
                            foreach (ShellEffectDTO shell in battleEntity.ShellWeaponEffects)
                            {
                                switch (shell.Effect)
                                {
                                case (byte)ShellWeaponEffectType.Blackout:
                                {
                                    Buff buff = new Buff(7, battleEntity.Level);
                                    if (ServerManager.Instance.RandomNumber() < shell.Value)
                                    {
                                        AddBuff(buff);
                                    }
                                    break;
                                }

                                case (byte)ShellWeaponEffectType.DeadlyBlackout:
                                {
                                    Buff buff = new Buff(66, battleEntity.Level);
                                    if (ServerManager.Instance.RandomNumber() < shell.Value)
                                    {
                                        AddBuff(buff);
                                    }
                                    break;
                                }

                                case (byte)ShellWeaponEffectType.MinorBleeding:
                                {
                                    Buff buff = new Buff(1, battleEntity.Level);
                                    if (ServerManager.Instance.RandomNumber() < shell.Value)
                                    {
                                        AddBuff(buff);
                                    }
                                    break;
                                }

                                case (byte)ShellWeaponEffectType.Bleeding:
                                {
                                    Buff buff = new Buff(21, battleEntity.Level);
                                    if (ServerManager.Instance.RandomNumber() < shell.Value)
                                    {
                                        AddBuff(buff);
                                    }
                                    break;
                                }

                                case (byte)ShellWeaponEffectType.HeavyBleeding:
                                {
                                    Buff buff = new Buff(42, battleEntity.Level);
                                    if (ServerManager.Instance.RandomNumber() < shell.Value)
                                    {
                                        AddBuff(buff);
                                    }
                                    break;
                                }

                                case (byte)ShellWeaponEffectType.Freeze:
                                {
                                    Buff buff = new Buff(27, battleEntity.Level);
                                    if (ServerManager.Instance.RandomNumber() < shell.Value)
                                    {
                                        AddBuff(buff);
                                    }
                                    break;
                                }
                                }
                            }
                        }
                    }
                    if (DamageList.ContainsKey(hitRequest.Session.Character.CharacterId))
                    {
                        DamageList[hitRequest.Session.Character.CharacterId] += damage;
                    }
                    else
                    {
                        DamageList.Add(hitRequest.Session.Character.CharacterId, damage);
                    }
                    if (isCaptureSkill)
                    {
                        damage = 0;
                    }
                    if (CurrentHp <= damage)
                    {
                        SetDeathStatement();
                    }
                    else
                    {
                        CurrentHp -= damage;
                    }

                    // only set the hit delay if we become the monsters target with this hit
                    if (Target == -1)
                    {
                        LastSkill = DateTime.Now;
                    }

                    int nearestDistance = 100;
                    foreach (KeyValuePair <long, long> kvp in DamageList)
                    {
                        ClientSession session = MapInstance.GetSessionByCharacterId(kvp.Key);
                        if (session != null)
                        {
                            int distance = Map.GetDistance(new MapCell
                            {
                                X = MapX,
                                Y = MapY
                            }, new MapCell
                            {
                                X = session.Character.PositionX,
                                Y = session.Character.PositionY
                            });
                            if (distance < nearestDistance)
                            {
                                nearestDistance = distance;
                                Target          = session.Character.CharacterId;
                            }
                        }
                    }

                    switch (hitRequest.TargetHitType)
                    {
                    case TargetHitType.SingleTargetHit:
                        if (!isCaptureSkill)
                        {
                            MapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, hitRequest.Session.Character.CharacterId, 3, MapMonsterId, hitRequest.Skill.SkillVNum, hitRequest.Skill.Cooldown, hitRequest.Skill.AttackAnimation, hitRequest.SkillEffect, hitRequest.Session.Character.PositionX, hitRequest.Session.Character.PositionY, IsAlive, (int)((float)CurrentHp / (float)MaxHp * 100), damage, hitmode, (byte)(hitRequest.Skill.SkillType - 1)));
                        }
                        break;

                    case TargetHitType.SingleTargetHitCombo:
                        MapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, hitRequest.Session.Character.CharacterId, 3, MapMonsterId, hitRequest.Skill.SkillVNum, hitRequest.Skill.Cooldown, hitRequest.SkillCombo.Animation, hitRequest.SkillCombo.Effect, hitRequest.Session.Character.PositionX, hitRequest.Session.Character.PositionY, IsAlive, (int)((float)CurrentHp / (float)MaxHp * 100), damage, hitmode, (byte)(hitRequest.Skill.SkillType - 1)));
                        break;

                    case TargetHitType.SingleAOETargetHit:
                        switch (hitmode)
                        {
                        case 1:
                            hitmode = 4;
                            break;

                        case 3:
                            hitmode = 6;
                            break;

                        default:
                            hitmode = 5;
                            break;
                        }
                        if (hitRequest.ShowTargetHitAnimation)
                        {
                            MapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, hitRequest.Session.Character.CharacterId, 3, MapMonsterId, hitRequest.Skill.SkillVNum, hitRequest.Skill.Cooldown, hitRequest.Skill.AttackAnimation, hitRequest.SkillEffect, hitRequest.Session.Character.PositionX, hitRequest.Session.Character.PositionY, IsAlive, (int)((float)CurrentHp / (float)MaxHp * 100), damage, hitmode, (byte)(hitRequest.Skill.SkillType - 1)));
                        }
                        else
                        {
                            MapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, hitRequest.Session.Character.CharacterId, 3, MapMonsterId, 0, 0, 0, 0, 0, 0, IsAlive, (int)((float)CurrentHp / (float)MaxHp * 100), damage, hitmode, (byte)(hitRequest.Skill.SkillType - 1)));
                        }
                        break;

                    case TargetHitType.AOETargetHit:
                        switch (hitmode)
                        {
                        case 1:
                            hitmode = 4;
                            break;

                        case 3:
                            hitmode = 6;
                            break;

                        default:
                            hitmode = 5;
                            break;
                        }
                        MapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, hitRequest.Session.Character.CharacterId, 3, MapMonsterId, hitRequest.Skill.SkillVNum, hitRequest.Skill.Cooldown, hitRequest.Skill.AttackAnimation, hitRequest.SkillEffect, hitRequest.Session.Character.PositionX, hitRequest.Session.Character.PositionY, IsAlive, (int)((float)CurrentHp / (float)MaxHp * 100), damage, hitmode, (byte)(hitRequest.Skill.SkillType - 1)));
                        break;

                    case TargetHitType.ZoneHit:
                        MapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, hitRequest.Session.Character.CharacterId, 3, MapMonsterId, hitRequest.Skill.SkillVNum, hitRequest.Skill.Cooldown, hitRequest.Skill.AttackAnimation, hitRequest.SkillEffect, hitRequest.MapX, hitRequest.MapY, IsAlive, (int)((float)CurrentHp / (float)MaxHp * 100), damage, 5, (byte)(hitRequest.Skill.SkillType - 1)));
                        break;

                    case TargetHitType.SpecialZoneHit:
                        MapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, hitRequest.Session.Character.CharacterId, 3, MapMonsterId, hitRequest.Skill.SkillVNum, hitRequest.Skill.Cooldown, hitRequest.Skill.AttackAnimation, hitRequest.SkillEffect, hitRequest.Session.Character.PositionX, hitRequest.Session.Character.PositionY, IsAlive, (int)((float)CurrentHp / (float)MaxHp * 100), damage, hitmode, (byte)(hitRequest.Skill.SkillType - 1)));
                        break;
                    }

                    if (CurrentHp <= 0 && !isCaptureSkill)
                    {
                        // generate the kill bonus
                        hitRequest.Session.Character.GenerateKillBonus(this);
                    }
                }
                else
                {
                    // monster already has been killed, send cancel
                    hitRequest.Session.SendPacket(StaticPacketHelper.Cancel(2, MapMonsterId));
                }
                if (IsBoss)
                {
                    MapInstance.Broadcast(GenerateBoss());
                }
            }

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

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

            // target following
            else if (MapInstance != null)
            {
                GetNearestOponent();
                HostilityTarget();

                ClientSession targetSession = MapInstance.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 (Skills != null && ServerManager.Instance.RandomNumber(0, 10) > 8)
                {
                    npcMonsterSkill = Skills.Where(s => (DateTime.Now - s.LastSkillUse).TotalMilliseconds >= 100 * s.Skill?.Cooldown)?.OrderBy(rnd => _random.Next())?.FirstOrDefault();
                }

                if (npcMonsterSkill?.Skill.TargetType == 1 && npcMonsterSkill?.Skill.HitType == 0)
                {
                    targetHit(targetSession, npcMonsterSkill);
                }

                // check if target is in range
                if (!targetSession.Character.InvisibleGm && !targetSession.Character.Invisible && targetSession.Character.Hp > 0)
                {
                    if (npcMonsterSkill != null && CurrentMp >= npcMonsterSkill.Skill.MpCost &&
                        Map.GetDistance(new MapCell
                    {
                        X = MapX,
                        Y = MapY
                    },
                                        new MapCell
                    {
                        X = targetSession.Character.PositionX,
                        Y = targetSession.Character.PositionY
                    }) < npcMonsterSkill.Skill.Range)
                    {
                        targetHit(targetSession, npcMonsterSkill);
                    }
                    else if (Map.GetDistance(new MapCell
                    {
                        X = MapX,
                        Y = MapY
                    },
                                             new MapCell
                    {
                        X = targetSession.Character.PositionX,
                        Y = targetSession.Character.PositionY
                    }) <= Monster.BasicRange)
                    {
                        targetHit(targetSession, npcMonsterSkill);
                    }
                    else
                    {
                        followTarget(targetSession);
                    }
                }
                else
                {
                    followTarget(targetSession);
                }
            }
        }
Ejemplo n.º 33
0
 public void AddMonster(MapMonster monster) => _monsters[monster.MapMonsterId] = monster;
Ejemplo n.º 34
0
 private int GetGold(MapMonster mapMonster)
 {
     Random random = new Random(DateTime.Now.Millisecond + mapMonster.MapMonsterId);
     int lowBaseGold = random.Next(6 * mapMonster.Monster?.Level ?? 1, 12 * mapMonster.Monster?.Level ?? 1);
     int actMultiplier = Session?.CurrentMap?.MapTypes?.Any(s => s.MapTypeId == (short)MapTypeEnum.Act52) ?? false ? 10 : 1;
     int gold = lowBaseGold * ServerManager.GoldRate * actMultiplier;
     return gold;
 }
Ejemplo n.º 35
0
 public void RemoveMonster(MapMonster monsterToRemove) => _monsters.Remove(monsterToRemove.MapMonsterId);
Ejemplo n.º 36
0
 public void AddMonster(MapMonster monster)
 {
     _monsters[monster.MapMonsterId] = monster;
 }