Dispensers can dispense items and liquids now
git-svn-id: http://mc-server.googlecode.com/svn/trunk@1105 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
17a2c1b388
commit
575abe8691
@ -442,7 +442,15 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
||||
m_IsDirty = ((cFurnaceEntity *)(*itr))->Tick( a_Dt ) | m_IsDirty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Tick block entities (dispensers)
|
||||
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->GetBlockType() == E_BLOCK_DISPENSER)
|
||||
{
|
||||
m_IsDirty = ((cDispenserEntity *)(*itr))->Tick( a_Dt ) | m_IsDirty;
|
||||
}
|
||||
}
|
||||
ApplyWeatherToTop(a_TickRandom);
|
||||
}
|
||||
|
||||
@ -1588,6 +1596,28 @@ bool cChunk::ForEachChest(cChestCallback & a_Callback)
|
||||
|
||||
|
||||
|
||||
bool cChunk::ForEachDispenser(cDispenserCallback & a_Callback)
|
||||
{
|
||||
// The blockentity list is locked by the parent chunkmap's CS
|
||||
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), itr2 = itr; itr != m_BlockEntities.end(); itr = itr2)
|
||||
{
|
||||
++itr2;
|
||||
if ((*itr)->GetBlockType() != E_BLOCK_DISPENSER)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (a_Callback.Item((cDispenserEntity *)*itr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} // for itr - m_BlockEntitites[]
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunk::ForEachFurnace(cFurnaceCallback & a_Callback)
|
||||
{
|
||||
// The blockentity list is locked by the parent chunkmap's CS
|
||||
@ -1650,6 +1680,38 @@ bool cChunk::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallb
|
||||
|
||||
|
||||
|
||||
bool cChunk::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback & a_Callback)
|
||||
{
|
||||
// The blockentity list is locked by the parent chunkmap's CS
|
||||
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), itr2 = itr; itr != m_BlockEntities.end(); itr = itr2)
|
||||
{
|
||||
++itr2;
|
||||
if (((*itr)->GetPosX() != a_BlockX) || ((*itr)->GetPosY() != a_BlockY) || ((*itr)->GetPosZ() != a_BlockZ))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((*itr)->GetBlockType() != E_BLOCK_DISPENSER)
|
||||
{
|
||||
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out
|
||||
return false;
|
||||
}
|
||||
|
||||
// The correct block entity is here
|
||||
if (a_Callback.Item((cDispenserEntity *)*itr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // for itr - m_BlockEntitites[]
|
||||
|
||||
// Not found:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunk::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback)
|
||||
{
|
||||
// The blockentity list is locked by the parent chunkmap's CS
|
||||
|
@ -168,12 +168,18 @@ public:
|
||||
/// Calls the callback for each chest; returns true if all chests processed, false if the callback aborted by returning true
|
||||
bool ForEachChest(cChestCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/// Calls the callback for each dispenser; returns true if all dispensers processed, false if the callback aborted by returning true
|
||||
bool ForEachDispenser(cDispenserCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/// Calls the callback for each furnace; returns true if all furnaces processed, false if the callback aborted by returning true
|
||||
bool ForEachFurnace(cFurnaceCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/// Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found
|
||||
bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Lua-acessible
|
||||
|
||||
/// Calls the callback for the dispenser at the specified coords; returns false if there's no dispenser at those coords, true if found
|
||||
bool DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/// Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords, true if found
|
||||
bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Lua-accessible
|
||||
|
||||
|
@ -1354,6 +1354,21 @@ bool cChunkMap::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback &
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback & a_Callback)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ);
|
||||
if ((Chunk == NULL) && !Chunk->IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Chunk->ForEachDispenser(a_Callback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
@ -1387,6 +1402,24 @@ bool cChunkMap::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCa
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback & a_Callback)
|
||||
{
|
||||
int ChunkX, ChunkZ;
|
||||
int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ;
|
||||
cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
|
||||
cCSLock Lock(m_CSLayers);
|
||||
cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
|
||||
if ((Chunk == NULL) && !Chunk->IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Chunk->DoWithDispenserAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback)
|
||||
{
|
||||
int ChunkX, ChunkZ;
|
||||
|
@ -184,12 +184,18 @@ public:
|
||||
/// Calls the callback for each chest in the specified chunk; returns true if all chests processed, false if the callback aborted by returning true
|
||||
bool ForEachChestInChunk (int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/// Calls the callback for each dispenser in the specified chunk; returns true if all dispensers processed, false if the callback aborted by returning true
|
||||
bool ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/// Calls the callback for each furnace in the specified chunk; returns true if all furnaces processed, false if the callback aborted by returning true
|
||||
bool ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/// Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found
|
||||
bool DoWithChestAt (int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Lua-acessible
|
||||
|
||||
/// Calls the callback for the dispenser at the specified coords; returns false if there's no dispenser at those coords, true if found
|
||||
bool DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback & a_Callback); // Lua-accessible
|
||||
|
||||
/// Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords, true if found
|
||||
bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Lua-accessible
|
||||
|
||||
|
@ -11,15 +11,30 @@
|
||||
#include "Server.h"
|
||||
#include "Pickup.h"
|
||||
#include "Root.h"
|
||||
#include "Simulator/FluidSimulator.h"
|
||||
#include <json/json.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define AddDispenserDir(x, y, z, dir) \
|
||||
switch (dir) \
|
||||
{ \
|
||||
case 2: (z) --; break; \
|
||||
case 3: (z) ++; break; \
|
||||
case 4: (x) --; break; \
|
||||
case 5: (x) ++; break; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cDispenserEntity::cDispenserEntity(int a_X, int a_Y, int a_Z, cWorld * a_World)
|
||||
: cBlockEntity( E_BLOCK_DISPENSER, a_X, a_Y, a_Z, a_World )
|
||||
, m_Items( new cItem[9] )
|
||||
, m_CanDispense( 0 )
|
||||
{
|
||||
SetBlockEntity(this); // cBlockEntityWindowOwner
|
||||
}
|
||||
@ -51,7 +66,7 @@ void cDispenserEntity::Destroy()
|
||||
{
|
||||
// Drop items
|
||||
cItems Pickups;
|
||||
for( int i = 0; i < 3; i++)
|
||||
for( int i = 0; i < 9; i++)
|
||||
{
|
||||
if( !m_Items[i].IsEmpty() )
|
||||
{
|
||||
@ -66,6 +81,120 @@ void cDispenserEntity::Destroy()
|
||||
|
||||
|
||||
|
||||
void cDispenserEntity::Dispense()
|
||||
{
|
||||
int Disp_X = m_PosX;
|
||||
int Disp_Y = m_PosY;
|
||||
int Disp_Z = m_PosZ;
|
||||
NIBBLETYPE Meta = m_World->GetBlockMeta( m_PosX, m_PosY, m_PosZ );
|
||||
AddDispenserDir( Disp_X, Disp_Y, Disp_Z, Meta );
|
||||
char OccupiedSlots[9];
|
||||
char SlotsCnt = 0;
|
||||
for( int i = 0; i < 9; i++)
|
||||
{
|
||||
if( !m_Items[i].IsEmpty() )
|
||||
{
|
||||
OccupiedSlots[SlotsCnt] = i;
|
||||
SlotsCnt++;
|
||||
}
|
||||
}
|
||||
if(SlotsCnt > 0)
|
||||
{
|
||||
MTRand r1;
|
||||
cItem Drop = m_Items[OccupiedSlots[r1.randInt() % SlotsCnt]];
|
||||
switch( m_Items[OccupiedSlots[r1.randInt() % SlotsCnt]].m_ItemType )
|
||||
{
|
||||
case E_ITEM_BUCKET:
|
||||
{
|
||||
BLOCKTYPE DispBlock = m_World->GetBlock( Disp_X, Disp_Y, Disp_Z );
|
||||
if( DispBlock == E_BLOCK_STATIONARY_WATER )
|
||||
{
|
||||
m_World->SetBlock( Disp_X, Disp_Y, Disp_Z, E_BLOCK_AIR, 0 );
|
||||
m_Items[OccupiedSlots[r1.randInt() % SlotsCnt]].m_ItemType = E_ITEM_WATER_BUCKET;
|
||||
}
|
||||
else if( DispBlock == E_BLOCK_STATIONARY_LAVA )
|
||||
{
|
||||
m_World->SetBlock( Disp_X, Disp_Y, Disp_Z, E_BLOCK_AIR, 0 );
|
||||
m_Items[OccupiedSlots[r1.randInt() % SlotsCnt]].m_ItemType = E_ITEM_LAVA_BUCKET;
|
||||
}
|
||||
else
|
||||
{
|
||||
cItems Pickups;
|
||||
Pickups.push_back(cItem(Drop.m_ItemType, 1, Drop.m_ItemHealth));
|
||||
m_World->SpawnItemPickups(Pickups, Disp_X, Disp_Y, Disp_Z);
|
||||
m_Items[OccupiedSlots[r1.randInt() % SlotsCnt]].m_ItemCount--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_ITEM_WATER_BUCKET:
|
||||
{
|
||||
BLOCKTYPE DispBlock = m_World->GetBlock( Disp_X, Disp_Y, Disp_Z );
|
||||
if( DispBlock == E_BLOCK_AIR || IsBlockLiquid(DispBlock) || cFluidSimulator::CanWashAway(DispBlock) )
|
||||
{
|
||||
m_World->SetBlock( Disp_X, Disp_Y, Disp_Z, E_BLOCK_STATIONARY_WATER, 0 );
|
||||
m_Items[OccupiedSlots[r1.randInt() % SlotsCnt]].m_ItemType = E_ITEM_BUCKET;
|
||||
}
|
||||
else
|
||||
{
|
||||
cItems Pickups;
|
||||
Pickups.push_back(cItem(Drop.m_ItemType, 1, Drop.m_ItemHealth));
|
||||
m_World->SpawnItemPickups(Pickups, Disp_X, Disp_Y, Disp_Z);
|
||||
m_Items[OccupiedSlots[r1.randInt() % SlotsCnt]].m_ItemCount--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_ITEM_LAVA_BUCKET:
|
||||
{
|
||||
BLOCKTYPE DispBlock = m_World->GetBlock( Disp_X, Disp_Y, Disp_Z );
|
||||
if( DispBlock == E_BLOCK_AIR || IsBlockLiquid(DispBlock) || cFluidSimulator::CanWashAway(DispBlock) )
|
||||
{
|
||||
m_World->SetBlock( Disp_X, Disp_Y, Disp_Z, E_BLOCK_STATIONARY_LAVA, 0 );
|
||||
m_Items[OccupiedSlots[r1.randInt() % SlotsCnt]].m_ItemType = E_ITEM_BUCKET;
|
||||
}
|
||||
else
|
||||
{
|
||||
cItems Pickups;
|
||||
Pickups.push_back(cItem(Drop.m_ItemType, 1, Drop.m_ItemHealth));
|
||||
m_World->SpawnItemPickups(Pickups, Disp_X, Disp_Y, Disp_Z);
|
||||
m_Items[OccupiedSlots[r1.randInt() % SlotsCnt]].m_ItemCount--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
cItems Pickups;
|
||||
Pickups.push_back(cItem(Drop.m_ItemType, 1, Drop.m_ItemHealth));
|
||||
m_World->SpawnItemPickups(Pickups, Disp_X, Disp_Y, Disp_Z);
|
||||
m_Items[OccupiedSlots[r1.randInt() % SlotsCnt]].m_ItemCount--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
char SmokeDir;
|
||||
switch( Meta )
|
||||
{
|
||||
case 2: SmokeDir = 1; break;
|
||||
case 3: SmokeDir = 7; break;
|
||||
case 4: SmokeDir = 3; break;
|
||||
case 5: SmokeDir = 5; break;
|
||||
}
|
||||
m_World->BroadcastSoundParticleEffect(2000, m_PosX * 8, m_PosY * 8, m_PosZ * 8, SmokeDir);
|
||||
m_World->BroadcastSoundEffect("random.click", m_PosX * 8, m_PosY * 8, m_PosZ * 8, 1.0f, 1.0f);
|
||||
cWindow * Window = GetWindow();
|
||||
if ( Window != NULL )
|
||||
{
|
||||
Window->BroadcastWholeWindow();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_World->BroadcastSoundEffect("random.click", m_PosX * 8, m_PosY * 8, m_PosZ * 8, 1.0f, 1.2f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cDispenserEntity::UsedBy(cPlayer * a_Player)
|
||||
{
|
||||
if (GetWindow() == NULL)
|
||||
@ -86,9 +215,23 @@ void cDispenserEntity::UsedBy(cPlayer * a_Player)
|
||||
|
||||
|
||||
|
||||
void cDispenserEntity::Activate()
|
||||
{
|
||||
m_CanDispense = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cDispenserEntity::Tick( float a_Dt )
|
||||
{
|
||||
return true;
|
||||
if(m_CanDispense)
|
||||
{
|
||||
m_CanDispense = 0;
|
||||
Dispense();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,9 +45,14 @@ public:
|
||||
const cItem * GetSlot(int i) const { return &(m_Items[i]); }
|
||||
|
||||
void SetSlot(int a_Slot, const cItem & a_Item);
|
||||
|
||||
void Activate();
|
||||
|
||||
private:
|
||||
cItem * m_Items;
|
||||
bool m_CanDispense;
|
||||
|
||||
void Dispense();
|
||||
};
|
||||
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "RedstoneSimulator.h"
|
||||
#include "../DispenserEntity.h"
|
||||
#include "../Piston.h"
|
||||
#include "../World.h"
|
||||
#include "../BlockID.h"
|
||||
@ -387,6 +388,36 @@ void cRedstoneSimulator::HandleChange( const Vector3i & a_BlockPos )
|
||||
}
|
||||
} // switch (BlockType)
|
||||
} // while (m_RefreshPistons[])
|
||||
|
||||
while (!m_RefreshDispensers.empty())
|
||||
{
|
||||
Vector3i pos = m_RefreshDispensers.back();
|
||||
m_RefreshDispensers.pop_back();
|
||||
|
||||
BLOCKTYPE BlockType = m_World->GetBlock(pos);
|
||||
if (BlockType == E_BLOCK_DISPENSER)
|
||||
{
|
||||
if (IsPowered(pos))
|
||||
{
|
||||
class cActivateDispenser :
|
||||
public cDispenserCallback
|
||||
{
|
||||
public:
|
||||
cActivateDispenser()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Item(cDispenserEntity * a_Dispenser) override
|
||||
{
|
||||
a_Dispenser->Activate();
|
||||
return false;
|
||||
}
|
||||
} ;
|
||||
cActivateDispenser DispAct;
|
||||
m_World->DoWithDispenserAt(pos.x, pos.y, pos.z, DispAct);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -416,6 +447,12 @@ bool cRedstoneSimulator::PowerBlock(const Vector3i & a_BlockPos, const Vector3i
|
||||
m_RefreshPistons.push_back(a_BlockPos);
|
||||
break;
|
||||
}
|
||||
|
||||
case E_BLOCK_DISPENSER:
|
||||
{
|
||||
m_RefreshDispensers.push_back(a_BlockPos);
|
||||
break;
|
||||
}
|
||||
|
||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
|
@ -71,6 +71,7 @@ private:
|
||||
BlockList m_BlocksBuffer;
|
||||
|
||||
BlockList m_RefreshPistons;
|
||||
BlockList m_RefreshDispensers;
|
||||
|
||||
BlockList m_RefreshTorchesAround;
|
||||
|
||||
|
@ -736,6 +736,15 @@ bool cWorld::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & a_
|
||||
|
||||
|
||||
|
||||
bool cWorld::ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback & a_Callback)
|
||||
{
|
||||
return m_ChunkMap->ForEachDispenserInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cWorld::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback)
|
||||
{
|
||||
return m_ChunkMap->ForEachFurnaceInChunk(a_ChunkX, a_ChunkZ, a_Callback);
|
||||
@ -754,6 +763,15 @@ bool cWorld::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallb
|
||||
|
||||
|
||||
|
||||
bool cWorld::DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback & a_Callback)
|
||||
{
|
||||
return m_ChunkMap->DoWithDispenserAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cWorld::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback)
|
||||
{
|
||||
return m_ChunkMap->DoWithFurnaceAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);
|
||||
|
@ -318,12 +318,18 @@ public:
|
||||
/// Calls the callback for each chest in the specified chunk; returns true if all chests processed, false if the callback aborted by returning true
|
||||
bool ForEachChestInChunk (int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
|
||||
/// Calls the callback for each dispenser in the specified chunk; returns true if all dispensers processed, false if the callback aborted by returning true
|
||||
bool ForEachDispenserInChunk(int a_ChunkX, int a_ChunkZ, cDispenserCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
|
||||
/// Calls the callback for each furnace in the specified chunk; returns true if all furnaces processed, false if the callback aborted by returning true
|
||||
bool ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
|
||||
/// Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found
|
||||
bool DoWithChestAt (int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
|
||||
/// Calls the callback for the dispenser at the specified coords; returns false if there's no dispenser at those coords, true if found
|
||||
bool DoWithDispenserAt(int a_BlockX, int a_BlockY, int a_BlockZ, cDispenserCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
|
||||
/// Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords, true if found
|
||||
bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user