1
0

Fixed cItemGrid API, no more changeable GetSlot().

Also fixed possible water and lava duplication glitches in the dispenser.

git-svn-id: http://mc-server.googlecode.com/svn/trunk@1520 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com 2013-05-26 20:52:39 +00:00
parent 46ce9df7d9
commit edbc2790e3
9 changed files with 142 additions and 87 deletions

View File

@ -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

View File

@ -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 */

View File

@ -37,48 +37,51 @@ 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)
switch (DispBlock)
{
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);
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
{
cItems Pickups;
Pickups.push_back(Drop.CopyOne());
m_World->SpawnItemPickups(Pickups, DispX, DispY, DispZ);
Drop.m_ItemCount--;
}
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;
}
@ -86,36 +89,29 @@ void cDispenserEntity::DropSpenseFromSlot(int a_SlotNum)
case E_ITEM_LAVA_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_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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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.