コード例 #1
0
        public override async Task Handle(RecvPacketOperations operation, IPacket packet, FieldUser user)
        {
            packet.Decode <int>();
            var position = packet.Decode <short>();
            var leader   = packet.Decode <bool>();

            if (!user.Character.Inventories[ItemInventoryType.Cash].Items.ContainsKey(position))
            {
                return;
            }

            var item = (ItemSlotPet)user.Character
                       .Inventories[ItemInventoryType.Cash]
                       .Items[position];
            var pet = user.Pets.FirstOrDefault(p => p.Item == item);

            // TODO: Follow the leader checks

            if (pet != null)
            {
                var id = pet.IDx;

                user.Pets.Remove(pet);
                user.Pets
                .Where(p => p.IDx > id)
                .ForEach(p => p.IDx--);
                await user.Field.BroadcastPacket(pet.GetLeaveFieldPacket());
            }
            else
            {
                if (user.Pets.Count >= 3)
                {
                    await user.ModifyStats(exclRequest : true);

                    return;
                }

                var id = leader ? 0 : user.Pets.Count;

                pet = new FieldUserPet(user, item, (byte)id);
                user.Pets
                .Where(p => p.IDx >= id)
                .ForEach(p => p.IDx++);
                user.Pets.Add(pet);
                await user.Field.BroadcastPacket(pet.GetEnterFieldPacket());
            }

            await user.ModifyStats(s =>
            {
                s.Pet1 = user.Pets.FirstOrDefault(p => p.IDx == 0)?.Item.CashItemSN ?? 0;
                s.Pet2 = user.Pets.FirstOrDefault(p => p.IDx == 1)?.Item.CashItemSN ?? 0;
                s.Pet3 = user.Pets.FirstOrDefault(p => p.IDx == 2)?.Item.CashItemSN ?? 0;
            }, true);
        }
コード例 #2
0
        private async Task OnTrunkMoneyRequest(FieldUser user, IPacket packet)
        {
            var amount = packet.Decode <int>();

            using (var p = new Packet(SendPacketOperations.TrunkResult))
            {
                var result = TrunkResult.MoneySuccess;

                if (amount < 0)
                {
                    amount = -amount;
                    if (amount > int.MaxValue - _trunk.Money)
                    {
                        result = TrunkResult.MoneyUnknown;
                    }
                    else if (user.Character.Money >= amount)
                    {
                        await user.ModifyStats(s => s.Money -= amount);

                        _trunk.Money += amount;
                    }
                    else
                    {
                        result = TrunkResult.PutNoMoney;
                    }
                }
                else
                {
                    if (amount > int.MaxValue - user.Character.Money)
                    {
                        result = TrunkResult.MoneyUnknown;
                    }
                    if (_trunk.Money >= amount)
                    {
                        _trunk.Money -= amount;
                        await user.ModifyStats(s => s.Money += amount);
                    }
                    else
                    {
                        result = TrunkResult.PutNoMoney;
                    }
                }

                p.Encode <byte>((byte)result);
                if (result == TrunkResult.MoneySuccess)
                {
                    EncodeData(user, p);
                }

                await user.SendPacket(p);
            }
        }
コード例 #3
0
        public override async Task Handle(RecvPacketOperations operation, IPacket packet, FieldUser user)
        {
            packet.Decode <int>();
            var type = (ModifyStatType)packet.Decode <int>();

            if (user.Character.AP > 0)
            {
                await user.ModifyStats(s =>
                {
                    switch (type)
                    {
                    case ModifyStatType.STR:
                        s.STR++;
                        break;

                    case ModifyStatType.DEX:
                        s.DEX++;
                        break;

                    case ModifyStatType.INT:
                        s.INT++;
                        break;

                    case ModifyStatType.LUK:
                        s.LUK++;
                        break;
                    }

                    s.AP--;
                }, true);
            }
        }
コード例 #4
0
        public override async Task Handle(RecvPacketOperations operation, IPacket packet, FieldUser user)
        {
            packet.Decode <int>();
            var stat = (ModifyStatType)packet.Decode <int>();
            var hp   = 0;
            var mp   = 0;

            if (stat.HasFlag(ModifyStatType.HP))
            {
                hp = packet.Decode <short>();
            }

            if (stat.HasFlag(ModifyStatType.MP))
            {
                mp = packet.Decode <short>();
            }

            // TODO: portable chair
            // TODO: rope endurance?
            // TODO: checks

            if (hp > 0 || mp > 0)
            {
                await user.ModifyStats(s =>
                {
                    s.HP += hp;
                    s.MP += mp;
                });
            }
        }
コード例 #5
0
        public static async Task <QuestResult> Act(this QuestTemplate template, QuestState state, FieldUser user)
        {
            var act = template.Act[state];

            if (!user.Character.HasSlotFor(act.Items
                                           .Select(i =>
            {
                var item = user.Service.TemplateManager.Get <ItemTemplate>(i.TemplateID);
                var slot = item.ToItemSlot();

                if (slot is ItemSlotBundle bundle)
                {
                    bundle.Number = (short)i.Quantity;
                }

                return(slot);
            })
                                           .ToList()))
            {
                return(QuestResult.ActFailedInventory);
            }

            if (act.EXP != 0)
            {
                await user.ModifyStats(s => s.EXP += act.EXP);

                await user.Message(new IncEXPMessage
                {
                    EXP     = act.EXP,
                    OnQuest = true
                });
            }

            if (act.Items.Any())
            {
                await user.ModifyInventory(i =>
                                           act.Items.ForEach(ii =>
                {
                    if (ii.Quantity > 0)
                    {
                        i.Add(
                            user.Service.TemplateManager.Get <ItemTemplate>(ii.TemplateID),
                            (short)ii.Quantity
                            );
                    }
                    else
                    {
                        i.Remove(ii.TemplateID, (short)ii.Quantity);
                    }
                }
                                                             ));

                await user.Effect(new QuestEffect(act.Items
                                                  .Select(i => Tuple.Create(i.TemplateID, i.Quantity))
                                                  .ToList()));
            }

            return(QuestResult.ActSuccess);
        }
コード例 #6
0
ファイル: TradingRoom.cs プロジェクト: kaokaotw/Edelstein
        public override async Task Leave(FieldUser user, MiniRoomLeaveType type = MiniRoomLeaveType.Kicked)
        {
            var pair = Users.FirstOrDefault(kv => kv.Value == user);

            var items = _item[pair.Key].Values;
            var money = _money[pair.Key];

            await user.ModifyInventory(i => items.ForEach(i.Add));

            await user.ModifyStats(s => s.Money += money);

            _item.Remove(pair.Key);
            _money.Remove(pair.Key);
            await base.Leave(user, type);
        }
コード例 #7
0
        public override async Task Handle(
            RecvPacketOperations operation,
            IPacket packet,
            FieldUser user,
            StatChangeItemTemplate template,
            ItemSlot item
            )
        {
            var stats = template.GetTemporaryStats();

            if (stats.Count > 0)
            {
                await user.ModifyTemporaryStats(ts =>
                {
                    if (template.Time > 0)
                    {
                        var expire = DateTime.Now.AddSeconds(template.Time);
                        stats.ForEach(t => ts.Set(t.Key, -template.ID, t.Value, expire));
                    }
                    else
                    {
                        stats.ForEach(t => ts.Set(t.Key, -template.ID, t.Value));
                    }
                });
            }

            if (!stats.ContainsKey(TemporaryStatType.Morph))
            {
                var incHP = 0;
                var incMP = 0;

                incHP += template.HP;
                incMP += template.MP;
                incHP += user.BasicStat.MaxHP * (template.HPr / 100);
                incMP += user.BasicStat.MaxMP * (template.MPr / 100);

                if (incHP > 0 || incMP > 0)
                {
                    await user.ModifyStats(s =>
                    {
                        s.HP += incHP;
                        s.MP += incMP;
                    });
                }
            }

            await user.ModifyInventory(i => i.Remove(item, 1), true);
        }
コード例 #8
0
        public override async Task Handle(RecvPacketOperations operation, IPacket packet, FieldUser user)
        {
            packet.Decode <int>();
            var count = packet.Decode <int>();
            var inc   = new Dictionary <int, int>();

            for (var i = 0; i < count; i++)
            {
                inc.Add(packet.Decode <int>(), packet.Decode <int>());
            }

            var total = inc.Values.Sum();

            if (user.Character.AP < total)
            {
                return;
            }

            await user.ModifyStats(s =>
            {
                inc.ForEach(p =>
                {
                    var type  = (ModifyStatType)p.Key;
                    var value = (short)p.Value;

                    switch (type)
                    {
                    case ModifyStatType.STR:
                        s.STR += value;
                        break;

                    case ModifyStatType.DEX:
                        s.DEX += value;
                        break;

                    case ModifyStatType.INT:
                        s.INT += value;
                        break;

                    case ModifyStatType.LUK:
                        s.LUK += value;
                        break;
                    }
                });

                s.AP -= (short)total;
            }, true);
        }
コード例 #9
0
        public override async Task Handle(RecvPacketOperations operation, IPacket packet, FieldUser user)
        {
            var templateID = packet.Decode <int>();

            if (!user.Character.HasItem(templateID))
            {
                return;
            }

            user.PortableChairID = templateID;
            await user.ModifyStats(exclRequest : true);

            using var p = new Packet(SendPacketOperations.UserSetActivePortableChair);
            p.Encode <int>(user.ID);
            p.Encode <int>(templateID);
            await user.Field.BroadcastPacket(user, p);
        }
コード例 #10
0
        protected override async Task Execute(FieldUser sender, LevelUpCommandOption option)
        {
            if (option.Value < 0)
            {
                await sender.Message("This command cannot de-level character use only positive integers!");

                return;
            }

            await sender.ModifyStats(s =>
            {
                for (var i = 0; i < option.Value; i++)
                {
                    s.LevelUp();
                }
            });

            await sender.Message($"Successfully underwent level up {option.Value} times!");
        }
コード例 #11
0
        private async Task OnTrunkGetItemRequest(FieldUser user, IPacket packet)
        {
            packet.Decode <byte>();
            var pos  = packet.Decode <byte>();
            var item = _trunk.Items.ToList()[pos];

            using (var p = new Packet(SendPacketOperations.TrunkResult))
            {
                var result = TrunkResult.GetSuccess;

                if (item == null)
                {
                    result = TrunkResult.GetUnknown;
                }
                if (user.Character.Money < _getFee)
                {
                    result = TrunkResult.GetNoMoney;
                }
                if (!user.Character.HasSlotFor(item))
                {
                    result = TrunkResult.GetHavingOnlyItem;
                }

                p.Encode <byte>((byte)result);

                if (result == TrunkResult.GetSuccess)
                {
                    item.ID        = 0;
                    item.ItemTrunk = null;
                    _trunk.Items.Remove(item);
                    await user.ModifyStats(s => s.Money -= _getFee);

                    await user.ModifyInventory(i => i.Add(item));

                    EncodeData(user, p);
                }

                await user.SendPacket(p);
            }
        }
コード例 #12
0
        public override async Task Handle(RecvPacketOperations operation, IPacket packet, FieldUser user)
        {
            packet.Decode <int>();
            var templateID = packet.Decode <int>();
            var template   = user.Service.TemplateManager.Get <SkillTemplate>(templateID);
            var skillLevel = user.Character.GetSkillLevel(templateID);

            if (template == null)
            {
                return;
            }
            if (skillLevel <= 0)
            {
                return;
            }

            var level = template.LevelData[skillLevel];
            var stats = level.GetTemporaryStats();

            if (stats.Count > 0)
            {
                await user.ModifyTemporaryStats(ts =>
                {
                    if (level.Time > 0)
                    {
                        var expire = DateTime.Now.AddSeconds(level.Time);
                        stats.ForEach(t => ts.Set(t.Key, templateID, t.Value, expire));
                    }
                    else
                    {
                        stats.ForEach(t => ts.Set(t.Key, templateID, t.Value));
                    }
                });
            }
            // TODO: party/map buffs

            await user.Effect(new SkillUseEffect(templateID, (byte)skillLevel), local : false, remote : true);

            await user.ModifyStats(exclRequest : true);
        }
コード例 #13
0
ファイル: TradingRoom.cs プロジェクト: kaokaotw/Edelstein
        private async Task OnPutMoney(FieldUser user, IPacket packet)
        {
            if (Users.Count < 2)
            {
                return;
            }
            if (_locked)
            {
                return;
            }

            var pair   = Users.FirstOrDefault(kv => kv.Value == user);
            var amount = packet.Decode <int>();

            if (user.Character.Money < amount)
            {
                return;
            }

            _money[pair.Key] += amount;
            await user.ModifyStats(s => s.Money -= amount, true);

            IPacket GetPutMoneyPacket(byte position, int money)
            {
                using (var p = new Packet(SendPacketOperations.MiniRoom))
                {
                    p.Encode <byte>((byte)MiniRoomAction.TRP_PutMoney);
                    p.Encode <byte>(position);
                    p.Encode <int>(money);
                    return(p);
                }
            }

            await user.SendPacket(GetPutMoneyPacket(0x0, _money[pair.Key]));

            await BroadcastPacket(user, GetPutMoneyPacket(0x1, _money[pair.Key]));
        }
コード例 #14
0
 public override void PickUp(FieldUser user)
 {
     user.ModifyStats(s => s.Money += Money, true);
 }
コード例 #15
0
        private async Task OnTrunkPutItemRequest(FieldUser user, IPacket packet)
        {
            var pos        = packet.Decode <short>();
            var templateID = packet.Decode <int>();
            var number     = packet.Decode <short>();
            var inventory  = user.Character.GetInventory((ItemInventoryType)(templateID / 1000000));
            var item       = inventory.Items.FirstOrDefault(i => i.Position == pos);

            using (var p = new Packet(SendPacketOperations.TrunkResult))
            {
                var result = TrunkResult.PutSuccess;

                switch (item)
                {
                case null:
                case ItemSlotBundle bundle when bundle.Number < number:
                    result = TrunkResult.PutUnknown;
                    break;
                }

                if (user.Character.Money < _putFee)
                {
                    result = TrunkResult.GetNoMoney;
                }
                if (_trunk.Items.Count >= _trunk.SlotMax)
                {
                    result = TrunkResult.PutNoSpace;
                }

                p.Encode <byte>((byte)result);

                if (result == TrunkResult.PutSuccess)
                {
                    await user.ModifyStats(s => s.Money -= _putFee);

                    await user.ModifyInventory(i =>
                    {
                        if (!ItemConstants.IsTreatSingly(item.TemplateID))
                        {
                            if (!(item is ItemSlotBundle bundle))
                            {
                                return;
                            }
                            if (bundle.Number < number)
                            {
                                return;
                            }

                            item = i.Take(bundle, number);
                        }
                        else
                        {
                            i.Remove(item);
                        }
                    });

                    _trunk.Items.Add(item);
                    EncodeData(user, p);
                }

                await user.SendPacket(p);
            }
        }
コード例 #16
0
        private void OnUserShopRequest(FieldUser user, InPacket packet)
        {
            var type = packet.Decode <byte>();

            switch (type)
            {
            case 0:     // Buy
            {
                var pos        = packet.Decode <short>();
                var templateID = packet.Decode <int>();
                var count      = packet.Decode <short>();
                var shopItem   = _shop.Items
                                 .OrderBy(i => i.Position)
                                 .ToList()[pos];

                using (var p = new OutPacket(GameSendOperations.ShopResult))
                {
                    byte result = 0x0;

                    if (shopItem != null)
                    {
                        if (shopItem.TemplateID != templateID)
                        {
                            result = 0x10;
                        }
                        if (shopItem.Quantity > 1)
                        {
                            count = 1;
                        }
                        if (count > shopItem.MaxPerSlot)
                        {
                            count = shopItem.MaxPerSlot;
                        }
                        if (shopItem.Price > 0)
                        {
                            if (user.Character.Money < shopItem.Price * count)
                            {
                                result = 0xA;
                            }
                        }
                        if (shopItem.TokenTemplateID > 0)
                        {
                            if (user.Character.GetItemCount(shopItem.TokenTemplateID) <
                                shopItem.TokenPrice * count)
                            {
                                result = 0xD;
                            }
                        }
                        if (shopItem.Stock == 0)
                        {
                            result = 0x1;
                        }
                        // TODO: level limits

                        var templates = user.Socket.WvsGame.ItemTemplates;
                        var item      = templates.Get(shopItem.TemplateID).ToItemSlot();

                        if (item is ItemSlotBundle bundle)
                        {
                            bundle.Number = (short)(count * shopItem.Quantity);
                        }
                        if (!user.Character.HasSlotFor(item))
                        {
                            result = 0x3;
                        }

                        if (result == 0x0)
                        {
                            if (shopItem.Price > 0)
                            {
                                user.ModifyStats(s => s.Money -= shopItem.Price * count);
                            }
                            if (shopItem.TokenTemplateID > 0)
                            {
                                user.ModifyInventory(i => i.Remove(
                                                         shopItem.TokenTemplateID,
                                                         shopItem.TokenPrice * count
                                                         ));
                            }
                            if (shopItem.Stock > 0)
                            {
                                shopItem.Stock--;
                            }
                            if (shopItem.ItemPeriod > 0)
                            {
                                item.DateExpire = DateTime.Now.AddMinutes(shopItem.ItemPeriod);
                            }

                            user.ModifyInventory(i => i.Add(item));
                        }
                    }
                    else
                    {
                        result = 0x10;
                    }

                    p.Encode <byte>(result);
                    user.SendPacket(p);
                }


                break;
            }

            case 1:     // Sell
            {
                var pos        = packet.Decode <short>();
                var templateID = packet.Decode <int>();
                var count      = packet.Decode <short>();
                var inventory  = user.Character.GetInventory((ItemInventoryType)(templateID / 1000000));
                var item       = inventory.Items.FirstOrDefault(i => i.Position == pos);

                using (var p = new OutPacket(GameSendOperations.ShopResult))
                {
                    byte result = 0x0;

                    if (item != null)
                    {
                        user.ModifyInventory(i =>
                            {
                                if (item is ItemSlotBundle bundle)
                                {
                                    if (!ItemInfo.IsRechargeableItem(item.TemplateID))
                                    {
                                        if (count < bundle.Number)
                                        {
                                            bundle.Number -= count;
                                            i.UpdateQuantity(bundle);
                                            return;
                                        }
                                    }
                                }

                                count = 1;
                                i.Remove(item);
                            });

                        var templates = user.Socket.WvsGame.ItemTemplates;
                        var template  = templates.Get(item.TemplateID);
                        var price     = template.SellPrice * count;

                        if (ItemInfo.IsRechargeableItem(item.TemplateID))
                        {
                            price += ((ItemSlotBundle)item).Number;
                        }

                        user.ModifyStats(s => s.Money += price);
                    }
                    else
                    {
                        result = 0x10;
                    }

                    p.Encode <byte>(result);
                    user.SendPacket(p);
                }

                break;
            }

            case 2:     // Recharge
            {
                // TODO: recharge
                using (var p = new OutPacket(GameSendOperations.ShopResult))
                {
                    p.Encode <byte>(0x3);
                    user.SendPacket(p);
                }

                break;
            }

            case 3:     // Close
                user.Dialogue = null;
                break;
            }
        }
コード例 #17
0
        protected override async Task Execute(FieldUser sender, StatCommandOption option)
        {
            if (option.Value < 0)
            {
                await sender.Message("This command cannot use negative integers use only positive integers!");

                return;
            }

            switch (option.Type)
            {
            case ModifyStatType.Skin:
            case ModifyStatType.Face:
            case ModifyStatType.Hair:
                await sender.Prompt(target =>
                                    target.AskAvatar("Is this style okay?", new[] { option.Value })
                                    );

                break;
            }

            await sender.ModifyStats(s =>
            {
                switch (option.Type)
                {
                case ModifyStatType.Skin:
                    s.Skin = (byte)option.Value;
                    break;

                case ModifyStatType.Face:
                    s.Face = option.Value;
                    break;

                case ModifyStatType.Hair:
                    s.Hair = option.Value;
                    break;

                case ModifyStatType.Pet:
                case ModifyStatType.Pet2:
                case ModifyStatType.Pet3:
                    break;

                case ModifyStatType.Level:
                    s.Level = (byte)option.Value;
                    break;

                case ModifyStatType.Job:
                    s.Job = (short)option.Value;
                    break;

                case ModifyStatType.STR:
                    s.STR = (short)option.Value;
                    break;

                case ModifyStatType.DEX:
                    s.DEX = (short)option.Value;
                    break;

                case ModifyStatType.INT:
                    s.INT = (short)option.Value;
                    break;

                case ModifyStatType.LUK:
                    s.LUK = (short)option.Value;
                    break;

                case ModifyStatType.HP:
                    s.HP = option.Value;
                    break;

                case ModifyStatType.MaxHP:
                    s.MaxHP = option.Value;
                    break;

                case ModifyStatType.MP:
                    s.MP = option.Value;
                    break;

                case ModifyStatType.MaxMP:
                    s.MaxMP = option.Value;
                    break;

                case ModifyStatType.AP:
                    s.AP = (short)option.Value;
                    break;

                case ModifyStatType.SP:
                    if (option.ExtendSP.HasValue)
                    {
                        s.SetExtendSP(option.ExtendSP.Value, (byte)option.Value);
                    }
                    else
                    {
                        s.SP = (short)option.Value;
                    }
                    break;

                case ModifyStatType.EXP:
                    s.EXP = option.Value;
                    break;

                case ModifyStatType.POP:
                    s.POP = (short)option.Value;
                    break;

                case ModifyStatType.Money:
                    s.Money = option.Value;
                    break;

                case ModifyStatType.TempEXP:
                    s.TempEXP = option.Value;
                    break;
                }
            });

            await sender.Message($"Successfully set {option.Type} to {option.Value}");
        }
コード例 #18
0
        public override async Task Handle(RecvPacketOperations operation, IPacket packet, FieldUser user)
        {
            packet.Decode <int>();
            var templateID = packet.Decode <int>();
            var template   = user.Service.TemplateManager.Get <SkillTemplate>(templateID);

            Console.WriteLine(template);

            if (template == null)
            {
                return;
            }

            var job      = template.ID / 10000;
            var jobLevel = (byte)SkillConstants.GetJobLevel(job);

            if (jobLevel == 0)
            {
                var sp = Math.Min(user.Character.Level - 1, job == 3000 ? 9 : 6);
                for (var i = 0; i < 3; i++)
                {
                    sp -= user.Character.GetSkillLevel(job * 1000 + 1000 + i);
                }
                if (sp > 0)
                {
                    await user.ModifySkills(s => s.Add(templateID), true);
                }
                return;
            }

            if (SkillConstants.IsExtendSPJob(job) && user.Character.GetExtendSP(jobLevel) <= 0)
            {
                return;
            }
            if (!SkillConstants.IsExtendSPJob(job) && user.Character.SP <= 0)
            {
                return;
            }

            var maxLevel = template.MaxLevel;

            if (SkillConstants.IsSkillNeedMasterLevel(templateID))
            {
                maxLevel = (short)user.Character.GetSkillMasterLevel(templateID);
            }

            if (user.Character.GetSkillLevel(templateID) >= maxLevel)
            {
                return;
            }

            await user.ModifyStats(s =>
            {
                if (SkillConstants.IsExtendSPJob(job))
                {
                    s.SetExtendSP(jobLevel, (byte)(s.GetExtendSP(jobLevel) - 1));
                }
                else
                {
                    s.SP--;
                }
            });

            await user.ModifySkills(s => s.Add(templateID), true);
        }