コード例 #1
0
ファイル: MagicalItem.cs プロジェクト: YounessT28/NosServer
        public override void Use(ClientSession session, ref ItemInstance inv, byte Option = 0, string[] packetsplit = null)
        {
            if (session.Character.IsVehicled)
            {
                session.SendPacket(session.Character.GenerateSay(Language.Instance.GetMessageFromKey("CANT_DO_VEHICLED"), 10));
                return;
            }

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

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

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

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

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

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

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

                            case 1:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            default:
                Logger.Warn(string.Format(Language.Instance.GetMessageFromKey("NO_HANDLER_ITEM"), GetType(), VNum, Effect, EffectValue));
                break;
            }
        }
コード例 #2
0
        public static void NRun(ClientSession Session, NRunPacket packet)
        {
            if (!Session.HasCurrentMapInstance)
            {
                return;
            }
            MapNpc        npc = Session.CurrentMapInstance.Npcs.Find(s => s.MapNpcId == packet.NpcId);
            TeleporterDTO tp;

            switch (packet.Runner)
            {
            case 1:
                if (Session.Character.Class != (byte)ClassType.Adventurer)
                {
                    Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ADVENTURER"), 0));
                    return;
                }
                if (Session.Character.Level < 15 || Session.Character.JobLevel < 20)
                {
                    Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("LOW_LVL"), 0));
                    return;
                }
                if (packet.Type == (byte)Session.Character.Class)
                {
                    return;
                }
                if (Session.Character.Inventory.All(i => i.Type != InventoryType.Wear))
                {
                    Session.Character.Inventory.AddNewToInventory((short)(4 + (packet.Type * 14)), type: InventoryType.Wear);
                    Session.Character.Inventory.AddNewToInventory((short)(81 + (packet.Type * 13)), type: InventoryType.Wear);
                    switch (packet.Type)
                    {
                    case 1:
                        Session.Character.Inventory.AddNewToInventory(68, type: InventoryType.Wear);
                        Session.Character.Inventory.AddNewToInventory(2082, 10);
                        break;

                    case 2:
                        Session.Character.Inventory.AddNewToInventory(78, type: InventoryType.Wear);
                        Session.Character.Inventory.AddNewToInventory(2083, 10);
                        break;

                    case 3:
                        Session.Character.Inventory.AddNewToInventory(86, type: InventoryType.Wear);
                        break;
                    }
                    Session.CurrentMapInstance?.Broadcast(Session.Character.GenerateEq());
                    Session.SendPacket(Session.Character.GenerateEquipment());
                    Session.Character.ChangeClass((ClassType)packet.Type);
                }
                else
                {
                    Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("EQ_NOT_EMPTY"), 0));
                }
                break;

            case 2:
                Session.SendPacket("wopen 1 0");
                break;

            case 4:
                Mate mate = Session.Character.Mates.Find(s => s.MateTransportId == packet.NpcId);
                switch (packet.Type)
                {
                case 2:
                    if (mate != null)
                    {
                        if (Session.Character.Level >= mate.Level)
                        {
                            Mate teammate = Session.Character.Mates.Where(s => s.IsTeamMember).FirstOrDefault(s => s.MateType == mate.MateType);
                            if (teammate != null)
                            {
                                teammate.IsTeamMember = false;
                                teammate.MapX         = teammate.PositionX;
                                teammate.MapY         = teammate.PositionY;
                            }
                            mate.IsTeamMember = true;
                        }
                        else
                        {
                            Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("PET_HIGHER_LEVEL"), 0));
                        }
                    }
                    break;

                case 3:
                    if (mate != null && Session.Character.Miniland == Session.Character.MapInstance)
                    {
                        mate.IsTeamMember = false;
                        mate.MapX         = mate.PositionX;
                        mate.MapY         = mate.PositionY;
                    }
                    break;

                case 4:
                    if (mate != null)
                    {
                        if (Session.Character.Miniland == Session.Character.MapInstance)
                        {
                            mate.IsTeamMember = false;
                            mate.MapX         = mate.PositionX;
                            mate.MapY         = mate.PositionY;
                        }
                        else
                        {
                            Session.SendPacket($"qna #n_run^4^5^3^{mate.MateTransportId} {Language.Instance.GetMessageFromKey("ASK_KICK_PET")}");
                        }
                        break;
                    }
                    break;

                case 5:
                    if (mate != null)
                    {
                        Session.SendPacket(UserInterfaceHelper.GenerateDelay(3000, 10, $"#n_run^4^6^3^{mate.MateTransportId}"));
                    }
                    break;

                case 6:
                    if (mate != null && Session.Character.Miniland != Session.Character.MapInstance)
                    {
                        mate.IsTeamMember = false;
                        Session.CurrentMapInstance.Broadcast(mate.GenerateOut());
                        Session.SendPacket(Session.Character.GenerateSay(string.Format(Language.Instance.GetMessageFromKey("PET_KICKED"), mate.Name), 11));
                        Session.SendPacket(UserInterfaceHelper.GenerateMsg(string.Format(Language.Instance.GetMessageFromKey("PET_KICKED"), mate.Name), 0));
                    }
                    break;

                case 7:
                    if (mate != null)
                    {
                        if (Session.Character.Mates.Any(s => s.MateType == mate.MateType && s.IsTeamMember))
                        {
                            Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ALREADY_PET_IN_TEAM"), 11));
                            Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ALREADY_PET_IN_TEAM"), 0));
                        }
                        else
                        {
                            Session.SendPacket(UserInterfaceHelper.GenerateDelay(3000, 10, $"#n_run^4^9^3^{mate.MateTransportId}"));
                        }
                    }
                    break;

                case 9:
                    if (mate != null && Session.Character.Level >= mate.Level)
                    {
                        mate.PositionX    = (short)(Session.Character.PositionX + (mate.MateType == MateType.Partner ? -1 : 1));
                        mate.PositionY    = (short)(Session.Character.PositionY + 1);
                        mate.IsTeamMember = true;
                        Session.CurrentMapInstance?.Broadcast(mate.GenerateIn());
                    }
                    else
                    {
                        Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("PET_HIGHER_LEVEL"), 0));
                    }
                    break;
                }
                Session.SendPacket(Session.Character.GeneratePinit());
                Session.SendPackets(Session.Character.GeneratePst());
                break;

            case 10:
                Session.SendPacket("wopen 3 0");
                break;

            case 12:
                Session.SendPacket($"wopen {packet.Type} 0");
                break;

            case 14:
                Session.SendPacket("wopen 27 0");
                string recipelist = "m_list 2";
                if (npc != null)
                {
                    List <Recipe> tps = npc.Recipes;
                    recipelist  = tps.Where(s => s.Amount > 0).Aggregate(recipelist, (current, s) => current + $" {s.ItemVNum}");
                    recipelist += " -100";
                    Session.SendPacket(recipelist);
                }
                break;

            case 15:
                if (npc != null)
                {
                    if (packet.Value == 2)
                    {
                        Session.SendPacket($"qna #n_run^15^1^1^{npc.MapNpcId} {Language.Instance.GetMessageFromKey("ASK_CHANGE_SPAWNLOCATION")}");
                    }
                    else
                    {
                        switch (npc.MapId)
                        {
                        case 1:
                            Session.Character.SetRespawnPoint(1, 79, 116);
                            break;

                        case 20:
                            Session.Character.SetRespawnPoint(20, 9, 92);
                            break;

                        case 145:
                            Session.Character.SetRespawnPoint(145, 13, 110);
                            break;
                        }
                        Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("RESPAWNLOCATION_CHANGED"), 0));
                    }
                }
                break;

            case 16:
                tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type);
                if (tp != null)
                {
                    if (Session.Character.Gold >= 1000 * packet.Type)
                    {
                        Session.Character.Gold -= 1000 * packet.Type;
                        Session.SendPacket(Session.Character.GenerateGold());
                        ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY);
                    }
                    else
                    {
                        Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10));
                    }
                }
                break;

            case 17:
                double currentRunningSeconds   = (DateTime.Now - Process.GetCurrentProcess().StartTime.AddSeconds(-50)).TotalSeconds;
                double timeSpanSinceLastPortal = currentRunningSeconds - Session.Character.LastPortal;
                if (!(timeSpanSinceLastPortal >= 4) || !Session.HasCurrentMapInstance || ServerManager.Instance.ChannelId == 51 || Session.CurrentMapInstance.MapInstanceId == ServerManager.Instance.ArenaInstance.MapInstanceId || Session.CurrentMapInstance.MapInstanceId == ServerManager.Instance.FamilyArenaInstance.MapInstanceId)
                {
                    Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("CANT_MOVE"), 10));
                    return;
                }
                if (Session.Character.Gold >= 500 * (1 + packet.Type))
                {
                    Session.Character.LastPortal = currentRunningSeconds;
                    Session.Character.Gold      -= 500 * (1 + packet.Type);
                    Session.SendPacket(Session.Character.GenerateGold());
                    MapCell pos = packet.Type == 0 ? ServerManager.Instance.ArenaInstance.Map.GetRandomPosition() : ServerManager.Instance.FamilyArenaInstance.Map.GetRandomPosition();
                    ServerManager.Instance.ChangeMapInstance(Session.Character.CharacterId, packet.Type == 0 ? ServerManager.Instance.ArenaInstance.MapInstanceId : ServerManager.Instance.FamilyArenaInstance.MapInstanceId, pos.X, pos.Y);
                }
                else
                {
                    Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10));
                }
                break;

            case 18:
                Session.SendPacket(Session.Character.GenerateNpcDialog(17));
                break;

            case 26:
                tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type);
                if (tp != null)
                {
                    if (Session.Character.Gold >= 5000 * packet.Type)
                    {
                        Session.Character.Gold -= 5000 * packet.Type;
                        ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY);
                    }
                    else
                    {
                        Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10));
                    }
                }
                break;

            case 45:
                tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type);
                if (tp != null)
                {
                    if (Session.Character.Gold >= 500)
                    {
                        Session.Character.Gold -= 500;
                        Session.SendPacket(Session.Character.GenerateGold());
                        ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY);
                    }
                    else
                    {
                        Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10));
                    }
                }
                break;

            case 132:
                tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type);
                if (tp != null)
                {
                    ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY);
                }
                break;

            case 135:
                if (TalentArena.IsRunning)
                {
                    TalentArena.RegisteredParticipants[Session.Character.CharacterId] = Session;
                    Session.SendPacket(UserInterfaceHelper.GenerateBSInfo(0, 3, 300, 5));
                }
                break;

            case 150:
                if (npc != null)
                {
                    if (Session.Character.Family != null)
                    {
                        if (Session.Character.Family.LandOfDeath != null && npc.EffectActivated)
                        {
                            if (Session.Character.Level >= 55)
                            {
                                ServerManager.Instance.ChangeMapInstance(Session.Character.CharacterId, Session.Character.Family.LandOfDeath.MapInstanceId, 153, 145);
                            }
                            else
                            {
                                Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("LOD_REQUIERE_LVL"), 0));
                            }
                        }
                        else
                        {
                            Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("LOD_CLOSED"), 0));
                        }
                    }
                    else
                    {
                        Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("NEED_FAMILY"), 0));
                    }
                }
                break;

            case 301:
                tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type);
                if (tp != null)
                {
                    ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY);
                }
                break;

            case 1600:
                Session.SendPacket(Session.Character.OpenFamilyWarehouse());
                break;

            case 1601:
                Session.SendPackets(Session.Character.OpenFamilyWarehouseHist());
                break;

            case 1602:
                if (Session.Character.Family?.FamilyLevel >= 3 && Session.Character.Family.WarehouseSize < 21)
                {
                    if (Session.Character.FamilyCharacter.Authority == FamilyAuthority.Head)
                    {
                        if (500000 >= Session.Character.Gold)
                        {
                            Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10));
                            return;
                        }
                        Session.Character.Family.WarehouseSize = 21;
                        Session.Character.Gold -= 500000;
                        Session.SendPacket(Session.Character.GenerateGold());
                        FamilyDTO fam = Session.Character.Family;
                        DAOFactory.FamilyDAO.InsertOrUpdate(ref fam);
                        ServerManager.Instance.FamilyRefresh(Session.Character.Family.FamilyId);
                    }
                    else
                    {
                        Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 10));
                        Session.SendPacket(UserInterfaceHelper.GenerateModal(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 1));
                    }
                }
                break;

            case 1603:
                if (Session.Character.Family?.FamilyLevel >= 7 && Session.Character.Family.WarehouseSize < 49)
                {
                    if (Session.Character.FamilyCharacter.Authority == FamilyAuthority.Head)
                    {
                        if (2000000 >= Session.Character.Gold)
                        {
                            Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10));
                            return;
                        }
                        Session.Character.Family.WarehouseSize = 49;
                        Session.Character.Gold -= 2000000;
                        Session.SendPacket(Session.Character.GenerateGold());
                        FamilyDTO fam = Session.Character.Family;
                        DAOFactory.FamilyDAO.InsertOrUpdate(ref fam);
                        ServerManager.Instance.FamilyRefresh(Session.Character.Family.FamilyId);
                    }
                    else
                    {
                        Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 10));
                        Session.SendPacket(UserInterfaceHelper.GenerateModal(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 1));
                    }
                }
                break;

            case 1604:
                if (Session.Character.Family?.FamilyLevel >= 5 && Session.Character.Family.MaxSize < 70)
                {
                    if (Session.Character.FamilyCharacter.Authority == FamilyAuthority.Head)
                    {
                        if (5000000 >= Session.Character.Gold)
                        {
                            Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10));
                            return;
                        }
                        Session.Character.Family.MaxSize = 70;
                        Session.Character.Gold          -= 5000000;
                        Session.SendPacket(Session.Character.GenerateGold());
                        FamilyDTO fam = Session.Character.Family;
                        DAOFactory.FamilyDAO.InsertOrUpdate(ref fam);
                        ServerManager.Instance.FamilyRefresh(Session.Character.Family.FamilyId);
                    }
                    else
                    {
                        Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 10));
                        Session.SendPacket(UserInterfaceHelper.GenerateModal(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 1));
                    }
                }
                break;

            case 1605:
                if (Session.Character.Family?.FamilyLevel >= 9 && Session.Character.Family.MaxSize < 100)
                {
                    if (Session.Character.FamilyCharacter.Authority == FamilyAuthority.Head)
                    {
                        if (10000000 >= Session.Character.Gold)
                        {
                            Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10));
                            return;
                        }
                        Session.Character.Family.MaxSize = 100;
                        Session.Character.Gold          -= 10000000;
                        Session.SendPacket(Session.Character.GenerateGold());
                        FamilyDTO fam = Session.Character.Family;
                        DAOFactory.FamilyDAO.InsertOrUpdate(ref fam);
                        ServerManager.Instance.FamilyRefresh(Session.Character.Family.FamilyId);
                    }
                    else
                    {
                        Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 10));
                        Session.SendPacket(UserInterfaceHelper.GenerateModal(Language.Instance.GetMessageFromKey("ONLY_HEAD_CAN_BUY"), 1));
                    }
                }
                break;

            case 23:
                if (packet.Type == 0)
                {
                    if (Session.Character.Group?.CharacterCount == 3)
                    {
                        foreach (ClientSession s in Session.Character.Group.Characters.GetAllItems())
                        {
                            if (s.Character.Family != null)
                            {
                                Session.SendPacket(UserInterfaceHelper.GenerateInfo(Language.Instance.GetMessageFromKey("GROUP_MEMBER_ALREADY_IN_FAMILY")));
                                return;
                            }
                        }
                    }
                    if (Session.Character.Group == null || Session.Character.Group.CharacterCount != 3)
                    {
                        Session.SendPacket(UserInterfaceHelper.GenerateInfo(Language.Instance.GetMessageFromKey("FAMILY_GROUP_NOT_FULL")));
                        return;
                    }
                    Session.SendPacket(UserInterfaceHelper.GenerateInbox($"#glmk^ {14} 1 {Language.Instance.GetMessageFromKey("CREATE_FAMILY").Replace(' ', '^')}"));
                }
                else
                {
                    if (Session.Character.Family == null)
                    {
                        Session.SendPacket(UserInterfaceHelper.GenerateInfo(Language.Instance.GetMessageFromKey("NOT_IN_FAMILY")));
                        return;
                    }
                    if (Session.Character.Family != null && Session.Character.FamilyCharacter != null && Session.Character.FamilyCharacter.Authority != FamilyAuthority.Head)
                    {
                        Session.SendPacket(UserInterfaceHelper.GenerateInfo(Language.Instance.GetMessageFromKey("NOT_FAMILY_HEAD")));
                        return;
                    }
                    Session.SendPacket($"qna #glrm^1 {Language.Instance.GetMessageFromKey("DISMISS_FAMILY")}");
                }

                break;

            case 60:
                StaticBonusDTO medal = Session.Character.StaticBonusList.Find(s => s.StaticBonusType == StaticBonusType.BazaarMedalGold || s.StaticBonusType == StaticBonusType.BazaarMedalSilver);
                byte           Medal = 0;
                int            Time  = 0;
                if (medal != null)
                {
                    Medal = medal.StaticBonusType == StaticBonusType.BazaarMedalGold ? (byte)MedalType.Gold : (byte)MedalType.Silver;
                    Time  = (int)(medal.DateEnd - DateTime.Now).TotalHours;
                }
                Session.SendPacket($"wopen 32 {Medal} {Time}");
                break;

            case 5002:
                tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type);
                if (tp != null)
                {
                    //Session.SendPacket("it 3");
                    if (ServerManager.Instance.ChannelId == 51)
                    {
                        string connection = CommunicationServiceClient.Instance.RetrieveOriginWorld(Session.Account.AccountId);
                        if (string.IsNullOrWhiteSpace(connection))
                        {
                            return;
                        }
                        Session.Character.MapId = tp.MapId;
                        Session.Character.MapX  = tp.MapX;
                        Session.Character.MapY  = tp.MapY;
                        int port = Convert.ToInt32(connection.Split(':')[1]);
                        Session.Character.ChangeChannel(connection.Split(':')[0], port, 3);
                    }
                    else
                    {
                        ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY);
                    }
                }
                break;

            case 5001:
                if (npc != null)
                {
                    MapInstance map = null;
                    switch (Session.Character.Faction)
                    {
                    case FactionType.None:
                        Session.SendPacket(UserInterfaceHelper.GenerateInfo("You need to be part of a faction to join Act 4"));
                        return;

                    case FactionType.Angel:
                        map = ServerManager.GetAllMapInstances().Find(s => s.MapInstanceType.Equals(MapInstanceType.Act4ShipAngel));

                        break;

                    case FactionType.Demon:
                        map = ServerManager.GetAllMapInstances().Find(s => s.MapInstanceType.Equals(MapInstanceType.Act4ShipDemon));

                        break;
                    }
                    if (map == null || npc.EffectActivated)
                    {
                        Session.SendPacket(UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("SHIP_NOTARRIVED"), 0));
                        return;
                    }
                    if (3000 > Session.Character.Gold)
                    {
                        Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 10));
                        return;
                    }
                    Session.Character.Gold -= 3000;
                    MapCell pos = map.Map.GetRandomPosition();
                    ServerManager.Instance.ChangeMapInstance(Session.Character.CharacterId, map.MapInstanceId, pos.X, pos.Y);
                }
                break;

            case 5004:
                if (npc != null)
                {
                    ServerManager.Instance.ChangeMap(Session.Character.CharacterId, 145, 50, 41);
                }
                break;

            case 5011:
                if (npc != null)
                {
                    ServerManager.Instance.ChangeMap(Session.Character.CharacterId, 170, 127, 46);
                }
                break;

            case 5012:
                tp = npc?.Teleporters?.FirstOrDefault(s => s.Index == packet.Type);
                if (tp != null)
                {
                    ServerManager.Instance.ChangeMap(Session.Character.CharacterId, tp.MapId, tp.MapX, tp.MapY);
                }
                break;

            default:
                Logger.Warn(string.Format(Language.Instance.GetMessageFromKey("NO_NRUN_HANDLER"), packet.Runner));
                break;
            }
        }