bool cSlotArea::CollectItemsToHand(cItem & a_Dragging, cPlayer & a_Player, bool a_CollectFullStacks) { int NumSlots = GetNumSlots(); for (int i = 0; i < NumSlots; i++) { const cItem & SlotItem = *GetSlot(i, a_Player); if (!SlotItem.IsEqual(a_Dragging)) { continue; } int ToMove = a_Dragging.GetMaxStackSize() - a_Dragging.m_ItemCount; if (ToMove > SlotItem.m_ItemCount) { ToMove = SlotItem.m_ItemCount; } a_Dragging.m_ItemCount += ToMove; cItem NewSlot(SlotItem); NewSlot.m_ItemCount -= ToMove; SetSlot(i, a_Player, NewSlot); if (!NewSlot.IsEmpty()) { // There are leftovers in the slot, so a_Dragging must be full return true; } } // for i - Slots[] // a_Dragging may be full if there were exactly the number of items needed to fill it return a_Dragging.IsFullStack(); }
void cSlotAreaArmor::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) { if (ItemCategory::IsHelmet(a_ItemStack.m_ItemType) && GetSlot(0, a_Player)->IsEmpty()) { if (a_ShouldApply) { SetSlot(0, a_Player, a_ItemStack.CopyOne()); } a_ItemStack.m_ItemCount -= 1; } else if (ItemCategory::IsChestPlate(a_ItemStack.m_ItemType) && GetSlot(1, a_Player)->IsEmpty()) { if (a_ShouldApply) { SetSlot(1, a_Player, a_ItemStack.CopyOne()); } a_ItemStack.m_ItemCount -= 1; } else if (ItemCategory::IsLeggings(a_ItemStack.m_ItemType) && GetSlot(2, a_Player)->IsEmpty()) { if (a_ShouldApply) { SetSlot(2, a_Player, a_ItemStack.CopyOne()); } a_ItemStack.m_ItemCount -= 1; } else if (ItemCategory::IsBoots(a_ItemStack.m_ItemType) && GetSlot(3, a_Player)->IsEmpty()) { if (a_ShouldApply) { SetSlot(3, a_Player, a_ItemStack.CopyOne()); } a_ItemStack.m_ItemCount -= 1; } }
/* \brief Check if two item are similar so pileable \author Endymion \todo add amx vars and events \note if same item is compared, false is returned */ inline bool operator ==( cItem& a, cItem& b ) { return ( a.pileable && b.pileable ) && ( a.getSerial32() != b.getSerial32() ) && ( a.getScriptID() == b.getScriptID() ) && ( a.getId() == b.getId() ) && ( a.getColor() == b.getColor() ) && ( a.poisoned == b.poisoned ); }
void cProtocol125::WriteItem(const cItem & a_Item) { short ItemType = a_Item.m_ItemType; ASSERT(ItemType >= -1); // Check validity of packets in debug runtime if (ItemType <= 0) { // Fix, to make sure no invalid values are sent. ItemType = -1; } WriteShort(ItemType); if (a_Item.IsEmpty()) { return; } WriteChar (a_Item.m_ItemCount); WriteShort(a_Item.m_ItemDamage); if (cItem::IsEnchantable(a_Item.m_ItemType)) { // TODO: Implement enchantments WriteShort(-1); } }
void cSlotAreaAnvil::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) { for (int i = 0; i < 2; i++) { const cItem * Slot = GetSlot(i, a_Player); if (!Slot->IsEqual(a_ItemStack) && (!Slot->IsEmpty() || a_KeepEmptySlots)) { // Different items continue; } int NumFit = ItemHandler(Slot->m_ItemType)->GetMaxStackSize() - Slot->m_ItemCount; if (NumFit <= 0) { // Full stack already continue; } if (NumFit > a_ItemStack.m_ItemCount) { NumFit = a_ItemStack.m_ItemCount; } if (a_ShouldApply) { cItem NewSlot(a_ItemStack); NewSlot.m_ItemCount = Slot->m_ItemCount + NumFit; SetSlot(i, a_Player, NewSlot); } a_ItemStack.m_ItemCount -= NumFit; if (a_ItemStack.IsEmpty()) { UpdateResult(a_Player); return; } } // for i - Slots UpdateResult(a_Player); }
/// Moves one of the specified itemstack into this hopper. Returns true if contents have changed. Doesn't change the itemstack. bool cHopperEntity::MoveItemsFromSlot(const cItem & a_ItemStack, bool a_AllowNewStacks) { cItem One(a_ItemStack.CopyOne()); if (m_Contents.AddItem(One, a_AllowNewStacks) > 0) { return true; } return false; }
void cHero::giveItem(cItem iItem) { if (iItem.getType() == item_weapon && mWeapon.getType() != item_armor) { mWeapon.setItem(iItem.getName(), iItem.getType(), iItem.getBonus()); } else if (iItem.getType() == item_armor && mArmor.getType() != item_weapon) { mArmor.setItem(iItem.getName(), iItem.getType(), iItem.getBonus()); } }
void cSlotAreaEnchanting::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_Apply, bool a_KeepEmptySlots) { const cItem * Slot = GetSlot(0, a_Player); if (!Slot->IsEmpty()) { return; } if (a_Apply) { SetSlot(0, a_Player, a_ItemStack.CopyOne()); } a_ItemStack.m_ItemCount -= 1; if (a_ItemStack.m_ItemCount <= 0) { a_ItemStack.Empty(); } UpdateResult(a_Player); }
bool cItems::ContainsType(const cItem & a_Item) { for (auto itr : *this) { if (a_Item.IsSameType(itr)) { return true; } } return false; }
bool cItems::Contains(const cItem & a_Item) { for (auto itr : *this) { if (a_Item.IsEqual(itr)) { return true; } } return false; }
int cProtocol125::ParseItem(cItem & a_Item) { HANDLE_PACKET_READ(ReadBEShort, short, ItemType); if (ItemType <= -1) { a_Item.Empty(); return PARSE_OK; } a_Item.m_ItemType = ItemType; HANDLE_PACKET_READ(ReadChar, char, ItemCount); HANDLE_PACKET_READ(ReadBEShort, short, ItemDamage); a_Item.m_ItemCount = ItemCount; a_Item.m_ItemDamage = ItemDamage; if (ItemCount <= 0) { a_Item.Empty(); } if (!cItem::IsEnchantable(ItemType)) { return PARSE_OK; } HANDLE_PACKET_READ(ReadBEShort, short, EnchantNumBytes); if (EnchantNumBytes <= 0) { return PARSE_OK; } // TODO: Enchantment not implemented yet! if (!m_ReceivedData.SkipRead((size_t)EnchantNumBytes)) { return PARSE_INCOMPLETE; } return PARSE_OK; }
void cWindow::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, cSlotArea * a_ExcludeArea, bool a_ShouldApply) { // Ask each slot area to take as much of the stack as it can. // First ask only slots that already have the same kind of item // Then ask any remaining slots for (int Pass = 0; Pass < 2; ++Pass) { if (m_ShouldDistributeToHotbarFirst) { // First distribute into the hotbar: if (a_ExcludeArea != m_SlotAreas.back()) { m_SlotAreas.back()->DistributeStack(a_ItemStack, a_Player, a_ShouldApply, (Pass == 0)); if (a_ItemStack.IsEmpty()) { // Distributed it all return; } } } // The distribute to all other areas: cSlotAreas::iterator end = m_ShouldDistributeToHotbarFirst ? (m_SlotAreas.end() - 1) : m_SlotAreas.end(); for (cSlotAreas::iterator itr = m_SlotAreas.begin(); itr != end; ++itr) { if (*itr == a_ExcludeArea) { continue; } (*itr)->DistributeStack(a_ItemStack, a_Player, a_ShouldApply, (Pass == 0)); if (a_ItemStack.IsEmpty()) { // Distributed it all return; } } // for itr - m_SlotAreas[] } // for Pass - repeat twice }
void cHorse::SetHorseArmor(cItem a_Armor) { if (ItemCategory::IsHorseArmor(a_Armor.m_ItemType)) { m_World->BroadcastSoundEffect("entity.horse.armor", GetPosition(), 1.0f, 0.8f); } else if (!a_Armor.IsEmpty()) { return; // Invalid item } m_Armor = std::move(a_Armor); m_World->BroadcastEntityMetadata(*this); }
int cItemGrid::AddItem(cItem & a_ItemStack, bool a_AllowNewStacks, int a_PrioritarySlot) { int NumLeft = a_ItemStack.m_ItemCount; int MaxStack = a_ItemStack.GetMaxStackSize(); // Try prioritarySlot first: if ( (a_PrioritarySlot != -1) && ( m_Slots[a_PrioritarySlot].IsEmpty() || m_Slots[a_PrioritarySlot].IsEqual(a_ItemStack) ) ) { NumLeft -= AddItemToSlot(a_ItemStack, a_PrioritarySlot, NumLeft, MaxStack); } // Scan existing stacks: for (int i = 0; i < m_NumSlots; i++) { if (m_Slots[i].IsEqual(a_ItemStack)) { NumLeft -= AddItemToSlot(a_ItemStack, i, NumLeft, MaxStack); } if (NumLeft <= 0) { // All items fit return a_ItemStack.m_ItemCount; } } // for i - m_Slots[] if (!a_AllowNewStacks) { return (a_ItemStack.m_ItemCount - NumLeft); } for (int i = 0; i < m_NumSlots; i++) { if (m_Slots[i].IsEmpty()) { NumLeft -= AddItemToSlot(a_ItemStack, i, NumLeft, MaxStack); } if (NumLeft <= 0) { // All items fit return a_ItemStack.m_ItemCount; } } // for i - m_Slots[] return (a_ItemStack.m_ItemCount - NumLeft); }
void cHorse::SetHorseSaddle(cItem a_Saddle) { if (a_Saddle.m_ItemType == E_ITEM_SADDLE) { m_World->BroadcastSoundEffect("entity.horse.saddle", GetPosition(), 1.0f, 0.8f); } else if (!a_Saddle.IsEmpty()) { return; // Invalid item } m_Saddle = std::move(a_Saddle); m_World->BroadcastEntityMetadata(*this); }
int cProtocol132::ParseItem(cItem & a_Item) { HANDLE_PACKET_READ(ReadBEShort, short, ItemType); if (ItemType <= -1) { a_Item.Empty(); return PARSE_OK; } a_Item.m_ItemType = ItemType; HANDLE_PACKET_READ(ReadChar, char, ItemCount); HANDLE_PACKET_READ(ReadBEShort, short, ItemDamage); a_Item.m_ItemCount = ItemCount; a_Item.m_ItemDamage = ItemDamage; if (ItemCount <= 0) { a_Item.Empty(); } HANDLE_PACKET_READ(ReadBEShort, short, MetadataLength); if (MetadataLength <= 0) { return PARSE_OK; } // Read the metadata AString Metadata; Metadata.resize((size_t)MetadataLength); if (!m_ReceivedData.ReadBuf((void *)Metadata.data(), (size_t)MetadataLength)) { return PARSE_INCOMPLETE; } return ParseItemMetadata(a_Item, Metadata); }
void cWindow::DistributeStackToAreas(cItem & a_ItemStack, cPlayer & a_Player, cSlotAreas & a_AreasInOrder, bool a_ShouldApply, bool a_BackFill) { /* Ask each slot area to take as much of the stack as it can. First ask only slots that already have the same kind of item Then ask any remaining slots */ for (size_t Pass = 0; Pass < 2; Pass++) { for (auto SlotArea : a_AreasInOrder) { SlotArea->DistributeStack(a_ItemStack, a_Player, a_ShouldApply, (Pass == 0), a_BackFill); if (a_ItemStack.IsEmpty()) { // Distributed it all return; } } } }
void cProtocol132::WriteItem(const cItem & a_Item) { short ItemType = a_Item.m_ItemType; ASSERT(ItemType >= -1); // Check validity of packets in debug runtime if (ItemType <= 0) { // Fix, to make sure no invalid values are sent. ItemType = -1; } if (a_Item.IsEmpty()) { WriteShort(-1); return; } WriteShort(ItemType); WriteChar (a_Item.m_ItemCount); WriteShort(a_Item.m_ItemDamage); if (a_Item.m_Enchantments.IsEmpty()) { WriteShort(-1); return; } // Send the enchantments: cFastNBTWriter Writer; const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, Writer, TagName); Writer.Finish(); AString Compressed; CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed); WriteShort((short)Compressed.size()); SendData(Compressed.data(), Compressed.size()); }