Skip to content

Commit

Permalink
Refactored block-to-pickup conversion. (cuberite#4417)
Browse files Browse the repository at this point in the history
  • Loading branch information
madmaxoft authored Oct 16, 2019
1 parent 241d97b commit 221cc4e
Show file tree
Hide file tree
Showing 121 changed files with 2,490 additions and 1,738 deletions.
13 changes: 12 additions & 1 deletion Server/Plugins/APIDump/APIDesc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7909,6 +7909,17 @@ end
Notes = "Adds a new item to the end of the collection",
},
},
AddItemGrid =
{
Params =
{
{
Name = "ItemGrid",
Type = "cItemGrid",
},
},
Notes = "Adds a copy of each item in the specified {{cItemGrid|ItemGrid}}.",
},
Clear =
{
Notes = "Removes all items from the collection",
Expand All @@ -7921,7 +7932,7 @@ end
Type = "cItems",
},
},
Notes = "Creates a new cItems object",
Notes = "Creates a new empty cItems object",
},
Contains =
{
Expand Down
65 changes: 58 additions & 7 deletions Server/Plugins/APIDump/Classes/World.lua
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
Type = "boolean",
},
},
Notes = "Replaces the specified block with air, without dropping the usual pickups for the block. Wakes up the simulators for the block and its neighbors. Returns true on success, or false if the chunk is not loaded or invalid coords.",
Notes = "Replaces the specified block with air, without dropping the usual pickups for the block. Wakes up the simulators for the block and its neighbors. Returns true on success, or false if the chunk is not loaded or invalid coords. See also DropBlockAsPickups() for the version that drops pickups.",
},
DoExplosionAt =
{
Expand Down Expand Up @@ -1072,6 +1072,34 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
},
Notes = "If there is the player with the uuid, calls the CallbackFunction with the {{cPlayer}} parameter representing the player. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cPlayer|Player}})</pre> The function returns false if the player was not found, or whatever bool value the callback returned if the player was found.",
},
DropBlockAsPickups =
{
Params =
{
{
Name = "BlockPos",
Type = "Vector3i",
},
{
Name = "Digger",
Type = "cEntity",
IsOptional = true,
},
{
Name = "Tool",
Type = "cItem",
IsOptional = true,
},
},
Returns =
{
{
Name = "IsSuccess",
Type = "boolean",
}
},
Notes = "Digs up the specified block and spawns the appropriate pickups for it. The optional Digger parameter specifies the {{cEntity|entity}} who dug the block, usually a {{cPlayer|player}}. The optional Tool parameter specifies the tool used to dig the block, not present means an empty hand. Returns true on success, false if the chunk is not present. See also DigBlock() for the pickup-less version.",
},
FastSetBlock =
{
{
Expand Down Expand Up @@ -2459,6 +2487,34 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
},
Notes = "Returns true if the specified location has wet weather (rain or storm), using the same logic as IsWeatherWetAt, except that any rain-blocking blocks above the specified position will block the precipitation and this function will return false.",
},
PickupsFromBlock =
{
Params =
{
{
Name = "BlockPos",
Type = "Vector3i",
},
{
Name = "Digger",
Type = "cEntity",
IsOptional = true,
},
{
Name = "Tool",
Type = "cItem",
IsOptional = true,
},
},
Returns =
{
{
Name = "Items",
Type = "cItems",
},
},
Notes = "Returns all the pickups that would result if the Digger dug up the block at BlockPos using Tool. Digger is usually a {{cPlayer}}, but can be nil for natural causes. Tool is usually the equipped {{cItem|item}}, can be nil for empty hand. Returns an empty {{cItems}} object if the chunk is not present."
},
PrepareChunk =
{
Params =
Expand Down Expand Up @@ -2685,13 +2741,8 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
Name = "BlockMeta",
Type = "number",
},
{
Name = "ShouldSendToClients",
Type = "boolean",
IsOptional = true,
},
},
Notes = "Sets the block at the specified coords, replaces the block entities for the previous block type, creates a new block entity for the new block, if appropriate, and wakes up the simulators. This is the preferred way to set blocks, as opposed to FastSetBlock(), which is only to be used under special circumstances. If ShouldSendToClients is true (default), the change is broadcast to all players who have this chunk loaded; if false, the change is made server-side only.",
Notes = "Sets the block at the specified coords, replaces the block entities for the previous block type, creates a new block entity for the new block, if appropriate, and wakes up the simulators. This is the preferred way to set blocks, as opposed to FastSetBlock(), which is only to be used under special circumstances.",
},
SetBlockMeta =
{
Expand Down
2 changes: 1 addition & 1 deletion src/Bindings/Plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class cPlugin

/** Calls the specified hook with the params given. Returns the bool that the hook callback returns. */
virtual bool OnBlockSpread (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) = 0;
virtual bool OnBlockToPickups (cWorld & a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0;
virtual bool OnBlockToPickups (cWorld & a_World, Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool, cItems & a_Pickups) = 0;
virtual bool OnBrewingCompleting (cWorld & a_World, cBrewingstandEntity & a_BrewingstandEntity) = 0;
virtual bool OnBrewingCompleted (cWorld & a_World, cBrewingstandEntity & a_BrewingstandEntity) = 0;
virtual bool OnChat (cPlayer & a_Player, AString & a_Message) = 0;
Expand Down
19 changes: 17 additions & 2 deletions src/Bindings/PluginLua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,24 @@ bool cPluginLua::OnBlockSpread(cWorld & a_World, int a_BlockX, int a_BlockY, int



bool cPluginLua::OnBlockToPickups(cWorld & a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups)
bool cPluginLua::OnBlockToPickups(
cWorld & a_World,
Vector3i a_BlockPos,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta,
const cBlockEntity * a_BlockEntity,
const cEntity * a_Digger,
const cItem * a_Tool,
cItems & a_Pickups
)
{
return CallSimpleHooks(cPluginManager::HOOK_BLOCK_TO_PICKUPS, &a_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, &a_Pickups);
// TODO: Change the hook signature to reflect the real parameters to this function, once we are allowed to make breaking API changes
return CallSimpleHooks(
cPluginManager::HOOK_BLOCK_TO_PICKUPS,
&a_World,
a_Digger,
a_BlockPos.x, a_BlockPos.y, a_BlockPos.z,
a_BlockType, a_BlockMeta, &a_Pickups
);
}


Expand Down
2 changes: 1 addition & 1 deletion src/Bindings/PluginLua.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class cPluginLua :
virtual void Tick(float a_Dt) override;

virtual bool OnBlockSpread (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) override;
virtual bool OnBlockToPickups (cWorld & a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) override;
virtual bool OnBlockToPickups (cWorld & a_World, Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool, cItems & a_Pickups) override;
virtual bool OnBrewingCompleting (cWorld & a_World, cBrewingstandEntity & a_BrewingstandEntity) override;
virtual bool OnBrewingCompleted (cWorld & a_World, cBrewingstandEntity & a_BrewingstandEntity) override;
virtual bool OnChat (cPlayer & a_Player, AString & a_Message) override;
Expand Down
10 changes: 7 additions & 3 deletions src/Bindings/PluginManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,14 +248,18 @@ bool cPluginManager::CallHookBlockSpread(cWorld & a_World, int a_BlockX, int a_B


bool cPluginManager::CallHookBlockToPickups(
cWorld & a_World, cEntity * a_Digger,
int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta,
cWorld & a_World,
Vector3i a_BlockPos,
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta,
const cBlockEntity * a_BlockEntity,
const cEntity * a_Digger,
const cItem * a_Tool,
cItems & a_Pickups
)
{
return GenericCallHook(HOOK_BLOCK_TO_PICKUPS, [&](cPlugin * a_Plugin)
{
return a_Plugin->OnBlockToPickups(a_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_Pickups);
return a_Plugin->OnBlockToPickups(a_World, a_BlockPos, a_BlockType, a_BlockMeta, a_BlockEntity, a_Digger, a_Tool, a_Pickups);
}
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Bindings/PluginManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ class cPluginManager

// Calls for individual hooks. Each returns false if the action is to continue or true if the plugin wants to abort
bool CallHookBlockSpread (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source);
bool CallHookBlockToPickups (cWorld & a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups);
bool CallHookBlockToPickups (cWorld & a_World, Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool, cItems & a_Pickups);
bool CallHookBrewingCompleting (cWorld & a_World, cBrewingstandEntity & a_Brewingstand);
bool CallHookBrewingCompleted (cWorld & a_World, cBrewingstandEntity & a_Brewingstand);
bool CallHookChat (cPlayer & a_Player, AString & a_Message);
Expand Down
30 changes: 30 additions & 0 deletions src/BlockArea.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "Blocks/BlockHandler.h"
#include "ChunkData.h"
#include "BlockEntities/BlockEntity.h"
#include "Item.h"



Expand Down Expand Up @@ -2215,6 +2216,21 @@ bool cBlockArea::ForEachBlockEntity(cBlockEntityCallback a_Callback)



cItems cBlockArea::PickupsFromBlock(Vector3i a_AbsPos, const cEntity * a_Digger, const cItem * a_Tool)
{
auto relPos = a_AbsPos - m_Origin;
BLOCKTYPE blockType;
NIBBLETYPE blockMeta;
GetRelBlockTypeMeta(relPos.x, relPos.y, relPos.z, blockType, blockMeta);
auto blockEntity = GetBlockEntityRel(relPos);
auto handler = BlockHandler(blockType);
return handler->ConvertToPickups(blockMeta, blockEntity, a_Digger, a_Tool);
}





void cBlockArea::SetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array)
{
if (a_Array == nullptr)
Expand Down Expand Up @@ -2710,6 +2726,20 @@ void cBlockArea::RemoveNonMatchingBlockEntities(void)



cBlockEntity * cBlockArea::GetBlockEntityRel(Vector3i a_RelPos)
{
if (!HasBlockEntities())
{
return nullptr;
}
auto itr = m_BlockEntities->find(MakeIndex(a_RelPos));
return (itr == m_BlockEntities->end()) ? nullptr : itr->second;
}





////////////////////////////////////////////////////////////////////////////////
// cBlockArea::sBlockEntityDeleter:

Expand Down
7 changes: 7 additions & 0 deletions src/BlockArea.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

// fwd:
class cCuboid;
class cItems;
using cBlockEntityCallback = cFunctionRef<bool(cBlockEntity &)>;


Expand Down Expand Up @@ -421,6 +422,9 @@ class cBlockArea
/** Direct read-only access to block entities. */
const cBlockEntities & GetBlockEntities(void) const { ASSERT(HasBlockEntities()); return *m_BlockEntities; }

/** Returns the pickups that would result if the block at the specified position was mined by a_Digger, using a_Tool. */
cItems PickupsFromBlock(Vector3i a_AbsPos, const cEntity * a_Digger = nullptr, const cItem * a_Tool = nullptr);


protected:

Expand Down Expand Up @@ -520,6 +524,9 @@ class cBlockArea
/** Removes from m_BlockEntities those BEs that no longer match the blocktype at their coords. */
void RemoveNonMatchingBlockEntities(void);

/** Returns the cBlockEntity at the specified coords, or nullptr if none. */
cBlockEntity * GetBlockEntityRel(Vector3i a_RelPos);

// tolua_begin
} ;
// tolua_end
Expand Down
5 changes: 0 additions & 5 deletions src/BlockInServerPluginInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ class cBlockInServerPluginInterface :
return cPluginManager::Get()->CallHookBlockSpread(m_World, a_BlockX, a_BlockY, a_BlockZ, a_Source);
}

virtual bool CallHookBlockToPickups(cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) override
{
return cPluginManager::Get()->CallHookBlockToPickups(m_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_Pickups);
}

virtual bool CallHookPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override
{
return cPluginManager::Get()->CallHookPlayerBreakingBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_BlockType, a_BlockMeta);
Expand Down
12 changes: 10 additions & 2 deletions src/Blocks/BlockAnvil.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,19 @@ class cBlockAnvilHandler :
{
}

virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override




virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override
{
a_Pickups.push_back(cItem(E_BLOCK_ANVIL, 1, a_BlockMeta >> 2));
return cItem(m_BlockType, 1, a_BlockMeta >> 2);
}





virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
{
cWindow * Window = new cAnvilWindow(a_BlockX, a_BlockY, a_BlockZ);
Expand Down
40 changes: 18 additions & 22 deletions src/Blocks/BlockBed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,33 @@



void cBlockBedHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
void cBlockBedHandler::OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta)
{
Vector3i ThisPos(a_BlockX, a_BlockY, a_BlockZ);
NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(ThisPos);
Vector3i Direction = MetaDataToDirection(OldMeta & 0x3);
if (OldMeta & 0x8)
auto Direction = MetaDataToDirection(a_OldBlockMeta & 0x03);
if ((a_OldBlockMeta & 0x08) != 0)
{
// Was pillow
if (a_ChunkInterface.GetBlock(ThisPos - Direction) == E_BLOCK_BED)
if (a_ChunkInterface.GetBlock(a_BlockPos - Direction) == E_BLOCK_BED)
{
// First replace the bed with air
a_ChunkInterface.FastSetBlock(ThisPos - Direction, E_BLOCK_AIR, 0);
a_ChunkInterface.FastSetBlock(a_BlockPos - Direction, E_BLOCK_AIR, 0);

// Then destroy the bed entity
Vector3i PillowPos(ThisPos - Direction);
a_ChunkInterface.SetBlock(PillowPos.x, PillowPos.y, PillowPos.z, E_BLOCK_AIR, 0);
Vector3i PillowPos(a_BlockPos - Direction);
a_ChunkInterface.SetBlock(PillowPos, E_BLOCK_AIR, 0);
}
}
else
{
// Was foot end
if (a_ChunkInterface.GetBlock(ThisPos + Direction) == E_BLOCK_BED)
if (a_ChunkInterface.GetBlock(a_BlockPos + Direction) == E_BLOCK_BED)
{
// First replace the bed with air
a_ChunkInterface.FastSetBlock(ThisPos + Direction, E_BLOCK_AIR, 0);
a_ChunkInterface.FastSetBlock(a_BlockPos + Direction, E_BLOCK_AIR, 0);

// Then destroy the bed entity
Vector3i FootPos(ThisPos + Direction);
a_ChunkInterface.SetBlock(FootPos.x, FootPos.y, FootPos.z, E_BLOCK_AIR, 0);
Vector3i FootPos(a_BlockPos + Direction);
a_ChunkInterface.SetBlock(FootPos, E_BLOCK_AIR, 0);
}
}
}
Expand Down Expand Up @@ -155,14 +153,12 @@ void cBlockBedHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWor



void cBlockBedHandler::ConvertToPickups(cWorldInterface & a_WorldInterface, cItems & a_Pickups, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ)
cItems cBlockBedHandler::ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool)
{
short Color = E_META_WOOL_RED;
a_WorldInterface.DoWithBedAt(a_BlockX, a_BlockY, a_BlockZ, [&](cBedEntity & a_Bed)
{
Color = a_Bed.GetColor();
return true;
}
);
a_Pickups.Add(cItem(E_ITEM_BED, 1, Color));
short color = E_META_WOOL_RED;
if (a_BlockEntity != nullptr)
{
color = reinterpret_cast<cBedEntity *>(a_BlockEntity)->GetColor();
}
return cItem(E_ITEM_BED, 1, color);
}
Loading

0 comments on commit 221cc4e

Please sign in to comment.