public void Handle(Packet iPacket) { iPacket.ReadInt(); ItemConstants.ItemType type = (ItemConstants.ItemType)iPacket.ReadByte(); short source = iPacket.ReadShort(); short destination = iPacket.ReadShort(); short quantity = iPacket.ReadShort(); try { Item item = this[type, source]; if (destination < 0) { item.Equip(); } else if (source < 0 && destination > 0) { item.Unequip(destination); } else if (destination == 0) { item.Drop(quantity); } else { item.Move(destination); } } catch (InventoryFullException) { this.NotifyFull(); } }
public void NotifyInventoryIsFull(Character character, ItemConstants.ItemType inventoryType) { switch (inventoryType) { case ItemConstants.ItemType.Equipment: Character.Notify(character, "Your equipment(EQP) inventory is full!.", ServerConstants.NoticeType.Popup); break; case ItemConstants.ItemType.Etcetera: Character.Notify(character, "Your etcetera(ETC) inventory is full!.", ServerConstants.NoticeType.Popup); break; case ItemConstants.ItemType.Usable: Character.Notify(character, "Your usable(USE) inventory is full!.", ServerConstants.NoticeType.Popup); break; case ItemConstants.ItemType.Setup: Character.Notify(character, "Your setup inventory is full!.", ServerConstants.NoticeType.Popup); break; case ItemConstants.ItemType.Cash: Character.Notify(character, "Your cash inventory is full!.", ServerConstants.NoticeType.Popup); break; case ItemConstants.ItemType.Count: Character.Notify(character, "Your count inventory is full!.", ServerConstants.NoticeType.Popup); break; default: throw new ArgumentOutOfRangeException(nameof(inventoryType), inventoryType, null); } }
public sbyte GetNextFreeSlot(ItemConstants.ItemType type) { for (sbyte i = 1; i <= this.MaxSlots[type]; i++) { if (this[type, i] == null) { return(i); } } throw new InventoryFullException(); }
public IEnumerable <Item> this[ItemConstants.ItemType type] { get { foreach (Item loopItem in this.Items) { if (loopItem.Type == type && !loopItem.IsEquipped) { yield return(loopItem); } } } }
public int RemainingSlots(ItemConstants.ItemType type) { short remaining = this.MaxSlots[type]; foreach (Item item in this) { if (item.Type == type) { remaining--; } } return(remaining); }
public bool IsFull(ItemConstants.ItemType type) { short count = 0; foreach (Item item in this) { if (item.Type == type) { count++; } } return(count == this.MaxSlots[type]); }
public Item this[ItemConstants.ItemType type, short slot] { get { foreach (Item item in this) { if (item.Type == type && item.Slot == slot) { return(item); } } return(null); } }
public void CharItemsHandler(Packet inPacket) { int ticks = inPacket.ReadInt(); ItemConstants.ItemType type = (ItemConstants.ItemType)inPacket.ReadByte(); short sourceSlot = inPacket.ReadShort(); short destinationSlot = inPacket.ReadShort(); short itemQuantity = inPacket.ReadShort(); try { Item item = this[type, sourceSlot]; // destinationSlot < 0 means "into equipable slot" if (destinationSlot < 0) { Item.EquipItem(item); } // sourceSlot < 0 means "from equipable slot" destinationSlot > 0 means "into inventory slot" else if (sourceSlot < 0 && destinationSlot > 0) { Item.UnequipItem(item, destinationSlot); } // destinationSlot == 0 means "neither to equipable slot nor to inventory slot" else if (destinationSlot == 0) { Item.DropItem(item, itemQuantity); } else { Item.MoveItem(item, destinationSlot); } } catch (InventoryFullException) { NotifyInventoryIsFull(Parent, type); } }
public void Handle(Character character, InteractionConstants.InteractionCode code, Packet iPacket) { switch (code) { case InteractionConstants.InteractionCode.Invite: { int characterID = iPacket.ReadInt(); if (!Owner.Map.Characters.Contains(characterID)) { // TODO: What does happen in case the invitee left? return; } Character invitee = Owner.Map.Characters[characterID]; if (invitee.Trade != null) { using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionConstants.InteractionCode.Decline) .WriteByte(2) .WriteString(invitee.Name); Owner.Client.Send(oPacket); } } else { invitee.Trade = this; Visitor = invitee; using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionConstants.InteractionCode.Invite) .WriteByte(3) .WriteString(Owner.Name) .WriteBytes(new byte[4] { 0xB7, 0x50, 0x00, 0x00 }); Visitor.Client.Send(oPacket); } } } break; case InteractionConstants.InteractionCode.Decline: { using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionConstants.InteractionCode.Decline) .WriteByte(3) .WriteString(character.Name); Owner.Client.Send(oPacket); } Owner.Trade = null; Visitor.Trade = null; Owner = null; Visitor = null; } break; case InteractionConstants.InteractionCode.Visit: { if (Owner == null) { Visitor = null; character.Trade = null; Character.Notify(character, "Trade has been closed.", ServerConstants.NoticeType.Popup); } else { Started = true; using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionConstants.InteractionCode.Visit) .WriteByte(1) .WriteBytes(Visitor.AppearanceToByteArray()) .WriteString(Visitor.Name); Owner.Client.Send(oPacket); } using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionConstants.InteractionCode.Room) .WriteByte(3) .WriteByte(2) .WriteByte(1) .WriteByte(0) .WriteBytes(Owner.AppearanceToByteArray()) .WriteString(Owner.Name) .WriteByte(1) .WriteBytes(Visitor.AppearanceToByteArray()) .WriteString(Visitor.Name) .WriteByte(byte.MaxValue); Visitor.Client.Send(oPacket); } } } break; case InteractionConstants.InteractionCode.SetItems: { ItemConstants.ItemType type = (ItemConstants.ItemType)iPacket.ReadByte(); short slot = iPacket.ReadShort(); short quantity = iPacket.ReadShort(); byte targetSlot = iPacket.ReadByte(); Item item = character.Items[type, slot]; if (item.IsBlocked) { return; } if (quantity > item.Quantity) { return; } if (quantity < item.Quantity) { item.Quantity -= quantity; Item.UpdateItem(item); item = new Item(item.MapleID, quantity); } else { character.Items.RemoveItemFromInventory(item, true); } item.Slot = 0; using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionConstants.InteractionCode.SetItems) .WriteByte(0) .WriteByte(targetSlot) .WriteBytes(item.ToByteArray(true)); if (character == Owner) { OwnerItems.Add(item); Owner.Client.Send(oPacket); } else { VisitorItems.Add(item); Visitor.Client.Send(oPacket); } } using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionConstants.InteractionCode.SetItems) .WriteByte(1) .WriteByte(targetSlot) .WriteBytes(item.ToByteArray(true)); if (character == Owner) { Visitor.Client.Send(oPacket); } else { Owner.Client.Send(oPacket); } } } break; case InteractionConstants.InteractionCode.SetMeso: { int meso = iPacket.ReadInt(); if (meso < 0 || meso > character.Stats.Meso) { return; } // TODO: The meso written in this packet is the added meso amount. // The amount that should be written is the total amount. using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionConstants.InteractionCode.SetMeso) .WriteByte(0) .WriteInt(meso); if (character == Owner) { if (OwnerLocked) { return; } OwnerMeso += meso; Owner.Stats.Meso -= meso; Owner.Client.Send(oPacket); } else { if (VisitorLocked) { return; } VisitorMeso += meso; Visitor.Stats.Meso -= meso; Visitor.Client.Send(oPacket); } } using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionConstants.InteractionCode.SetMeso) .WriteByte(1) .WriteInt(meso); if (Owner == character) { Visitor.Client.Send(oPacket); } else { oPacket.WriteInt(OwnerMeso); Owner.Client.Send(oPacket); } } } break; case InteractionConstants.InteractionCode.Exit: { if (Started) { Cancel(); using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionConstants.InteractionCode.Exit) .WriteByte(0) .WriteByte(2); Owner.Client.Send(oPacket); Visitor.Client.Send(oPacket); } Owner.Trade = null; Visitor.Trade = null; Owner = null; Visitor = null; } else { using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionConstants.InteractionCode.Exit) .WriteByte(0) .WriteByte(2); Owner.Client.Send(oPacket); } Owner.Trade = null; Owner = null; } } break; case InteractionConstants.InteractionCode.Confirm: { using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket.WriteByte((byte)InteractionConstants.InteractionCode.Confirm); if (character == Owner) { OwnerLocked = true; Visitor.Client.Send(oPacket); } else { VisitorLocked = true; Owner.Client.Send(oPacket); } } if (OwnerLocked && VisitorLocked) { Complete(); using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionConstants.InteractionCode.Exit) .WriteByte(0) .WriteByte(6); Owner.Client.Send(oPacket); Visitor.Client.Send(oPacket); } Owner.Trade = null; Visitor.Trade = null; Owner = null; Visitor = null; } } break; case InteractionConstants.InteractionCode.Chat: { string text = iPacket.ReadString(); using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionConstants.InteractionCode.Chat) .WriteByte(8) .WriteBool(Owner != character) .WriteString("{0} : {1}", character.Name, text); Owner.Client.Send(oPacket); Visitor.Client.Send(oPacket); } } break; case InteractionConstants.InteractionCode.Create: break; case InteractionConstants.InteractionCode.Room: break; case InteractionConstants.InteractionCode.Open: break; case InteractionConstants.InteractionCode.TradeBirthday: break; case InteractionConstants.InteractionCode.AddItem: break; case InteractionConstants.InteractionCode.Buy: break; case InteractionConstants.InteractionCode.UpdateItems: break; case InteractionConstants.InteractionCode.RemoveItem: break; case InteractionConstants.InteractionCode.OpenStore: break; default: throw new ArgumentOutOfRangeException(nameof(code), code, null); } }
public void Handle(Packet iPacket) { StorageAction action = (StorageAction)iPacket.ReadByte(); switch (action) { case StorageAction.Withdraw: { ItemConstants.ItemType type = (ItemConstants.ItemType)iPacket.ReadByte(); byte slot = iPacket.ReadByte(); Item item = this.Items[slot]; if (item == null) { return; } this.Items.Remove(item); item.Delete(); item.IsStored = false; this.Parent.Items.Add(item, forceGetSlot: true); List <Item> itemsByType = new List <Item>(); foreach (Item loopItem in this.Items) { if (loopItem.Type == item.Type) { itemsByType.Add(loopItem); } } using (Packet oPacket = new Packet(ServerOperationCode.Storage)) { oPacket .WriteByte(13) .WriteByte(this.Slots) .WriteShort((short)(2 << (byte)item.Type)) .WriteShort() .WriteInt() .WriteByte((byte)itemsByType.Count); foreach (Item loopItem in itemsByType) { oPacket.WriteBytes(loopItem.ToByteArray(true, true)); } this.Parent.Client.Send(oPacket); } } break; case StorageAction.Deposit: { short slot = iPacket.ReadShort(); int itemID = iPacket.ReadInt(); short quantity = iPacket.ReadShort(); Item item = this.Parent.Items[itemID, slot]; if (this.IsFull) { using (Packet oPacket = new Packet(ServerOperationCode.Storage)) { oPacket.WriteByte(17); this.Parent.Client.Send(oPacket); } return; } if (this.Parent.Meso <= this.Npc.StorageCost) { this.Parent.Notify("You don't have enough meso to store the item.", NoticeType.Popup); // TOOD: Is there a packet for this? return; } this.Parent.Meso -= this.Npc.StorageCost; this.Parent.Items.Remove(item, true); item.Parent = this.Parent.Items; // NOTE: This is needed because when we remove the item is sets parent to none. item.Slot = (short)this.Items.Count; item.IsStored = true; this.Items.Add(item); List <Item> itemsByType = new List <Item>(); foreach (Item loopItem in this.Items) { if (loopItem.Type == item.Type) { itemsByType.Add(loopItem); } } using (Packet oPacket = new Packet(ServerOperationCode.Storage)) { oPacket .WriteByte(13) .WriteByte(this.Slots) .WriteShort((short)(2 << (byte)item.Type)) .WriteShort() .WriteInt() .WriteByte((byte)itemsByType.Count); foreach (Item loopItem in itemsByType) { oPacket.WriteBytes(loopItem.ToByteArray(true, true)); } this.Parent.Client.Send(oPacket); } } break; case StorageAction.ModifyMeso: { int meso = iPacket.ReadInt(); if (meso > 0) // NOTE: Withdraw meso. { // TODO: Meso checks. } else // NOTE: Deposit meso. { // TODO: Meso checks. } this.Meso -= meso; this.Parent.Meso += meso; using (Packet oPacket = new Packet(ServerOperationCode.Storage)) { oPacket .WriteByte(19) .WriteByte(this.Slots) .WriteShort(2) .WriteShort() .WriteInt() .WriteInt(this.Meso); this.Parent.Client.Send(oPacket); } } break; case StorageAction.Leave: { this.Save(); } break; } }
public void UseCashItem(Packet iPacket) { short slot = iPacket.ReadShort(); int itemID = iPacket.ReadInt(); bool itemUsed = false; Item item = this[ItemConstants.ItemType.Cash, slot]; if (item == null || itemID != item.MapleID) { return; } switch (item.MapleID) { #region TeleportRocks case (int)ItemConstants.UsableCashItems.TeleportRock: { } break; case (int)ItemConstants.UsableCashItems.CokeTeleportRock: { } break; case (int)ItemConstants.UsableCashItems.VIPTeleportRock: { itemUsed = this.Parent.Trocks.Use(itemID, iPacket); } break; #endregion #region AP/SP Reset case (int)ItemConstants.UsableCashItems.APReset: { CharacterConstants.StatisticType statDestination = (CharacterConstants.StatisticType)iPacket.ReadInt(); CharacterConstants.StatisticType statSource = (CharacterConstants.StatisticType)iPacket.ReadInt(); CharacterStats.AddAbility(this.Parent, statDestination, 1, true); CharacterStats.AddAbility(this.Parent, statSource, -1, true); itemUsed = true; } break; case (int)ItemConstants.UsableCashItems.SPReset1stJob: { if (!CharacterJobs.IsFirstJob(this.Parent)) { return; } //TODO: skill change itemUsed = true; } break; case (int)ItemConstants.UsableCashItems.SPReset2stJob: { if (!CharacterJobs.IsSecondJob(this.Parent)) { return; } //TODO: skill change itemUsed = true; } break; case (int)ItemConstants.UsableCashItems.SPReset3stJob: { if (!CharacterJobs.IsThirdJob(this.Parent)) { return; } //TODO: skill change itemUsed = true; } break; case (int)ItemConstants.UsableCashItems.SPReset4stJob: { if (!CharacterJobs.IsFourthJob(this.Parent)) { return; } //TODO: skill change itemUsed = true; } break; #endregion #region ItemTags/ItemGuards case (int)ItemConstants.UsableCashItems.ItemTag: { short targetSlot = iPacket.ReadShort(); if (targetSlot == 0) { return; } Item targetItem = this[ItemConstants.ItemType.Equipment, targetSlot]; if (targetItem == null) { return; } targetItem.Creator = this.Parent.Name; targetItem.Update(); // TODO: This does not seem to update the item's creator. itemUsed = true; } break; case (int)ItemConstants.UsableCashItems.ItemGuard: { } break; case (int)ItemConstants.UsableCashItems.Incubator: //doest belong here by name only by ordering of usableCashItemsID { } break; case (int)ItemConstants.UsableCashItems.ItemGuard7Days: { } break; case (int)ItemConstants.UsableCashItems.ItemGuard30Days: { } break; case (int)ItemConstants.UsableCashItems.ItemGuard90Days: { } break; #endregion #region Megaphones/Messengers case (int)ItemConstants.UsableCashItems.CheapMegaphone: { // NOTE: You can't use a megaphone unless you're over level 10. if (this.Parent.Level < 11) { return; } string text = iPacket.ReadString(); string message = string.Format($"{this.Parent.Name} : {text}"); // TODO: Include medal name. // NOTE: In GMS, this sends to everyone on the current channel, not the map (despite the item's description). using (Packet oPacket = new Packet(ServerOperationCode.BroadcastMsg)) { oPacket .WriteByte((byte)NoticeType.Megaphone) .WriteString(message); //this.Parent.Client.Channel.Broadcast(oPacket); } itemUsed = true; } break; case (int)ItemConstants.UsableCashItems.Megaphone: { if (this.Parent.Level < 11) { return; } string text = iPacket.ReadString(); string message = string.Format($"{this.Parent.Name} : {text}"); // TODO: Include medal name. // NOTE: In GMS, this sends to everyone on the current channel, not the map (despite the item's description). using (Packet oPacket = new Packet(ServerOperationCode.BroadcastMsg)) { oPacket .WriteByte((byte)NoticeType.Megaphone) .WriteString(message); //this.Parent.Client.Channel.Broadcast(oPacket); } itemUsed = true; } break; case (int)ItemConstants.UsableCashItems.SuperMegaphone: { if (this.Parent.Level < 11) { return; } string text = iPacket.ReadString(); bool whisper = iPacket.ReadBool(); string message = string.Format($"{this.Parent.Name} : {text}"); // TODO: Include medal name. using (Packet oPacket = new Packet(ServerOperationCode.BroadcastMsg)) { oPacket .WriteByte((byte)NoticeType.SuperMegaphone) .WriteString(message) .WriteByte(WvsGame.ChannelID) .WriteBool(whisper); //this.Parent.Client.World.Broadcast(oPacket); } itemUsed = true; } break; case (int)ItemConstants.UsableCashItems.HeartMegaphone: { if (this.Parent.Level < 11) { return; } } break; case (int)ItemConstants.UsableCashItems.SkullMegaphone: { if (this.Parent.Level < 11) { return; } } break; case (int)ItemConstants.UsableCashItems.MapleTVMessenger: { if (this.Parent.Level < 11) { return; } } break; case (int)ItemConstants.UsableCashItems.MapleTVStarMessenger: { if (this.Parent.Level < 11) { return; } } break; case (int)ItemConstants.UsableCashItems.MapleTVHeartMessenger: { if (this.Parent.Level < 11) { return; } } break; case (int)ItemConstants.UsableCashItems.Megassenger: { if (this.Parent.Level < 11) { return; } } break; case (int)ItemConstants.UsableCashItems.StarMegassenger: { if (this.Parent.Level < 11) { return; } } break; case (int)ItemConstants.UsableCashItems.HeartMegassenger: { if (this.Parent.Level < 11) { return; } } break; case (int)ItemConstants.UsableCashItems.ItemMegaphone: // NOTE: Item Megaphone. { if (this.Parent.Level < 11) { return; } string text = iPacket.ReadString(); bool whisper = iPacket.ReadBool(); bool includeItem = iPacket.ReadBool(); Item targetItem = null; if (includeItem) { ItemConstants.ItemType type = (ItemConstants.ItemType)iPacket.ReadInt(); short targetSlot = iPacket.ReadShort(); targetItem = this[type, targetSlot]; if (targetItem == null) { return; } } string message = string.Format($"{this.Parent.Name} : {text}"); // TODO: Include medal name. using (Packet oPacket = new Packet(ServerOperationCode.BroadcastMsg)) { oPacket .WriteByte((byte)NoticeType.ItemMegaphone) .WriteString(message) .WriteByte(WvsGame.ChannelID) .WriteBool(whisper) .WriteByte((byte)(targetItem != null ? targetItem.Slot : 0)); if (targetItem != null) { oPacket.WriteBytes(targetItem.ToByteArray(true)); } //this.Parent.Client.World.Broadcast(oPacket); } itemUsed = true; } break; #endregion #region FloatingMessage case (int)ItemConstants.UsableCashItems.KoreanKite: { } break; case (int)ItemConstants.UsableCashItems.HeartBalloon: { } break; case (int)ItemConstants.UsableCashItems.GraduationBanner: { } break; case (int)ItemConstants.UsableCashItems.AdmissionBanner: { } break; #endregion #region otherStuff case (int)ItemConstants.UsableCashItems.Note: // NOTE: Memo. { //string targetName = iPacket.ReadString(); //string message = iPacket.ReadString(); //if (this.Parent.Client.World.IsCharacterOnline(targetName)) //{ // using (Packet oPacket = new Packet(ServerOperationCode.MemoResult)) // { // oPacket // .WriteByte((byte)MemoResult.Error) // .WriteByte((byte)MemoError.ReceiverOnline); // this.Parent.Client.Send(oPacket); // } //} //else if (!Database.Exists("characters", "Name = {0}", targetName)) //{ // using (Packet oPacket = new Packet(ServerOperationCode.MemoResult)) // { // oPacket // .WriteByte((byte)MemoResult.Error) // .WriteByte((byte)MemoError.ReceiverInvalidName); // this.Parent.Client.Send(oPacket); // } //} //else if (false) // TODO: Receiver's inbox is full. I believe the maximum amount is 5, but need to verify. //{ // using (Packet oPacket = new Packet(ServerOperationCode.MemoResult)) // { // oPacket // .WriteByte((byte)MemoResult.Error) // .WriteByte((byte)MemoError.ReceiverInboxFull); // this.Parent.Client.Send(oPacket); // } //} //else //{ // Datum datum = new Datum("memos"); // datum["CharacterID"] = Database.Fetch("characters", "ID", "Name = {0}", targetName); // datum["Sender"] = this.Parent.Name; // datum["Message"] = message; // datum["Received"] = DateTime.Now; // datum.Insert(); // using (Packet oPacket = new Packet(ServerOperationCode.MemoResult)) // { // oPacket.WriteByte((byte)MemoResult.Sent); // this.Parent.Client.Send(oPacket); // } // used = true; //} } break; case (int)ItemConstants.UsableCashItems.CongratulatorySong: { } break; case (int)ItemConstants.UsableCashItems.PetNameTag: { //// TODO: Get the summoned pet. //string name = iPacket.ReadString(); //using (Packet oPacket = new Packet(ServerOperationCode.PetNameChanged)) //{ // oPacket // .WriteInt(this.Parent.ID) // .WriteByte() // NOTE: Index. // .WriteString(name) // .WriteByte(); // this.Parent.Map.Broadcast(oPacket); //} } break; case (int)ItemConstants.UsableCashItems.BronzeSackofMesos: { } break; case (int)ItemConstants.UsableCashItems.SilverSackofMesos: { } break; case (int)ItemConstants.UsableCashItems.GoldSackofMesos: { this.Parent.Meso += item.Meso; // TODO: We definitely need a GainMeso method with inChat parameter. using (Packet oPacket = new Packet(ServerOperationCode.Message)) { oPacket .WriteByte((byte)MessageType.IncreaseMeso) .WriteInt(item.Meso) .WriteShort(); this.Parent.Client.Send(oPacket); } itemUsed = true; } break; case (int)ItemConstants.UsableCashItems.FungusScroll: { } break; case (int)ItemConstants.UsableCashItems.OinkerDelight: { } break; case (int)ItemConstants.UsableCashItems.ZetaNightmare: { } break; case (int)ItemConstants.UsableCashItems.ChalkBoard: { } break; case (int)ItemConstants.UsableCashItems.ChalkBoard2: { string text = iPacket.ReadString(); this.Parent.Chalkboard = text; } break; case (int)ItemConstants.UsableCashItems.ScissorsofKarma: { } break; case (int)ItemConstants.UsableCashItems.ViciousHammer: { } break; #endregion } if (itemUsed) { this.Remove(itemID, 1); } else { Character.Release(this.Parent); // TODO: Blank inventory update. } }
public void Gather(Packet iPacket) { iPacket.ReadInt(); // NOTE: Ticks. ItemConstants.ItemType type = (ItemConstants.ItemType)iPacket.ReadByte(); }
public void CharStorageHandler(Packet inPacket) { NPCsConstants.StorageAction actionType = (NPCsConstants.StorageAction)inPacket.ReadByte(); switch (actionType) { case NPCsConstants.StorageAction.WithdrawItem: { // Read packet data ItemConstants.ItemType itemType = (ItemConstants.ItemType)inPacket.ReadByte(); byte itemSlot = inPacket.ReadByte(); // First seek slot to find the item to withdraw in if (itemSlot < 0 || itemSlot > Slots) { return; // TODO: storage exceptions on wrongly received/read data from packet, CharacterStorageExceptions.WrongSlotRecieved } // Slot is valid thus seek an item on its position Item item = Items[itemSlot]; if (item == null) { return; // TODO: CharacterStorageExceptions.ItemCouldNotBeFound } // Do i actually have free inventory slot to place withdrawn item in? if (Parent.Items.IsInventoryFull(item.ItemType)) { Parent.Client.Send(CharacterPackets.StorageErrorPacket(Parent, NPCsConstants.StoragePacketType.ErrorPlayerInventoryFull)); return; } // Even if i do, still i may not have enough mesos to demand this payed service :( int costToWithdraw = 1000; // TODO: how is the cost actually calculated? if (Parent.Stats.Meso < costToWithdraw) { Parent.Client.Send(CharacterPackets.StorageErrorPacket(Parent, NPCsConstants.StoragePacketType.ErrorNotEnoughMesos)); return; } if (Parent.Stats.Meso >= costToWithdraw) { // Devour character mesos Maple.Meso.giveMesos(Parent, costToWithdraw); // Remove item from storage Items.Remove(item); // Delete item from Database Item.DeleteItemFromDB(item); // Set stored flag to false item.IsStored = false; // Add item to char. items Parent.Items.AddItemToInventory(item, forceGetSlot: true); // routine to get count of items of same type List <Item> itemsByType = new List <Item>(); foreach (Item loopItem in Items) { if (loopItem.Type == item.Type) { itemsByType.Add(loopItem); } } Parent.Client.Send(CharacterPackets.StorageRemoveItem(Parent, item, itemsByType)); } } break; case NPCsConstants.StorageAction.DepositItem: { // Read packet data short slot = inPacket.ReadShort(); int itemID = inPacket.ReadInt(); short quantity = inPacket.ReadShort(); // TODO: slot validation, quantity validation // try to get item to deposit from slot in char. inventory Item item = Parent.Items[itemID, slot]; // storage full cant deposit if (IsFull) { Parent.Client.Send(CharacterPackets.StorageErrorPacket(Parent, NPCsConstants.StoragePacketType.ErrorStorageInventoryFull)); return; } // not enough mesos to pay for deposit if (Parent.Stats.Meso <= Npc.StorageCost) { Parent.Client.Send(CharacterPackets.StorageErrorPacket(Parent, NPCsConstants.StoragePacketType.ErrorNotEnoughMesos)); return; } if (Parent.Stats.Meso >= Npc.StorageCost) { //devour character mesos Parent.Stats.Meso -= Npc.StorageCost; // remove item form inventory Parent.Items.RemoveItemFromInventory(item, true); // NOTE: This is needed because when we remove the item is sets parent to none. item.Parent = Parent.Items; // slot in storage is maxCount of items in it item.Slot = (short)Items.Count; // set flag on item item.IsStored = true; // add item to storage Items.Add(item); // routine to get count of items of same type List <Item> itemsByType = new List <Item>(); foreach (Item loopItem in Items) { if (loopItem.Type == item.Type) { itemsByType.Add(loopItem); } } Parent.Client.Send(CharacterPackets.StorageAddItem(Parent, item, itemsByType)); } } break; case NPCsConstants.StorageAction.ArrangeItem: { Parent.Client.Send(CharacterPackets.StorageArrangeItems(Parent)); } break; case NPCsConstants.StorageAction.ChangeMesos: { int meso = inPacket.ReadInt(); if (meso > 0) // NOTE: Withdraw meso. { // TODO: Meso checks. } else // NOTE: Deposit meso. { // TODO: Meso checks. } Meso -= meso; Parent.Stats.Meso += meso; Parent.Client.Send(CharacterPackets.StorageChangeMesos(Parent)); } break; case NPCsConstants.StorageAction.CloseStorage: { Save(); } break; case NPCsConstants.StorageAction.OpenStorage: break; default: throw new ArgumentOutOfRangeException(); } }
public void Handle(Character character, InteractionCode code, Packet iPacket) { switch (code) { case InteractionCode.OpenStore: { this.Owner.Map.PlayerShops.Add(this); this.Opened = true; } break; case InteractionCode.AddItem: { ItemConstants.ItemType type = (ItemConstants.ItemType)iPacket.ReadByte(); short slot = iPacket.ReadShort(); short bundles = iPacket.ReadShort(); short perBundle = iPacket.ReadShort(); int price = iPacket.ReadInt(); short quantity = (short)(bundles * perBundle); Item item = character.Items[type, slot]; if (item == null) { return; } if (perBundle < 0 || perBundle * bundles > 2000 || bundles < 0 || price < 0) { return; } if (quantity > item.Quantity) { return; } if (quantity < item.Quantity) { item.Quantity -= quantity; item.Update(); } else { character.Items.Remove(item, true); } PlayerShopItem shopItem = new PlayerShopItem(item.MapleID, bundles, quantity, price); this.Items.Add(shopItem); this.UpdateItems(); } break; case InteractionCode.RemoveItem: { if (character == this.Owner) { short slot = iPacket.ReadShort(); PlayerShopItem shopItem = this.Items[slot]; if (shopItem == null) { return; } if (shopItem.Quantity > 0) { this.Owner.Items.Add(new Item(shopItem.MapleID, shopItem.Quantity)); } this.Items.Remove(shopItem); this.UpdateItems(); } } break; case InteractionCode.Exit: { if (character == this.Owner) { this.Close(); } else { this.RemoveVisitor(character); } } break; case InteractionCode.Buy: { short slot = iPacket.ReadByte(); short quantity = iPacket.ReadShort(); PlayerShopItem shopItem = this.Items[slot]; if (shopItem == null) { return; } if (character == this.Owner) { return; } if (quantity > shopItem.Quantity) { return; } if (character.Meso < shopItem.MerchantPrice * quantity) { return; } shopItem.Quantity -= quantity; character.Meso -= shopItem.MerchantPrice * quantity; this.Owner.Meso += shopItem.MerchantPrice * quantity; character.Items.Add(new Item(shopItem.MapleID, quantity)); this.UpdateItems(); // TODO: This doesn't mark the item as sold. bool noItemLeft = true; foreach (PlayerShopItem loopShopItem in this.Items) { if (loopShopItem.Quantity > 0) { noItemLeft = false; break; } } if (noItemLeft) { // TODO: Close the owner's shop. // TODO: Notify the owner the shop has been closed due to items being sold out. this.Close(); } } break; case InteractionCode.Chat: { string text = iPacket.ReadString(); using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.Chat) .WriteByte(8); byte sender = 0; for (int i = 0; i < this.Visitors.Length; i++) { if (this.Visitors[i] == character) { sender = (byte)(i + 1); } } oPacket .WriteByte(sender) .WriteString("{0} : {1}", character.Name, text); this.Broadcast(oPacket); } } break; } }
public void GatherItemsHandler(Packet inPacket) { int ticks = inPacket.ReadInt(); ItemConstants.ItemType type = (ItemConstants.ItemType)inPacket.ReadByte(); }