Merge pull request #439 from mc-server/Buckets
Made buckets work when the player does not 'look' at a block.
This commit is contained in:
commit
3a32a1e902
@ -5,6 +5,7 @@
|
|||||||
#include "../World.h"
|
#include "../World.h"
|
||||||
#include "../Simulator/FluidSimulator.h"
|
#include "../Simulator/FluidSimulator.h"
|
||||||
#include "../Blocks/BlockHandler.h"
|
#include "../Blocks/BlockHandler.h"
|
||||||
|
#include "../LineBlockTracer.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -39,61 +40,54 @@ public:
|
|||||||
|
|
||||||
bool ScoopUpFluid(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace)
|
bool ScoopUpFluid(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace)
|
||||||
{
|
{
|
||||||
if (a_BlockFace < 0)
|
if (a_BlockFace > 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
|
|
||||||
BLOCKTYPE ClickedBlock;
|
Vector3i BlockPos;
|
||||||
NIBBLETYPE ClickedMeta;
|
if (!GetBlockFromTrace(a_World, a_Player, BlockPos))
|
||||||
a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedMeta);
|
{
|
||||||
LOGD("Bucket Clicked BlockType %d, meta %d", ClickedBlock, ClickedMeta);
|
return false; // Nothing in range.
|
||||||
if (ClickedMeta != 0)
|
}
|
||||||
|
|
||||||
|
if (a_World->GetBlockMeta(BlockPos.x, BlockPos.y, BlockPos.z) != 0)
|
||||||
{
|
{
|
||||||
// Not a source block
|
// Not a source block
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a_Player->GetGameMode() == gmCreative)
|
BLOCKTYPE Block = a_World->GetBlock(BlockPos.x, BlockPos.y, BlockPos.z);
|
||||||
|
ENUM_ITEM_ID NewItem;
|
||||||
|
|
||||||
|
if (IsBlockWater(Block))
|
||||||
{
|
{
|
||||||
// In creative mode don't modify the inventory, just remove the fluid:
|
NewItem = E_ITEM_WATER_BUCKET;
|
||||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
}
|
||||||
return true;
|
else if (IsBlockLava(Block))
|
||||||
|
{
|
||||||
|
NewItem = E_ITEM_LAVA_BUCKET;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ENUM_ITEM_ID NewItem = E_ITEM_EMPTY;
|
// Give new bucket, filled with fluid when the gamemode is not creative:
|
||||||
switch (ClickedBlock)
|
if (!a_Player->IsGameModeCreative())
|
||||||
{
|
{
|
||||||
case E_BLOCK_WATER:
|
// Remove the bucket from the inventory
|
||||||
case E_BLOCK_STATIONARY_WATER:
|
if (!a_Player->GetInventory().RemoveOneEquippedItem())
|
||||||
{
|
{
|
||||||
NewItem = E_ITEM_WATER_BUCKET;
|
LOG("Clicked with an empty bucket, but cannot remove one from the inventory? WTF?");
|
||||||
break;
|
ASSERT(!"Inventory bucket mismatch");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
case E_BLOCK_LAVA:
|
a_Player->GetInventory().AddItem(cItem(NewItem), true, true);
|
||||||
case E_BLOCK_STATIONARY_LAVA:
|
|
||||||
{
|
|
||||||
NewItem = E_ITEM_LAVA_BUCKET;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Give new bucket, filled with fluid:
|
|
||||||
cItem Item(NewItem, 1);
|
|
||||||
a_Player->GetInventory().AddItem(Item, true, true);
|
|
||||||
|
|
||||||
// Remove water / lava block
|
// Remove water / lava block
|
||||||
a_Player->GetWorld()->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
a_Player->GetWorld()->SetBlock(BlockPos.x, BlockPos.y, BlockPos.z, E_BLOCK_AIR, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,4 +151,52 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GetBlockFromTrace(cWorld * a_World, cPlayer * a_Player, Vector3i & BlockPos)
|
||||||
|
{
|
||||||
|
class cCallbacks :
|
||||||
|
public cBlockTracer::cCallbacks
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vector3i m_Pos;
|
||||||
|
bool m_HasHitFluid;
|
||||||
|
|
||||||
|
|
||||||
|
cCallbacks(void) :
|
||||||
|
m_HasHitFluid(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override
|
||||||
|
{
|
||||||
|
if (a_BlockMeta != 0) // Even if it was a water block it would not be a source.
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType))
|
||||||
|
{
|
||||||
|
m_HasHitFluid = true;
|
||||||
|
m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} Callbacks;
|
||||||
|
|
||||||
|
cLineBlockTracer Tracer(*a_World, Callbacks);
|
||||||
|
Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector());
|
||||||
|
Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5);
|
||||||
|
|
||||||
|
Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z);
|
||||||
|
|
||||||
|
if (!Callbacks.m_HasHitFluid)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BlockPos.Set(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user