1
0

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:
Mattes D 2013-12-17 11:15:07 -08:00
commit 3a32a1e902

View File

@ -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,47 +40,42 @@ 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;
// In creative mode don't modify the inventory, just remove the fluid:
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
return true;
}
ENUM_ITEM_ID NewItem = E_ITEM_EMPTY; if (IsBlockWater(Block))
switch (ClickedBlock)
{
case E_BLOCK_WATER:
case E_BLOCK_STATIONARY_WATER:
{ {
NewItem = E_ITEM_WATER_BUCKET; NewItem = E_ITEM_WATER_BUCKET;
break;
} }
case E_BLOCK_LAVA: else if (IsBlockLava(Block))
case E_BLOCK_STATIONARY_LAVA:
{ {
NewItem = E_ITEM_LAVA_BUCKET; NewItem = E_ITEM_LAVA_BUCKET;
break; }
} else
{
default: return false; return false;
} }
// Give new bucket, filled with fluid when the gamemode is not creative:
if (!a_Player->IsGameModeCreative())
{
// Remove the bucket from the inventory // Remove the bucket from the inventory
if (!a_Player->GetInventory().RemoveOneEquippedItem()) if (!a_Player->GetInventory().RemoveOneEquippedItem())
{ {
@ -87,13 +83,11 @@ public:
ASSERT(!"Inventory bucket mismatch"); ASSERT(!"Inventory bucket mismatch");
return true; return true;
} }
a_Player->GetInventory().AddItem(cItem(NewItem), true, 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;
}
}; };