Replace buckets to the selected hotbar slot, rather than the first available. (#4580)
* Replace buckets to the selected hotbar slot, rather than the first available. Replicates vanilla behaviour, as well as being more logical. * Refactor cInventory::AddItem. Behaviour is now documented * Add new cInventory::ReplaceOneEquippedItem and ::SetEquippedItem methods * Return empty potion to the same slot after drinking * Replace buckets correctly in other situations, not simply water and lava Uses the new ReplaceOneEquippedItem method * Correct collecting water from source block with bottle * Add cPlayer::ReplaceOneEquippedItemTossRest method * Handle stacked filled buckets (in theory) Use new cPlayer::ReplaceOneEquippedItemTossRest method
This commit is contained in:
parent
d5c58c6b17
commit
cdc452916e
@ -6223,7 +6223,7 @@ These ItemGrids are available in the API and can be manipulated by the plugins,
|
||||
Type = "number",
|
||||
},
|
||||
},
|
||||
Notes = "Adds an item to the storage; if AllowNewStacks is true (default), will also create new stacks in empty slots. Returns the number of items added",
|
||||
Notes = "Adds an item to the storage; if AllowNewStacks is true (default), will also create new stacks in empty slots. Fills existing stacks first and fills the hotbar before the main inventory. Returns the number of items added",
|
||||
},
|
||||
AddItems =
|
||||
{
|
||||
@ -6617,6 +6617,28 @@ These ItemGrids are available in the API and can be manipulated by the plugins,
|
||||
},
|
||||
Notes = "Removes one item from the hotbar's currently selected slot. Returns true on success.",
|
||||
},
|
||||
ReplaceOneEquippedItem =
|
||||
{
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "Item",
|
||||
Type = "cItem",
|
||||
},
|
||||
{
|
||||
Name = "TryOtherSlots",
|
||||
Type = "boolean",
|
||||
IsOptional = true,
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "number",
|
||||
},
|
||||
},
|
||||
Notes = "Removes one item from the the current equipped item stack, and attempts to add the specified item stack back to the same slot. If it is not possible to place the item in the same slot, optionally (default true) tries to place the specified item elsewhere in the inventory. Returns the number of items successfully added. If the currently equipped slot is empty, its contents are simply set to the given Item.",
|
||||
},
|
||||
SendEquippedSlot =
|
||||
{
|
||||
Notes = "Sends the equipped item slot to the client",
|
||||
@ -6662,17 +6684,6 @@ These ItemGrids are available in the API and can be manipulated by the plugins,
|
||||
},
|
||||
Notes = "Sets the specified hotbar slot contents",
|
||||
},
|
||||
SetShieldSlot =
|
||||
{
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "Item",
|
||||
Type = "cItem",
|
||||
},
|
||||
},
|
||||
Notes = "Sets the shield slot content",
|
||||
},
|
||||
SetInventorySlot =
|
||||
{
|
||||
Params =
|
||||
@ -6688,6 +6699,17 @@ These ItemGrids are available in the API and can be manipulated by the plugins,
|
||||
},
|
||||
Notes = "Sets the specified main inventory slot contents",
|
||||
},
|
||||
SetShieldSlot =
|
||||
{
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "Item",
|
||||
Type = "cItem",
|
||||
},
|
||||
},
|
||||
Notes = "Sets the shield slot content",
|
||||
},
|
||||
SetSlot =
|
||||
{
|
||||
Params =
|
||||
@ -6703,6 +6725,17 @@ These ItemGrids are available in the API and can be manipulated by the plugins,
|
||||
},
|
||||
Notes = "Sets the specified slot contents",
|
||||
},
|
||||
SetEquippedItem =
|
||||
{
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "Item",
|
||||
Type = "cItem",
|
||||
},
|
||||
},
|
||||
Notes = "Sets current item in the equipped hotbar slot",
|
||||
},
|
||||
},
|
||||
Constants =
|
||||
{
|
||||
@ -10712,6 +10745,17 @@ a_Player:OpenWindow(Window);
|
||||
},
|
||||
Notes = "Places a block while impersonating the player. The {{OnPlayerPlacingBlock|HOOK_PLAYER_PLACING_BLOCK}} hook is called before the placement, and if it succeeds, the block is placed and the {{OnPlayerPlacedBlock|HOOK_PLAYER_PLACED_BLOCK}} hook is called. Returns true iff the block is successfully placed. Assumes that the block is in a currently loaded chunk.",
|
||||
},
|
||||
ReplaceOneEquippedItemTossRest =
|
||||
{
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "Item",
|
||||
Type = "cItem",
|
||||
},
|
||||
},
|
||||
Notes = "Removes one item from the the current equipped item stack, and attempts to add the specified item stack back to the same slot. If it is not possible to place the item in the same slot, tries to place the specified item elsewhere in the inventory. If this is not possible, then any remaining items are tossed. If the currently equipped slot is empty, its contents are simply set to the given Item.",
|
||||
},
|
||||
Respawn =
|
||||
{
|
||||
Notes = "Restores the health, extinguishes fire, makes visible and sends the Respawn packet.",
|
||||
|
@ -27,17 +27,31 @@ public:
|
||||
virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
|
||||
{
|
||||
NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta({a_BlockX, a_BlockY, a_BlockZ});
|
||||
switch (a_Player.GetEquippedItem().m_ItemType)
|
||||
auto EquippedItem = a_Player.GetEquippedItem();
|
||||
switch (EquippedItem.m_ItemType)
|
||||
{
|
||||
case E_ITEM_BUCKET:
|
||||
{
|
||||
if (Meta == 3)
|
||||
{
|
||||
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0);
|
||||
// Give new bucket, filled with fluid when the gamemode is not creative:
|
||||
if (!a_Player.IsGameModeCreative())
|
||||
{
|
||||
a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_WATER_BUCKET));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_ITEM_WATER_BUCKET:
|
||||
{
|
||||
if (Meta < 3)
|
||||
{
|
||||
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 3);
|
||||
// Give empty bucket back when the gamemode is not creative:
|
||||
if (!a_Player.IsGameModeCreative())
|
||||
{
|
||||
a_Player.GetInventory().RemoveOneEquippedItem();
|
||||
a_Player.GetInventory().AddItem(cItem(E_ITEM_BUCKET));
|
||||
a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_BUCKET));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -47,11 +61,27 @@ public:
|
||||
if (Meta > 0)
|
||||
{
|
||||
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, --Meta);
|
||||
a_Player.GetInventory().RemoveOneEquippedItem();
|
||||
a_Player.GetInventory().AddItem(cItem(E_ITEM_POTION));
|
||||
// Give new potion when the gamemode is not creative:
|
||||
if (!a_Player.IsGameModeCreative())
|
||||
{
|
||||
a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_POTION));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_ITEM_POTION:
|
||||
{
|
||||
// Refill cauldron with water bottles.
|
||||
if ((Meta < 3) && (EquippedItem.m_ItemDamage == 0))
|
||||
{
|
||||
a_ChunkInterface.SetBlockMeta(Vector3i(a_BlockX, a_BlockY, a_BlockZ), ++Meta);
|
||||
// Give empty bottle when the gamemode is not creative:
|
||||
if (!a_Player.IsGameModeCreative())
|
||||
{
|
||||
a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_GLASS_BOTTLE));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1211,9 +1211,9 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB
|
||||
cItem EquippedItem = m_Player->GetEquippedItem();
|
||||
cItem OffhandItem = m_Player->GetOffHandEquipedItem();
|
||||
|
||||
cInventory & Intentory = m_Player->GetInventory();
|
||||
Intentory.SetShieldSlot(EquippedItem);
|
||||
Intentory.SetHotbarSlot(Intentory.GetEquippedSlotNum(), OffhandItem);
|
||||
cInventory & Inventory = m_Player->GetInventory();
|
||||
Inventory.SetShieldSlot(EquippedItem);
|
||||
Inventory.SetEquippedItem(OffhandItem);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1959,6 +1959,25 @@ void cPlayer::TossEquippedItem(char a_Amount)
|
||||
|
||||
|
||||
|
||||
void cPlayer::ReplaceOneEquippedItemTossRest(const cItem & a_Item)
|
||||
{
|
||||
auto PlacedCount = GetInventory().ReplaceOneEquippedItem(a_Item);
|
||||
char ItemCountToToss = a_Item.m_ItemCount - static_cast<char>(PlacedCount);
|
||||
|
||||
if (ItemCountToToss == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cItem Pickup = a_Item;
|
||||
Pickup.m_ItemCount = ItemCountToToss;
|
||||
TossPickup(Pickup);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlayer::TossHeldItem(char a_Amount)
|
||||
{
|
||||
cItems Drops;
|
||||
|
@ -313,6 +313,13 @@ public:
|
||||
/** tosses the item in the selected hotbar slot */
|
||||
void TossEquippedItem(char a_Amount = 1);
|
||||
|
||||
/** Removes one item from the the current equipped item stack, and attempts to add the specified item stack
|
||||
back to the same slot. If it is not possible to place the item in the same slot, tries to place the specified
|
||||
item elsewhere in the inventory. If this is not possible, then any remaining items are tossed. If the currently
|
||||
equipped slot is empty, its contents are simply set to the given Item.
|
||||
*/
|
||||
void ReplaceOneEquippedItemTossRest(const cItem &);
|
||||
|
||||
/** tosses the item held in hand (when in UI windows) */
|
||||
void TossHeldItem(char a_Amount = 1);
|
||||
|
||||
|
@ -121,35 +121,38 @@ int cInventory::AddItem(const cItem & a_Item, bool a_AllowNewStacks)
|
||||
}
|
||||
}
|
||||
|
||||
for (int SlotIdx = 0; SlotIdx < m_InventorySlots.GetNumSlots(); ++SlotIdx)
|
||||
{
|
||||
auto & Slot = m_InventorySlots.GetSlot(SlotIdx);
|
||||
if (Slot.IsEqual(a_Item))
|
||||
{
|
||||
cItemHandler Handler(Slot.m_ItemType);
|
||||
int AmountToAdd = std::min(static_cast<char>(Handler.GetMaxStackSize() - Slot.m_ItemCount), ToAdd.m_ItemCount);
|
||||
res += AmountToAdd;
|
||||
|
||||
cItem SlotAdjusted(Slot);
|
||||
SlotAdjusted.m_ItemCount += AmountToAdd;
|
||||
m_InventorySlots.SetSlot(SlotIdx, SlotAdjusted);
|
||||
|
||||
ToAdd.m_ItemCount -= AmountToAdd;
|
||||
if (ToAdd.m_ItemCount == 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res += m_HotbarSlots.AddItem(ToAdd, a_AllowNewStacks);
|
||||
// Add to existing stacks in the hotbar.
|
||||
res += m_HotbarSlots.AddItem(ToAdd, false);
|
||||
ToAdd.m_ItemCount = static_cast<char>(a_Item.m_ItemCount - res);
|
||||
if (ToAdd.m_ItemCount == 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
res += m_InventorySlots.AddItem(ToAdd, a_AllowNewStacks);
|
||||
// Add to existing stacks in main inventory.
|
||||
res += m_InventorySlots.AddItem(ToAdd, false);
|
||||
ToAdd.m_ItemCount = static_cast<char>(a_Item.m_ItemCount - res);
|
||||
if (ToAdd.m_ItemCount == 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
// All existing stacks are now filled.
|
||||
if (!a_AllowNewStacks)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
// Try adding new stacks to the hotbar.
|
||||
res += m_HotbarSlots.AddItem(ToAdd, true);
|
||||
ToAdd.m_ItemCount = static_cast<char>(a_Item.m_ItemCount - res);
|
||||
if (ToAdd.m_ItemCount == 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
// Try adding new stacks to the main inventory.
|
||||
res += m_InventorySlots.AddItem(ToAdd, true);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -219,6 +222,50 @@ bool cInventory::RemoveOneEquippedItem(void)
|
||||
|
||||
|
||||
|
||||
int cInventory::ReplaceOneEquippedItem(const cItem & a_Item, bool a_TryOtherSlots)
|
||||
{
|
||||
// Ignore whether there was an item in the slot to remove.
|
||||
RemoveOneEquippedItem();
|
||||
|
||||
auto EquippedItem = GetEquippedItem();
|
||||
if (EquippedItem.IsEmpty())
|
||||
{
|
||||
SetEquippedItem(a_Item);
|
||||
return a_Item.m_ItemCount;
|
||||
}
|
||||
|
||||
// Handle case when equipped item is the same as the replacement item.
|
||||
cItem ItemsToAdd = a_Item;
|
||||
if (EquippedItem.IsEqual(ItemsToAdd))
|
||||
{
|
||||
cItemHandler Handler(ItemsToAdd.m_ItemType);
|
||||
auto AmountToAdd = std::min(static_cast<char>(Handler.GetMaxStackSize() - EquippedItem.m_ItemCount), ItemsToAdd.m_ItemCount);
|
||||
|
||||
EquippedItem.m_ItemCount += AmountToAdd;
|
||||
SetEquippedItem(EquippedItem);
|
||||
ItemsToAdd.m_ItemCount -= AmountToAdd;
|
||||
}
|
||||
|
||||
auto ItemsAdded = a_Item.m_ItemCount - ItemsToAdd.m_ItemCount;
|
||||
|
||||
if (ItemsToAdd.m_ItemCount == 0)
|
||||
{
|
||||
return ItemsAdded;
|
||||
}
|
||||
|
||||
if (!a_TryOtherSlots)
|
||||
{
|
||||
return ItemsAdded;
|
||||
}
|
||||
|
||||
// Try the rest of the inventory.
|
||||
return AddItem(ItemsToAdd) + ItemsAdded;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cInventory::HowManyItems(const cItem & a_Item)
|
||||
{
|
||||
return
|
||||
@ -300,6 +347,15 @@ void cInventory::SetShieldSlot(const cItem & a_Item)
|
||||
|
||||
|
||||
|
||||
void cInventory::SetEquippedItem(const cItem & a_Item)
|
||||
{
|
||||
SetHotbarSlot(GetEquippedSlotNum(), a_Item);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cInventory::SendEquippedSlot()
|
||||
{
|
||||
int EquippedSlotNum = cInventory::invArmorCount + cInventory::invInventoryCount + GetEquippedSlotNum();
|
||||
|
@ -71,6 +71,7 @@ public:
|
||||
/** Adds as many items out of a_ItemStack as can fit.
|
||||
If a_AllowNewStacks is set to false, only existing stacks can be topped up;
|
||||
if a_AllowNewStacks is set to true, empty slots can be used for the rest.
|
||||
Fills existing stacks first and fills the hotbar before the main inventory.
|
||||
Returns the number of items that fit.
|
||||
*/
|
||||
int AddItem(const cItem & a_ItemStack, bool a_AllowNewStacks = true);
|
||||
@ -90,6 +91,13 @@ public:
|
||||
/** Removes one item out of the currently equipped item stack, returns true if successful, false if empty-handed */
|
||||
bool RemoveOneEquippedItem(void);
|
||||
|
||||
/** Removes one item from the the current equipped item stack, and attempts to add the specified item stack
|
||||
back to the same slot. If it is not possible to place the item in the same slot, optionally (default true) tries to
|
||||
place the specified item elsewhere in the inventory. Returns the number of items successfully added. If the
|
||||
currently equipped slot is empty, its contents are simply set to the given Item.
|
||||
*/
|
||||
int ReplaceOneEquippedItem(const cItem & a_Item, bool a_TryOtherSlots = true);
|
||||
|
||||
/** Returns the number of items of type a_Item that are stored */
|
||||
int HowManyItems(const cItem & a_Item);
|
||||
|
||||
@ -143,6 +151,8 @@ public:
|
||||
void SetHotbarSlot(int a_HotBarSlotNum, const cItem & a_Item);
|
||||
/** Sets current item in shield slot */
|
||||
void SetShieldSlot(const cItem & a_Item);
|
||||
/** Sets current item in the equipped hotbar slot */
|
||||
void SetEquippedItem(const cItem & a_Item);
|
||||
/** Sets equiped item to the a_SlotNum slot number */
|
||||
void SetEquippedSlotNum(int a_SlotNum);
|
||||
/** Returns slot number of equiped item */
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
{
|
||||
Item.Empty();
|
||||
}
|
||||
a_Player->GetInventory().SetHotbarSlot(a_Player->GetInventory().GetEquippedSlotNum(), Item);
|
||||
a_Player->GetInventory().SetEquippedItem(Item);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -83,8 +83,11 @@ public:
|
||||
return false; // Nothing in range.
|
||||
}
|
||||
|
||||
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||
a_Player->GetInventory().AddItem(cItem(E_ITEM_POTION));
|
||||
// Give back a filled water bottle if gamemode is not creative:
|
||||
if (!a_Player->IsGameModeCreative())
|
||||
{
|
||||
a_Player->ReplaceOneEquippedItemTossRest(cItem(E_ITEM_POTION));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} ;
|
||||
|
@ -70,15 +70,15 @@ public:
|
||||
}
|
||||
|
||||
BLOCKTYPE Block = a_World->GetBlock(BlockPos.x, BlockPos.y, BlockPos.z);
|
||||
ENUM_ITEM_ID NewItem;
|
||||
ENUM_ITEM_ID NewItemType;
|
||||
|
||||
if (IsBlockWater(Block))
|
||||
{
|
||||
NewItem = E_ITEM_WATER_BUCKET;
|
||||
NewItemType = E_ITEM_WATER_BUCKET;
|
||||
}
|
||||
else if (IsBlockLava(Block))
|
||||
{
|
||||
NewItem = E_ITEM_LAVA_BUCKET;
|
||||
NewItemType = E_ITEM_LAVA_BUCKET;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -101,18 +101,7 @@ public:
|
||||
// Give new bucket, filled with fluid when the gamemode is not creative:
|
||||
if (!a_Player->IsGameModeCreative())
|
||||
{
|
||||
// Remove the bucket from the inventory
|
||||
if (!a_Player->GetInventory().RemoveOneEquippedItem())
|
||||
{
|
||||
LOG("Clicked with an empty bucket, but cannot remove one from the inventory? WTF?");
|
||||
ASSERT(!"Inventory bucket mismatch");
|
||||
return true;
|
||||
}
|
||||
if (a_Player->GetInventory().AddItem(cItem(NewItem)) != 1)
|
||||
{
|
||||
// The bucket didn't fit, toss it as a pickup:
|
||||
a_Player->TossPickup(cItem(NewItem));
|
||||
}
|
||||
a_Player->ReplaceOneEquippedItemTossRest(cItem(NewItemType));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -154,19 +143,10 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
// Give back an empty bucket if the gamemode is not creative:
|
||||
if (!a_Player->IsGameModeCreative())
|
||||
{
|
||||
// Remove fluid bucket, add empty bucket:
|
||||
if (!a_Player->GetInventory().RemoveOneEquippedItem())
|
||||
{
|
||||
LOG("Clicked with a full bucket, but cannot remove one from the inventory? WTF?");
|
||||
ASSERT(!"Inventory bucket mismatch");
|
||||
return false;
|
||||
}
|
||||
if (!a_Player->GetInventory().AddItem(cItem(E_ITEM_BUCKET)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
a_Player->ReplaceOneEquippedItemTossRest(cItem(E_ITEM_BUCKET));
|
||||
}
|
||||
|
||||
// Wash away anything that was there prior to placing:
|
||||
|
@ -77,8 +77,7 @@ public:
|
||||
|
||||
if (!a_Player->IsGameModeCreative())
|
||||
{
|
||||
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||
a_Player->GetInventory().AddItem(cItem(E_ITEM_GLASS_BOTTLE));
|
||||
a_Player->ReplaceOneEquippedItemTossRest(cItem(E_ITEM_GLASS_BOTTLE));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -44,10 +44,10 @@ void cCow::OnRightClicked(cPlayer & a_Player)
|
||||
short HeldItem = a_Player.GetEquippedItem().m_ItemType;
|
||||
if (HeldItem == E_ITEM_BUCKET)
|
||||
{
|
||||
// Milk the cow.
|
||||
if (!a_Player.IsGameModeCreative())
|
||||
{
|
||||
a_Player.GetInventory().RemoveOneEquippedItem();
|
||||
a_Player.GetInventory().AddItem(cItem(E_ITEM_MILK));
|
||||
a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_MILK));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,18 +43,18 @@ void cMooshroom::OnRightClicked(cPlayer & a_Player)
|
||||
{
|
||||
case E_ITEM_BUCKET:
|
||||
{
|
||||
// Milk the cow.
|
||||
if (!a_Player.IsGameModeCreative())
|
||||
{
|
||||
a_Player.GetInventory().RemoveOneEquippedItem();
|
||||
a_Player.GetInventory().AddItem(cItem(E_ITEM_MILK));
|
||||
a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_MILK));
|
||||
}
|
||||
} break;
|
||||
case E_ITEM_BOWL:
|
||||
{
|
||||
// Soup the cow.
|
||||
if (!a_Player.IsGameModeCreative())
|
||||
{
|
||||
a_Player.GetInventory().RemoveOneEquippedItem();
|
||||
a_Player.GetInventory().AddItem(cItem(E_ITEM_MUSHROOM_SOUP));
|
||||
a_Player.ReplaceOneEquippedItemTossRest(cItem(E_ITEM_MUSHROOM_SOUP));
|
||||
}
|
||||
} break;
|
||||
case E_ITEM_SHEARS:
|
||||
|
Loading…
Reference in New Issue
Block a user