summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2013-05-26 22:52:39 +0200
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2013-05-26 22:52:39 +0200
commitedbc2790e31f27195835ef184a9d452bc83b2c56 (patch)
tree6d6904f240ad9e7d9f61ee99a9e6a18da4663a7c
parentClarified documentation on the cItemGrid:RemoveItem() functions (diff)
downloadcuberite-edbc2790e31f27195835ef184a9d452bc83b2c56.tar
cuberite-edbc2790e31f27195835ef184a9d452bc83b2c56.tar.gz
cuberite-edbc2790e31f27195835ef184a9d452bc83b2c56.tar.bz2
cuberite-edbc2790e31f27195835ef184a9d452bc83b2c56.tar.lz
cuberite-edbc2790e31f27195835ef184a9d452bc83b2c56.tar.xz
cuberite-edbc2790e31f27195835ef184a9d452bc83b2c56.tar.zst
cuberite-edbc2790e31f27195835ef184a9d452bc83b2c56.zip
-rw-r--r--source/Bindings.cpp10
-rw-r--r--source/Bindings.h2
-rw-r--r--source/DispenserEntity.cpp139
-rw-r--r--source/DispenserEntity.h6
-rw-r--r--source/DropSpenserEntity.cpp25
-rw-r--r--source/DropSpenserEntity.h5
-rw-r--r--source/DropperEntity.cpp10
-rw-r--r--source/ItemGrid.cpp25
-rw-r--r--source/ItemGrid.h7
9 files changed, 142 insertions, 87 deletions
diff --git a/source/Bindings.cpp b/source/Bindings.cpp
index a6229c761..a3a23acce 100644
--- a/source/Bindings.cpp
+++ b/source/Bindings.cpp
@@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
-** Generated automatically by tolua++-1.0.92 on 05/26/13 17:28:14.
+** Generated automatically by tolua++-1.0.92 on 05/26/13 22:51:07.
*/
#ifndef __cplusplus
@@ -15038,7 +15038,7 @@ static int tolua_AllToLua_cItemGrid_AddItem00(lua_State* tolua_S)
if (
!tolua_isusertype(tolua_S,1,"cItemGrid",0,&tolua_err) ||
(tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) ||
- !tolua_isboolean(tolua_S,3,0,&tolua_err) ||
+ !tolua_isboolean(tolua_S,3,1,&tolua_err) ||
!tolua_isnoobj(tolua_S,4,&tolua_err)
)
goto tolua_lerror;
@@ -15047,7 +15047,7 @@ static int tolua_AllToLua_cItemGrid_AddItem00(lua_State* tolua_S)
{
cItemGrid* self = (cItemGrid*) tolua_tousertype(tolua_S,1,0);
cItem* a_ItemStack = ((cItem*) tolua_tousertype(tolua_S,2,0));
- bool a_AllowNewStacks = ((bool) tolua_toboolean(tolua_S,3,0));
+ bool a_AllowNewStacks = ((bool) tolua_toboolean(tolua_S,3,true));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItem'", NULL);
#endif
@@ -15074,7 +15074,7 @@ static int tolua_AllToLua_cItemGrid_AddItems00(lua_State* tolua_S)
if (
!tolua_isusertype(tolua_S,1,"cItemGrid",0,&tolua_err) ||
(tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItems",0,&tolua_err)) ||
- !tolua_isboolean(tolua_S,3,0,&tolua_err) ||
+ !tolua_isboolean(tolua_S,3,1,&tolua_err) ||
!tolua_isnoobj(tolua_S,4,&tolua_err)
)
goto tolua_lerror;
@@ -15083,7 +15083,7 @@ static int tolua_AllToLua_cItemGrid_AddItems00(lua_State* tolua_S)
{
cItemGrid* self = (cItemGrid*) tolua_tousertype(tolua_S,1,0);
cItems* a_ItemStackList = ((cItems*) tolua_tousertype(tolua_S,2,0));
- bool a_AllowNewStacks = ((bool) tolua_toboolean(tolua_S,3,0));
+ bool a_AllowNewStacks = ((bool) tolua_toboolean(tolua_S,3,true));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItems'", NULL);
#endif
diff --git a/source/Bindings.h b/source/Bindings.h
index ca0f4e02a..2b47c8dd7 100644
--- a/source/Bindings.h
+++ b/source/Bindings.h
@@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
-** Generated automatically by tolua++-1.0.92 on 05/26/13 17:28:14.
+** Generated automatically by tolua++-1.0.92 on 05/26/13 22:51:07.
*/
/* Exported function */
diff --git a/source/DispenserEntity.cpp b/source/DispenserEntity.cpp
index 73aed05a6..8d64c01e0 100644
--- a/source/DispenserEntity.cpp
+++ b/source/DispenserEntity.cpp
@@ -37,85 +37,81 @@ void cDispenserEntity::DropSpenseFromSlot(int a_SlotNum)
NIBBLETYPE Meta = m_World->GetBlockMeta(m_PosX, m_PosY, m_PosZ);
AddDropSpenserDir(DispX, DispY, DispZ, Meta);
- cItem & Drop = m_Contents.GetSlot(a_SlotNum);
-
// Dispense the item:
- switch (Drop.m_ItemType)
+ switch (m_Contents.GetSlot(a_SlotNum).m_ItemType)
{
case E_ITEM_BUCKET:
{
BLOCKTYPE DispBlock = m_World->GetBlock(DispX, DispY, DispZ);
- if (DispBlock == E_BLOCK_STATIONARY_WATER)
- {
- m_World->SetBlock(DispX, DispY, DispZ, E_BLOCK_AIR, 0);
- Drop.m_ItemType = E_ITEM_WATER_BUCKET; // TODO: Duplication glitch - bucket stacking allows you to duplicate water
- }
- else if (DispBlock == E_BLOCK_STATIONARY_LAVA)
- {
- m_World->SetBlock(DispX, DispY, DispZ, E_BLOCK_AIR, 0);
- Drop.m_ItemType = E_ITEM_LAVA_BUCKET; // TODO: Duplication glitch - bucket stacking allows you to duplicate lava
- }
- else
+ switch (DispBlock)
{
- cItems Pickups;
- Pickups.push_back(Drop.CopyOne());
- m_World->SpawnItemPickups(Pickups, DispX, DispY, DispZ);
- Drop.m_ItemCount--;
+ case E_BLOCK_STATIONARY_WATER:
+ case E_BLOCK_WATER:
+ {
+ if (ScoopUpLiquid(a_SlotNum, E_ITEM_WATER_BUCKET))
+ {
+ m_World->SetBlock(DispX, DispY, DispZ, E_BLOCK_AIR, 0);
+ }
+ break;
+ }
+ case E_BLOCK_STATIONARY_LAVA:
+ case E_BLOCK_LAVA:
+ {
+ if (ScoopUpLiquid(a_SlotNum, E_ITEM_LAVA_BUCKET))
+ {
+ m_World->SetBlock(DispX, DispY, DispZ, E_BLOCK_AIR, 0);
+ }
+ break;
+ }
+ default:
+ {
+ DropFromSlot(a_SlotNum);
+ break;
+ }
}
break;
- }
+ } // E_ITEM_BUCKET
case E_ITEM_WATER_BUCKET:
{
BLOCKTYPE DispBlock = m_World->GetBlock(DispX, DispY, DispZ);
- if ((DispBlock == E_BLOCK_AIR) || IsBlockLiquid(DispBlock) || cFluidSimulator::CanWashAway(DispBlock))
+ if (PlaceLiquid(DispBlock, a_SlotNum))
{
- m_World->SetBlock(DispX, DispY, DispZ, E_BLOCK_STATIONARY_WATER, 0);
- Drop.m_ItemType = E_ITEM_BUCKET;
+ m_World->SetBlock(DispX, DispY, DispZ, E_BLOCK_WATER, 0);
}
else
{
- cItems Pickups;
- Pickups.push_back(Drop.CopyOne());
- m_World->SpawnItemPickups(Pickups, DispX, DispY, DispZ);
- Drop.m_ItemCount--;
+ DropFromSlot(a_SlotNum);
}
break;
}
case E_ITEM_LAVA_BUCKET:
{
- BLOCKTYPE DispBlock = m_World->GetBlock( DispX, DispY, DispZ );
- if ((DispBlock == E_BLOCK_AIR) || IsBlockLiquid(DispBlock) || cFluidSimulator::CanWashAway(DispBlock))
+ BLOCKTYPE DispBlock = m_World->GetBlock(DispX, DispY, DispZ);
+ if (PlaceLiquid(DispBlock, a_SlotNum))
{
- m_World->SetBlock(DispX, DispY, DispZ, E_BLOCK_STATIONARY_LAVA, 0);
- Drop.m_ItemType = E_ITEM_BUCKET;
+ m_World->SetBlock(DispX, DispY, DispZ, E_BLOCK_LAVA, 0);
}
else
{
- cItems Pickups;
- Pickups.push_back(Drop.CopyOne());
- m_World->SpawnItemPickups(Pickups, DispX, DispY, DispZ);
- Drop.m_ItemCount--;
+ DropFromSlot(a_SlotNum);
}
break;
}
case E_ITEM_SPAWN_EGG:
{
- if (m_World->SpawnMob(DispX + 0.5, DispY, DispZ + 0.5, Drop.m_ItemDamage) >= 0)
+ if (m_World->SpawnMob(DispX + 0.5, DispY, DispZ + 0.5, m_Contents.GetSlot(a_SlotNum).m_ItemDamage) >= 0)
{
- Drop.m_ItemCount--;
+ m_Contents.ChangeSlotCount(a_SlotNum, -1);
}
break;
}
default:
{
- cItems Pickups;
- Pickups.push_back(Drop.CopyOne());
- m_World->SpawnItemPickups(Pickups, DispX, DispY, DispZ);
- Drop.m_ItemCount--;
+ DropFromSlot(a_SlotNum);
break;
}
} // switch (ItemType)
@@ -125,3 +121,66 @@ void cDispenserEntity::DropSpenseFromSlot(int a_SlotNum)
+
+bool cDispenserEntity::ScoopUpLiquid(int a_SlotNum, short a_BucketItemType)
+{
+ cItem LiquidBucket(a_BucketItemType, 1);
+ if (m_Contents.GetSlot(a_SlotNum).m_ItemCount == 1)
+ {
+ // Special case: replacing one empty bucket with one full bucket
+ m_Contents.SetSlot(a_SlotNum, LiquidBucket);
+ return true;
+ }
+
+ // There are stacked buckets at the selected slot, see if a full bucket will fit somewhere else
+ if (m_Contents.HowManyCanFit(LiquidBucket) < 1)
+ {
+ // Cannot fit into m_Contents
+ return false;
+ }
+
+ m_Contents.ChangeSlotCount(a_SlotNum, -1);
+ m_Contents.AddItem(LiquidBucket);
+ return true;
+}
+
+
+
+
+
+bool cDispenserEntity::PlaceLiquid(BLOCKTYPE a_BlockInFront, int a_SlotNum)
+{
+ if (
+ (a_BlockInFront != E_BLOCK_AIR) &&
+ !IsBlockLiquid(a_BlockInFront) &&
+ !cFluidSimulator::CanWashAway(a_BlockInFront)
+ )
+ {
+ // Not a suitable block in front
+ return false;
+ }
+
+ cItem EmptyBucket(E_ITEM_BUCKET, 1);
+ if (m_Contents.GetSlot(a_SlotNum).m_ItemCount == 1)
+ {
+ // Change the single full bucket present into a single empty bucket
+ m_Contents.SetSlot(a_SlotNum, EmptyBucket);
+ return true;
+ }
+
+ // There are full buckets stacked at this slot, check if we can fit in the empty bucket
+ if (m_Contents.HowManyCanFit(EmptyBucket) < 1)
+ {
+ // The empty bucket wouldn't fit into m_Contents
+ return false;
+ }
+
+ // The empty bucket fits in, remove one full bucket and add the empty one
+ m_Contents.ChangeSlotCount(a_SlotNum, -1);
+ m_Contents.AddItem(EmptyBucket);
+ return true;
+}
+
+
+
+
diff --git a/source/DispenserEntity.h b/source/DispenserEntity.h
index 9d788128f..ad6400921 100644
--- a/source/DispenserEntity.h
+++ b/source/DispenserEntity.h
@@ -28,6 +28,12 @@ public:
private:
// cDropSpenser overrides:
virtual void DropSpenseFromSlot(int a_SlotNum) override;
+
+ /// If such a bucket can fit, adds it to m_Contents and returns true
+ bool ScoopUpLiquid(int a_SlotNum, short a_BucketItemType);
+
+ /// If the a_BlockInFront is liquidable and the empty bucket can fit, does the m_Contents processing and returns true
+ bool PlaceLiquid(BLOCKTYPE a_BlockInFront, int a_SlotNum);
} ; // tolua_export
diff --git a/source/DropSpenserEntity.cpp b/source/DropSpenserEntity.cpp
index 580f96944..3830e1d01 100644
--- a/source/DropSpenserEntity.cpp
+++ b/source/DropSpenserEntity.cpp
@@ -146,8 +146,14 @@ bool cDropSpenserEntity::LoadFromJson(const Json::Value & a_Value)
int SlotIdx = 0;
for (Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr)
{
- m_Contents.GetSlot(SlotIdx).FromJson(*itr);
+ cItem Contents;
+ Contents.FromJson(*itr);
+ m_Contents.SetSlot(SlotIdx, Contents);
SlotIdx++;
+ if (SlotIdx >= m_Contents.GetNumSlots())
+ {
+ return true;
+ }
}
return true;
@@ -210,3 +216,20 @@ void cDropSpenserEntity::UsedBy(cPlayer * a_Player)
+
+void cDropSpenserEntity::DropFromSlot(int a_SlotNum)
+{
+ int DispX = m_PosX;
+ int DispY = m_PosY;
+ int DispZ = m_PosZ;
+ NIBBLETYPE Meta = m_World->GetBlockMeta(m_PosX, m_PosY, m_PosZ);
+ AddDropSpenserDir(DispX, DispY, DispZ, Meta);
+
+ cItems Pickups;
+ Pickups.push_back(m_Contents.RemoveOneItem(a_SlotNum));
+ m_World->SpawnItemPickups(Pickups, DispX, DispY, DispZ);
+}
+
+
+
+
diff --git a/source/DropSpenserEntity.h b/source/DropSpenserEntity.h
index d6e1144b1..f4221808c 100644
--- a/source/DropSpenserEntity.h
+++ b/source/DropSpenserEntity.h
@@ -67,13 +67,16 @@ public:
// tolua_end
-private:
+protected:
bool m_ShouldDropSpense; ///< If true, the dropspenser will dropspense an item in the next tick
void DropSpense(void);
/// Override this function to provide the specific behavior for item dropspensing (drop / shoot / pour / ...)
virtual void DropSpenseFromSlot(int a_SlotNum) = 0;
+
+ /// Helper function, drops one item from the specified slot (like a dropper)
+ void DropFromSlot(int a_SlotNum);
} ; // tolua_export
diff --git a/source/DropperEntity.cpp b/source/DropperEntity.cpp
index dab320eb1..39c2cf3bd 100644
--- a/source/DropperEntity.cpp
+++ b/source/DropperEntity.cpp
@@ -34,15 +34,7 @@ cDropperEntity::cDropperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld
void cDropperEntity::DropSpenseFromSlot(int a_SlotNum)
{
- int DispX = m_PosX;
- int DispY = m_PosY;
- int DispZ = m_PosZ;
- NIBBLETYPE Meta = m_World->GetBlockMeta(m_PosX, m_PosY, m_PosZ);
- AddDropSpenserDir(DispX, DispY, DispZ, Meta);
-
- cItems Pickups;
- Pickups.push_back(m_Contents.RemoveOneItem(a_SlotNum).CopyOne());
- m_World->SpawnItemPickups(Pickups, DispX, DispY, DispZ);
+ DropFromSlot(a_SlotNum);
}
diff --git a/source/ItemGrid.cpp b/source/ItemGrid.cpp
index 5a432e80f..33cae3e17 100644
--- a/source/ItemGrid.cpp
+++ b/source/ItemGrid.cpp
@@ -81,15 +81,6 @@ const cItem & cItemGrid::GetSlot(int a_X, int a_Y) const
-cItem & cItemGrid::GetSlot(int a_X, int a_Y)
-{
- return GetSlot(GetSlotNum(a_X, a_Y));
-}
-
-
-
-
-
const cItem & cItemGrid::GetSlot(int a_SlotNum) const
{
if ((a_SlotNum < 0) || (a_SlotNum >= m_NumSlots))
@@ -106,22 +97,6 @@ const cItem & cItemGrid::GetSlot(int a_SlotNum) const
-cItem & cItemGrid::GetSlot(int a_SlotNum)
-{
- if ((a_SlotNum < 0) || (a_SlotNum >= m_NumSlots))
- {
- LOGWARNING("%s: Invalid slot number, %d out of %d slots",
- __FUNCTION__, a_SlotNum, m_NumSlots
- );
- return m_Slots[0];
- }
- return m_Slots[a_SlotNum];
-}
-
-
-
-
-
void cItemGrid::SetSlot(int a_X, int a_Y, const cItem & a_Item)
{
SetSlot(GetSlotNum(a_X, a_Y), a_Item);
diff --git a/source/ItemGrid.h b/source/ItemGrid.h
index 80ea17c8b..72b7d3b03 100644
--- a/source/ItemGrid.h
+++ b/source/ItemGrid.h
@@ -46,9 +46,6 @@ public:
/// Converts slot number into XY coords; sets coords to -1 on invalid slot number. Exported in ManualBindings.cpp
void GetSlotCoords(int a_SlotNum, int & a_X, int & a_Y) const;
- cItem & GetSlot(int a_X, int a_Y); // TODO: This will be removed!
- cItem & GetSlot(int a_SlotNum); // TODO: This will be removed!
-
// tolua_begin
// Retrieve slots by coords or slot number; Logs warning and returns the first slot on invalid coords / slotnum
@@ -76,7 +73,7 @@ public:
if a_AllowNewStacks is set to true, empty slots can be used for the rest
Returns the number of items that fit.
*/
- int AddItem(cItem & a_ItemStack, bool a_AllowNewStacks);
+ int AddItem(cItem & a_ItemStack, bool a_AllowNewStacks = true);
/** Same as AddItem, but works on an entire list of item stacks.
The a_ItemStackList is modified to reflect the leftover items.
@@ -84,7 +81,7 @@ public:
if a_AllowNewStacks is set to true, empty slots can be used for the rest
Returns the total number of items that fit.
*/
- int AddItems(cItems & a_ItemStackList, bool a_AllowNewStacks);
+ int AddItems(cItems & a_ItemStackList, bool a_AllowNewStacks = true);
/** Adds (or subtracts, if a_AddToCount is negative) to the count of items in the specified slot.
If the slot is empty, ignores the call.