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); }
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); } }
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); } }
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; }); } }
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); }
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); }
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); }
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); }
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); }
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!"); }
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); } }
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); }
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])); }
public override void PickUp(FieldUser user) { user.ModifyStats(s => s.Money += Money, true); }
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); } }
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; } }
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}"); }
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); }