1
0
Fork 0

A new Block handling system :o

It was really a lot of work :D
Took me the complete weekend :D

Would really like to here your opinion on this =)
The aim of this is to put all the actions for one block in one place so it is not spread around the source. (ToPickup, Action in cWorld, Action in cChunk, Action here, action there :D)

git-svn-id: http://mc-server.googlecode.com/svn/trunk@671 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
lapayo94@gmail.com 2012-07-15 20:36:34 +00:00
parent 265a969391
commit 14dce23845
93 changed files with 3614 additions and 1249 deletions

View File

@ -46,6 +46,8 @@ INCLUDE = -I.\
-Isource/md5\
-IWebServer\
-Isource/packets\
-Isource/items\
-Isource/blocks\
-Itolua++-1.0.93/src/lib\
-Ilua-5.1.4/src\
-Izlib-1.2.7\

View File

@ -1934,6 +1934,294 @@
>
</File>
</Filter>
<Filter
Name="Blocks"
>
<File
RelativePath="..\source\blocks\Block.cpp"
>
</File>
<File
RelativePath="..\source\blocks\Block.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockCactus.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockChest.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockCloth.cpp"
>
</File>
<File
RelativePath="..\source\blocks\BlockCloth.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockCrops.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockDirt.cpp"
>
</File>
<File
RelativePath="..\source\blocks\BlockDirt.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockDispenser.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockDoor.cpp"
>
</File>
<File
RelativePath="..\source\blocks\BlockDoor.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockEntity.cpp"
>
</File>
<File
RelativePath="..\source\blocks\BlockEntity.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockFire.cpp"
>
</File>
<File
RelativePath="..\source\blocks\BlockFire.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockFlower.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockFluid.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockFurnace.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockGlowstone.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockIce.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockLadder.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockLeaves.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockMelon.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockMushroom.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockPiston.cpp"
>
</File>
<File
RelativePath="..\source\blocks\BlockPiston.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockRedstone.cpp"
>
</File>
<File
RelativePath="..\source\blocks\BlockRedstone.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockRedstoneOre.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockRedstoneRepeater.cpp"
>
</File>
<File
RelativePath="..\source\blocks\BlockRedstoneRepeater.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockRedstoneTorch.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockSapling.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockSign.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockSlab.cpp"
>
</File>
<File
RelativePath="..\source\blocks\BlockSlab.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockSnow.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockStairs.cpp"
>
</File>
<File
RelativePath="..\source\blocks\BlockStairs.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockStems.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockStone.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockSugarcane.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockTallGrass.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockTorch.cpp"
>
</File>
<File
RelativePath="..\source\blocks\BlockTorch.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockVine.cpp"
>
</File>
<File
RelativePath="..\source\blocks\BlockVine.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockWood.h"
>
</File>
<File
RelativePath="..\source\blocks\BlockWorkbench.cpp"
>
</File>
<File
RelativePath="..\source\blocks\BlockWorkbench.h"
>
</File>
</Filter>
<Filter
Name="Items"
>
<File
RelativePath="..\source\items\Item.cpp"
>
</File>
<File
RelativePath="..\source\items\Item.h"
>
</File>
<File
RelativePath="..\source\items\ItemBucket.h"
>
</File>
<File
RelativePath="..\source\items\ItemCloth.h"
>
</File>
<File
RelativePath="..\source\items\ItemDoor.h"
>
</File>
<File
RelativePath="..\source\items\ItemDye.h"
>
</File>
<File
RelativePath="..\source\items\ItemHoe.h"
>
</File>
<File
RelativePath="..\source\items\ItemLeaves.h"
>
</File>
<File
RelativePath="..\source\items\ItemLighter.h"
>
</File>
<File
RelativePath="..\source\items\ItemPickaxe.h"
>
</File>
<File
RelativePath="..\source\items\ItemRedstoneDust.h"
>
</File>
<File
RelativePath="..\source\items\ItemSapling.h"
>
</File>
<File
RelativePath="..\source\items\ItemSeeds.h"
>
</File>
<File
RelativePath="..\source\items\ItemShears.h"
>
</File>
<File
RelativePath="..\source\items\ItemShovel.h"
>
</File>
<File
RelativePath="..\source\items\ItemSlab.h"
>
</File>
<File
RelativePath="..\source\items\ItemSugarcane.h"
>
</File>
<File
RelativePath="..\source\items\ItemSword.h"
>
</File>
<File
RelativePath="..\source\items\ItemWood.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="Config files"

View File

@ -305,6 +305,20 @@
<ClCompile Include="..\source\BioGen.cpp" />
<ClCompile Include="..\source\BlockArea.cpp" />
<ClCompile Include="..\source\BlockID.cpp" />
<ClCompile Include="..\source\blocks\BlockCloth.cpp" />
<ClCompile Include="..\source\blocks\BlockDirt.cpp" />
<ClCompile Include="..\source\blocks\BlockDoor.cpp" />
<ClCompile Include="..\source\blocks\BlockEntity.cpp" />
<ClCompile Include="..\source\blocks\BlockFire.cpp" />
<ClCompile Include="..\source\blocks\BlockPiston.cpp" />
<ClCompile Include="..\source\blocks\BlockRedstone.cpp" />
<ClCompile Include="..\source\blocks\BlockRedstoneRepeater.cpp" />
<ClCompile Include="..\source\blocks\BlockSlab.cpp" />
<ClCompile Include="..\source\blocks\BlockStairs.cpp" />
<ClCompile Include="..\source\blocks\BlockTorch.cpp" />
<ClCompile Include="..\source\blocks\BlockVine.cpp" />
<ClCompile Include="..\source\blocks\BlockWorkbench.cpp" />
<ClCompile Include="..\source\blocks\Block.cpp" />
<ClCompile Include="..\source\cAggressiveMonster.cpp" />
<ClCompile Include="..\Source\cAuthenticator.cpp" />
<ClCompile Include="..\source\cBlockingTCPLink.cpp" />
@ -401,6 +415,7 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\source\HeiGen.cpp" />
<ClCompile Include="..\source\items\Item.cpp" />
<ClCompile Include="..\source\LeakFinder.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug with optimized Noise|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
@ -498,6 +513,43 @@
<ClInclude Include="..\source\BioGen.h" />
<ClInclude Include="..\source\BlockArea.h" />
<ClInclude Include="..\Source\BlockID.h" />
<ClInclude Include="..\source\blocks\BlockCactus.h" />
<ClInclude Include="..\source\blocks\BlockChest.h" />
<ClInclude Include="..\source\blocks\BlockCloth.h" />
<ClInclude Include="..\source\blocks\BlockCrops.h" />
<ClInclude Include="..\source\blocks\BlockDirt.h" />
<ClInclude Include="..\source\blocks\BlockDispenser.h" />
<ClInclude Include="..\source\blocks\BlockDoor.h" />
<ClInclude Include="..\source\blocks\BlockEntity.h" />
<ClInclude Include="..\source\blocks\BlockFire.h" />
<ClInclude Include="..\source\blocks\BlockFlower.h" />
<ClInclude Include="..\source\blocks\BlockFluid.h" />
<ClInclude Include="..\source\blocks\BlockFurnace.h" />
<ClInclude Include="..\source\blocks\BlockGlowstone.h" />
<ClInclude Include="..\source\blocks\BlockIce.h" />
<ClInclude Include="..\source\blocks\BlockLadder.h" />
<ClInclude Include="..\source\blocks\BlockLeaves.h" />
<ClInclude Include="..\source\blocks\BlockMelon.h" />
<ClInclude Include="..\source\blocks\BlockMushroom.h" />
<ClInclude Include="..\source\blocks\BlockPiston.h" />
<ClInclude Include="..\source\blocks\BlockRedstone.h" />
<ClInclude Include="..\source\blocks\BlockRedstoneOre.h" />
<ClInclude Include="..\source\blocks\BlockRedstoneRepeater.h" />
<ClInclude Include="..\source\blocks\BlockRedstoneTorch.h" />
<ClInclude Include="..\source\blocks\BlockSapling.h" />
<ClInclude Include="..\source\blocks\BlockSign.h" />
<ClInclude Include="..\source\blocks\BlockSlab.h" />
<ClInclude Include="..\source\blocks\BlockSnow.h" />
<ClInclude Include="..\source\blocks\BlockStairs.h" />
<ClInclude Include="..\source\blocks\BlockStems.h" />
<ClInclude Include="..\source\blocks\BlockStone.h" />
<ClInclude Include="..\source\blocks\BlockSugarcane.h" />
<ClInclude Include="..\source\blocks\BlockTallGrass.h" />
<ClInclude Include="..\source\blocks\BlockTorch.h" />
<ClInclude Include="..\source\blocks\BlockVine.h" />
<ClInclude Include="..\source\blocks\BlockWood.h" />
<ClInclude Include="..\source\blocks\BlockWorkbench.h" />
<ClInclude Include="..\source\blocks\Block.h" />
<ClInclude Include="..\source\cAggressiveMonster.h" />
<ClInclude Include="..\Source\cAuthenticator.h" />
<ClInclude Include="..\source\cBlockingTCPLink.h" />
@ -567,7 +619,6 @@
<ClInclude Include="..\source\cSpider.h" />
<ClInclude Include="..\source\cSquid.h" />
<ClInclude Include="..\source\cStairs.h" />
<ClInclude Include="..\source\cStep.h" />
<ClInclude Include="..\source\cStringMap.h" />
<ClInclude Include="..\source\cSurvivalInventory.h" />
<ClInclude Include="..\Source\cTCPLink.h" />
@ -591,6 +642,24 @@
<ClInclude Include="..\source\FinishGen.h" />
<ClInclude Include="..\source\Globals.h" />
<ClInclude Include="..\source\HeiGen.h" />
<ClInclude Include="..\source\items\ItemBucket.h" />
<ClInclude Include="..\source\items\ItemCloth.h" />
<ClInclude Include="..\source\items\Item.h" />
<ClInclude Include="..\source\items\ItemDoor.h" />
<ClInclude Include="..\source\items\ItemDye.h" />
<ClInclude Include="..\source\items\ItemHoe.h" />
<ClInclude Include="..\source\items\ItemLeaves.h" />
<ClInclude Include="..\source\items\ItemLighter.h" />
<ClInclude Include="..\source\items\ItemPickaxe.h" />
<ClInclude Include="..\source\items\ItemRedstoneDust.h" />
<ClInclude Include="..\source\items\ItemSapling.h" />
<ClInclude Include="..\source\items\ItemSeeds.h" />
<ClInclude Include="..\source\items\ItemShears.h" />
<ClInclude Include="..\source\items\ItemShovel.h" />
<ClInclude Include="..\source\items\ItemSlab.h" />
<ClInclude Include="..\source\items\ItemSugarcane.h" />
<ClInclude Include="..\source\items\ItemSword.h" />
<ClInclude Include="..\source\items\ItemWood.h" />
<ClInclude Include="..\source\LeakFinder.h" />
<ClInclude Include="..\source\LightingThread.h" />
<ClInclude Include="..\Source\LuaFunctions.h" />

View File

@ -439,6 +439,12 @@
<Filter Include="cPluginManager\cSquirrelCommandBinder">
<UniqueIdentifier>{0a0b9b8e-ac72-4755-98e5-87cbc835016a}</UniqueIdentifier>
</Filter>
<Filter Include="Blocks">
<UniqueIdentifier>{9013ce6d-8f75-4f87-90c6-99aa07b3c8f8}</UniqueIdentifier>
</Filter>
<Filter Include="Items">
<UniqueIdentifier>{2bd505e5-cfc9-44f4-8295-4a36185c7c54}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\source\cServer.cpp">
@ -920,6 +926,51 @@
<ClCompile Include="..\source\cSquirrelCommandBinder.cpp">
<Filter>cPluginManager\cSquirrelCommandBinder</Filter>
</ClCompile>
<ClCompile Include="..\source\blocks\BlockEntity.cpp">
<Filter>Blocks</Filter>
</ClCompile>
<ClCompile Include="..\source\blocks\BlockFire.cpp">
<Filter>Blocks</Filter>
</ClCompile>
<ClCompile Include="..\source\blocks\BlockPiston.cpp">
<Filter>Blocks</Filter>
</ClCompile>
<ClCompile Include="..\source\blocks\BlockRedstone.cpp">
<Filter>Blocks</Filter>
</ClCompile>
<ClCompile Include="..\source\blocks\BlockRedstoneRepeater.cpp">
<Filter>Blocks</Filter>
</ClCompile>
<ClCompile Include="..\source\blocks\BlockSlab.cpp">
<Filter>Blocks</Filter>
</ClCompile>
<ClCompile Include="..\source\blocks\BlockTorch.cpp">
<Filter>Blocks</Filter>
</ClCompile>
<ClCompile Include="..\source\blocks\BlockVine.cpp">
<Filter>Blocks</Filter>
</ClCompile>
<ClCompile Include="..\source\blocks\BlockWorkbench.cpp">
<Filter>Blocks</Filter>
</ClCompile>
<ClCompile Include="..\source\blocks\BlockCloth.cpp">
<Filter>Blocks</Filter>
</ClCompile>
<ClCompile Include="..\source\blocks\BlockDirt.cpp">
<Filter>Blocks</Filter>
</ClCompile>
<ClCompile Include="..\source\blocks\BlockDoor.cpp">
<Filter>Blocks</Filter>
</ClCompile>
<ClCompile Include="..\source\blocks\Block.cpp">
<Filter>Blocks</Filter>
</ClCompile>
<ClCompile Include="..\source\items\Item.cpp">
<Filter>Items</Filter>
</ClCompile>
<ClCompile Include="..\source\blocks\BlockStairs.cpp">
<Filter>Blocks</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\source\cServer.h">
@ -1425,7 +1476,6 @@
<ClInclude Include="..\source\FastNBT.h">
<Filter>Storage</Filter>
</ClInclude>
<ClInclude Include="..\source\cStep.h" />
<ClInclude Include="..\source\CraftingRecipes.h" />
<ClInclude Include="..\source\squirrelbindings\SquirrelBindings.h">
<Filter>LuaBindings\SquirrelBindings</Filter>
@ -1449,6 +1499,171 @@
<ClInclude Include="..\source\squirrelbindings\SquirrelArray.h">
<Filter>LuaBindings\SquirrelBindings</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockDoor.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockEntity.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockFire.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockPiston.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockRedstone.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockRedstoneRepeater.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockSlab.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockSnow.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockTallGrass.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockTorch.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockVine.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockWorkbench.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockCloth.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockDirt.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\Block.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockWood.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemCloth.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemHoe.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemSlab.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemWood.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\items\Item.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemShears.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockLeaves.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemSapling.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockSapling.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemLeaves.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemBucket.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockFluid.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemRedstoneDust.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockChest.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockDispenser.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockFurnace.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockStairs.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockLadder.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockSign.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemLighter.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemSeeds.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemDye.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockCrops.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockSugarcane.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemSugarcane.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockFlower.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockMushroom.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockCactus.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockStems.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockRedstoneTorch.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockGlowstone.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemPickaxe.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemShovel.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemSword.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockRedstoneOre.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockStone.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockMelon.h">
<Filter>Blocks</Filter>
</ClInclude>
<ClInclude Include="..\source\items\ItemDoor.h">
<Filter>Items</Filter>
</ClInclude>
<ClInclude Include="..\source\blocks\BlockIce.h">
<Filter>Blocks</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\source\AllToLua.pkg">

View File

@ -7,7 +7,6 @@ $cfile "ChunkDef.h"
$cfile "cTorch.h"
$cfile "cStairs.h"
$cfile "cStep.h"
$cfile "cLadder.h"
$cfile "cVine.h"

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 07/15/12 14:45:49.
** Generated automatically by tolua++-1.0.92 on 07/15/12 22:27:57.
*/
#ifndef __cplusplus
@ -18,7 +18,6 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S);
#include "ChunkDef.h"
#include "cTorch.h"
#include "cStairs.h"
#include "cStep.h"
#include "cLadder.h"
#include "cVine.h"
#include "../iniFile/iniFile.h"
@ -184,26 +183,25 @@ static void tolua_reg_types (lua_State* tolua_S)
{
tolua_usertype(tolua_S,"TakeDamageInfo");
tolua_usertype(tolua_S,"cLuaItems");
tolua_usertype(tolua_S,"cCraftingGrid");
tolua_usertype(tolua_S,"cCraftingRecipe");
tolua_usertype(tolua_S,"cPlugin");
tolua_usertype(tolua_S,"cLuaChunk");
tolua_usertype(tolua_S,"cCraftingGrid");
tolua_usertype(tolua_S,"cStringMap");
tolua_usertype(tolua_S,"cPluginManager");
tolua_usertype(tolua_S,"cLuaChunk");
tolua_usertype(tolua_S,"cBlockArea");
tolua_usertype(tolua_S,"cPluginManager");
tolua_usertype(tolua_S,"Lua__cPacket_BlockDig");
tolua_usertype(tolua_S,"Lua__cTCPLink");
tolua_usertype(tolua_S,"cServer");
tolua_usertype(tolua_S,"cRoot");
tolua_usertype(tolua_S,"cVine");
tolua_usertype(tolua_S,"cTracer");
tolua_usertype(tolua_S,"Lua__cTCPLink");
tolua_usertype(tolua_S,"cPawn");
tolua_usertype(tolua_S,"cGroup");
tolua_usertype(tolua_S,"cPlugin::CommandStruct");
tolua_usertype(tolua_S,"cPickup");
tolua_usertype(tolua_S,"cItems");
tolua_usertype(tolua_S,"cPacket_Login");
tolua_usertype(tolua_S,"cClientHandle");
tolua_usertype(tolua_S,"cStep");
tolua_usertype(tolua_S,"cTracer");
tolua_usertype(tolua_S,"cFurnaceRecipe");
tolua_usertype(tolua_S,"cMCLogger");
tolua_usertype(tolua_S,"cChatColor");
@ -228,12 +226,12 @@ static void tolua_reg_types (lua_State* tolua_S)
tolua_usertype(tolua_S,"Lua__cEntity");
tolua_usertype(tolua_S,"cPacket_BlockPlace");
tolua_usertype(tolua_S,"cLadder");
tolua_usertype(tolua_S,"cWebPlugin");
tolua_usertype(tolua_S,"Lua__cPlayer");
tolua_usertype(tolua_S,"cWebPlugin");
tolua_usertype(tolua_S,"cIniFile");
tolua_usertype(tolua_S,"cEntity");
tolua_usertype(tolua_S,"HTTPRequest");
tolua_usertype(tolua_S,"cPawn");
tolua_usertype(tolua_S,"cVine");
tolua_usertype(tolua_S,"cPlayer");
tolua_usertype(tolua_S,"cTorch");
tolua_usertype(tolua_S,"HTTPFormData");
@ -336,36 +334,6 @@ static int tolua_AllToLua_cStairs_RotationToMetaData00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* method: DirectionToMetaData of class cStep */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cStep_DirectionToMetaData00
static int tolua_AllToLua_cStep_DirectionToMetaData00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertable(tolua_S,1,"cStep",0,&tolua_err) ||
!tolua_isnumber(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
int a_Direction = ((int) tolua_tonumber(tolua_S,2,0));
{
char tolua_ret = (char) cStep::DirectionToMetaData(a_Direction);
tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'DirectionToMetaData'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: DirectionToMetaData of class cLadder */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cLadder_DirectionToMetaData00
static int tolua_AllToLua_cLadder_DirectionToMetaData00(lua_State* tolua_S)
@ -21154,10 +21122,6 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_beginmodule(tolua_S,"cStairs");
tolua_function(tolua_S,"RotationToMetaData",tolua_AllToLua_cStairs_RotationToMetaData00);
tolua_endmodule(tolua_S);
tolua_cclass(tolua_S,"cStep","cStep","",NULL);
tolua_beginmodule(tolua_S,"cStep");
tolua_function(tolua_S,"DirectionToMetaData",tolua_AllToLua_cStep_DirectionToMetaData00);
tolua_endmodule(tolua_S);
tolua_cclass(tolua_S,"cLadder","cLadder","",NULL);
tolua_beginmodule(tolua_S,"cLadder");
tolua_function(tolua_S,"DirectionToMetaData",tolua_AllToLua_cLadder_DirectionToMetaData00);

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 07/15/12 14:45:49.
** Generated automatically by tolua++-1.0.92 on 07/15/12 22:27:58.
*/
/* Exported function */

View File

@ -18,6 +18,7 @@ bool g_BlockTransparent[256];
bool g_BlockOneHitDig[256];
bool g_BlockPistonBreakable[256];
bool g_BlockIsSnowable[256];
bool g_BlockRequiresSpecialTool[256];
@ -174,6 +175,7 @@ public:
memset( g_BlockOneHitDig, 0x00, sizeof( g_BlockOneHitDig ) );
memset( g_BlockPistonBreakable, 0x00, sizeof( g_BlockPistonBreakable ) );
memset( g_BlockIsSnowable, 0xff, sizeof( g_BlockIsSnowable)); // Set all blocks' snowable to true
memset( g_BlockRequiresSpecialTool, false, sizeof( g_BlockRequiresSpecialTool));
// Emissive blocks
g_BlockLightValue[E_BLOCK_FIRE] = 15;
@ -324,6 +326,42 @@ public:
g_BlockIsSnowable[E_BLOCK_WALLSIGN] = false;
g_BlockIsSnowable[E_BLOCK_WATER] = false;
g_BlockIsSnowable[E_BLOCK_YELLOW_FLOWER] = false;
//Blocks that don´t drop without a special tool
g_BlockRequiresSpecialTool[E_BLOCK_DIAMOND_BLOCK] = true;
g_BlockRequiresSpecialTool[E_BLOCK_DIAMOND_ORE] = true;
g_BlockRequiresSpecialTool[E_BLOCK_GOLD_BLOCK] = true;
g_BlockRequiresSpecialTool[E_BLOCK_GOLD_ORE] = true;
g_BlockRequiresSpecialTool[E_BLOCK_IRON_BLOCK] = true;
g_BlockRequiresSpecialTool[E_BLOCK_IRON_ORE] = true;
g_BlockRequiresSpecialTool[E_BLOCK_REDSTONE_ORE] = true;
g_BlockRequiresSpecialTool[E_BLOCK_REDSTONE_ORE_GLOWING]= true;
g_BlockRequiresSpecialTool[E_BLOCK_LAPIS_ORE] = true;
g_BlockRequiresSpecialTool[E_BLOCK_LAPIS_BLOCK] = true;
g_BlockRequiresSpecialTool[E_BLOCK_EMERALD_ORE] = true;
g_BlockRequiresSpecialTool[E_BLOCK_COAL_ORE] = true;
g_BlockRequiresSpecialTool[E_BLOCK_OBSIDIAN] = true;
g_BlockRequiresSpecialTool[E_BLOCK_STONE] = true;
g_BlockRequiresSpecialTool[E_BLOCK_COBBLESTONE] = true;
g_BlockRequiresSpecialTool[E_BLOCK_END_STONE] = true;
g_BlockRequiresSpecialTool[E_BLOCK_MOSSY_COBBLESTONE] = true;
g_BlockRequiresSpecialTool[E_BLOCK_SANDSTONE] = true;
g_BlockRequiresSpecialTool[E_BLOCK_STONE_BRICKS] = true;
g_BlockRequiresSpecialTool[E_BLOCK_COBWEB] = true;
g_BlockRequiresSpecialTool[E_BLOCK_SNOW] = true;
g_BlockRequiresSpecialTool[E_BLOCK_NETHER_BRICK] = true;
g_BlockRequiresSpecialTool[E_BLOCK_NETHERRACK] = true;
g_BlockRequiresSpecialTool[E_BLOCK_STONE_SLAB] = true;
g_BlockRequiresSpecialTool[E_BLOCK_DOUBLE_STONE_SLAB] = true;
g_BlockRequiresSpecialTool[E_BLOCK_STONE_PRESSURE_PLATE]= true;
g_BlockRequiresSpecialTool[E_BLOCK_BRICK] = true;
g_BlockRequiresSpecialTool[E_BLOCK_COBBLESTONE_STAIRS] = true;
g_BlockRequiresSpecialTool[E_BLOCK_STONE_BRICK_STAIRS] = true;
g_BlockRequiresSpecialTool[E_BLOCK_SANDSTONE_STAIRS] = true;
g_BlockRequiresSpecialTool[E_BLOCK_NETHER_BRICK_STAIRS] = true;
g_BlockRequiresSpecialTool[E_BLOCK_VINES] = true;
}
} BlockPropertiesInitializer;

View File

@ -636,6 +636,7 @@ extern bool g_BlockTransparent[256];
extern bool g_BlockOneHitDig[256];
extern bool g_BlockPistonBreakable[256];
extern bool g_BlockIsSnowable[256];
extern bool g_BlockRequiresSpecialTool[256];

View File

@ -77,6 +77,17 @@ inline bool IsBlockLiquid(char a_BlockID)
return IsBlockWater(a_BlockID) || IsBlockLava(a_BlockID);
}
inline bool IsBlockTypeOfDirt(char a_BlockID)
{
switch (a_BlockID)
{
case E_BLOCK_DIRT:
case E_BLOCK_GRASS:
case E_BLOCK_FARMLAND:
return true;
}
return false;
}
@ -268,6 +279,11 @@ namespace ItemCategory
//tolua_end
inline bool BlockRequiresSpecialTool(BLOCKTYPE a_BlockID)
{
if(!IsValidBlock(a_BlockID)) return false;
return g_BlockRequiresSpecialTool[a_BlockID];
}
//tolua_begin

302
source/blocks/Block.cpp Normal file
View File

@ -0,0 +1,302 @@
#include "Globals.h"
#include "Block.h"
#include "../cItem.h"
#include "../cWorld.h"
#include "BlockDoor.h"
#include "BlockFire.h"
#include "BlockRedstone.h"
#include "BlockRedstoneTorch.h"
#include "BlockRedstoneRepeater.h"
#include "BlockPiston.h"
#include "BlockWorkbench.h"
#include "BlockEntity.h"
#include "BlockVine.h"
#include "BlockTallGrass.h"
#include "BlockSnow.h"
#include "BlockCloth.h"
#include "BlockSlab.h"
#include "BlockDirt.h"
#include "BlockTorch.h"
#include "BlockWood.h"
#include "BlockLeaves.h"
#include "BlockSapling.h"
#include "BlockFluid.h"
#include "BlockChest.h"
#include "BlockFurnace.h"
#include "BlockDispenser.h"
#include "BlockStairs.h"
#include "BlockLadder.h"
#include "BlockSign.h"
#include "BlockCrops.h"
#include "BlockSugarcane.h"
#include "BlockFlower.h"
#include "BlockMushroom.h"
#include "BlockCactus.h"
#include "BlockStems.h"
#include "BlockGlowstone.h"
#include "BlockRedstoneOre.h"
#include "BlockStone.h"
#include "BlockMelon.h"
#include "BlockIce.h"
bool cBlockHandler::m_HandlerInitialized = false;
cBlockHandler *cBlockHandler::m_BlockHandler[256];
cBlockHandler *cBlockHandler::GetBlockHandler(char a_BlockID)
{
if(!m_HandlerInitialized)
{ //We have to initialize
memset(m_BlockHandler, 0, sizeof(m_BlockHandler));
m_HandlerInitialized = true;
}
if(m_BlockHandler[a_BlockID])
return m_BlockHandler[a_BlockID];
return m_BlockHandler[a_BlockID] = CreateBlockHandler(a_BlockID);
}
cBlockHandler *cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockID)
{
switch(a_BlockID)
{
case E_BLOCK_WOODEN_DOOR:
case E_BLOCK_IRON_DOOR:
return new cBlockDoorHandler(a_BlockID);
case E_BLOCK_FIRE:
return new cBlockFireHandler(a_BlockID);
case E_BLOCK_REDSTONE_TORCH_ON:
case E_BLOCK_REDSTONE_TORCH_OFF:
return new cBlockRedstoneTorchHandler(a_BlockID);
case E_BLOCK_REDSTONE_WIRE:
return new cBlockRedstoneHandler(a_BlockID);
case E_BLOCK_PISTON:
case E_BLOCK_STICKY_PISTON:
return new cBlockPistonHandler(a_BlockID);
case E_BLOCK_REDSTONE_REPEATER_ON:
case E_BLOCK_REDSTONE_REPEATER_OFF:
return new cBlockRedstoneRepeaterHandler(a_BlockID);
case E_BLOCK_WORKBENCH:
return new cBlockWorkbenchHandler(a_BlockID);
case E_BLOCK_SNOW:
return new cBlockSnowHandler(a_BlockID);
case E_BLOCK_TALL_GRASS:
return new cBlockTallGrassHandler(a_BlockID);
case E_BLOCK_VINES:
return new cBlockVineHandler(a_BlockID);
case ::E_BLOCK_WOOL:
return new cBlockClothHandler(a_BlockID);
case E_BLOCK_WOODEN_SLAB:
case E_BLOCK_STONE_SLAB:
case E_BLOCK_DOUBLE_WOODEN_SLAB:
case E_BLOCK_DOUBLE_STONE_SLAB:
return new cBlockSlabHandler(a_BlockID);
case E_BLOCK_LOG:
case E_BLOCK_PLANKS:
return new cBlockWoodHandler(a_BlockID);
case E_BLOCK_TORCH:
return new cBlockTorchHandler(a_BlockID);
case E_BLOCK_DIRT:
case E_BLOCK_GRASS:
return new cBlockDirtHandler(a_BlockID);
case E_BLOCK_LEAVES:
return new cBlockLeavesHandler(a_BlockID);
case E_BLOCK_SAPLING:
return new cBlockSaplingHandler(a_BlockID);
case E_BLOCK_WATER:
case E_BLOCK_STATIONARY_WATER:
case E_BLOCK_STATIONARY_LAVA:
case E_BLOCK_LAVA:
return new cBlockFluidHandler(a_BlockID);
case E_BLOCK_DISPENSER:
return new cBlockDispenserHandler(a_BlockID);
case E_BLOCK_FURNACE:
case E_BLOCK_LIT_FURNACE:
return new cBlockFurnaceHandler(a_BlockID);
case E_BLOCK_CHEST:
return new cBlockChestHandler(a_BlockID);
case E_BLOCK_ICE:
return new cBlockIceHandler(a_BlockID);
case E_BLOCK_LADDER:
return new cBlockLadderHandler(a_BlockID);
case E_BLOCK_COBBLESTONE_STAIRS:
case E_BLOCK_BRICK_STAIRS:
case E_BLOCK_STONE_BRICK_STAIRS:
case E_BLOCK_NETHER_BRICK_STAIRS:
case E_BLOCK_WOODEN_STAIRS:
return new cBlockStairsHandler(a_BlockID);
case E_BLOCK_SIGN_POST:
case E_BLOCK_WALLSIGN:
return new cBlockSignHandler(a_BlockID);
case E_BLOCK_CROPS:
return new cBlockCropsHandler(a_BlockID);
case E_BLOCK_SUGARCANE:
return new cBlockSugarcaneHandler(a_BlockID);
case E_BLOCK_YELLOW_FLOWER:
case E_BLOCK_RED_ROSE:
return new cBlockFlowerHandler(a_BlockID);
case E_BLOCK_BROWN_MUSHROOM:
case E_BLOCK_RED_MUSHROOM:
return new cBlockMushroomHandler(a_BlockID);
case E_BLOCK_CACTUS:
return new cBlockCactusHandler(a_BlockID);
case E_BLOCK_MELON_STEM:
case E_BLOCK_PUMPKIN_STEM:
return new cBlockStemsHandler(a_BlockID);
case E_BLOCK_GLOWSTONE:
return new cBlockGlowstoneHandler(a_BlockID);
case E_BLOCK_REDSTONE_ORE:
case E_BLOCK_REDSTONE_ORE_GLOWING:
return new cBlockRedstoneOreHandler(a_BlockID);
case E_BLOCK_STONE:
case E_BLOCK_COBBLESTONE:
return new cBlockStoneHandler(a_BlockID);
case E_BLOCK_MELON:
return new cBlockMelonHandler(a_BlockID);
default:
return new cBlockHandler(a_BlockID);
break;
}
}
void cBlockHandler::Deinit()
{
for(int i = 0; i < 256; i++)
{
delete m_BlockHandler[i];
}
}
cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockID)
{
m_BlockID = a_BlockID;
}
void cBlockHandler::OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
}
void cBlockHandler::OnPlacedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_X, int a_Y, int a_Z, int a_Dir)
{
}
void cBlockHandler::OnDestroyedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_X, int a_Y, int a_Z)
{
}
void cBlockHandler::OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir)
{
//Notify the neighbors
NeighborChanged(a_World, a_X - 1, a_Y, a_Z);
NeighborChanged(a_World, a_X + 1, a_Y, a_Z);
NeighborChanged(a_World, a_X, a_Y - 1, a_Z);
NeighborChanged(a_World, a_X, a_Y + 1, a_Z);
NeighborChanged(a_World, a_X, a_Y, a_Z - 1);
NeighborChanged(a_World, a_X, a_Y, a_Z + 1);
}
void cBlockHandler::OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
//Notify the neighbors
NeighborChanged(a_World, a_X - 1, a_Y, a_Z);
NeighborChanged(a_World, a_X + 1, a_Y, a_Z);
NeighborChanged(a_World, a_X, a_Y - 1, a_Z);
NeighborChanged(a_World, a_X, a_Y + 1, a_Z);
NeighborChanged(a_World, a_X, a_Y, a_Z - 1);
NeighborChanged(a_World, a_X, a_Y, a_Z + 1);
}
void cBlockHandler::NeighborChanged(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
GetBlockHandler(a_World->GetBlock(a_X, a_Y, a_Z))->OnNeighborChanged(a_World, a_X, a_Y, a_Z);
}
void cBlockHandler::OnNeighborChanged(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
}
void cBlockHandler::OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z)
{
}
void cBlockHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir)
{
a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, a_BlockMeta);
OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
}
int cBlockHandler::GetTickRate()
{
return 10;
}
char cBlockHandler::GetDropCount()
{
return 1;
}
int cBlockHandler::GetDropID()
{
return m_BlockID;
}
char cBlockHandler::GetDropMeta(char a_BlockMeta)
{
return a_BlockMeta; //This keeps most textures. The few other blocks have to override this
}
void cBlockHandler::DropBlock(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
cItems Drops;
char Meta = a_World->GetBlockMeta(a_X, a_Y, a_Z);
char DropCount = GetDropCount();
int DropItem = GetDropID();
if(DropCount > 0 && DropItem != E_ITEM_EMPTY)
{
Drops.push_back(cItem((ENUM_ITEM_ID)DropItem, DropCount, GetDropMeta(Meta)));
a_World->SpawnItemPickups(Drops, a_X, a_Y, a_Z);
}
}
bool cBlockHandler::CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
return true;
}
bool cBlockHandler::IsUseable()
{
return false;
}
bool cBlockHandler::IsClickedThrough()
{
return false;
}
bool cBlockHandler::IgnoreBuildCollision()
{
return m_BlockID == E_BLOCK_AIR;
}
bool cBlockHandler::NeedsRandomTicks()
{
return false;
}
bool cBlockHandler::AllowBlockOnTop()
{
return true;
}
bool cBlockHandler::CanBePlacedOnSide()
{
return true;
}
bool cBlockHandler::DropOnUnsuitable()
{
return true;
}

54
source/blocks/Block.h Normal file
View File

@ -0,0 +1,54 @@
#pragma once
#include "../Defines.h"
class cWorld;
class cPlayer;
class cBlockHandler
{
public:
cBlockHandler(BLOCKTYPE a_BlockID);
//Called when the block gets ticked
virtual void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z);
virtual void OnPlacedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_X, int a_Y, int a_Z, int a_Dir);
virtual void OnDestroyedByPlayer(cWorld *a_World, cPlayer * a_Player, int a_X, int a_Y, int a_Z);
virtual void OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir);
virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z);
virtual void OnNeighborChanged(cWorld *a_World, int a_X, int a_Y, int a_Z);
static void NeighborChanged(cWorld *a_World, int a_X, int a_Y, int a_Z);
virtual void OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z);
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir);
virtual int GetTickRate();
virtual char GetDropCount();
virtual int GetDropID();
virtual char GetDropMeta(char a_BlockMeta);
virtual bool NeedsRandomTicks();
//Item is -2 if it wasn´t a player
virtual void DropBlock(cWorld *a_World, int a_X, int a_Y, int a_Z);
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z);
//This gets called if the player tries to place a block ontop of this block (Only if he aims directly on this block)
virtual bool AllowBlockOnTop();
virtual bool IsUseable();
virtual bool IsClickedThrough();
virtual bool IgnoreBuildCollision();
//Indicates this block can be placed on the side of other blocks. Default: true
virtual bool CanBePlacedOnSide();
//Does this block drops if it gets destroyed by an unsuitable situation? Default: true
virtual bool DropOnUnsuitable();
static cBlockHandler *GetBlockHandler(char a_BlockID);
static void Deinit();
protected:
char m_BlockID;
static cBlockHandler *CreateBlockHandler(BLOCKTYPE a_BlockID);
static cBlockHandler *m_BlockHandler[256];
static bool m_HandlerInitialized; //used to detect if the blockhandlers are initialized
};
inline cBlockHandler *BlockHandler(char a_BlockID) { return cBlockHandler::GetBlockHandler(a_BlockID); }

View File

@ -0,0 +1,51 @@
#pragma once
#include "Block.h"
class cBlockCactusHandler : public cBlockHandler
{
public:
cBlockCactusHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual char GetDropMeta(char a_BlockMeta)
{
return 0;
}
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
BLOCKTYPE Surface = a_World->GetBlock(a_X, a_Y - 1, a_Z);
if ((Surface != E_BLOCK_SAND) && (Surface != E_BLOCK_CACTUS))
{
// Cactus can only be placed on sand and itself
return false;
}
// Check surroundings. Cacti may ONLY be surrounded by air
if (
(a_World->GetBlock(a_X - 1, a_Y, a_Z) != E_BLOCK_AIR) ||
(a_World->GetBlock(a_X + 1, a_Y, a_Z) != E_BLOCK_AIR) ||
(a_World->GetBlock(a_X, a_Y, a_Z - 1) != E_BLOCK_AIR) ||
(a_World->GetBlock(a_X, a_Y, a_Z + 1) != E_BLOCK_AIR)
)
{
return false;
}
return true;
}
virtual bool AllowBlockOnTop()
{
return false;
}
virtual bool CanBePlacedOnSide()
{
return false;
}
};

View File

@ -0,0 +1,22 @@
#pragma once
#include "BlockEntity.h"
#include "../cWorld.h"
#include "../cPiston.h"
#include "../cPlayer.h"
class cBlockChestHandler : public cBlockEntityHandler
{
public:
cBlockChestHandler(BLOCKTYPE a_BlockID)
: cBlockEntityHandler(a_BlockID)
{
}
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir)
{
a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0));
OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
}
};

View File

@ -0,0 +1,9 @@
#include "Globals.h"
#include "BlockCloth.h"
#include "../cItem.h"
#include "../cPlayer.h"
cBlockClothHandler::cBlockClothHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "Block.h"
class cBlockClothHandler : public cBlockHandler
{
public:
cBlockClothHandler(BLOCKTYPE a_BlockID);
char GetDropMeta(char a_BlockMeta)
{
return a_BlockMeta;
}
};

View File

@ -0,0 +1,56 @@
#pragma once
#include "Block.h"
#include "../MersenneTwister.h"
#include "../cWorld.h"
class cBlockCropsHandler : public cBlockHandler
{
public:
cBlockCropsHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual bool NeedsRandomTicks() override
{
return true;
}
virtual int GetDropID()
{
return E_ITEM_EMPTY;
}
virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
MTRand rand;
NIBBLETYPE Meta = a_World->GetBlockMeta(a_X, a_Y, a_Z);
ENUM_ITEM_ID Drop = E_ITEM_EMPTY;
cItems Drops;
if(Meta & 0x7) //Is Wheat
{
Drops.push_back(cItem(E_ITEM_WHEAT, 1, 0));
}
if(rand.randInt(3) == 0)
{ //Drop an second seed
Drops.push_back(cItem(E_ITEM_SEEDS, 1, 0));
}
Drops.push_back(cItem(E_ITEM_SEEDS, 1, 0));
a_World->SpawnItemPickups(Drops, a_X, a_Y, a_Z);
}
void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
//TODO: Handle Growing here
}
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
return a_World->GetBlock(a_X, a_Y - 1, a_Z) == E_BLOCK_FARMLAND;
}
};

View File

@ -0,0 +1,9 @@
#include "Globals.h"
#include "BlockDirt.h"
#include "../cItem.h"
#include "../cWorld.h"
cBlockDirtHandler::cBlockDirtHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}

62
source/blocks/BlockDirt.h Normal file
View File

@ -0,0 +1,62 @@
#pragma once
#include "Block.h"
#include "../MersenneTwister.h"
#include "../cWorld.h"
class cBlockDirtHandler : public cBlockHandler
{
public:
cBlockDirtHandler(BLOCKTYPE a_BlockID);
virtual bool NeedsRandomTicks()
{
return m_BlockID == E_BLOCK_GRASS;
}
virtual int GetDropID()
{
return E_BLOCK_DIRT;
}
void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
if(m_BlockID == E_BLOCK_GRASS)
{
//Grass becomes dirt if there is something on top of them
BLOCKTYPE Above = a_World->GetBlock(a_X, a_Y + 1, a_Z);
if(!g_BlockTransparent[Above] && !g_BlockOneHitDig[Above])
{
a_World->FastSetBlock(a_X, a_Y, a_Z, E_BLOCK_DIRT, 0);
}
MTRand rand;
for (int i = 0; i < 2; i++) // Pick two blocks to grow to
{
int OfsX = rand.randInt(2) - 1; // [-1 .. 1]
int OfsY = rand.randInt(4) - 3; // [-3 .. 1]
int OfsZ = rand.randInt(2) - 1; // [-1 .. 1]
BLOCKTYPE DestBlock;
NIBBLETYPE DestMeta;
a_World->GetBlockTypeMeta(a_X + OfsX, a_Y + OfsY, a_Z + OfsZ, DestBlock, DestMeta);
if(DestBlock != E_BLOCK_DIRT)
{
continue;
}
BLOCKTYPE AboveDest;
NIBBLETYPE AboveMeta;
a_World->GetBlockTypeMeta(a_X + OfsX, a_Y + OfsY + 1, a_Z + OfsZ, AboveDest, AboveMeta);
if (g_BlockOneHitDig[AboveDest] || g_BlockTransparent[AboveDest])
{
a_World->FastSetBlock(a_X + OfsX, a_Y + OfsY, a_Z + OfsZ, E_BLOCK_GRASS, 0);
}
} // for i - repeat twice
}
}
};

View File

@ -0,0 +1,22 @@
#pragma once
#include "BlockEntity.h"
#include "../cWorld.h"
#include "../cPiston.h"
#include "../cPlayer.h"
class cBlockDispenserHandler : public cBlockEntityHandler
{
public:
cBlockDispenserHandler(BLOCKTYPE a_BlockID)
: cBlockEntityHandler(a_BlockID)
{
}
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir)
{
a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0));
OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
}
};

View File

@ -0,0 +1,60 @@
#include "Globals.h"
#include "BlockDoor.h"
#include "../cItem.h"
#include "../cWorld.h"
#include "../cDoors.h"
#include "../cPlayer.h"
cBlockDoorHandler::cBlockDoorHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
void cBlockDoorHandler::OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir)
{
}
void cBlockDoorHandler::OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
char OldMeta = a_World->GetBlockMeta(a_X, a_Y, a_Z);
if (OldMeta & 8)
{
// Was upper part of door
if (cDoors::IsDoor(a_World->GetBlock(a_X, a_Y - 1, a_Z)))
{
a_World->FastSetBlock(a_X, a_Y - 1, a_Z, E_BLOCK_AIR, 0);
}
}
else
{
// Was lower part
if (cDoors::IsDoor(a_World->GetBlock(a_X, a_Y + 1, a_Z)))
{
a_World->FastSetBlock(a_X, a_Y + 1, a_Z, E_BLOCK_AIR, 0);
}
}
}
void cBlockDoorHandler::OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z)
{
cDoors::ChangeDoor(a_World, a_X, a_Y, a_Z);
}
char cBlockDoorHandler::GetDropCount()
{
return 1;
}
void cBlockDoorHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir)
{
if (a_World->GetBlock(a_X, a_Y + 1, a_Z) == E_BLOCK_AIR)
{
a_BlockMeta = cDoors::RotationToMetaData(a_Player->GetRotation());
a_World->SetBlock(a_X, a_Y + 1, a_Z, m_BlockID, a_BlockMeta + 8);
a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, a_BlockMeta);
OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
}
}

29
source/blocks/BlockDoor.h Normal file
View File

@ -0,0 +1,29 @@
#pragma once
#include "Block.h"
class cBlockDoorHandler : public cBlockHandler
{
public:
cBlockDoorHandler(BLOCKTYPE a_BlockID);
virtual void OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir);
virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z);
virtual void OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z);
virtual char GetDropCount();
virtual bool IsUseable()
{
return true;
}
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir);
virtual int GetDropID()
{
return (m_BlockID == E_BLOCK_WOODEN_DOOR) ? E_ITEM_WOODEN_DOOR : E_ITEM_IRON_DOOR;
}
virtual bool CanBePlacedOnSide()
{
return false;
}
};

View File

@ -0,0 +1,15 @@
#include "Globals.h"
#include "BlockEntity.h"
#include "../cItem.h"
#include "../cPlayer.h"
#include "../cWorld.h"
cBlockEntityHandler::cBlockEntityHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
void cBlockEntityHandler::OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z)
{
a_World->UseBlockEntity(a_Player, a_X, a_Y, a_Z);
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "Block.h"
class cBlockEntityHandler : public cBlockHandler
{
public:
cBlockEntityHandler(BLOCKTYPE a_BlockID);
virtual void OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z);
virtual bool IsUseable()
{
return true;
}
};

View File

@ -0,0 +1,24 @@
#include "Globals.h"
#include "BlockFire.h"
#include "../cItem.h"
#include "../cWorld.h"
cBlockFireHandler::cBlockFireHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
void cBlockFireHandler::OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z)
{
a_World->DigBlock(a_X, a_Y, a_Z);
}
char cBlockFireHandler::GetDropCount()
{
return -1;
}
bool cBlockFireHandler::IsClickedThrough()
{
return true;
}

14
source/blocks/BlockFire.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include "Block.h"
class cBlockFireHandler : public cBlockHandler
{
public:
cBlockFireHandler(BLOCKTYPE a_BlockID);
virtual void OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z);
virtual bool IsClickedThrough();
virtual char GetDropCount();
};

View File

@ -0,0 +1,32 @@
#pragma once
#include "Block.h"
class cBlockFlowerHandler : public cBlockHandler
{
public:
cBlockFlowerHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual char GetDropMeta(char a_BlockMeta)
{
return 0;
}
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
return IsBlockTypeOfDirt(a_World->GetBlock(a_X, a_Y - 1, a_Z));
}
virtual bool AllowBlockOnTop()
{
return false;
}
virtual bool CanBePlacedOnSide()
{
return false;
}
};

View File

@ -0,0 +1,20 @@
#pragma once
#include "Block.h"
class cBlockFluidHandler : public cBlockHandler
{
public:
cBlockFluidHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual bool IgnoreBuildCollision()
{
return true;
}
};

View File

@ -0,0 +1,27 @@
#pragma once
#include "BlockEntity.h"
#include "../cWorld.h"
#include "../cPiston.h"
#include "../cPlayer.h"
class cBlockFurnaceHandler : public cBlockEntityHandler
{
public:
cBlockFurnaceHandler(BLOCKTYPE a_BlockID)
: cBlockEntityHandler(a_BlockID)
{
}
virtual int GetDropID()
{
return E_ITEM_FURNACE;
}
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir)
{
a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0));
OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
}
};

View File

@ -0,0 +1,22 @@
#pragma once
#include "Block.h"
class cBlockGlowstoneHandler : public cBlockHandler
{
public:
cBlockGlowstoneHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual char GetDropMeta(char a_BlockMeta)
{
return 0;
}
virtual int GetDropID()
{
return E_ITEM_GLOWSTONE_DUST;
}
};

26
source/blocks/BlockIce.h Normal file
View File

@ -0,0 +1,26 @@
#pragma once
#include "Block.h"
#include "../MersenneTwister.h"
#include "../cWorld.h"
class cBlockIceHandler : public cBlockHandler
{
public:
cBlockIceHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual int GetDropID()
{
return E_ITEM_EMPTY;
}
virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
a_World->FastSetBlock(a_X, a_Y, a_Z, E_BLOCK_STATIONARY_WATER, 8);
//This is called later than the real destroying of this ice block
}
};

View File

@ -0,0 +1,28 @@
#pragma once
#include "Block.h"
#include "../cWorld.h"
#include "../cLadder.h"
class cBlockLadderHandler : public cBlockHandler
{
public:
cBlockLadderHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir)
{
a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cLadder::DirectionToMetaData(a_Dir));
OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
}
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
char Dir = cLadder::MetaDataToDirection(a_World->GetBlockMeta( a_X, a_Y, a_Z));
AddDirection( a_X, a_Y, a_Z, Dir, true );
return a_World->GetBlock( a_X, a_Y, a_Z ) != E_BLOCK_AIR;
}
};

162
source/blocks/BlockLeaves.h Normal file
View File

@ -0,0 +1,162 @@
#pragma once
#include "Block.h"
#include "../MersenneTwister.h"
#include "../cWorld.h"
#include "../BlockArea.h"
// Leaves can be this many blocks that away (inclusive) from the log not to decay
#define LEAVES_CHECK_DISTANCE 6
#define PROCESS_NEIGHBOR(x,y,z) \
switch (a_Area.GetBlockType(x, y, z)) \
{ \
case E_BLOCK_LEAVES: a_Area.SetBlockType(x, y, z, E_BLOCK_SPONGE + i + 1); break; \
case E_BLOCK_LOG: return true; \
}
bool HasNearLog(cBlockArea &a_Area, int a_BlockX, int a_BlockY, int a_BlockZ);
class cBlockLeavesHandler : public cBlockHandler
{
public:
cBlockLeavesHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual int GetDropID()
{
MTRand rand;
if(rand.randInt(5) == 0)
{
return E_ITEM_SAPLING;
}
return E_ITEM_EMPTY;
}
void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
cBlockHandler::OnDestroyed(a_World, a_X, a_Y, a_Z);
//0.5% chance of dropping an apple
NIBBLETYPE Meta = a_World->GetBlockMeta(a_X, a_Y, a_Z);
//check if Oak (0x1 and 0x2 bit not set)
MTRand rand;
if(!(Meta & 3) && rand.randInt(200) == 100)
{
cItems Drops;
Drops.push_back(cItem(E_ITEM_RED_APPLE, 1, 0));
a_World->SpawnItemPickups(Drops, a_X, a_Y, a_Z);
}
}
virtual void OnNeighborChanged(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
NIBBLETYPE Meta = a_World->GetBlockMeta(a_X, a_Y, a_Z);
a_World->SetBlockMeta(a_X, a_Y, a_Z, Meta & 0x7); //Unset 0x8 bit so it gets checked for decay
}
virtual bool NeedsRandomTicks()
{
return true;
}
virtual void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
NIBBLETYPE Meta = a_World->GetBlockMeta(a_X, a_Y, a_Z);
if ((Meta & 0x04) != 0)
{
// Player-placed leaves, don't decay
return;
}
if (Meta & 0x8)
{
// These leaves have been checked for decay lately and nothing around them changed
return;
}
// Get the data around the leaves:
cBlockArea Area;
if (!Area.Read(
a_World,
a_X - LEAVES_CHECK_DISTANCE, a_X + LEAVES_CHECK_DISTANCE,
a_Y - LEAVES_CHECK_DISTANCE, a_Y + LEAVES_CHECK_DISTANCE,
a_Z - LEAVES_CHECK_DISTANCE, a_Z + LEAVES_CHECK_DISTANCE,
cBlockArea::baTypes)
)
{
// Cannot check leaves, a chunk is missing too close
return;
}
if (HasNearLog(Area, a_X, a_Y, a_Z))
{
// Wood found, the leaves stay; mark them as checked:
a_World->SetBlockMeta(a_X, a_Y, a_Z, Meta | 0x8);
return;
}
// Decay the leaves:
DropBlock(a_World, a_X, a_Y, a_Z);
a_World->DigBlock(a_X, a_Y, a_Z);
}
};
bool HasNearLog(cBlockArea &a_Area, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Filter the blocks into a {leaves, log, other (air)} set:
BLOCKTYPE * Types = a_Area.GetBlockTypes();
for (int i = a_Area.GetBlockCount() - 1; i > 0; i--)
{
switch (Types[i])
{
case E_BLOCK_LEAVES:
case E_BLOCK_LOG:
{
break;
}
default:
{
Types[i] = E_BLOCK_AIR;
break;
}
}
} // for i - Types[]
// Perform a breadth-first search to see if there's a log connected within 4 blocks of the leaves block:
// Simply replace all reachable leaves blocks with a sponge block plus iteration (in the Area) and see if we can reach a log in 4 iterations
a_Area.SetBlockType(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_SPONGE);
for (int i = 0; i < LEAVES_CHECK_DISTANCE; i++)
{
for (int y = a_BlockY - i; y <= a_BlockY + i; y++)
{
for (int z = a_BlockZ - i; z <= a_BlockZ + i; z++)
{
for (int x = a_BlockX - i; x <= a_BlockX + i; x++)
{
if (a_Area.GetBlockType(x, y, z) != E_BLOCK_SPONGE + i)
{
continue;
}
PROCESS_NEIGHBOR(x - 1, y, z);
PROCESS_NEIGHBOR(x + 1, y, z);
PROCESS_NEIGHBOR(x, y, z - 1);
PROCESS_NEIGHBOR(x, y, z + 1);
PROCESS_NEIGHBOR(x, y + 1, z);
PROCESS_NEIGHBOR(x, y - 1, z);
} // for x
} // for z
} // for y
} // for i - BFS iterations
return false;
}

View File

@ -0,0 +1,24 @@
#pragma once
#include "Block.h"
class cBlockMelonHandler : public cBlockHandler
{
public:
cBlockMelonHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual int GetDropID()
{
return E_ITEM_MELON_SLICE;
}
virtual char GetDropCount()
{
MTRand r1;
return 3 + r1.randInt(4);
}
};

View File

@ -0,0 +1,42 @@
#pragma once
#include "Block.h"
class cBlockMushroomHandler : public cBlockHandler
{
public:
cBlockMushroomHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual char GetDropMeta(char a_BlockMeta)
{
return 0;
}
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
switch (a_World->GetBlock(a_X, a_Y - 1, a_Z))
{
case E_BLOCK_GLASS:
case E_BLOCK_CACTUS:
case E_BLOCK_ICE:
case E_BLOCK_LEAVES:
case E_BLOCK_AIR:
return false;
}
return true;
}
virtual bool AllowBlockOnTop()
{
return false;
}
virtual bool CanBePlacedOnSide()
{
return false;
}
};

View File

@ -0,0 +1,51 @@
#include "Globals.h"
#include "BlockPiston.h"
#include "../cItem.h"
#include "../cWorld.h"
#include "../cRedstone.h"
#include "../cPlayer.h"
#include "../cPiston.h"
#define AddPistonDir(x, y, z, dir, amount) switch (dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\
case 2: (z)-=(amount); break; case 3: (z)+=(amount); break;\
case 4: (x)-=(amount); break; case 5: (x)+=(amount); break; }
cBlockPistonHandler::cBlockPistonHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
void cBlockPistonHandler::OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir)
{
}
void cBlockPistonHandler::OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
char OldMeta = a_World->GetBlockMeta(a_X, a_Y, a_Z);
int newX = a_X;
int newY = a_Y;
int newZ = a_Z;
AddPistonDir(newX, newY, newZ, OldMeta & ~(8), 1);
if (a_World->GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION)
{
a_World->SetBlock(newX, newY, newZ, E_BLOCK_AIR, 0);
}
}
void cBlockPistonHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir)
{
a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cPiston::RotationPitchToMetaData(a_Player->GetRotation(), a_Player->GetPitch()));
OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
cRedstone Redstone(a_World);
Redstone.ChangeRedstone(a_X, a_Y, a_Z, false);
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "Block.h"
class cBlockPistonHandler : public cBlockHandler
{
public:
cBlockPistonHandler(BLOCKTYPE a_BlockID);
virtual void OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir);
virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z);
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir);
};

View File

@ -0,0 +1,41 @@
#include "Globals.h"
#include "BlockRedstone.h"
#include "../cItem.h"
#include "../cWorld.h"
#include "../cRedstone.h"
#include "../cTorch.h"
cBlockRedstoneHandler::cBlockRedstoneHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
void cBlockRedstoneHandler::OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir)
{
cRedstone Redstone(a_World);
bool Added = false;
if(a_World->GetBlock(a_X, a_Y, a_Z) == E_BLOCK_REDSTONE_TORCH_ON)
Added = true;
Redstone.ChangeRedstone(a_X, a_Y, a_Z, Added);
}
void cBlockRedstoneHandler::OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
cRedstone Redstone(a_World);
Redstone.ChangeRedstone(a_X, a_Y, a_Z, false);
}
void cBlockRedstoneHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir)
{
switch(m_BlockID)
{
case E_BLOCK_REDSTONE_TORCH_ON:
case E_BLOCK_REDSTONE_TORCH_OFF:
a_BlockMeta = cTorch::DirectionToMetaData(a_Dir);
break;
}
a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, a_BlockMeta);
OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
}

View File

@ -0,0 +1,33 @@
#pragma once
#include "Block.h"
#include "../cWorld.h"
class cBlockRedstoneHandler : public cBlockHandler
{
public:
cBlockRedstoneHandler(BLOCKTYPE a_BlockID);
virtual void OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir);
virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z);
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir);
virtual bool AllowBlockOnTop()
{
return false;
}
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
return a_World->GetBlock(a_X, a_Y - 1, a_Z) != E_BLOCK_AIR;
}
virtual int GetDropID()
{
return E_ITEM_REDSTONE_DUST;
}
virtual bool CanBePlacedOnSide()
{
return false;
}
};

View File

@ -0,0 +1,26 @@
#pragma once
#include "Block.h"
#include "../MersenneTwister.h"
#include "../cWorld.h"
class cBlockRedstoneOreHandler : public cBlockHandler
{
public:
cBlockRedstoneOreHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual int GetDropID()
{
return E_ITEM_REDSTONE_DUST;
}
virtual char GetDropCount()
{
MTRand r1;
return 4 + r1.randInt(1);
}
};

View File

@ -0,0 +1,34 @@
#include "Globals.h"
#include "BlockRedstoneRepeater.h"
#include "../cItem.h"
#include "../cWorld.h"
#include "../cRedstone.h"
#include "../cPlayer.h"
cBlockRedstoneRepeaterHandler::cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
void cBlockRedstoneRepeaterHandler::OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir)
{
cRedstone Redstone(a_World);
Redstone.ChangeRedstone(a_X, a_Y, a_Z, false);
}
void cBlockRedstoneRepeaterHandler::OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
cRedstone Redstone(a_World);
Redstone.ChangeRedstone(a_X, a_Y, a_Z, false);
}
void cBlockRedstoneRepeaterHandler::OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z)
{
a_World->FastSetBlock(a_X, a_Y, a_Z, m_BlockID, ((a_World->GetBlockMeta(a_X, a_Y, a_Z) + 0x04) & 0x0f));
}
void cBlockRedstoneRepeaterHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir)
{
a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cRedstone::RepeaterRotationToMetaData(a_Player->GetRotation()));
OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
}

View File

@ -0,0 +1,46 @@
#pragma once
#include "Block.h"
#include "../cWorld.h"
class cBlockRedstoneRepeaterHandler : public cBlockHandler
{
public:
cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockID);
virtual void OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir);
virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z);
virtual void OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z);
virtual char GetDropMeta(char a_BlockMeta)
{
return 0;
}
virtual int GetDropID()
{
return E_ITEM_REDSTONE_REPEATER;
}
virtual bool IsUseable()
{
return true;
}
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir);
virtual bool AllowBlockOnTop()
{
return false;
}
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
return a_World->GetBlock(a_X, a_Y - 1, a_Z) != E_BLOCK_AIR;
}
virtual bool CanBePlacedOnSide()
{
return false;
}
};

View File

@ -0,0 +1,30 @@
#pragma once
#include "BlockRedstone.h"
#include "../cTorch.h"
class cBlockRedstoneTorchHandler : public cBlockRedstoneHandler
{
public:
cBlockRedstoneTorchHandler(BLOCKTYPE a_BlockID)
: cBlockRedstoneHandler(a_BlockID)
{
}
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
char Dir = cTorch::MetaDataToDirection(a_World->GetBlockMeta( a_X, a_Y, a_Z));
AddDirection( a_X, a_Y, a_Z, Dir, true );
return a_World->GetBlock( a_X, a_Y, a_Z ) != E_BLOCK_AIR;
}
virtual int GetDropID()
{
return E_ITEM_REDSTONE_TORCH_ON;
}
virtual bool CanBePlacedOnSide()
{
return true;
}
};

View File

@ -0,0 +1,51 @@
#pragma once
#include "Block.h"
#include "../cWorld.h"
class cBlockSaplingHandler : public cBlockHandler
{
public:
cBlockSaplingHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual bool NeedsRandomTicks() override
{
return true;
}
virtual char GetDropMeta(char a_BlockMeta)
{
return a_BlockMeta & 3; //Only the first 2 bits contain the display information the others are for growing
}
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
return IsBlockTypeOfDirt(a_World->GetBlock(a_X, a_Y - 1, a_Z));
}
virtual bool AllowBlockOnTop()
{
return false;
}
void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
NIBBLETYPE Meta = a_World->GetBlockMeta(a_X, a_Y, a_Z);
if ((Meta & 0x08) != 0)
{
a_World->GrowTree(a_X, a_Y, a_Z);
}
else
{
a_World->SetBlockMeta(a_X, a_Y, a_Z, Meta | 0x08);
}
}
virtual bool CanBePlacedOnSide()
{
return false;
}
};

42
source/blocks/BlockSign.h Normal file
View File

@ -0,0 +1,42 @@
#pragma once
#include "Block.h"
#include "../cWorld.h"
#include "../cSign.h"
#include "../cPlayer.h"
class cBlockSignHandler : public cBlockHandler
{
public:
cBlockSignHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir)
{
BLOCKTYPE Block;
NIBBLETYPE Meta;
if(a_Dir == 1)
{
Meta = cSign::RotationToMetaData(a_Player->GetRotation());
Block = E_BLOCK_SIGN_POST;
}else{
Meta = cSign::DirectionToMetaData(a_Dir);
Block = E_BLOCK_WALLSIGN;
}
a_World->SetBlock(a_X, a_Y, a_Z, Block, Meta);
OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
}
virtual int GetDropID()
{
return E_ITEM_SIGN;
}
virtual bool AllowBlockOnTop()
{
return false;
}
};

View File

@ -0,0 +1,17 @@
#include "Globals.h"
#include "BlockSlab.h"
#include "../cItem.h"
#include "../cPlayer.h"
#include "../cWorld.h"
cBlockSlabHandler::cBlockSlabHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
void cBlockSlabHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir)
{
a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, DirectionToMetaData( a_Dir, a_BlockMeta ));
OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
}

33
source/blocks/BlockSlab.h Normal file
View File

@ -0,0 +1,33 @@
#pragma once
#include "Block.h"
class cBlockSlabHandler : public cBlockHandler
{
public:
cBlockSlabHandler(BLOCKTYPE a_BlockID);
virtual char GetDropMeta(char a_BlockMeta)
{
return a_BlockMeta;
}
virtual char GetDropCount()
{
if(m_BlockID == E_BLOCK_DOUBLE_STONE_SLAB
|| m_BlockID == E_BLOCK_DOUBLE_WOODEN_SLAB)
return 2;
return 1;
}
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir);
static char DirectionToMetaData( char a_Direction, NIBBLETYPE Meta )
{
char result = Meta;
if( a_Direction == 0)
{
result |= 0x8;
}
return result;
}
};

39
source/blocks/BlockSnow.h Normal file
View File

@ -0,0 +1,39 @@
#pragma once
#include "Block.h"
class cBlockSnowHandler : public cBlockHandler
{
public:
cBlockSnowHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual bool IgnoreBuildCollision()
{
return true;
}
virtual int GetDropID()
{
return E_ITEM_SNOWBALL;
}
virtual char GetDropCount()
{
return 4;
}
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
return a_World->GetBlock(a_X, a_Y - 1, a_Z) != E_BLOCK_AIR;
}
virtual bool DropOnUnsuitable()
{
return false;
}
};

View File

@ -0,0 +1,18 @@
#include "Globals.h"
#include "BlockStairs.h"
#include "../cItem.h"
#include "../cVine.h"
#include "../cPlayer.h"
#include "../cWorld.h"
#include "../cStairs.h"
cBlockStairsHandler::cBlockStairsHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
void cBlockStairsHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir)
{
a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cStairs::RotationToMetaData(a_Player->GetRotation(), a_Dir));
OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "Block.h"
class cBlockStairsHandler : public cBlockHandler
{
public:
cBlockStairsHandler(BLOCKTYPE a_BlockID);
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir);
};

View File

@ -0,0 +1,41 @@
#pragma once
#include "Block.h"
#include "../MersenneTwister.h"
#include "../cWorld.h"
class cBlockStemsHandler : public cBlockHandler
{
public:
cBlockStemsHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual bool NeedsRandomTicks()
{
return true;
}
virtual char GetDropMeta(char a_BlockMeta)
{
return 0;
}
virtual int GetDropID()
{
if(m_BlockID == E_BLOCK_MELON_STEM)
return E_ITEM_MELON_SEEDS;
return E_ITEM_PUMPKIN_SEEDS;
}
void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
//TODO: Handle Growing here
}
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
return a_World->GetBlock(a_X, a_Y - 1, a_Z) == E_BLOCK_FARMLAND;
}
};

View File

@ -0,0 +1,18 @@
#pragma once
#include "Block.h"
#include "../MersenneTwister.h"
#include "../cWorld.h"
class cBlockStoneHandler : public cBlockHandler
{
public:
cBlockStoneHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual int GetDropID()
{
return E_ITEM_COBBLESTONE;
}
};

View File

@ -0,0 +1,43 @@
#pragma once
#include "Block.h"
#include "../MersenneTwister.h"
#include "../cWorld.h"
class cBlockSugarcaneHandler : public cBlockHandler
{
public:
cBlockSugarcaneHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual bool NeedsRandomTicks()
{
return true;
}
virtual int GetDropID()
{
return E_ITEM_SUGARCANE;
}
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
BLOCKTYPE Block = a_World->GetBlock(a_X, a_Y-1, a_Z);
if(!IsBlockTypeOfDirt(Block) && Block != E_BLOCK_SAND && Block != E_BLOCK_SUGARCANE)
return false;
return a_World->IsBlockDirectlyWatered(a_X, a_Y - 1, a_Z);
}
void OnUpdate(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
//TODO: Handle Growing here
}
virtual bool CanBePlacedOnSide()
{
return false;
}
};

View File

@ -0,0 +1,35 @@
#pragma once
#include "Block.h"
class cBlockTallGrassHandler : public cBlockHandler
{
public:
cBlockTallGrassHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
virtual bool IgnoreBuildCollision()
{
return true;
}
virtual int GetDropID()
{
return E_ITEM_SEEDS;
}
virtual char GetDropCount()
{
MTRand r1;
if(r1.randInt(10) == 5)
return 1;
return 0;
}
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
return a_World->GetBlock(a_X, a_Y - 1, a_Z) != E_BLOCK_AIR;
}
};

View File

@ -0,0 +1,15 @@
#include "Globals.h"
#include "BlockTorch.h"
#include "../cTorch.h"
#include "../cWorld.h"
cBlockTorchHandler::cBlockTorchHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
void cBlockTorchHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir)
{
a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cTorch::DirectionToMetaData(a_Dir));
OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
}

View File

@ -0,0 +1,25 @@
#pragma once
#include "Block.h"
#include "../cTorch.h"
#include "../cWorld.h"
class cBlockTorchHandler : public cBlockHandler
{
public:
cBlockTorchHandler(BLOCKTYPE a_BlockID);
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir);
virtual bool AllowBlockOnTop()
{
return false;
}
virtual bool CanBeAt(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
char Dir = cTorch::MetaDataToDirection(a_World->GetBlockMeta( a_X, a_Y, a_Z));
AddDirection( a_X, a_Y, a_Z, Dir, true );
return a_World->GetBlock( a_X, a_Y, a_Z ) != E_BLOCK_AIR;
}
};

View File

@ -0,0 +1,17 @@
#include "Globals.h"
#include "BlockVine.h"
#include "../cItem.h"
#include "../cVine.h"
#include "../cPlayer.h"
#include "../cWorld.h"
cBlockVineHandler::cBlockVineHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
void cBlockVineHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir)
{
a_World->SetBlock(a_X, a_Y, a_Z, m_BlockID, cVine::DirectionToMetaData(a_Dir));
OnPlacedByPlayer(a_World, a_Player, a_X, a_Y, a_Z, a_Dir);
}

23
source/blocks/BlockVine.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include "Block.h"
class cBlockVineHandler : public cBlockHandler
{
public:
cBlockVineHandler(BLOCKTYPE a_BlockID);
virtual bool IgnoreBuildCollision()
{
return true;
}
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, char a_BlockMeta, int a_X, int a_Y, int a_Z, char a_Dir);
virtual bool AllowBlockOnTop()
{
return false;
}
};

17
source/blocks/BlockWood.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include "Block.h"
class cBlockWoodHandler : public cBlockHandler
{
public:
cBlockWoodHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
char GetDropMeta(char a_BlockMeta)
{
return a_BlockMeta;
}
};

View File

@ -0,0 +1,24 @@
#include "Globals.h"
#include "BlockWorkbench.h"
#include "../cItem.h"
#include "../cPlayer.h"
#include "../cCraftingWindow.h"
cBlockWorkbenchHandler::cBlockWorkbenchHandler(BLOCKTYPE a_BlockID)
: cBlockHandler(a_BlockID)
{
}
void cBlockWorkbenchHandler::OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir)
{
}
void cBlockWorkbenchHandler::OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z)
{
}
void cBlockWorkbenchHandler::OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z)
{
cWindow* Window = new cCraftingWindow(0, true);
a_Player->OpenWindow(Window);
}

View File

@ -0,0 +1,19 @@
#pragma once
#include "Block.h"
class cBlockWorkbenchHandler : public cBlockHandler
{
public:
cBlockWorkbenchHandler(BLOCKTYPE a_BlockID);
virtual void OnPlaced(cWorld *a_World, int a_X, int a_Y, int a_Z, int a_Dir);
virtual void OnDestroyed(cWorld *a_World, int a_X, int a_Y, int a_Z);
virtual void OnClick(cWorld *a_World, cPlayer *a_Player, int a_X, int a_Y, int a_Z);
virtual bool IsUseable()
{
return true;
}
};

View File

@ -7,320 +7,3 @@
#include "MersenneTwister.h"
static void AddRandomDrop(cItems & a_Drops, MTRand & r1, int a_OneInNChance, ENUM_ITEM_ID a_ItemID)
{
if ((r1.randInt(16 * a_OneInNChance - 1) / 16) != 0)
{
return;
}
a_Drops.push_back(cItem(a_ItemID, 1));
}
void cBlockToPickup::ToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cItem & a_UsedItem, cItems & a_Drops)
{
MTRand r1;
switch (a_BlockType)
{
// Blocks that always drop themselves as the only item, no matter what tool; copy damage from meta:
case E_BLOCK_LOG:
case E_BLOCK_PLANKS:
case E_BLOCK_WOOL:
{
a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1, a_BlockMeta));
return;
}
// Blocks that always drop themselves as the only item, no matter what tool, set damage value zero:
case E_BLOCK_DIRT:
case E_BLOCK_SAPLING:
case E_BLOCK_SAND:
case E_BLOCK_TORCH:
case E_BLOCK_YELLOW_FLOWER:
case E_BLOCK_RED_ROSE:
case E_BLOCK_BROWN_MUSHROOM:
case E_BLOCK_RED_MUSHROOM:
case E_BLOCK_TNT:
case E_BLOCK_CRAFTING_TABLE:
case E_BLOCK_FURNACE:
case E_BLOCK_CACTUS:
case E_BLOCK_REDSTONE_TORCH_OFF:
case E_BLOCK_POWERED_RAIL:
case E_BLOCK_DETECTOR_RAIL:
case E_BLOCK_RAIL:
case E_BLOCK_LADDER:
case E_BLOCK_LEVER:
case E_BLOCK_WOODEN_PRESSURE_PLATE:
case E_BLOCK_STONE_BUTTON:
case E_BLOCK_JUKEBOX:
case E_BLOCK_FENCE:
case E_BLOCK_FENCE_GATE:
case E_BLOCK_PUMPKIN:
case E_BLOCK_NETHERRACK:
case E_BLOCK_SOULSAND:
case E_BLOCK_JACK_O_LANTERN:
case E_BLOCK_TRAPDOOR:
{
a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1, 0));
return;
}
// Blocks that always drop a single item, no matter what tool:
case E_BLOCK_SIGN_POST:
case E_BLOCK_WALLSIGN: a_Drops.push_back(cItem(E_ITEM_SIGN, 1)); return;
case E_BLOCK_REDSTONE_WIRE: a_Drops.push_back(cItem(E_ITEM_REDSTONE_DUST, 1)); return;
case E_BLOCK_GLOWSTONE: a_Drops.push_back(cItem(E_ITEM_GLOWSTONE_DUST, 1)); return;
case E_BLOCK_REDSTONE_REPEATER_OFF:
case E_BLOCK_REDSTONE_REPEATER_ON: a_Drops.push_back(cItem(E_ITEM_REDSTONE_REPEATER, 1)); return;
case E_BLOCK_COBWEB: a_Drops.push_back(cItem(E_ITEM_STRING, 1)); return;
case E_BLOCK_FARMLAND:
case E_BLOCK_GRASS: a_Drops.push_back(cItem(E_ITEM_DIRT, 1)); return;
case E_BLOCK_LIT_FURNACE: a_Drops.push_back(cItem(E_ITEM_FURNACE, 1)); return;
case E_BLOCK_SUGARCANE: a_Drops.push_back(cItem(E_ITEM_SUGARCANE, 1)); return;
case E_BLOCK_PUMPKIN_STEM: a_Drops.push_back(cItem(E_ITEM_PUMPKIN_SEEDS, 1)); return;
case E_BLOCK_MELON_STEM: a_Drops.push_back(cItem(E_ITEM_MELON_SEEDS, 1)); return;
// Doors seem to need their meta set to 1
case E_BLOCK_WOODEN_DOOR: a_Drops.push_back(cItem(E_ITEM_WOODEN_DOOR, 1, 1)); return;
case E_BLOCK_IRON_DOOR: a_Drops.push_back(cItem(E_ITEM_IRON_DOOR, 1, 1)); return;
////////////////////////
// Ores:
// Coal ore requires a pickaxe:
case E_BLOCK_COAL_ORE:
{
if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID))
{
a_Drops.push_back(cItem(E_ITEM_COAL, 1));
}
return;
}
// Iron ore requires a stone or better pickaxe:
case E_BLOCK_IRON_ORE:
{
if (
(a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) ||
(a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) ||
(a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE)
)
{
a_Drops.push_back(cItem(E_ITEM_IRON_ORE, 1));
}
return;
}
// Gold and diamond ores require an iron or better pickaxe:
case E_BLOCK_GOLD_ORE:
case E_BLOCK_DIAMOND_ORE:
{
if (
(a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) ||
(a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE)
)
{
a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1));
}
return;
}
// Obsidian require a diamond pickaxe:
case E_BLOCK_OBSIDIAN:
{
if (a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE)
{
a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1));
}
return;
}
// Redstone requires an iron or better pickaxe:
case E_BLOCK_REDSTONE_ORE_GLOWING:
case E_BLOCK_REDSTONE_ORE:
{
if (
(a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) ||
(a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE)
)
{
a_Drops.push_back(cItem(E_ITEM_REDSTONE_DUST, 4 + (short)r1.randInt(1)));
}
return;
}
// Lapis ore requires a stone or better pickaxe:
case E_BLOCK_LAPIS_ORE:
{
if (
(a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) ||
(a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) ||
(a_UsedItem.m_ItemID == E_ITEM_GOLD_PICKAXE) ||
(a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE)
)
{
a_Drops.push_back(cItem(E_ITEM_DYE, 4 + (short)r1.randInt(4), E_META_DYE_BLUE));
}
return;
}
////////////////////////
// Resource blocks:
// Iron and lapis blocks require a stone or better pickaxe:
case E_BLOCK_IRON_BLOCK:
case E_BLOCK_LAPIS_BLOCK:
{
if (
(a_UsedItem.m_ItemID == E_ITEM_STONE_PICKAXE) ||
(a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) ||
(a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE)
)
{
a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1));
}
return;
}
// Diamond and gold blocks require an iron or better pickaxe:
case E_BLOCK_DIAMOND_BLOCK:
{
if (
(a_UsedItem.m_ItemID == E_ITEM_IRON_PICKAXE) ||
(a_UsedItem.m_ItemID == E_ITEM_DIAMOND_PICKAXE)
)
{
a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1));
}
}
// These blocks require a pickaxe to drop themselves:
case E_BLOCK_COBBLESTONE:
case E_BLOCK_BRICK:
case E_BLOCK_NETHER_BRICK:
case E_BLOCK_MOSSY_COBBLESTONE:
case E_BLOCK_STONE_SLAB:
case E_BLOCK_COBBLESTONE_STAIRS:
case E_BLOCK_STONE_BRICK_STAIRS:
case E_BLOCK_NETHER_BRICK_STAIRS:
case E_BLOCK_SANDSTONE_STAIRS:
case E_BLOCK_SANDSTONE:
case E_BLOCK_STONE_PRESSURE_PLATE:
{
if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID))
{
a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1));
}
return;
}
// Stone requires a pickaxe to drop cobblestone:
case E_BLOCK_STONE:
{
if (ItemCategory::IsPickaxe(a_UsedItem.m_ItemID))
{
a_Drops.push_back(cItem(E_ITEM_COBBLESTONE, 1));
}
return;
}
// Snow requires a shovel to harvest:
case E_BLOCK_SNOW:
{
if (ItemCategory::IsShovel(a_UsedItem.m_ItemID))
{
a_Drops.push_back(cItem(E_ITEM_SNOWBALL, 1));
}
return;
}
// Leaves require shears for harvesting and have a chance of dropping a sapling and a red apple:
case E_BLOCK_LEAVES:
{
if (a_UsedItem.m_ItemID == E_ITEM_SHEARS)
{
a_Drops.push_back(cItem(E_ITEM_LEAVES, 1));
}
else
{
AddRandomDrop(a_Drops, r1, 5, E_ITEM_SAPLING);
if (a_BlockMeta == E_META_LEAVES_APPLE)
{
AddRandomDrop(a_Drops, r1, 200, E_ITEM_APPLE);
}
}
return;
}
// Crops drop a wheat and possibly another seeds when ripe; always drop at least a single seed
case E_BLOCK_CROPS:
{
if (a_BlockMeta == 7)
{
AddRandomDrop(a_Drops, r1, 3, E_ITEM_SEEDS);
a_Drops.push_back(cItem(E_ITEM_WHEAT, 1));
}
a_Drops.push_back(cItem(E_ITEM_SEEDS, 1));
return;
}
// Vines drop only with shears, otherwise they are destroyed
case E_BLOCK_VINES:
{
if (a_UsedItem.m_ItemID == E_ITEM_SHEARS)
{
a_Drops.push_back(cItem(E_ITEM_VINES, 1));
}
return;
}
// Snow drops only when using a shovel
case E_BLOCK_SNOW_BLOCK:
{
if (ItemCategory::IsShovel(a_UsedItem.m_ItemID))
{
a_Drops.push_back(cItem(E_ITEM_SNOWBALL, 4, 0)); return;
}
return;
}
// Random multi-drop blocks:
case E_BLOCK_TALL_GRASS: a_Drops.push_back(cItem(E_ITEM_SEEDS, (short)r1.randInt(3) / 2, 1)); return;
case E_BLOCK_MELON: a_Drops.push_back(cItem(E_ITEM_MELON_SLICE, 3 + (short)r1.randInt(2), 1)); return;
// Fixed multi-drop blocks:
case E_BLOCK_DOUBLE_STONE_SLAB: a_Drops.push_back(cItem(E_ITEM_STONE_SLAB, 2, 0)); return;
case E_BLOCK_DOUBLE_WOODEN_SLAB: a_Drops.push_back(cItem(E_ITEM_STEP, 2, 0)); return;
default:
{
return;
}
} // switch (a_BlockType)
}

View File

@ -16,7 +16,6 @@ class cBlockToPickup // tolua_export
{ // tolua_export
public:
/// For a given block and tool, returns the list of drops generated
static void ToPickup(BLOCKTYPE a_BlockID, NIBBLETYPE a_BlockMeta, const cItem & a_UsedItem, cItems & a_Drops); // tolua_export
/// Returns true if the tool used for the block is the right one for the job. cClientHandle uses this to determine whether to decrease tool durability twice as much
static bool IsRightTool(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, ENUM_ITEM_ID a_UsedTool); // tolua_export

View File

@ -29,21 +29,21 @@
#include "cPlayer.h"
#include "BlockArea.h"
#include "cPluginManager.h"
#include "blocks/Block.h"
#include "packets/cPacket_DestroyEntity.h"
#include "packets/cPacket_PreChunk.h"
#include "packets/cPacket_BlockChange.h"
#include "packets/cPacket_MultiBlock.h"
#include "blocks/Block.h"
#include <json/json.h>
// Leaves can be this many blocks that away (inclusive) from the log not to decay
#define LEAVES_CHECK_DISTANCE 6
@ -449,7 +449,20 @@ void cChunk::CheckBlocks(void)
{
unsigned int index = (*itr);
Vector3i BlockPos = IndexToCoordinate(index);
Vector3i WorldPos = PositionToWorldPosition( BlockPos );
cBlockHandler * Handler = BlockHandler(GetBlock(index));
if(!Handler->CanBeAt(m_World, WorldPos.x, WorldPos.y, WorldPos.z))
{
if(Handler->DropOnUnsuitable())
{
Handler->DropBlock(m_World, WorldPos.x, WorldPos.y, WorldPos.z);
}
m_World->SetBlock(WorldPos.x, WorldPos.y, WorldPos.z, E_BLOCK_AIR, 0);
}
/*
BLOCKTYPE BlockType = GetBlock(index);
NIBBLETYPE BlockMeta = GetMeta (index);
switch (BlockType)
@ -524,14 +537,8 @@ void cChunk::CheckBlocks(void)
}
break;
}
// If anything next to a leaves block changes, set the leaves' "check for decay" bit (clear bit 0x08):
case E_BLOCK_LEAVES:
{
cChunkDef::SetNibble(m_BlockMeta, index, BlockMeta & 0x07);
break;
}
} // switch (BlockType)
*/
} // for itr - ToTickBlocks[]
}
@ -585,89 +592,24 @@ void cChunk::TickBlocks(MTRand & a_TickRandom)
break;
}
case E_BLOCK_GRASS: TickGrass (m_BlockTickX, m_BlockTickY, m_BlockTickZ, a_TickRandom); break;
case E_BLOCK_PUMPKIN_STEM:
case E_BLOCK_MELON_STEM: TickMelonPumpkin(m_BlockTickX, m_BlockTickY, m_BlockTickZ, Index, ID, a_TickRandom); break;
case E_BLOCK_FARMLAND: TickFarmland (m_BlockTickX, m_BlockTickY, m_BlockTickZ); break;
case E_BLOCK_SUGARCANE: GrowSugarcane (m_BlockTickX, m_BlockTickY, m_BlockTickZ, 1); break;
case E_BLOCK_CACTUS: GrowCactus (m_BlockTickX, m_BlockTickY, m_BlockTickZ, 1); break;
case E_BLOCK_SAPLING:
{
// Check the highest bit, if set, grow the tree, if not, set it (1-bit delay):
NIBBLETYPE Meta = GetMeta(m_BlockTickX, m_BlockTickY, m_BlockTickZ);
if ((Meta & 0x08) != 0)
{
m_World->GrowTree( m_BlockTickX + m_PosX*Width, m_BlockTickY, m_BlockTickZ + m_PosZ*Width );
}
else
{
SetMeta(m_BlockTickX, m_BlockTickY, m_BlockTickZ, Meta | 0x08);
}
break;
}
case E_BLOCK_LEAVES: TickLeaves(m_BlockTickX, m_BlockTickY, m_BlockTickZ, a_TickRandom); break;
default:
{
cBlockHandler *Handler = BlockHandler(ID);
if(Handler->NeedsRandomTicks())
Handler->OnUpdate(m_World, m_BlockTickX + m_PosX*Width, m_BlockTickY, m_BlockTickZ + m_PosZ*Width);
break;
}
}
}
}
void cChunk::TickGrass(int a_RelX, int a_RelY, int a_RelZ, MTRand & a_TickRandom)
{
// Grass turns into dirt if there's another block on top of it:
{
BLOCKTYPE AboveBlock = cChunkDef::GetBlock(m_BlockTypes, a_RelX, a_RelY + 1, a_RelZ);
if (!((g_BlockOneHitDig[AboveBlock]) || (g_BlockTransparent[AboveBlock])))
{
FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0);
return;
}
}
// Grass spreads to nearby blocks if there's enough light (TODO) and free space above that block
// Ref.: http://www.minecraftwiki.net/wiki/Grass_Block#Growth
for (int i = 0; i < 2; i++) // Pick two blocks to grow to
{
int OfsX = a_TickRandom.randInt(2) - 1; // [-1 .. 1]
int OfsY = a_TickRandom.randInt(4) - 3; // [-3 .. 1]
int OfsZ = a_TickRandom.randInt(2) - 1; // [-1 .. 1]
BLOCKTYPE DestBlock;
NIBBLETYPE DestMeta;
if (
!UnboundedRelGetBlock(a_RelX + OfsX, a_RelY + OfsY, a_RelZ + OfsZ, DestBlock, DestMeta) ||
(DestBlock != E_BLOCK_DIRT)
)
{
continue;
}
BLOCKTYPE AboveDest;
NIBBLETYPE AboveMeta;
if (
UnboundedRelGetBlock(a_RelX + OfsX, a_RelY + OfsY + 1, a_RelZ + OfsZ, AboveDest, AboveMeta) &&
((g_BlockOneHitDig[AboveDest]) || (g_BlockTransparent[AboveDest]))
// TODO: Query dest light, if it's enough
)
{
UnboundedRelFastSetBlock(a_RelX + OfsX, a_RelY + OfsY, a_RelZ + OfsZ, E_BLOCK_GRASS, 0);
}
} // for i - repeat twice
}
void cChunk::TickMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, int a_BlockIdx, BLOCKTYPE a_BlockType, MTRand & a_TickRandom)
{
NIBBLETYPE Meta = GetMeta(a_BlockIdx);
@ -762,120 +704,6 @@ void cChunk::TickFarmland(int a_RelX, int a_RelY, int a_RelZ)
void cChunk::TickLeaves(int a_RelX, int a_RelY, int a_RelZ, MTRand & a_TickRandom)
{
// Since leaves-checking is a costly operation, it is done only if leaves are marked for checking (Meta has its 0x08 bit cleared)
// The meta bit 0x08 bit is cleared (check flag set) each time a block next to the leaves changes
NIBBLETYPE Meta = GetMeta(a_RelX, a_RelY, a_RelZ);
if ((Meta & 0x04) != 0)
{
// Player-placed leaves, don't decay
return;
}
if ((Meta & 0x08) != 0)
{
// These leaves have been checked for decay lately and nothing around them changed
return;
}
// Get the data around the leaves:
cBlockArea Area;
int BaseX = cChunkDef::Width * m_PosX + a_RelX;
int BaseZ = cChunkDef::Width * m_PosZ + a_RelZ;
if (!Area.Read(
m_World,
BaseX - LEAVES_CHECK_DISTANCE, BaseX + LEAVES_CHECK_DISTANCE,
a_RelY - LEAVES_CHECK_DISTANCE, a_RelY + LEAVES_CHECK_DISTANCE,
BaseZ - LEAVES_CHECK_DISTANCE, BaseZ + LEAVES_CHECK_DISTANCE,
cBlockArea::baTypes)
)
{
// Cannot check leaves, a chunk is missing too close
return;
}
if (HasNearLog(Area, BaseX, a_RelY, BaseZ))
{
// Log found, the leaves stay; mark them as checked:
SetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ, Meta & 0x07);
return;
}
// Decay the leaves:
m_World->DigBlock(m_PosX * cChunkDef::Width + a_RelX, a_RelY, m_PosZ * cChunkDef::Width + a_RelZ);
// Let them drop something if the random is right:
cItems PickupItems;
cBlockToPickup::ToPickup(E_BLOCK_LEAVES, Meta, cItem(), PickupItems);
// Allow plugins to change the dropped objects:
cRoot::Get()->GetPluginManager()->CallHookBlockToPickup(E_BLOCK_LEAVES, Meta, NULL, cItem(), PickupItems);
m_World->SpawnItemPickups(PickupItems, BaseX, a_RelY, BaseZ);
}
#define PROCESS_NEIGHBOR(x,y,z) \
switch (a_Area.GetBlockType(x, y, z)) \
{ \
case E_BLOCK_LEAVES: a_Area.SetBlockType(x, y, z, E_BLOCK_SPONGE + i + 1); break; \
case E_BLOCK_LOG: return true; \
}
bool cChunk::HasNearLog(cBlockArea & a_Area, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Filter the blocks into a {leaves, log, other (air)} set:
BLOCKTYPE * Types = a_Area.GetBlockTypes();
for (int i = a_Area.GetBlockCount() - 1; i > 0; i--)
{
switch (Types[i])
{
case E_BLOCK_LEAVES:
case E_BLOCK_LOG:
{
break;
}
default:
{
Types[i] = E_BLOCK_AIR;
break;
}
}
} // for i - Types[]
// Perform a breadth-first search to see if there's a log connected within 4 blocks of the leaves block:
// Simply replace all reachable leaves blocks with a sponge block plus iteration (in the Area) and see if we can reach a log in 4 iterations
a_Area.SetBlockType(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_SPONGE);
for (int i = 0; i < LEAVES_CHECK_DISTANCE; i++)
{
for (int y = a_BlockY - i; y <= a_BlockY + i; y++)
{
for (int z = a_BlockZ - i; z <= a_BlockZ + i; z++)
{
for (int x = a_BlockX - i; x <= a_BlockX + i; x++)
{
if (a_Area.GetBlockType(x, y, z) != E_BLOCK_SPONGE + i)
{
continue;
}
PROCESS_NEIGHBOR(x - 1, y, z);
PROCESS_NEIGHBOR(x + 1, y, z);
PROCESS_NEIGHBOR(x, y, z - 1);
PROCESS_NEIGHBOR(x, y, z + 1);
PROCESS_NEIGHBOR(x, y + 1, z);
PROCESS_NEIGHBOR(x, y - 1, z);
} // for x
} // for z
} // for y
} // for i - BFS iterations
return false;
}
void cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_TickRandom)
{

View File

@ -257,7 +257,6 @@ private:
void TickGrass (int a_RelX, int a_RelY, int a_RelZ, MTRand & a_TickRandom);
void TickMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, int a_BlockIdx, BLOCKTYPE a_BlockType, MTRand & a_TickRandom);
void TickFarmland (int a_RelX, int a_RelY, int a_RelZ);
void TickLeaves (int a_RelX, int a_RelY, int a_RelZ, MTRand & a_TickRandom);
/// Grows sugarcane by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking)
void GrowSugarcane (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks);

View File

@ -14,8 +14,6 @@
#include "cCraftingWindow.h"
#include "cItem.h"
#include "cTorch.h"
#include "cStairs.h"
#include "cStep.h"
#include "cDoors.h"
#include "cLadder.h"
#include "cVine.h"
@ -27,6 +25,8 @@
#include "cChatColor.h"
#include "cSocket.h"
#include "cTimer.h"
#include "items/Item.h"
#include "blocks/Block.h"
#include "cTracer.h"
#include "Vector3f.h"
@ -796,6 +796,11 @@ void cClientHandle::HandleBlockDig(cPacket_BlockDig * a_Packet)
m_Player->TossItem(false);
return;
}
if (a_Packet->m_Status == 0x05)
{
LOGINFO("BlockDig: Status 5 not implemented");
}
cWorld* World = m_Player->GetWorld();
BLOCKTYPE OldBlock = World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
@ -814,94 +819,35 @@ void cClientHandle::HandleBlockDig(cPacket_BlockDig * a_Packet)
((a_Packet->m_Status == 0x00) && (m_Player->GetGameMode() == 1))
);
if ((OldBlock == E_BLOCK_WOODEN_DOOR) && !bBroken)
{
cDoors::ChangeDoor(m_Player->GetWorld(), a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
}
cItem &Equipped = m_Player->GetInventory().GetEquippedItem();
cItemHandler *ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemID);
cItems PickupItems;
if (bBroken && !(m_Player->GetGameMode() == 1)) // broken
if(bBroken)
{
cBlockToPickup::ToPickup(OldBlock, OldMeta, m_Player->GetInventory().GetEquippedItem(), PickupItems);
ItemHandler->OnBlockDestroyed(World, m_Player, &Equipped, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
// Allow plugins to change the dropped objects:
cRoot::Get()->GetPluginManager()->CallHookBlockToPickup(OldBlock, OldMeta, m_Player, m_Player->GetInventory().GetEquippedItem(), PickupItems);
}
int pX = a_Packet->m_PosX;
unsigned char pY = a_Packet->m_PosY;
int pZ = a_Packet->m_PosZ;
BlockHandler(OldBlock)->OnDestroyedByPlayer(World, m_Player, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
World->DigBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
}else{
cBlockHandler *Handler = cBlockHandler::GetBlockHandler(OldBlock);
Handler->OnClick(World, m_Player, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
AddDirection(pX, pY, pZ, a_Packet->m_Direction);
ItemHandler->OnDiggingBlock(World, m_Player, &Equipped, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Direction);
char PossibleBlock = World->GetBlock(pX, pY, pZ);
//Check for clickthrough-blocks:
int pX = a_Packet->m_PosX;
unsigned char pY = a_Packet->m_PosY;
int pZ = a_Packet->m_PosZ;
AddDirection(pX, pY, pZ, a_Packet->m_Direction);
if (PossibleBlock == E_BLOCK_FIRE)
{
a_Packet->m_PosX = pX;
a_Packet->m_PosY = pY;
a_Packet->m_PosZ = pZ;
bBroken = true;
}
if (!bBroken)
{
return;
}
if (!World->DigBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ))
{
return;
}
World->SpawnItemPickups(PickupItems, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
switch (OldBlock)
{
case E_BLOCK_REDSTONE_TORCH_ON:
case E_BLOCK_REDSTONE_TORCH_OFF:
case E_BLOCK_REDSTONE_WIRE:
Handler = cBlockHandler::GetBlockHandler(World->GetBlock(pX, pY, pZ));
if(Handler->IsClickedThrough())
{
cRedstone Redstone(World);
Redstone.ChangeRedstone(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, false);
break;
Handler->OnClick(World, m_Player, pX, pY, pZ);
}
}
if ((OldBlock == E_BLOCK_PISTON) || (OldBlock == E_BLOCK_STICKY_PISTON))
{
int newX = a_Packet->m_PosX;
int newY = a_Packet->m_PosY;
int newZ = a_Packet->m_PosZ;
AddPistonDir(newX, newY, newZ, OldMeta & ~(8), 1);
if (World->GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION)
{
World->SetBlock(newX, newY, newZ, E_BLOCK_AIR, 0);
}
}
if (cDoors::IsDoor(OldBlock))
{
// Special actions for destroyed door (Destroy second part)
if (OldMeta & 8)
{
// Was upper part of door
if (cDoors::IsDoor(World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY - 1, a_Packet->m_PosZ)))
{
World->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY - 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0);
}
}
else
{
// Was lower part
if (cDoors::IsDoor(World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ)))
{
World->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0);
}
}
}
m_Player->UseEquippedItem();
}
@ -943,490 +889,85 @@ void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet)
}
return;
}
cWorld * World = m_Player->GetWorld();
//LOG("%i %i %i %i %i %i", a_Packet->m_Count, a_Packet->m_Direction, a_Packet->m_ItemType, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
//printf("Place Dir:%i %i %i %i : %i\n", a_Packet->m_Direction, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_ItemType);
// 'use' useable items instead of placing blocks
bool bPlaceBlock = true;
bool UpdateRedstone = false;
bool AddedCurrent = false;
if (a_Packet->m_Direction >= 0)
cBlockHandler *Handler = cBlockHandler::GetBlockHandler(World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ));
if(Handler->IsUseable())
{
cWorld * World = m_Player->GetWorld();
BLOCKTYPE BlockType = 0;
NIBBLETYPE BlockMeta;
World->GetBlockTypeMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, BlockType, BlockMeta);
switch (BlockType)
{
case E_BLOCK_REDSTONE_REPEATER_ON:
case E_BLOCK_REDSTONE_REPEATER_OFF:
{
// no need to update redstone current with a repeater
// Find meta value of repeater and change it to one step more:
World->FastSetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, BlockType, ((BlockMeta + 0x04) & 0x0f));
bPlaceBlock = false;
break;
}
case E_BLOCK_WORKBENCH:
{
bPlaceBlock = false;
cWindow* Window = new cCraftingWindow(0, true);
m_Player->OpenWindow(Window);
break;
}
case E_BLOCK_FURNACE:
case E_BLOCK_LIT_FURNACE:
case E_BLOCK_CHEST:
{
bPlaceBlock = false;
m_Player->GetWorld()->UseBlockEntity(m_Player, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
break;
}
case E_BLOCK_WOODEN_DOOR:
{
bPlaceBlock = false;
cDoors::ChangeDoor(m_Player->GetWorld(), a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
break;
}
default:
{
break;
}
} // switch (BlockID)
} // if (Direction >= 0)
// Some checks to see if it's a placeable item :P
if (bPlaceBlock)
{
cItem Item;
Item.m_ItemID = Equipped.m_ItemID;
Item.m_ItemCount = 1;
LOGD("Placing item of type %i at {%d, %d, %d}",
(int)a_Packet->m_ItemType,
a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ
);
if (m_Player->EatItem(Item.m_ItemID))
{
m_Player->GetInventory().RemoveItem(Item);
return;
}
Handler->OnClick(World, m_Player, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
}else{
cItemHandler *ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemID);
if (a_Packet->m_Direction < 0)
if(ItemHandler->OnItemUse(World, m_Player, &Equipped, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Direction))
{
// clicked in air
return;
}
bool isDoor = false;
//TODO: Wrong Blocks!
BLOCKTYPE ClickedBlock = m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
if (ItemCategory::IsHoe(Item.m_ItemID))
//Nothing here :P
}else if(ItemHandler->IsPlaceable())
{
if ((ClickedBlock == E_BLOCK_DIRT) || (ClickedBlock == E_BLOCK_GRASS))
if (a_Packet->m_Direction < 0)
{
m_Player->GetWorld()->FastSetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, E_BLOCK_FARMLAND, 0);
}
return;
}
NIBBLETYPE MetaData = (NIBBLETYPE)Equipped.m_ItemHealth; // This generally works for logs & planks, others will override
bool LavaBucket = false;
bool WaterBucket = false;
bool bRemoveItem = true;
bool bIgnoreCollision = false;
if (ClickedBlock == E_BLOCK_STEP)
{
// Only make double slab if meta values are the same and if player clicked either on top or on bottom of the block (direction either 0 or 1)
if (MetaData == ( m_Player->GetWorld()->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ) & 0x7) && a_Packet->m_Direction <= 1)
//if (MetaData == m_Player->GetWorld()->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ) && a_Packet->m_Direction == 1)
{
a_Packet->m_ItemType = E_BLOCK_DOUBLE_STEP;
if(a_Packet->m_Direction == 1)
{
a_Packet->m_PosY--;
}
else
{
a_Packet->m_PosY++;
}
bIgnoreCollision = true;
}
}
if ((ClickedBlock == E_BLOCK_SNOW) || (ClickedBlock == E_BLOCK_TALL_GRASS) || (ClickedBlock == E_BLOCK_VINES))
{
switch (a_Packet->m_Direction)
{
case 1:
a_Packet->m_PosY--;
break;
case 2:
a_Packet->m_PosZ++;
break;
case 3:
a_Packet->m_PosZ--;
break;
case 4:
a_Packet->m_PosX++;
break;
case 5:
a_Packet->m_PosX--;
break;
default: break;
}
bIgnoreCollision = true;
}
// Special handling for special items:
switch (a_Packet->m_ItemType)
{
case E_ITEM_BUCKET:
{
// TODO: Change this, it is just a small hack to get it working a little bit. seems like the Client sends the position from the first hitable block :s
ClickedBlock = (int)m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ);
LOG("Bucket Clicked BlockID: %d", ClickedBlock);
switch (ClickedBlock)
{
case E_BLOCK_WATER:
case E_BLOCK_STATIONARY_WATER:
{
WaterBucket = true;
break;
}
case E_BLOCK_LAVA:
case E_BLOCK_STATIONARY_LAVA:
{
LavaBucket = true;
break;
}
}
break;
} // case E_ITEM_BUCKET
case E_ITEM_LAVA_BUCKET:
{
if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item)))
{
a_Packet->m_ItemType = E_BLOCK_LAVA;
if (m_Player->GetGameMode() == 1)
{
break; //No new Bucket for creative players
}
cItem NewItem;
NewItem.m_ItemID = E_ITEM_BUCKET;
NewItem.m_ItemCount = 1;
m_Player->GetInventory().AddItem(NewItem);
}
break;
} // case E_ITEM_LAVA_BUCKET
case E_ITEM_WATER_BUCKET:
{
if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item)))
{
a_Packet->m_ItemType = E_BLOCK_WATER;
if (m_Player->GetGameMode() == 1)
{
break; //No new Bucket for creative players
}
cItem NewItem;
NewItem.m_ItemID = E_ITEM_BUCKET;
NewItem.m_ItemCount = 1;
m_Player->GetInventory().AddItem(NewItem);
}
break;
}
case E_BLOCK_TORCH:
{
MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction);
break;
}
case E_BLOCK_REDSTONE_TORCH_OFF:
{
MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction);
if (g_BlockTransparent[ (int)m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY+2, a_Packet->m_PosZ) ] == true)
{
//if block above is transparent
//printf("transparent above me\n");
}
else
{
//printf("transparent not above me\n");
}
UpdateRedstone = true;
AddedCurrent = false;
break;
}
case E_BLOCK_REDSTONE_TORCH_ON:
{
MetaData = cTorch::DirectionToMetaData(a_Packet->m_Direction);
UpdateRedstone = true;
AddedCurrent = true;
break;
}
case E_ITEM_REDSTONE_DUST:
{
MetaData = 0;
a_Packet->m_ItemType = E_BLOCK_REDSTONE_WIRE;
UpdateRedstone = true;
AddedCurrent = false;
break;
}
case E_ITEM_REDSTONE_REPEATER:
{
MetaData = cRedstone::RepeaterRotationToMetaData(m_Player->GetRotation());
a_Packet->m_ItemType = E_BLOCK_REDSTONE_REPEATER_OFF;
UpdateRedstone = true;
AddedCurrent = false;
break;
}
case E_BLOCK_PISTON:
case E_BLOCK_STICKY_PISTON:
{
MetaData = cPiston::RotationPitchToMetaData(m_Player->GetRotation(), m_Player->GetPitch());
UpdateRedstone = true;
AddedCurrent = false;
break;
}
case E_ITEM_IRON_DOOR:
{
a_Packet->m_ItemType = E_BLOCK_IRON_DOOR;
MetaData = cDoors::RotationToMetaData(m_Player->GetRotation());
isDoor = true;
break;
}
case E_ITEM_WOODEN_DOOR:
{
a_Packet->m_ItemType = E_BLOCK_WOODEN_DOOR;
MetaData = cDoors::RotationToMetaData(m_Player->GetRotation());
isDoor = true;
break;
}
case E_BLOCK_CHEST:
case E_BLOCK_FURNACE:
case E_BLOCK_DISPENSER:
{
MetaData = cPiston::RotationPitchToMetaData(m_Player->GetRotation(), 0); // Same orientation as pistons, just ignore pitch
break;
}
case E_BLOCK_STEP:
{
MetaData += cStep::DirectionToMetaData( a_Packet->m_Direction );
break;
}
case E_BLOCK_COBBLESTONE_STAIRS:
case E_BLOCK_BRICK_STAIRS:
case E_BLOCK_STONE_BRICK_STAIRS:
case E_BLOCK_NETHER_BRICK_STAIRS:
case E_BLOCK_WOODEN_STAIRS:
{
MetaData = cStairs::RotationToMetaData(m_Player->GetRotation(), a_Packet->m_Direction);
break;
}
case E_BLOCK_VINES:
{
MetaData = cVine::DirectionToMetaData(a_Packet->m_Direction);
break;
}
case E_BLOCK_LADDER:
{
MetaData = cLadder::DirectionToMetaData(a_Packet->m_Direction);
break;
}
case E_ITEM_SIGN:
{
LOGD("Sign Dir: %i", a_Packet->m_Direction);
if (a_Packet->m_Direction == 1)
{
LOGD("Player Rotation: %f", m_Player->GetRotation());
MetaData = cSign::RotationToMetaData(m_Player->GetRotation());
LOGD("Sign rotation %i", MetaData);
a_Packet->m_ItemType = E_BLOCK_SIGN_POST;
}
else
{
MetaData = cSign::DirectionToMetaData(a_Packet->m_Direction);
a_Packet->m_ItemType = E_BLOCK_WALLSIGN;
}
break;
}
case E_ITEM_FLINT_AND_STEEL:
{
a_Packet->m_ItemType = E_ITEM_FIRE;
m_Player->UseEquippedItem();
bRemoveItem = false;
break;
}
case E_BLOCK_LEAVES:
{
MetaData += 0x4;
break;
}
case E_ITEM_SEEDS:
{
if (ClickedBlock != E_BLOCK_FARMLAND)
{
return;
}
a_Packet->m_ItemType = E_BLOCK_CROPS;
break;
}
case E_ITEM_MELON_SEEDS:
{
if (ClickedBlock != E_BLOCK_FARMLAND)
{
return;
}
a_Packet->m_ItemType = E_BLOCK_MELON_STEM;
break;
}
case E_ITEM_PUMPKIN_SEEDS:
{
if (ClickedBlock != E_BLOCK_FARMLAND)
{
return;
}
a_Packet->m_ItemType = E_BLOCK_PUMPKIN_STEM;
break;
}
case E_ITEM_DYE:
{
// Handle bonemeal and dyes on sheep
if (HandleDyes(a_Packet))
{
if (m_Player->GetGameMode() == eGameMode_Survival)
{
m_Player->GetInventory().RemoveItem(Item);
}
return;
}
break;
}
case E_ITEM_SUGARCANE:
{
a_Packet->m_ItemType = E_BLOCK_SUGARCANE;
break;
}
default:
{
break;
}
} // switch (a_Packet->m_ItemType)
if (LavaBucket)
{
if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item))) {
cItem NewItem;
NewItem.m_ItemID = E_ITEM_LAVA_BUCKET;
NewItem.m_ItemCount = 1;
m_Player->GetInventory().AddItem(NewItem);
m_Player->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0);
}
}
else if (WaterBucket)
{
if ((m_Player->GetGameMode() == 1) || (m_Player->GetInventory().RemoveItem(Item)))
{
cItem NewItem;
NewItem.m_ItemID = E_ITEM_WATER_BUCKET;
NewItem.m_ItemCount = 1;
m_Player->GetInventory().AddItem(NewItem);
m_Player->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, E_BLOCK_AIR, 0);
}
}
else if (IsValidBlock(a_Packet->m_ItemType))
{
int X = a_Packet->m_PosX;
int Y = a_Packet->m_PosY;
int Z = a_Packet->m_PosZ;
AddDirection(X, Y, Z, a_Packet->m_Direction);
int PlaceBlock = m_Player->GetWorld()->GetBlock(X, Y, Z);
if (
(PlaceBlock != E_BLOCK_AIR)
&& (PlaceBlock != E_BLOCK_WATER)
&& (PlaceBlock != E_BLOCK_STATIONARY_WATER)
&& (PlaceBlock != E_BLOCK_LAVA)
&& (PlaceBlock != E_BLOCK_STATIONARY_LAVA)
&& !bIgnoreCollision
)
{
//tried to place a block *into* another?
return; // happens when you place a block aiming at side of block like torch or stem
}
// Check whether selected item is allowed to be placed on specific surface
if (!m_Player->GetWorld()->IsPlacingItemLegal(a_Packet->m_ItemType, X, Y, Z))
{
// If we don't send the block, MC is happy placing cacti underwater:
m_Player->GetWorld()->SendBlockTo(X, Y, Z, m_Player);
// clicked in air
return;
}
if (bRemoveItem)
int X = a_Packet->m_PosX;
int Y = a_Packet->m_PosY;
int Z = a_Packet->m_PosZ;
char Dir = a_Packet->m_Direction;
BLOCKTYPE ClickedBlock = World->GetBlock(X, Y, Z);
cBlockHandler *Handler = cBlockHandler::GetBlockHandler(ClickedBlock);
if(Handler->IgnoreBuildCollision())
{
if ((m_Player->GetGameMode() != 1) && !m_Player->GetInventory().RemoveItem(Item))
Handler->OnDestroyedByPlayer(World, m_Player, X, Y, Z);
World->FastSetBlock(X, Y, Z, E_BLOCK_AIR, 0);
}else{
AddDirection(X, Y, Z, a_Packet->m_Direction);
//Check for Blocks not allowing placement on top
if(Dir == 1 && !Handler->AllowBlockOnTop())
{
//Resend the old block
//Some times the client still places the block O.o
World->SendBlockTo(X, Y, Z, m_Player);
return;
}
}
if (isDoor)
{
if ((m_Player->GetWorld()->GetBlock(X, Y + 1, Z) == E_BLOCK_AIR) || (m_Player->GetWorld()->GetBlock(X, Y + 1, Z) == E_BLOCK_AIR))
int PlaceBlock = m_Player->GetWorld()->GetBlock(X, Y, Z);
if (!BlockHandler(PlaceBlock)->IgnoreBuildCollision())
{
m_Player->GetWorld()->SetBlock(X, Y + 1, Z, (char)a_Packet->m_ItemType, MetaData + 8);
m_Player->GetWorld()->SetBlock(X, Y, Z, (char)a_Packet->m_ItemType, MetaData);
//tried to place a block *into* another?
return; // happens when you place a block aiming at side of block like torch or stem
}
}
else
{
m_Player->GetWorld()->SetBlock(X, Y, Z, (char)a_Packet->m_ItemType, MetaData);
}
cBlockHandler *NewBlock = BlockHandler(ItemHandler->GetBlockType());
if (UpdateRedstone)
//cannot be placed on the side of an other block
if(Dir != 1 && !NewBlock->CanBePlacedOnSide())
return;
if(NewBlock->CanBeAt(World, X, Y, Z))
{
cRedstone Redstone(m_Player->GetWorld());
Redstone.ChangeRedstone(a_Packet->m_PosX, a_Packet->m_PosY + 1, a_Packet->m_PosZ, AddedCurrent);
ItemHandler->PlaceBlock(World, m_Player, &m_Player->GetInventory().GetEquippedItem(), X, Y, Z, a_Packet->m_Direction);
}else{
World->SendBlockTo(X, Y, Z, m_Player); //Send the old block back to the player
return;
}
} else if(ItemHandler->IsFood()) {
cItem Item;
Item.m_ItemID = Equipped.m_ItemID;
Item.m_ItemCount = 1;
if (m_Player->EatItem(Item.m_ItemID))
{
ItemHandler->OnFoodEaten(World, m_Player, &Item);
m_Player->GetInventory().RemoveItem(Item);
return;
}
}
}
/*
// FakeTruth's "magic stick of removal" :D
// TODO: Turn this into a plugin
if (m_Username.compare("FakeTruth") == 0)
{
if (a_Packet->m_ItemType == 280)
{
cRoot::Get()->GetWorld()->SetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, 0, 0);
}
}
*/
}
@ -1624,29 +1165,6 @@ void cClientHandle::HandleKeepAlive(cPacket_KeepAlive * a_Packet)
}
bool cClientHandle::HandleDyes(cPacket_BlockPlace * a_Packet)
{
cItem & Equipped = m_Player->GetInventory().GetEquippedItem();
// TODO: Handle coloring the sheep, too
// Handle growing the plants:
if (Equipped.m_ItemHealth == E_META_DYE_WHITE)
{
cWorld * World = m_Player->GetWorld();
return World->GrowPlant(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, true);
}
return false;
}
bool cClientHandle::CheckBlockInteractionsRate(void)
{
ASSERT(m_Player != NULL);

View File

@ -9,7 +9,7 @@
#include "BlockID.h"
#include "Defines.h"
#include "cItem.h"
#include "cBlockToPickup.h"
#include "blocks/Block.h"
@ -356,9 +356,11 @@ void cFluidSimulator::Simulate( float a_Dt )
{
if( bWashedAwayItem )
{
cItems Drops;
cBlockToPickup::ToPickup(DownID, m_World->GetBlockMeta(pos.x, pos.y - 1, pos.z), E_ITEM_EMPTY, Drops);
m_World->SpawnItemPickups(Drops, pos.x, pos.y - 1, pos.z);
cBlockHandler * Handler = BlockHandler(DownID);
if(Handler->DropOnUnsuitable())
{
Handler->DropBlock(m_World, pos.x, pos.y - 1, pos.z);
}
}
if (pos.y > 0)
{
@ -390,9 +392,11 @@ void cFluidSimulator::Simulate( float a_Dt )
{
if (bWashedAwayItem)
{
cItems Drops;
cBlockToPickup::ToPickup(DownID, m_World->GetBlockMeta(p.x, p.y, p.z), E_ITEM_EMPTY, Drops);
m_World->SpawnItemPickups(Drops, p.x, p.y, p.z);
cBlockHandler * Handler = BlockHandler(DownID);
if(Handler->DropOnUnsuitable())
{
Handler->DropBlock(m_World, p.x, p.y, p.z);
}
}
if( p.y == pos.y )

View File

@ -13,6 +13,7 @@
#include "BlockID.h"
#include "packets/cPacket_BlockAction.h"
#include "cServer.h"
#include "blocks/Block.h"
extern bool g_BlockPistonBreakable[];
@ -67,9 +68,11 @@ void cPiston::ExtendPiston( int pistx, int pisty, int pistz )
NIBBLETYPE currMeta = m_World->GetBlockMeta(pistx, pisty, pistz);
if (currBlock != E_BLOCK_AIR)
{
cItems PickupItems;
cBlockToPickup::ToPickup(currBlock, currMeta, E_ITEM_EMPTY, PickupItems);
m_World->SpawnItemPickups(PickupItems, pistx, pisty, pistz);
cBlockHandler * Handler = BlockHandler(currBlock);
if(Handler->DropOnUnsuitable())
{
Handler->DropBlock(m_World, pistx, pisty, pistz);
}
recalc = true;
}
int oldx = pistx, oldy = pisty, oldz = pistz;

View File

@ -20,8 +20,8 @@ public:
static char RotationPitchToMetaData( float a_Rotation, float a_Pitch )
{
LOG("pre:a_Rotation %f \n",a_Rotation);
LOG("a_Pitch %f \n",a_Pitch);
LOGD("pre:a_Rotation %f \n",a_Rotation);
LOGD("a_Pitch %f \n",a_Pitch);
if (a_Pitch >= 50.f ){
return 0x1;

View File

@ -14,6 +14,10 @@
#include "cThread.h"
#include "cFileFormatUpdater.h"
#include "cRedstone.h"
#include "blocks/Block.h"
#include "items/Item.h"
#include "squirrelbindings/SquirrelFunctions.h"
#include "squirrelbindings/SquirrelBindings.h"
#include "../iniFile/iniFile.h"
@ -168,6 +172,11 @@ void cRoot::Start()
m_Authenticator.Stop();
LOG("Stopping plugin manager...");
delete m_PluginManager; m_PluginManager = 0; // This should be first
#if USE_SQUIRREL
CloseSquirrelVM();
#endif
LOG("Freeing MonsterConfig...");
delete m_MonsterConfig; m_MonsterConfig = 0;
LOG("Stopping WebAdmin...");
@ -179,6 +188,10 @@ void cRoot::Start()
delete m_GroupManager; m_GroupManager = 0;
LOG("Unloading worlds...");
UnloadWorlds();
cItemHandler::Deinit();
cBlockHandler::Deinit();
LOG("Destroying server...");
//delete HeartBeat; HeartBeat = 0;
delete m_Server; m_Server = 0;

View File

@ -1,15 +0,0 @@
#pragma once
class cStep //tolua_export
{ //tolua_export
public:
static char DirectionToMetaData( int a_Direction ) //tolua_export
{ //tolua_export
char result = 0x0;
if( a_Direction == 0)
{
result = 0x8;
}
return result;
} //tolua_export
}; //tolua_export

View File

@ -42,6 +42,7 @@
#include "cTracer.h"
#include "Trees.h"
#include "cPluginManager.h"
#include "blocks/Block.h"
#include "packets/cPacket_TimeUpdate.h"
@ -288,6 +289,10 @@ cWorld::cWorld( const AString & a_WorldName )
m_LastSave = 0;
m_LastUnload = 0;
//preallocate some memory for ticking blocks so we don´t need to allocate that often
m_BlockTickQueue.reserve(1000);
m_BlockTickQueueCopy.reserve(1000);
//Simulators:
m_WaterSimulator = new cWaterSimulator( this );
m_LavaSimulator = new cLavaSimulator( this );
@ -355,94 +360,11 @@ void cWorld::CastThunderbolt ( int a_X, int a_Y, int a_Z )
BroadcastToChunkOfBlock(a_X, a_Y, a_Z, &ThunderboltPacket);
}
bool cWorld::IsPlacingItemLegal(Int16 a_ItemType, int a_BlockX, int a_BlockY, int a_BlockZ)
{
BLOCKTYPE SurfaceBlock = GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ);
switch (a_ItemType)
{
case E_BLOCK_YELLOW_FLOWER: // Can ONLY be placed on dirt/grass
case E_BLOCK_RED_ROSE:
case E_BLOCK_SAPLING:
{
switch (SurfaceBlock)
{
case E_BLOCK_DIRT:
case E_BLOCK_GRASS:
case E_BLOCK_FARMLAND:
{
return true;
}
}
return false;
}
case E_BLOCK_BROWN_MUSHROOM: // Can be placed on pretty much anything, with exceptions
case E_BLOCK_RED_MUSHROOM:
{
switch (SurfaceBlock)
{
case E_BLOCK_GLASS:
case E_BLOCK_YELLOW_FLOWER:
case E_BLOCK_RED_ROSE:
case E_BLOCK_BROWN_MUSHROOM:
case E_BLOCK_RED_MUSHROOM:
case E_BLOCK_CACTUS:
{
return false;
}
}
return true;
}
case E_BLOCK_CACTUS:
{
if ((SurfaceBlock != E_BLOCK_SAND) && (SurfaceBlock != E_BLOCK_CACTUS))
{
// Cactus can only be placed on sand and itself
return false;
}
// Check surroundings. Cacti may ONLY be surrounded by air
if (
(GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) != E_BLOCK_AIR) ||
(GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) != E_BLOCK_AIR) ||
(GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) != E_BLOCK_AIR) ||
(GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) != E_BLOCK_AIR)
)
{
return false;
}
return true;
}
case E_ITEM_SEEDS:
case E_ITEM_MELON_SEEDS:
case E_ITEM_PUMPKIN_SEEDS:
{
// Seeds can go only on the farmland block:
return (SurfaceBlock == E_BLOCK_FARMLAND);
}
} // switch (a_Packet->m_ItemType)
return true;
}
void cWorld::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ)
{
return m_ChunkMap->SetNextBlockTick(a_BlockX, a_BlockY, a_BlockZ);
}
void cWorld::InitializeSpawn(void)
{
int ChunkX = 0, ChunkY = 0, ChunkZ = 0;
@ -555,6 +477,8 @@ void cWorld::Tick(float a_Dt)
}
m_ChunkMap->Tick(a_Dt, m_TickRand);
TickQueuedBlocks(a_Dt);
GetSimulatorManager()->Simulate(a_Dt);
@ -1110,9 +1034,14 @@ int cWorld::GetBiomeAt (int a_BlockX, int a_BlockZ)
void cWorld::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta )
{
if(a_BlockType == E_BLOCK_AIR)
{
BlockHandler(GetBlock(a_X, a_Y, a_Z))->OnDestroyed(this, a_X, a_Y, a_Z);
}
m_ChunkMap->SetBlock(a_X, a_Y, a_Z, a_BlockType, a_BlockMeta);
GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z);
BlockHandler(a_BlockType)->OnPlaced(this, a_X, a_Y, a_Z, a_BlockMeta);
}
@ -1264,6 +1193,8 @@ bool cWorld::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure)
bool cWorld::DigBlock( int a_X, int a_Y, int a_Z)
{
cBlockHandler *Handler = cBlockHandler::GetBlockHandler(GetBlock(a_X, a_Y, a_Z));
Handler->OnDestroyed(this, a_X, a_Y, a_Z);
return m_ChunkMap->DigBlock(a_X, a_Y, a_Z);
}
@ -1902,3 +1833,45 @@ void cWorld::GetChunkStats(int & a_NumValid, int & a_NumDirty, int & a_NumInLigh
void cWorld::TickQueuedBlocks(float a_Dt)
{
if(m_BlockTickQueue.empty())
return;
m_BlockTickQueueCopy.clear();
m_BlockTickQueue.swap(m_BlockTickQueueCopy);
for(std::vector<BlockTickQueueItem *>::iterator itr = m_BlockTickQueueCopy.begin(); itr != m_BlockTickQueueCopy.end(); itr++)
{
BlockTickQueueItem *Block = (*itr);
Block->ToWait -= a_Dt;
if(Block->ToWait <= 0)
{
BlockHandler(GetBlock(Block->X, Block->Y, Block->Z))->OnUpdate(this, Block->X, Block->Y, Block->Z);
delete Block; //We don´t have to remove it from the vector, this will happen automatically on the next tick
}else{
m_BlockTickQueue.push_back(Block); //Keep the block in the queue
}
}
}
void cWorld::QueueBlockForTick(int a_X, int a_Y, int a_Z, float a_Time)
{
BlockTickQueueItem *Block = new BlockTickQueueItem;
Block->X = a_X;
Block->Y = a_Y;
Block->Z = a_Z;
Block->ToWait = a_Time;
m_BlockTickQueue.push_back(Block);
}
bool cWorld::IsBlockDirectlyWatered(int a_X, int a_Y, int a_Z)
{
return IsBlockWater(GetBlock(a_X - 1, a_Y, a_Z))
|| IsBlockWater(GetBlock(a_X + 1, a_Y, a_Z))
|| IsBlockWater(GetBlock(a_X, a_Y, a_Z - 1))
|| IsBlockWater(GetBlock(a_X, a_Y, a_Z + 1));
}

View File

@ -54,6 +54,7 @@ typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
class cWorld //tolua_export
{ //tolua_export
public:
@ -330,6 +331,17 @@ public:
/// Stops threads that belong to this world (part of deinit)
void StopThreads(void);
void TickQueuedBlocks(float a_Dt);
struct BlockTickQueueItem
{
int X;
int Y;
int Z;
float ToWait;
};
void QueueBlockForTick(int a_X, int a_Y, int a_Z, float a_Time);
void CastThunderbolt (int a_X, int a_Y, int a_Z); //tolua_export
void SetWeather ( eWeather a_Weather ); //tolua_export
@ -339,14 +351,14 @@ public:
cChunkGenerator & GetGenerator(void) { return m_Generator; }
cWorldStorage & GetStorage (void) { return m_Storage; }
cChunkMap * GetChunkMap (void) { return m_ChunkMap; }
bool IsPlacingItemLegal(Int16 a_ItemType, int a_BlockX, int a_BlockY, int a_BlockZ);
/// Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call
void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export
int GetMaxSugarcaneHeight(void) const { return m_MaxSugarcaneHeight; } // tolua_export
int GetMaxCactusHeight (void) const { return m_MaxCactusHeight; } // tolua_export
bool IsBlockDirectlyWatered(int a_X, int a_Y, int a_Z);
private:
@ -370,6 +382,9 @@ private:
// The cRedstone class simulates redstone and needs access to m_RSList
friend class cRedstone;
std::vector<int> m_RSList;
std::vector<BlockTickQueueItem *> m_BlockTickQueue;
std::vector<BlockTickQueueItem *> m_BlockTickQueueCopy; //Second is for safely removing the objects from the queue
cSimulatorManager * m_SimulatorManager;
cSandSimulator * m_SandSimulator;

224
source/items/Item.cpp Normal file
View File

@ -0,0 +1,224 @@
#include "Globals.h"
#include "Item.h"
#include "../cItem.h"
#include "../cWorld.h"
#include "../cPlayer.h"
//Handler
#include "ItemCloth.h"
#include "ItemHoe.h"
#include "ItemSlab.h"
#include "ItemWood.h"
#include "ItemShears.h"
#include "ItemLeaves.h"
#include "ItemSapling.h"
#include "ItemBucket.h"
#include "ItemLighter.h"
#include "ItemRedstoneDust.h"
#include "ItemSeeds.h"
#include "ItemDye.h"
#include "ItemSugarcane.h"
#include "ItemPickaxe.h"
#include "ItemShovel.h"
#include "ItemSword.h"
#include "ItemDoor.h"
#include "../blocks/Block.h"
bool cItemHandler::m_HandlerInitialized = false;
cItemHandler *cItemHandler::m_ItemHandler[2266];
cItemHandler *cItemHandler::GetItemHandler(int a_ItemID)
{
if(a_ItemID < 0) a_ItemID = 0;
if(!m_HandlerInitialized)
{ //We have to initialize
memset(m_ItemHandler, 0, sizeof(m_ItemHandler));
m_HandlerInitialized = true;
}
if(m_ItemHandler[a_ItemID])
return m_ItemHandler[a_ItemID];
m_ItemHandler[a_ItemID] = CreateItemHandler(a_ItemID);
return m_ItemHandler[a_ItemID];
}
cItemHandler *cItemHandler::CreateItemHandler(int a_ItemID)
{
switch(a_ItemID)
{
case E_ITEM_WOODEN_HOE:
case E_ITEM_STONE_HOE:
case E_ITEM_IRON_HOE:
case E_ITEM_GOLD_HOE:
case E_ITEM_DIAMOND_HOE:
return new cItemHoeHandler(a_ItemID);
case E_ITEM_WHITE_CLOTH:
return new cItemClothHandler(a_ItemID);
case E_ITEM_STONE_SLAB:
case E_ITEM_WOODEN_SLAB:
return new cItemSlabHandler(a_ItemID);
case E_ITEM_LOG:
case E_ITEM_WOOD:
return new cItemWoodHandler(a_ItemID);
case E_ITEM_SHEARS:
return new cItemShearsHandler(a_ItemID);
case E_ITEM_LEAVES:
return new cItemLeavesHandler(a_ItemID);
case E_ITEM_SAPLING:
return new cItemSaplingHandler(a_ItemID);
case E_ITEM_REDSTONE_DUST:
return new cItemRedstoneDustHandler(a_ItemID);
case E_ITEM_BUCKET:
case E_ITEM_WATER_BUCKET:
case E_ITEM_LAVA_BUCKET:
return new cItemBucketHandler(a_ItemID);
case E_ITEM_FLINT_AND_STEEL:
return new cItemLighterHandler(a_ItemID);
case E_ITEM_PUMPKIN_SEEDS:
case E_ITEM_MELON_SEEDS:
case E_ITEM_SEEDS:
return new cItemSeedsHandler(a_ItemID);
case E_ITEM_DYE:
return new cItemDyeHandler(a_ItemID);
case E_ITEM_SUGARCANE:
return new cItemSugarcaneHandler(a_ItemID);
case E_ITEM_WOODEN_PICKAXE:
case E_ITEM_STONE_PICKAXE:
case E_ITEM_IRON_PICKAXE:
case E_ITEM_GOLD_PICKAXE:
case E_ITEM_DIAMOND_PICKAXE:
return new cItemPickaxeHandler(a_ItemID);
case E_ITEM_WOODEN_SHOVEL:
case E_ITEM_STONE_SHOVEL:
case E_ITEM_IRON_SHOVEL:
case E_ITEM_GOLD_SHOVEL:
case E_ITEM_DIAMOND_SHOVEL:
return new cItemShovelHandler(a_ItemID);
case E_ITEM_WOODEN_SWORD:
case E_ITEM_STONE_SWORD:
case E_ITEM_IRON_SWORD:
case E_ITEM_GOLD_SWORD:
case E_ITEM_DIAMOND_SWORD:
return new cItemSwordHandler(a_ItemID);
case E_ITEM_IRON_DOOR:
case E_ITEM_WOODEN_DOOR:
return new cItemDoorHandler(a_ItemID);
default:
return new cItemHandler(a_ItemID);
break;
}
}
void cItemHandler::Deinit()
{
for(int i = 0; i < 2266; i++)
{
delete m_ItemHandler[i];
}
}
cItemHandler::cItemHandler(int a_ItemID)
{
m_ItemID = a_ItemID;
}
bool cItemHandler::OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir)
{
return false;
}
bool cItemHandler::OnDiggingBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir)
{
return false;
}
void cItemHandler::OnBlockDestroyed(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z)
{
char Block = a_World->GetBlock(a_X, a_Y, a_Z);
cBlockHandler *Handler = cBlockHandler::GetBlockHandler(Block);
if(a_Player->GetGameMode() == eGameMode_Survival)
{
if(!BlockRequiresSpecialTool(Block) || CanHarvestBlock(Block))
{
Handler->DropBlock(a_World, a_X, a_Y, a_Z);
}
}
a_Player->UseEquippedItem();
}
void cItemHandler::OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item)
{
}
int cItemHandler::GetMaxStackSize()
{
return 64;
}
int cItemHandler::GetMaxDamage()
{
return 0;
}
bool cItemHandler::IsTool()
{
return
(m_ItemID >= 256 && m_ItemID <= 259)
|| (m_ItemID == 261)
|| (m_ItemID >= 267 && m_ItemID <= 279)
|| (m_ItemID >= 283 && m_ItemID <= 286)
|| (m_ItemID >= 290 && m_ItemID <= 294)
|| (m_ItemID >= 256 && m_ItemID <= 259)
|| (m_ItemID == 325)
|| (m_ItemID == 346);
}
bool cItemHandler::IsFood()
{
return
(m_ItemID == 260)
|| (m_ItemID == 282)
|| (m_ItemID == 297)
|| (m_ItemID >= 319 && m_ItemID <= 320)
|| (m_ItemID == 335)
|| (m_ItemID >= 349 && m_ItemID <= 350)
|| (m_ItemID == 357)
|| (m_ItemID == 360)
|| (m_ItemID >= 363 && m_ItemID <= 366);
}
bool cItemHandler::IsPlaceable()
{
return m_ItemID >= 1 && m_ItemID <= 136;
}
bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockID)
{
return false;
}
BLOCKTYPE cItemHandler::GetBlockType()
{
return m_ItemID;
}
char cItemHandler::GetBlockMeta(char a_ItemMeta)
{
return a_ItemMeta; //This keeps most textures. The few other items have to override this
}
void cItemHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir)
{
BLOCKTYPE Block = GetBlockType();
cBlockHandler *Handler = cBlockHandler::GetBlockHandler(Block);
Handler->PlaceBlock(a_World, a_Player, GetBlockMeta(a_Item->m_ItemHealth), a_X, a_Y, a_Z, a_Dir);
if(a_Player->GetGameMode() == eGameMode_Survival)
a_Player->GetInventory().RemoveItem(cItem(a_Item->m_ItemID, 1));
}

45
source/items/Item.h Normal file
View File

@ -0,0 +1,45 @@
#pragma once
#include "../Defines.h"
class cWorld;
class cPlayer;
class cItemHandler
{
public:
cItemHandler(int a_ItemID);
virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir); //eg for fishing or hoes
virtual bool OnDiggingBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir);
virtual void OnBlockDestroyed(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z);
virtual void OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item);
virtual int GetMaxStackSize();
virtual int GetMaxDamage();
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir);
virtual bool IsTool();
virtual bool IsFood();
//Blocks simply get placed
virtual bool IsPlaceable();
virtual BLOCKTYPE GetBlockType();
virtual char GetBlockMeta(char a_ItemMeta);
virtual bool CanHarvestBlock(BLOCKTYPE a_BlockID);
static cItemHandler *GetItemHandler(int a_ItemID);
static void Deinit();
protected:
int m_ItemID;
static cItemHandler *CreateItemHandler(int m_ItemID);
static cItemHandler *m_ItemHandler[2266];
static bool m_HandlerInitialized; //used to detect if the itemhandlers are initialized
};
//Short function
inline cItemHandler *ItemHandler(int a_ItemID) { return cItemHandler::GetItemHandler(a_ItemID); }

75
source/items/ItemBucket.h Normal file
View File

@ -0,0 +1,75 @@
#pragma once
#include "Item.h"
#include "../cWorld.h"
class cItemBucketHandler : public cItemHandler
{
public:
cItemBucketHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir)
{
switch(m_ItemID)
{
case E_ITEM_BUCKET:
{
AddDirection(a_X, a_Y, a_Z, a_Dir);
BLOCKTYPE ClickedBlock = a_World->GetBlock(a_X, a_Y, a_Z);
LOG("Bucket Clicked BlockID: %d", ClickedBlock);
ENUM_ITEM_ID NewItem = E_ITEM_EMPTY;
switch (ClickedBlock)
{
case E_BLOCK_WATER:
case E_BLOCK_STATIONARY_WATER:
NewItem = E_ITEM_WATER_BUCKET;
break;
case E_BLOCK_LAVA:
case E_BLOCK_STATIONARY_LAVA:
NewItem = E_ITEM_LAVA_BUCKET;
break;
}
if (NewItem != E_ITEM_EMPTY
&& (a_Player->GetGameMode() == 1 || (a_Player->GetInventory().RemoveItem(cItem(a_Item->m_ItemID, 1)))))
{
//Give New Bucket
a_Player->GetInventory().AddItem(cItem(NewItem, 1));
//remove water block
a_Player->GetWorld()->SetBlock(a_X, a_Y, a_Z, E_BLOCK_AIR, 0);
return true;
}
}
break;
case E_ITEM_WATER_BUCKET:
case E_ITEM_LAVA_BUCKET:
{
BLOCKTYPE NewBlock = (m_ItemID == E_ITEM_LAVA_BUCKET) ? E_BLOCK_LAVA : E_BLOCK_WATER;
AddDirection(a_X, a_Y, a_Z, a_Dir);
if(a_World->GetBlock(a_X, a_Y, a_Z) == E_BLOCK_AIR)
{
if ((a_Player->GetGameMode() == 1) || (a_Player->GetInventory().RemoveItem(cItem(a_Item->m_ItemID, 1))))
{
a_World->SetBlock(a_X, a_Y, a_Z, NewBlock, 0);
if (a_Player->GetGameMode() == 1)
{
break; //No new Bucket for creative players
}
a_Player->GetInventory().AddItem(cItem(E_ITEM_BUCKET, 1));
return true;
}
}
}
break;
}
return false;
}
};

18
source/items/ItemCloth.h Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include "Item.h"
class cItemClothHandler : public cItemHandler
{
public:
cItemClothHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual char GetBlockMeta(char a_ItemMeta)
{
return a_ItemMeta;
}
};

25
source/items/ItemDoor.h Normal file
View File

@ -0,0 +1,25 @@
#pragma once
#include "Item.h"
#include "../cWorld.h"
class cItemDoorHandler : public cItemHandler
{
public:
cItemDoorHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual bool IsPlaceable()
{
return true;
}
virtual BLOCKTYPE GetBlockType()
{
return (m_ItemID == E_ITEM_WOODEN_DOOR) ? E_BLOCK_WOODEN_DOOR : E_BLOCK_IRON_DOOR;
}
};

32
source/items/ItemDye.h Normal file
View File

@ -0,0 +1,32 @@
#pragma once
#include "Item.h"
#include "../cWorld.h"
#include "../cPlayer.h"
class cItemDyeHandler : public cItemHandler
{
public:
cItemDyeHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir)
{
// TODO: Handle coloring the sheep, too (OnItemUseOnEntity maybe)
// Handle growing the plants:
if (a_Item->m_ItemHealth == E_META_DYE_WHITE)
{
if(a_World->GrowPlant(a_X, a_Y, a_Z, true))
{
if (a_Player->GetGameMode() == eGameMode_Survival)
{
a_Player->GetInventory().RemoveItem(cItem(a_Item->m_ItemID, 1, a_Item->m_ItemHealth));
return true;
}
}
}
return false;
}
};

29
source/items/ItemHoe.h Normal file
View File

@ -0,0 +1,29 @@
#pragma once
#include "Item.h"
#include "../cWorld.h"
#include "../cPlayer.h"
class cItemHoeHandler : public cItemHandler
{
public:
cItemHoeHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir)
{
BLOCKTYPE Block = a_World->GetBlock(a_X, a_Y, a_Z);
if(Block == E_BLOCK_DIRT || Block == E_BLOCK_GRASS)
{
a_World->FastSetBlock(a_X, a_Y, a_Z, E_BLOCK_FARMLAND, 0);
a_Player->UseEquippedItem();
return true;
}
return false;
}
};

17
source/items/ItemLeaves.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include "Item.h"
class cItemLeavesHandler : public cItemHandler
{
public:
cItemLeavesHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual char GetBlockMeta(char a_ItemMeta)
{
return a_ItemMeta | 0x4; //0x4 bit set means this is a player places leave
}
};

View File

@ -0,0 +1,27 @@
#pragma once
#include "Item.h"
#include "../cWorld.h"
#include "../cPlayer.h"
class cItemLighterHandler : public cItemHandler
{
public:
cItemLighterHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir)
{
a_Player->UseEquippedItem();
AddDirection(a_X, a_Y, a_Z, a_Dir);
a_World->SetBlock(a_X, a_Y, a_Z, E_BLOCK_FIRE, 0); //0 -> new fire TODO: Make Firesimulator use this
return false;
}
};

View File

@ -0,0 +1,72 @@
#pragma once
#include "Item.h"
#include "../cWorld.h"
#include "../cPlayer.h"
class cItemPickaxeHandler : public cItemHandler
{
public:
cItemPickaxeHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
char PickaxeLevel()
{
switch(m_ItemID)
{
case E_ITEM_WOODEN_PICKAXE:
case E_ITEM_GOLD_PICKAXE:
return 1;
case E_ITEM_STONE_PICKAXE:
return 2;
case E_ITEM_IRON_PICKAXE:
return 3;
case E_ITEM_DIAMOND_PICKAXE:
return 4;
default:
return 0;
}
}
virtual bool CanHarvestBlock(BLOCKTYPE a_BlockID)
{
switch(a_BlockID)
{
case E_BLOCK_OBSIDIAN:
return PickaxeLevel() >= 4;
case E_BLOCK_DIAMOND_BLOCK:
case E_BLOCK_DIAMOND_ORE:
case E_BLOCK_GOLD_BLOCK:
case E_BLOCK_GOLD_ORE:
case E_BLOCK_REDSTONE_ORE:
case E_BLOCK_REDSTONE_ORE_GLOWING:
case E_BLOCK_EMERALD_ORE:
return PickaxeLevel() >= 3;
case E_BLOCK_IRON_BLOCK:
case E_BLOCK_IRON_ORE:
case E_BLOCK_LAPIS_ORE:
case E_BLOCK_LAPIS_BLOCK:
return PickaxeLevel() >= 2;
case E_BLOCK_COAL_ORE:
case E_BLOCK_STONE:
case E_BLOCK_COBBLESTONE:
case E_BLOCK_END_STONE:
case E_BLOCK_MOSSY_COBBLESTONE:
case E_BLOCK_SANDSTONE_STAIRS:
case E_BLOCK_SANDSTONE:
case E_BLOCK_STONE_BRICKS:
case E_BLOCK_NETHER_BRICK:
case E_BLOCK_NETHERRACK:
case E_BLOCK_STONE_SLAB:
case E_BLOCK_DOUBLE_STONE_SLAB:
case E_BLOCK_STONE_PRESSURE_PLATE:
case E_BLOCK_BRICK:
case E_BLOCK_COBBLESTONE_STAIRS:
case E_BLOCK_STONE_BRICK_STAIRS:
case E_BLOCK_NETHER_BRICK_STAIRS:
return PickaxeLevel() >= 1;
}
}
};

View File

@ -0,0 +1,27 @@
#pragma once
#include "Item.h"
class cItemRedstoneDustHandler : public cItemHandler
{
public:
cItemRedstoneDustHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual bool IsPlaceable()
{
return true;
}
virtual BLOCKTYPE GetBlockType()
{
return E_BLOCK_REDSTONE_WIRE;
}
virtual char GetBlockMeta(char a_ItemMeta)
{
return 0;
}
};

View File

@ -0,0 +1,20 @@
#pragma once
#include "Item.h"
class cItemSaplingHandler : public cItemHandler
{
public:
cItemSaplingHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual char GetBlockMeta(char a_ItemMeta)
{
//Only the first 2 bits are important
return a_ItemMeta & 3;
}
};

58
source/items/ItemSeeds.h Normal file
View File

@ -0,0 +1,58 @@
#pragma once
#include "Item.h"
#include "../cWorld.h"
class cItemSeedsHandler : public cItemHandler
{
public:
cItemSeedsHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual bool IsPlaceable()
{
return true;
}
virtual bool AllowBlockOnTop()
{
return false;
}
virtual BLOCKTYPE GetBlockType()
{
switch(m_ItemID)
{
case E_ITEM_SEEDS:
return E_BLOCK_CROPS;
case E_ITEM_MELON_SEEDS:
E_BLOCK_MELON_STEM;
case E_ITEM_PUMPKIN_SEEDS:
E_BLOCK_PUMPKIN_STEM;
default:
return E_BLOCK_AIR;
}
}
virtual char GetBlockMeta(char a_ItemMeta)
{
return 0; //Not grown yet
}
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir)
{
int X = a_X,
Y = a_Y,
Z = a_Z;
AddDirection(X, Y, Z, a_Dir, true);
if(a_World->GetBlock(X, Y, Z) != E_BLOCK_FARMLAND)
return;
return cItemHandler::PlaceBlock(a_World, a_Player, a_Item, a_X, a_Y, a_Z, a_Dir);
}
};

41
source/items/ItemShears.h Normal file
View File

@ -0,0 +1,41 @@
#pragma once
#include "Item.h"
#include "../cWorld.h"
#include "../cPlayer.h"
class cItemShearsHandler : public cItemHandler
{
public:
cItemShearsHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual bool IsTool()
{
return true;
}
virtual bool OnDiggingBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir) override
{
BLOCKTYPE Block = a_World->GetBlock(a_X, a_Y, a_Z);
if(Block == E_BLOCK_LEAVES)
{
cItems Drops;
Drops.push_back(cItem(E_ITEM_LEAVES, 1, a_World->GetBlockMeta(a_X, a_Y, a_Z)));
a_World->SpawnItemPickups(Drops, a_X, a_Y, a_Z);
a_World->SetBlock(a_X, a_Y, a_Z, E_BLOCK_AIR, 0);
a_Player->UseEquippedItem();
return true;
}
return false;
}
virtual bool CanHarvestBlock(BLOCKTYPE a_BlockID)
{
return a_BlockID == E_BLOCK_COBWEB
|| a_BlockID == E_BLOCK_VINES;
}
};

35
source/items/ItemShovel.h Normal file
View File

@ -0,0 +1,35 @@
#pragma once
#include "Item.h"
#include "../cWorld.h"
#include "../cPlayer.h"
#include "../blocks/Block.h"
class cItemShovelHandler : public cItemHandler
{
public:
cItemShovelHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual bool OnDiggingBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir) override
{
BLOCKTYPE Block = a_World->GetBlock(a_X, a_Y, a_Z);
if(Block == E_BLOCK_SNOW)
{
BlockHandler(Block)->DropBlock(a_World, a_X, a_Y, a_Z);
a_World->SetBlock(a_X, a_Y, a_Z, E_BLOCK_AIR, 0);
a_Player->UseEquippedItem();
return true;
}
return false;
}
virtual bool CanHarvestBlock(BLOCKTYPE a_BlockID)
{
return a_BlockID == E_BLOCK_SNOW;
}
};

39
source/items/ItemSlab.h Normal file
View File

@ -0,0 +1,39 @@
#pragma once
#include "Item.h"
#include "../cWorld.h"
class cItemSlabHandler : public cItemHandler
{
public:
cItemSlabHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir)
{
BLOCKTYPE Block;
NIBBLETYPE Meta;
a_World->GetBlockTypeMeta(a_X, a_Y, a_Z, Block, Meta);
if( (a_Dir == 0 || a_Dir == 1) //Only when clicking on top or on bottom of the block
&& (Block == E_BLOCK_WOODEN_SLAB || Block == E_BLOCK_STONE_SLAB) //It is a slab
&& (Block == a_Item->m_ItemID) //Same slab
&& ((Meta & 0x7) == (a_Item->m_ItemHealth & 0x7))) //Same Texture
{
if(a_Player->GetInventory().RemoveItem(cItem(a_Item->m_ItemID, 1)))
{
a_World->SetBlock(a_X, a_Y, a_Z, Block - 1, Meta); //Block - 1 simple hack to save one if statement
return true;
}
}
return false;
}
virtual char GetBlockMeta(char a_ItemMeta)
{
return a_ItemMeta;
}
};

View File

@ -0,0 +1,34 @@
#pragma once
#include "Item.h"
#include "../cWorld.h"
class cItemSugarcaneHandler : public cItemHandler
{
public:
cItemSugarcaneHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual bool IsPlaceable()
{
return true;
}
virtual bool AllowBlockOnTop()
{
return false;
}
virtual BLOCKTYPE GetBlockType()
{
return E_BLOCK_SUGARCANE;
}
virtual char GetBlockMeta(char a_ItemMeta)
{
return 0; //Not grown yet
}
};

19
source/items/ItemSword.h Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include "Item.h"
#include "../cWorld.h"
#include "../cPlayer.h"
class cItemSwordHandler : public cItemHandler
{
public:
cItemSwordHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual bool CanHarvestBlock(BLOCKTYPE a_BlockID)
{
return a_BlockID == E_BLOCK_COBWEB;
}
};

17
source/items/ItemWood.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include "Item.h"
class cItemWoodHandler : public cItemHandler
{
public:
cItemWoodHandler(int a_ItemID)
: cItemHandler(a_ItemID)
{
}
virtual char GetBlockMeta(char a_ItemMeta)
{
return a_ItemMeta;
}
};

View File

@ -13,13 +13,6 @@
#endif // _WIN32
#include "squirrelbindings/SquirrelBindings.h"
#if USE_SQUIRREL
#pragma warning(push)
#pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus
#pragma warning(pop)
#endif
@ -189,9 +182,6 @@ int main( int argc, char **argv )
LOGERROR("Unknown exception!");
}
#if USE_SQUIRREL
CloseSquirrelVM();
#endif
#if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER)
DeinitLeakFinder();