public void SendInventoryItemsUpdate(eInventoryWindowType windowType, ICollection <InventoryItem> itemsToUpdate) { }
/// <summary> /// Sends inventory items to the client. If windowType is one of the client inventory windows then the client /// will display the window. Once the window is displayed to the client all handling of items in the window /// is done in the move item request handlers /// </summary> /// <param name="items"></param> /// <param name="windowType"></param> protected override void SendInventoryItemsPartialUpdate(IDictionary<int, InventoryItem> items, eInventoryWindowType windowType) { //ChatUtil.SendDebugMessage(m_gameClient, string.Format("SendItemsPartialUpdate: windowType: {0}, {1}", windowType, items == null ? "nothing" : items[0].Name)); using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.InventoryUpdate))) { GameVault houseVault = m_gameClient.Player.ActiveInventoryObject as GameVault; pak.WriteByte((byte)(items.Count)); pak.WriteByte(0x00); // new in 189b+, show shield in left hand pak.WriteByte((byte)((m_gameClient.Player.IsCloakInvisible ? 0x01 : 0x00) | (m_gameClient.Player.IsHelmInvisible ? 0x02 : 0x00))); // new in 189b+, cloack/helm visibility if (windowType == eInventoryWindowType.HouseVault && houseVault != null) pak.WriteByte((byte)(houseVault.Index + 1)); // Add the vault number to the window caption else pak.WriteByte((byte)((m_gameClient.Player.IsCloakHoodUp ? 0x01 : 0x00) | (int)m_gameClient.Player.ActiveQuiverSlot)); //bit0 is hood up bit4 to 7 is active quiver // ^ in 1.89b+, 0 bit - showing hooded cloack, if not hooded not show cloack at all ? pak.WriteByte(m_gameClient.Player.VisibleActiveWeaponSlots); pak.WriteByte((byte)windowType); foreach (var entry in items) { pak.WriteByte((byte)(entry.Key)); WriteItemData(pak, entry.Value); } SendTCP(pak); } }
/// <summary> /// Legacy inventory update. This handler silently /// assumes that a slot on the client matches a slot on the server. /// </summary> /// <param name="slots"></param> /// <param name="preAction"></param> protected override void SendInventorySlotsUpdateRange(ICollection<int> slots, eInventoryWindowType windowType) { using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.InventoryUpdate))) { GameVault houseVault = m_gameClient.Player.ActiveInventoryObject as GameVault; pak.WriteByte((byte)(slots == null ? 0 : slots.Count)); pak.WriteByte(0); // CurrentSpeed & 0xFF (not used for player, only for NPC) pak.WriteByte((byte)((m_gameClient.Player.IsCloakInvisible ? 0x01 : 0x00) | (m_gameClient.Player.IsHelmInvisible ? 0x02 : 0x00))); // new in 189b+, cloack/helm visibility if (windowType == eInventoryWindowType.HouseVault && houseVault != null) { pak.WriteByte((byte)(houseVault.Index + 1)); // Add the vault number to the window caption } else { pak.WriteByte((byte)((m_gameClient.Player.IsCloakHoodUp ? 0x01 : 0x00) | (int)m_gameClient.Player.ActiveQuiverSlot)); //bit0 is hood up bit4 to 7 is active quiver } pak.WriteByte((byte)m_gameClient.Player.VisibleActiveWeaponSlots); pak.WriteByte((byte)windowType); if (slots != null) { foreach (int updatedSlot in slots) { if (updatedSlot >= (int)eInventorySlot.Consignment_First && updatedSlot <= (int)eInventorySlot.Consignment_Last) { log.Error("PacketLib198:SendInventorySlotsUpdateBase - GameConsignmentMerchant inventory is no longer cached with player. Use a Dictionary<int, InventoryItem> instead."); pak.WriteByte((byte)(updatedSlot - (int)eInventorySlot.Consignment_First + (int)eInventorySlot.HousingInventory_First)); } else { pak.WriteByte((byte)(updatedSlot)); } WriteItemData(pak, m_gameClient.Player.Inventory.GetItem((eInventorySlot)(updatedSlot))); } } SendTCP(pak); } }
public void SendInventoryItemsUpdate(IDictionary<int, InventoryItem> updateItems, eInventoryWindowType windowType) { if (SendInventoryItemsUpdateDictMethod != null) SendInventoryItemsUpdateDictMethod(this, updateItems, windowType); }
/// <summary> /// New inventory update handler. This handler takes into account that /// a slot on the client isn't necessarily the same as a slot on the /// server, e.g. house vaults. /// </summary> /// <param name="updateItems"></param> /// <param name="windowType"></param> public override void SendInventoryItemsUpdate(IDictionary<int, InventoryItem> updateItems, eInventoryWindowType windowType) { if (m_gameClient.Player == null) return; if (updateItems == null) updateItems = new Dictionary<int, InventoryItem>(); if (updateItems.Count <= ServerProperties.Properties.MAX_ITEMS_PER_PACKET) { SendInventoryItemsPartialUpdate(updateItems, windowType); return; } var items = new Dictionary<int, InventoryItem>(ServerProperties.Properties.MAX_ITEMS_PER_PACKET); foreach (var item in updateItems) { items.Add(item.Key, item.Value); if (items.Count >= ServerProperties.Properties.MAX_ITEMS_PER_PACKET) { SendInventoryItemsPartialUpdate(items, windowType); items.Clear(); windowType = eInventoryWindowType.Update; } } if (items.Count > 0) SendInventoryItemsPartialUpdate(items, windowType); }
/// <summary> /// New inventory update handler. This handler takes into account that /// a slot on the client isn't necessarily the same as a slot on the /// server, e.g. house vaults. /// </summary> /// <param name="updateItems"></param> /// <param name="windowType"></param> public override void SendInventoryItemsUpdate(IDictionary <int, InventoryItem> updateItems, eInventoryWindowType windowType) { if (m_gameClient.Player == null) { return; } if (updateItems == null) { updateItems = new Dictionary <int, InventoryItem>(); } if (updateItems.Count <= ServerProperties.Properties.MAX_ITEMS_PER_PACKET) { SendInventoryItemsPartialUpdate(updateItems, windowType); return; } var items = new Dictionary <int, InventoryItem>(ServerProperties.Properties.MAX_ITEMS_PER_PACKET); foreach (var item in updateItems) { items.Add(item.Key, item.Value); if (items.Count >= ServerProperties.Properties.MAX_ITEMS_PER_PACKET) { SendInventoryItemsPartialUpdate(items, windowType); items.Clear(); windowType = eInventoryWindowType.Update; } } if (items.Count > 0) { SendInventoryItemsPartialUpdate(items, windowType); } }
/// <summary> /// Legacy inventory update. This handler silently /// assumes that a slot on the client matches a slot on the server. /// </summary> /// <param name="slots"></param> /// <param name="preAction"></param> protected override void SendInventorySlotsUpdateRange(ICollection <int> slots, eInventoryWindowType windowType) { using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.InventoryUpdate))) { GameVault houseVault = m_gameClient.Player.ActiveInventoryObject as GameVault; pak.WriteByte((byte)(slots == null ? 0 : slots.Count)); pak.WriteByte(0); // CurrentSpeed & 0xFF (not used for player, only for NPC) pak.WriteByte((byte)((m_gameClient.Player.IsCloakInvisible ? 0x01 : 0x00) | (m_gameClient.Player.IsHelmInvisible ? 0x02 : 0x00))); // new in 189b+, cloack/helm visibility if (windowType == eInventoryWindowType.HouseVault && houseVault != null) { pak.WriteByte((byte)(houseVault.Index + 1)); // Add the vault number to the window caption } else { pak.WriteByte((byte)((m_gameClient.Player.IsCloakHoodUp ? 0x01 : 0x00) | (int)m_gameClient.Player.ActiveQuiverSlot)); //bit0 is hood up bit4 to 7 is active quiver } pak.WriteByte((byte)m_gameClient.Player.VisibleActiveWeaponSlots); pak.WriteByte((byte)windowType); if (slots != null) { foreach (int updatedSlot in slots) { if (updatedSlot >= (int)eInventorySlot.Consignment_First && updatedSlot <= (int)eInventorySlot.Consignment_Last) { log.Error("PacketLib198:SendInventorySlotsUpdateBase - GameConsignmentMerchant inventory is no longer cached with player. Use a Dictionary<int, InventoryItem> instead."); pak.WriteByte((byte)(updatedSlot - (int)eInventorySlot.Consignment_First + (int)eInventorySlot.HousingInventory_First)); } else { pak.WriteByte((byte)(updatedSlot)); } WriteItemData(pak, m_gameClient.Player.Inventory.GetItem((eInventorySlot)(updatedSlot))); } } SendTCP(pak); } }
public virtual void SendInventoryItemsUpdate(IDictionary<int, InventoryItem> updateItems, eInventoryWindowType windowType) { }
protected virtual void SendInventoryItemsPartialUpdate(IDictionary<int, InventoryItem> items, eInventoryWindowType windowType) { }
protected override void SendInventorySlotsUpdateRange(ICollection <int> slots, eInventoryWindowType windowType) { using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.InventoryUpdate))) { pak.WriteByte((byte)(slots == null ? 0 : slots.Count)); pak.WriteByte((byte)((m_gameClient.Player.IsCloakHoodUp ? 0x01 : 0x00) | (int)m_gameClient.Player.ActiveQuiverSlot)); //bit0 is hood up bit4 to 7 is active quiver pak.WriteByte((byte)m_gameClient.Player.VisibleActiveWeaponSlots); pak.WriteByte((byte)windowType); if (slots != null) { foreach (int updatedSlot in slots) { if (updatedSlot >= (int)eInventorySlot.Consignment_First && updatedSlot <= (int)eInventorySlot.Consignment_Last) { pak.WriteByte((byte)(updatedSlot - (int)eInventorySlot.Consignment_First + (int)eInventorySlot.HousingInventory_First)); } else { pak.WriteByte((byte)(updatedSlot)); } InventoryItem item = null; item = m_gameClient.Player.Inventory.GetItem((eInventorySlot)updatedSlot); if (item == null) { pak.Fill(0x00, 19); continue; } pak.WriteByte((byte)item.Level); int value1; // some object types use this field to display count int value2; // some object types use this field to display count switch (item.Object_Type) { case (int)eObjectType.Arrow: case (int)eObjectType.Bolt: case (int)eObjectType.Poison: case (int)eObjectType.GenericItem: value1 = item.Count; value2 = item.SPD_ABS; break; case (int)eObjectType.Thrown: value1 = item.DPS_AF; value2 = item.Count; break; case (int)eObjectType.Instrument: value1 = (item.DPS_AF == 2 ? 0 : item.DPS_AF); value2 = 0; break; // unused case (int)eObjectType.Shield: value1 = item.Type_Damage; value2 = item.DPS_AF; break; case (int)eObjectType.AlchemyTincture: case (int)eObjectType.SpellcraftGem: value1 = 0; value2 = 0; /* * must contain the quality of gem for spell craft and think same for tincture */ break; case (int)eObjectType.HouseWallObject: case (int)eObjectType.HouseFloorObject: case (int)eObjectType.GardenObject: value1 = 0; value2 = item.SPD_ABS; /* * Value2 byte sets the width, only lower 4 bits 'seem' to be used (so 1-15 only) * * The byte used for "Hand" (IE: Mini-delve showing a weapon as Left-Hand * usabe/TwoHanded), the lower 4 bits store the height (1-15 only) */ break; default: value1 = item.DPS_AF; value2 = item.SPD_ABS; break; } pak.WriteByte((byte)value1); pak.WriteByte((byte)value2); if (item.Object_Type == (int)eObjectType.GardenObject) { pak.WriteByte((byte)(item.DPS_AF)); } else { pak.WriteByte((byte)(item.Hand << 6)); } pak.WriteByte((byte)((item.Type_Damage > 3 ? 0 : item.Type_Damage << 6) | item.Object_Type)); pak.WriteShort((ushort)item.Weight); pak.WriteByte(item.ConditionPercent); // % of con pak.WriteByte(item.DurabilityPercent); // % of dur pak.WriteByte((byte)item.Quality); // % of qua pak.WriteByte((byte)item.Bonus); // % bonus pak.WriteShort((ushort)item.Model); pak.WriteByte((byte)item.Extension); int flag = 0; if (item.Emblem != 0) { pak.WriteShort((ushort)item.Emblem); flag |= (item.Emblem & 0x010000) >> 16; // = 1 for newGuildEmblem } else { pak.WriteShort((ushort)item.Color); } // flag |= 0x01; // newGuildEmblem flag |= 0x02; // enable salvage button AbstractCraftingSkill skill = CraftingMgr.getSkillbyEnum(m_gameClient.Player.CraftingPrimarySkill); if (skill != null && skill is AdvancedCraftingSkill /* && ((AdvancedCraftingSkill)skill).IsAllowedToCombine(m_gameClient.Player, item)*/) { flag |= 0x04; // enable craft button } ushort icon1 = 0; ushort icon2 = 0; string spell_name1 = ""; string spell_name2 = ""; if (item.Object_Type != (int)eObjectType.AlchemyTincture) { SpellLine chargeEffectsLine = SkillBase.GetSpellLine(GlobalSpellsLines.Item_Effects); if (chargeEffectsLine != null) { if (item.SpellID > 0 /* && item.Charges > 0*/) { Spell spell = SkillBase.FindSpell(item.SpellID, chargeEffectsLine); if (spell != null) { flag |= 0x08; icon1 = spell.Icon; spell_name1 = spell.Name; // or best spl.Name ? } } if (item.SpellID1 > 0 /* && item.Charges > 0*/) { Spell spell = SkillBase.FindSpell(item.SpellID1, chargeEffectsLine); if (spell != null) { flag |= 0x10; icon2 = spell.Icon; spell_name2 = spell.Name; // or best spl.Name ? } } } } pak.WriteByte((byte)flag); if ((flag & 0x08) == 0x08) { pak.WriteShort((ushort)icon1); pak.WritePascalString(spell_name1); } if ((flag & 0x10) == 0x10) { pak.WriteShort((ushort)icon2); pak.WritePascalString(spell_name2); } pak.WriteByte((byte)item.Effect); string name = item.Name; if (item.Count > 1) { name = item.Count + " " + name; } if (item.SellPrice > 0) { if (ServerProperties.Properties.CONSIGNMENT_USE_BP) { name += "[" + item.SellPrice.ToString() + " BP]"; } else { name += "[" + Money.GetString(item.SellPrice) + "]"; } } pak.WritePascalString(name); } } SendTCP(pak); } }
protected override void SendInventorySlotsUpdateRange(ICollection<int> slots, eInventoryWindowType windowType) { using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.InventoryUpdate))) { pak.WriteByte((byte)(slots == null ? 0 : slots.Count)); pak.WriteByte((byte)((m_gameClient.Player.IsCloakHoodUp ? 0x01 : 0x00) | (int)m_gameClient.Player.ActiveQuiverSlot)); //bit0 is hood up bit4 to 7 is active quiver pak.WriteByte((byte)m_gameClient.Player.VisibleActiveWeaponSlots); pak.WriteByte((byte)windowType); if (slots != null) { foreach (int updatedSlot in slots) { if (updatedSlot >= (int)eInventorySlot.Consignment_First && updatedSlot <= (int)eInventorySlot.Consignment_Last) pak.WriteByte((byte)(updatedSlot - (int)eInventorySlot.Consignment_First + (int)eInventorySlot.HousingInventory_First)); else pak.WriteByte((byte)(updatedSlot)); InventoryItem item = null; item = m_gameClient.Player.Inventory.GetItem((eInventorySlot)updatedSlot); if (item == null) { pak.Fill(0x00, 19); continue; } pak.WriteByte((byte)item.Level); int value1; // some object types use this field to display count int value2; // some object types use this field to display count switch (item.Object_Type) { case (int)eObjectType.Arrow: case (int)eObjectType.Bolt: case (int)eObjectType.Poison: case (int)eObjectType.GenericItem: value1 = item.Count; value2 = item.SPD_ABS; break; case (int)eObjectType.Thrown: value1 = item.DPS_AF; value2 = item.Count; break; case (int)eObjectType.Instrument: value1 = (item.DPS_AF == 2 ? 0 : item.DPS_AF); value2 = 0; break; // unused case (int)eObjectType.Shield: value1 = item.Type_Damage; value2 = item.DPS_AF; break; case (int)eObjectType.AlchemyTincture: case (int)eObjectType.SpellcraftGem: value1 = 0; value2 = 0; /* must contain the quality of gem for spell craft and think same for tincture */ break; case (int)eObjectType.HouseWallObject: case (int)eObjectType.HouseFloorObject: case (int)eObjectType.GardenObject: value1 = 0; value2 = item.SPD_ABS; /* Value2 byte sets the width, only lower 4 bits 'seem' to be used (so 1-15 only) The byte used for "Hand" (IE: Mini-delve showing a weapon as Left-Hand usabe/TwoHanded), the lower 4 bits store the height (1-15 only) */ break; default: value1 = item.DPS_AF; value2 = item.SPD_ABS; break; } pak.WriteByte((byte)value1); pak.WriteByte((byte)value2); if (item.Object_Type == (int)eObjectType.GardenObject) pak.WriteByte((byte)(item.DPS_AF)); else pak.WriteByte((byte)(item.Hand << 6)); pak.WriteByte((byte)((item.Type_Damage > 3 ? 0 : item.Type_Damage << 6) | item.Object_Type)); pak.WriteShort((ushort)item.Weight); pak.WriteByte(item.ConditionPercent); // % of con pak.WriteByte(item.DurabilityPercent); // % of dur pak.WriteByte((byte)item.Quality); // % of qua pak.WriteByte((byte)item.Bonus); // % bonus pak.WriteShort((ushort)item.Model); pak.WriteByte((byte)item.Extension); int flag = 0; if (item.Emblem != 0) { pak.WriteShort((ushort)item.Emblem); flag |= (item.Emblem & 0x010000) >> 16; // = 1 for newGuildEmblem } else pak.WriteShort((ushort)item.Color); // flag |= 0x01; // newGuildEmblem flag |= 0x02; // enable salvage button AbstractCraftingSkill skill = CraftingMgr.getSkillbyEnum(m_gameClient.Player.CraftingPrimarySkill); if (skill != null && skill is AdvancedCraftingSkill/* && ((AdvancedCraftingSkill)skill).IsAllowedToCombine(m_gameClient.Player, item)*/) flag |= 0x04; // enable craft button ushort icon1 = 0; ushort icon2 = 0; string spell_name1 = ""; string spell_name2 = ""; if (item.Object_Type != (int)eObjectType.AlchemyTincture) { SpellLine chargeEffectsLine = SkillBase.GetSpellLine(GlobalSpellsLines.Item_Effects); if (chargeEffectsLine != null) { if (item.SpellID > 0/* && item.Charges > 0*/) { Spell spell = SkillBase.FindSpell(item.SpellID, chargeEffectsLine); if (spell != null) { flag |= 0x08; icon1 = spell.Icon; spell_name1 = spell.Name; // or best spl.Name ? } } if (item.SpellID1 > 0/* && item.Charges > 0*/) { Spell spell = SkillBase.FindSpell(item.SpellID1, chargeEffectsLine); if (spell != null) { flag |= 0x10; icon2 = spell.Icon; spell_name2 = spell.Name; // or best spl.Name ? } } } } pak.WriteByte((byte)flag); if ((flag & 0x08) == 0x08) { pak.WriteShort((ushort)icon1); pak.WritePascalString(spell_name1); } if ((flag & 0x10) == 0x10) { pak.WriteShort((ushort)icon2); pak.WritePascalString(spell_name2); } pak.WriteByte((byte)item.Effect); string name = item.Name; if (item.Count > 1) name = item.Count + " " + name; if (item.SellPrice > 0) { if (ServerProperties.Properties.CONSIGNMENT_USE_BP) name += "[" + item.SellPrice.ToString() + " BP]"; else name += "[" + Money.GetString(item.SellPrice) + "]"; } pak.WritePascalString(name); } } SendTCP(pak); } }
public void SendInventoryItemsPartialUpdate(IDictionary<int, InventoryItem> items, eInventoryWindowType windowType) { }
public void SendInventoryItemsUpdate(eInventoryWindowType windowType, ICollection<InventoryItem> itemsToUpdate) { }
protected override void SendInventorySlotsUpdateRange(ICollection <int> slots, eInventoryWindowType windowType) { using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.InventoryUpdate))) { pak.WriteByte((byte)(slots == null ? 0 : slots.Count)); pak.WriteByte((byte)((m_gameClient.Player.IsCloakHoodUp ? 0x01 : 0x00) | (int)m_gameClient.Player.ActiveQuiverSlot)); //bit0 is hood up bit4 to 7 is active quiver pak.WriteByte((byte)m_gameClient.Player.VisibleActiveWeaponSlots); pak.WriteByte((byte)windowType); if (slots != null) { foreach (int updatedSlot in slots) { if (updatedSlot >= (int)eInventorySlot.Consignment_First && updatedSlot <= (int)eInventorySlot.Consignment_Last) { pak.WriteByte((byte)(updatedSlot - (int)eInventorySlot.Consignment_First + (int)eInventorySlot.HousingInventory_First)); } else { pak.WriteByte((byte)(updatedSlot)); } InventoryItem item = null; item = m_gameClient.Player.Inventory.GetItem((eInventorySlot)updatedSlot); if (item == null) { pak.Fill(0x00, 19); continue; } pak.WriteByte((byte)item.Level); int value1; // some object types use this field to display count int value2; // some object types use this field to display count switch (item.Object_Type) { case (int)eObjectType.Arrow: case (int)eObjectType.Bolt: case (int)eObjectType.Poison: case (int)eObjectType.GenericItem: value1 = item.Count; value2 = item.SPD_ABS; break; case (int)eObjectType.Thrown: value1 = item.DPS_AF; value2 = item.Count; break; case (int)eObjectType.Instrument: value1 = (item.DPS_AF == 2 ? 0 : item.DPS_AF); value2 = 0; break; // unused case (int)eObjectType.Shield: value1 = item.Type_Damage; value2 = item.DPS_AF; break; case (int)eObjectType.AlchemyTincture: case (int)eObjectType.SpellcraftGem: value1 = 0; value2 = 0; /* * must contain the quality of gem for spell craft and think same for tincture */ break; case (int)eObjectType.GardenObject: value1 = 0; value2 = item.SPD_ABS; /* * Value2 byte sets the width, only lower 4 bits 'seem' to be used (so 1-15 only) * * The byte used for "Hand" (IE: Mini-delve showing a weapon as Left-Hand * usabe/TwoHanded), the lower 4 bits store the height (1-15 only) */ break; default: value1 = item.DPS_AF; value2 = item.SPD_ABS; break; } pak.WriteByte((byte)value1); pak.WriteByte((byte)value2); if (item.Object_Type == (int)eObjectType.GardenObject) { pak.WriteByte((byte)(item.DPS_AF)); } else { pak.WriteByte((byte)(item.Hand << 6)); } pak.WriteByte((byte)((item.Type_Damage > 3 ? 0 : item.Type_Damage << 6) | item.Object_Type)); pak.WriteShort((ushort)item.Weight); pak.WriteByte(item.ConditionPercent); // % of con pak.WriteByte(item.DurabilityPercent); // % of dur pak.WriteByte((byte)item.Quality); // % of qua pak.WriteByte((byte)item.Bonus); // % bonus pak.WriteShort((ushort)item.Model); pak.WriteByte((byte)item.Extension); if (item.Emblem != 0) { pak.WriteShort((ushort)item.Emblem); } else { pak.WriteShort((ushort)item.Color); } pak.WriteShort((ushort)item.Effect); string name = item.Name; if (item.Count > 1) { name = item.Count + " " + name; } if (item.SellPrice > 0) { if (ServerProperties.Properties.CONSIGNMENT_USE_BP) { name += "[" + item.SellPrice.ToString() + " BP]"; } else { name += "[" + Money.GetString(item.SellPrice) + "]"; } } pak.WritePascalString(name); } } SendTCP(pak); } }
public void SendInventoryItemsUpdate(IDictionary <int, InventoryItem> updateItems, eInventoryWindowType windowType) { }
public virtual void SendInventoryItemsUpdate(eInventoryWindowType windowType, ICollection<InventoryItem> itemsToUpdate) { if (m_gameClient.Player == null) return; if (itemsToUpdate == null) { SendInventorySlotsUpdateRange(null, windowType); return; } // clients crash if too long packet is sent // so we send big updates in parts var slotsToUpdate = new List<int>(Math.Min(ServerProperties.Properties.MAX_ITEMS_PER_PACKET, itemsToUpdate.Count)); foreach (InventoryItem item in itemsToUpdate) { if (item == null) continue; slotsToUpdate.Add(item.SlotPosition); if (slotsToUpdate.Count >= ServerProperties.Properties.MAX_ITEMS_PER_PACKET) { SendInventorySlotsUpdateRange(slotsToUpdate, windowType); slotsToUpdate.Clear(); windowType = eInventoryWindowType.Update; } } if (slotsToUpdate.Count > 0) { SendInventorySlotsUpdateRange(slotsToUpdate, windowType); } }
public void SendInventoryItemsPartialUpdate(IDictionary <int, InventoryItem> items, eInventoryWindowType windowType) { }
protected virtual void SendInventorySlotsUpdateRange(ICollection<int> slots, eInventoryWindowType windowType) { using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.InventoryUpdate))) { pak.WriteByte((byte) (slots == null ? 0 : slots.Count)); pak.WriteByte( (byte) ((m_gameClient.Player.IsCloakHoodUp ? 0x01 : 0x00) | (int) m_gameClient.Player.ActiveQuiverSlot)); //bit0 is hood up bit4 to 7 is active quiver pak.WriteByte(m_gameClient.Player.VisibleActiveWeaponSlots); pak.WriteByte((byte)windowType); //preAction (0x00 - Do nothing) if (slots != null) { foreach (int updatedSlot in slots) { if (updatedSlot >= (int) eInventorySlot.Consignment_First && updatedSlot <= (int) eInventorySlot.Consignment_Last) pak.WriteByte( (byte) (updatedSlot - (int) eInventorySlot.Consignment_First + (int) eInventorySlot.HousingInventory_First)); else pak.WriteByte((byte) (updatedSlot)); InventoryItem item = m_gameClient.Player.Inventory.GetItem((eInventorySlot) updatedSlot); if (item == null) { pak.Fill(0x00, 18); continue; } pak.WriteByte((byte) item.Level); int value1; // some object types use this field to display count int value2; // some object types use this field to display count switch (item.Object_Type) { case (int) eObjectType.Arrow: case (int) eObjectType.Bolt: case (int) eObjectType.Poison: case (int) eObjectType.GenericItem: value1 = item.Count; value2 = item.SPD_ABS; break; case (int) eObjectType.Thrown: value1 = item.DPS_AF; value2 = item.Count; break; case (int) eObjectType.Instrument: value1 = (item.DPS_AF == 2 ? 0 : item.DPS_AF); // 0x00 = Lute ; 0x01 = Drum ; 0x03 = Flute value2 = 0; break; // unused case (int) eObjectType.Shield: value1 = item.Type_Damage; value2 = item.DPS_AF; break; case (int) eObjectType.GardenObject: value1 = 0; value2 = item.SPD_ABS; break; default: value1 = item.DPS_AF; value2 = item.SPD_ABS; break; } pak.WriteByte((byte) value1); pak.WriteByte((byte) value2); if (item.Object_Type == (int) eObjectType.GardenObject) pak.WriteByte((byte) (item.DPS_AF)); else pak.WriteByte((byte) (item.Hand << 6)); pak.WriteByte((byte) ((item.Type_Damage > 3 ? 0 : item.Type_Damage << 6) | item.Object_Type)); pak.WriteShort((ushort) item.Weight); pak.WriteByte(item.ConditionPercent); // % of con pak.WriteByte(item.DurabilityPercent); // % of dur pak.WriteByte((byte) item.Quality); // % of qua pak.WriteByte((byte) item.Bonus); // % bonus pak.WriteShort((ushort) item.Model); if (item.Emblem != 0) pak.WriteShort((ushort) item.Emblem); else pak.WriteShort((ushort) item.Color); pak.WriteShort((ushort) item.Effect); string name = item.Name; if (item.Count > 1) name = item.Count + " " + name; if (item.SellPrice > 0) { if (ServerProperties.Properties.CONSIGNMENT_USE_BP) name += "[" + item.SellPrice + " BP]"; else name += "[" + Money.GetString(item.SellPrice) + "]"; } pak.WritePascalString(name); } } SendTCP(pak); } }
/// <summary> /// Sends inventory items to the client. If windowType is one of the client inventory windows then the client /// will display the window. Once the window is displayed to the client all handling of items in the window /// is done in the move item request handlers /// </summary> /// <param name="items"></param> /// <param name="windowType"></param> protected override void SendInventoryItemsPartialUpdate(IDictionary <int, InventoryItem> items, eInventoryWindowType windowType) { //ChatUtil.SendDebugMessage(m_gameClient, string.Format("SendItemsPartialUpdate: windowType: {0}, {1}", windowType, items == null ? "nothing" : items[0].Name)); using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.InventoryUpdate))) { GameVault houseVault = m_gameClient.Player.ActiveInventoryObject as GameVault; pak.WriteByte((byte)(items.Count)); pak.WriteByte(0x00); // new in 189b+, show shield in left hand pak.WriteByte((byte)((m_gameClient.Player.IsCloakInvisible ? 0x01 : 0x00) | (m_gameClient.Player.IsHelmInvisible ? 0x02 : 0x00))); // new in 189b+, cloack/helm visibility if (windowType == eInventoryWindowType.HouseVault && houseVault != null) { pak.WriteByte((byte)(houseVault.Index + 1)); // Add the vault number to the window caption } else { pak.WriteByte((byte)((m_gameClient.Player.IsCloakHoodUp ? 0x01 : 0x00) | (int)m_gameClient.Player.ActiveQuiverSlot)); //bit0 is hood up bit4 to 7 is active quiver } // ^ in 1.89b+, 0 bit - showing hooded cloack, if not hooded not show cloack at all ? pak.WriteByte(m_gameClient.Player.VisibleActiveWeaponSlots); pak.WriteByte((byte)windowType); foreach (var entry in items) { pak.WriteByte((byte)(entry.Key)); WriteItemData(pak, entry.Value); } SendTCP(pak); } }
public virtual void SendInventoryItemsPartialUpdate(List<InventoryItem> items, eInventoryWindowType windowType) { }
protected override void SendInventorySlotsUpdateRange(ICollection<int> slots, eInventoryWindowType windowType) { GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.InventoryUpdate)); pak.WriteByte((byte)(slots == null ? 0 : slots.Count)); pak.WriteByte((byte)((m_gameClient.Player.IsCloakHoodUp ? 0x01 : 0x00) | (int)m_gameClient.Player.ActiveQuiverSlot)); //bit0 is hood up bit4 to 7 is active quiver pak.WriteByte((byte)m_gameClient.Player.VisibleActiveWeaponSlots); pak.WriteByte((byte)windowType); //preAction (0x00 - Do nothing) if (slots != null) { foreach (int updatedSlot in slots) { if (updatedSlot >= (int)eInventorySlot.Consignment_First && updatedSlot <= (int)eInventorySlot.Consignment_Last) pak.WriteByte((byte)(updatedSlot - (int)eInventorySlot.Consignment_First + (int)eInventorySlot.HousingInventory_First)); else pak.WriteByte((byte)(updatedSlot)); InventoryItem item = null; item = m_gameClient.Player.Inventory.GetItem((eInventorySlot)updatedSlot); if (item == null) { pak.Fill(0x00, 19); continue; } pak.WriteByte((byte)item.Level); int value1; // some object types use this field to display count int value2; // some object types use this field to display count switch (item.Object_Type) { case (int)eObjectType.GenericItem: value1 = item.Count & 0xFF; value2 = (item.Count >> 8) & 0xFF; break; case (int)eObjectType.Arrow: case (int)eObjectType.Bolt: case (int)eObjectType.Poison: value1 = item.Count; value2 = item.SPD_ABS; break; case (int)eObjectType.Thrown: value1 = item.DPS_AF; value2 = item.Count; break; case (int)eObjectType.Instrument: value1 = (item.DPS_AF == 2 ? 0 : item.DPS_AF); value2 = 0; break; // unused case (int)eObjectType.Shield: value1 = item.Type_Damage; value2 = item.DPS_AF; break; case (int)eObjectType.AlchemyTincture: case (int)eObjectType.SpellcraftGem: value1 = 0; value2 = 0; /* must contain the quality of gem for spell craft and think same for tincture */ break; case (int)eObjectType.HouseWallObject: case (int)eObjectType.HouseFloorObject: case (int)eObjectType.GardenObject: value1 = 0; value2 = item.SPD_ABS; /* Value2 byte sets the width, only lower 4 bits 'seem' to be used (so 1-15 only) The byte used for "Hand" (IE: Mini-delve showing a weapon as Left-Hand usabe/TwoHanded), the lower 4 bits store the height (1-15 only) */ break; default: value1 = item.DPS_AF; value2 = item.SPD_ABS; break; } pak.WriteByte((byte)value1); pak.WriteByte((byte)value2); if (item.Object_Type == (int)eObjectType.GardenObject) pak.WriteByte((byte)(item.DPS_AF)); else pak.WriteByte((byte)(item.Hand << 6)); pak.WriteByte((byte)((item.Type_Damage > 3 ? 0 : item.Type_Damage << 6) | item.Object_Type)); pak.WriteShort((ushort)item.Weight); pak.WriteByte(item.ConditionPercent); // % of con pak.WriteByte(item.DurabilityPercent); // % of dur pak.WriteByte((byte)item.Quality); // % of qua pak.WriteByte((byte)item.Bonus); // % bonus pak.WriteShort((ushort)item.Model); pak.WriteByte((byte)item.Extension); int effect = item.Effect; if (item.Emblem != 0) { pak.WriteShort((ushort)item.Emblem); effect |= (item.Emblem & 0x010000) >> 8; // = 1 for newGuildEmblem } else pak.WriteShort((ushort)item.Color); pak.WriteShort((ushort)effect); string name = item.Name; if (item.Count > 1) name = item.Count + " " + name; if (item.SellPrice > 0) { if (ServerProperties.Properties.CONSIGNMENT_USE_BP) name += "[" + item.SellPrice.ToString() + " BP]"; else name += "[" + Money.GetString(item.SellPrice) + "]"; } pak.WritePascalString(name); } } SendTCP(pak); }
public void SendInventoryItemsUpdate(eInventoryWindowType windowType, ICollection<InventoryItem> itemsToUpdate) { if (SendInventoryItemsUpdateWindowMethod != null) SendInventoryItemsUpdateWindowMethod(this, windowType, itemsToUpdate); }