Merge branch 'master' into 1.8-Protocol
Conflicts: src/Items/ItemHoe.h
This commit is contained in:
commit
69afc4dbba
@ -1885,13 +1885,13 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
|
||||
},
|
||||
BindCommand =
|
||||
{
|
||||
{ Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "(STATIC) Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error." },
|
||||
{ Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error." },
|
||||
{ Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "(STATIC) Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split, {{cPlayer|Player}})</pre> The Split parameter contains an array-table of the words that the player has sent, Player is the {{cPlayer}} object representing the player who sent the command. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server sends a warning to the player that the command is unknown (this is so that subcommands can be implemented)." },
|
||||
{ Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split, {{cPlayer|Player}})</pre> The Split parameter contains an array-table of the words that the player has sent, Player is the {{cPlayer}} object representing the player who sent the command. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server sends a warning to the player that the command is unknown (this is so that subcommands can be implemented)." },
|
||||
},
|
||||
BindConsoleCommand =
|
||||
{
|
||||
{ Params = "Command, Callback, HelpString", Return = "[bool]", Notes = "(STATIC) Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error." },
|
||||
{ Params = "Command, Callback, HelpString", Return = "[bool]", Notes = "Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error." },
|
||||
{ Params = "Command, Callback, HelpString", Return = "[bool]", Notes = "(STATIC) Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split)</pre> The Split parameter contains an array-table of the words that the admin has typed. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server issues a warning to the console that the command is unknown (this is so that subcommands can be implemented)." },
|
||||
{ Params = "Command, Callback, HelpString", Return = "[bool]", Notes = "Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split)</pre> The Split parameter contains an array-table of the words that the admin has typed. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server issues a warning to the console that the command is unknown (this is so that subcommands can be implemented)." },
|
||||
},
|
||||
CallPlugin = { Params = "PluginName, FunctionName, [FunctionArgs...]", Return = "[FunctionRets]", Notes = "(STATIC) Calls the specified function in the specified plugin, passing all the given arguments to it. If it succeeds, it returns all the values returned by that function. If it fails, returns no value at all. Note that only strings, numbers, bools, nils and classes can be used for parameters and return values; tables and functions cannot be copied across plugins." },
|
||||
DisablePlugin = { Params = "PluginName", Return = "bool", Notes = "Disables a plugin specified by its name. Returns true if the plugin was disabled, false if it wasn't found or wasn't active." },
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 203c2fb68bbf871eaf4ca98756a113d74d620dea
|
||||
Subproject commit 27b9d111818af3b05bcf4153bb6e380fe1dd6816
|
@ -590,7 +590,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
|
||||
a_Info[E_BLOCK_LOG ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_LEAVES ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_SPONGE ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_GLASS ].m_PlaceSound = "dig.glass";
|
||||
a_Info[E_BLOCK_GLASS ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_LAPIS_ORE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_LAPIS_BLOCK ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_DISPENSER ].m_PlaceSound = "dig.stone";
|
||||
@ -647,7 +647,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
|
||||
a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_STONE_BUTTON ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_SNOW ].m_PlaceSound = "dig.snow";
|
||||
a_Info[E_BLOCK_ICE ].m_PlaceSound = "dig.glass";
|
||||
a_Info[E_BLOCK_ICE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_SNOW_BLOCK ].m_PlaceSound = "dig.snow";
|
||||
a_Info[E_BLOCK_CACTUS ].m_PlaceSound = "dig.cloth";
|
||||
a_Info[E_BLOCK_CLAY ].m_PlaceSound = "dig.gravel";
|
||||
@ -657,20 +657,20 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
|
||||
a_Info[E_BLOCK_PUMPKIN ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_NETHERRACK ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_SOULSAND ].m_PlaceSound = "dig.sand";
|
||||
a_Info[E_BLOCK_GLOWSTONE ].m_PlaceSound = "dig.glass";
|
||||
a_Info[E_BLOCK_NETHER_PORTAL ].m_PlaceSound = "dig.glass";
|
||||
a_Info[E_BLOCK_GLOWSTONE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_NETHER_PORTAL ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_JACK_O_LANTERN ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_CAKE ].m_PlaceSound = "dig.snow";
|
||||
a_Info[E_BLOCK_REDSTONE_REPEATER_OFF ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_REDSTONE_REPEATER_ON ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_STAINED_GLASS ].m_PlaceSound = "dig.glass";
|
||||
a_Info[E_BLOCK_STAINED_GLASS ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_TRAPDOOR ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_SILVERFISH_EGG ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_STONE_BRICKS ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_IRON_BARS ].m_PlaceSound = "dig.metal";
|
||||
a_Info[E_BLOCK_GLASS_PANE ].m_PlaceSound = "dig.glass";
|
||||
a_Info[E_BLOCK_GLASS_PANE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_MELON ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_PUMPKIN_STEM ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_MELON_STEM ].m_PlaceSound = "dig.wood";
|
||||
@ -687,12 +687,12 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
|
||||
a_Info[E_BLOCK_ENCHANTMENT_TABLE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_BREWING_STAND ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_CAULDRON ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_END_PORTAL ].m_PlaceSound = "dig.glass";
|
||||
a_Info[E_BLOCK_END_PORTAL_FRAME ].m_PlaceSound = "dig.glass";
|
||||
a_Info[E_BLOCK_END_PORTAL ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_END_PORTAL_FRAME ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_END_STONE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_DRAGON_EGG ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_PlaceSound = "dig.glass";
|
||||
a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_PlaceSound = "dig.glass";
|
||||
a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_WOODEN_SLAB ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_COCOA_POD ].m_PlaceSound = "dig.wood";
|
||||
@ -712,7 +712,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
|
||||
a_Info[E_BLOCK_CARROTS ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_POTATOES ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_HEAD ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_ANVIL ].m_PlaceSound = "dig.anvil";
|
||||
a_Info[E_BLOCK_ANVIL ].m_PlaceSound = "random.anvil_land";
|
||||
a_Info[E_BLOCK_TRAPPED_CHEST ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE ].m_PlaceSound = "dig.wood";
|
||||
@ -727,7 +727,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
|
||||
a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_PlaceSound = "dig.metal";
|
||||
a_Info[E_BLOCK_DROPPER ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_STAINED_CLAY ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_PlaceSound = "dig.glass";
|
||||
a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_NEW_LEAVES ].m_PlaceSound = "dig.grass";
|
||||
a_Info[E_BLOCK_NEW_LOG ].m_PlaceSound = "dig.wood";
|
||||
a_Info[E_BLOCK_ACACIA_WOOD_STAIRS ].m_PlaceSound = "dig.wood";
|
||||
@ -736,7 +736,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
|
||||
a_Info[E_BLOCK_CARPET ].m_PlaceSound = "dig.cloth";
|
||||
a_Info[E_BLOCK_HARDENED_CLAY ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_BLOCK_OF_COAL ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_PACKED_ICE ].m_PlaceSound = "dig.glass";
|
||||
a_Info[E_BLOCK_PACKED_ICE ].m_PlaceSound = "dig.stone";
|
||||
a_Info[E_BLOCK_BIG_FLOWER ].m_PlaceSound = "dig.grass";
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ void cBlockBedHandler::OnPlacedByPlayer(
|
||||
if (a_BlockMeta < 8)
|
||||
{
|
||||
Vector3i Direction = MetaDataToDirection(a_BlockMeta);
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z, E_BLOCK_BED, a_BlockMeta | 0x8);
|
||||
a_ChunkInterface.SetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z, E_BLOCK_BED, a_BlockMeta | 0x8);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ void cBlockDoorHandler::OnPlacedByPlayer(
|
||||
{
|
||||
a_TopBlockMeta = 9;
|
||||
}
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta);
|
||||
a_ChunkInterface.SetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, a_TopBlockMeta);
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,49 +28,12 @@ public:
|
||||
|
||||
virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
|
||||
{
|
||||
bool Found = false;
|
||||
|
||||
EMCSBiome Biome = a_Chunk.GetBiomeAt(a_RelX, a_RelZ);
|
||||
if (a_Chunk.GetWorld()->IsWeatherWet() && !IsBiomeNoDownfall(Biome))
|
||||
{
|
||||
// Rain hydrates farmland, too, except in Desert biomes.
|
||||
Found = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Search for water in a close proximity:
|
||||
// Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles
|
||||
// TODO: Rewrite this to use the chunk and its neighbors directly
|
||||
cBlockArea Area;
|
||||
int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
|
||||
if (!Area.Read(a_Chunk.GetWorld(), BlockX - 4, BlockX + 4, a_RelY, a_RelY + 1, BlockZ - 4, BlockZ + 4))
|
||||
{
|
||||
// Too close to the world edge, cannot check surroundings; don't tick at all
|
||||
return;
|
||||
}
|
||||
|
||||
size_t NumBlocks = Area.GetBlockCount();
|
||||
BLOCKTYPE * BlockTypes = Area.GetBlockTypes();
|
||||
for (size_t i = 0; i < NumBlocks; i++)
|
||||
{
|
||||
if (IsBlockWater(BlockTypes[i]))
|
||||
{
|
||||
Found = true;
|
||||
break;
|
||||
}
|
||||
} // for i - BlockTypes[]
|
||||
}
|
||||
|
||||
NIBBLETYPE BlockMeta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
|
||||
|
||||
if (Found)
|
||||
if (IsWaterInNear(a_Chunk, a_RelX, a_RelY, a_RelZ))
|
||||
{
|
||||
// Water was found, hydrate the block until hydration reaches 7:
|
||||
if (BlockMeta < 7)
|
||||
{
|
||||
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, ++BlockMeta);
|
||||
}
|
||||
// Water was found, set block meta to 7
|
||||
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, 7);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -82,7 +45,8 @@ public:
|
||||
}
|
||||
|
||||
// Farmland too dry. If nothing is growing on top, turn back to dirt:
|
||||
switch (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ))
|
||||
BLOCKTYPE UpperBlock = (a_RelY >= cChunkDef::Height) ? E_BLOCK_AIR : a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ);
|
||||
switch (UpperBlock)
|
||||
{
|
||||
case E_BLOCK_CROPS:
|
||||
case E_BLOCK_POTATOES:
|
||||
@ -95,16 +59,63 @@ public:
|
||||
}
|
||||
default:
|
||||
{
|
||||
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0);
|
||||
a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override
|
||||
{
|
||||
if (a_BlockY >= cChunkDef::Height)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BLOCKTYPE UpperBlock = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ);
|
||||
if (cBlockInfo::FullyOccupiesVoxel(UpperBlock))
|
||||
{
|
||||
a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_DIRT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
a_Pickups.Add(E_BLOCK_DIRT, 1, 0); // Reset meta
|
||||
}
|
||||
|
||||
bool IsWaterInNear(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
|
||||
{
|
||||
if (a_Chunk.GetWorld()->IsWeatherWetAt(a_RelX, a_RelZ))
|
||||
{
|
||||
// Rain hydrates farmland, too, except in Desert biomes.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Search for water in a close proximity:
|
||||
// Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles
|
||||
// TODO: Rewrite this to use the chunk and its neighbors directly
|
||||
cBlockArea Area;
|
||||
int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
|
||||
if (!Area.Read(a_Chunk.GetWorld(), BlockX - 4, BlockX + 4, a_RelY, a_RelY + 1, BlockZ - 4, BlockZ + 4))
|
||||
{
|
||||
// Too close to the world edge, cannot check surroundings
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t NumBlocks = Area.GetBlockCount();
|
||||
BLOCKTYPE * BlockTypes = Area.GetBlockTypes();
|
||||
for (size_t i = 0; i < NumBlocks; i++)
|
||||
{
|
||||
if (IsBlockWater(BlockTypes[i]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
} // for i - BlockTypes[]
|
||||
|
||||
return false;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -126,11 +126,11 @@ public:
|
||||
{
|
||||
if (Dir == 1)
|
||||
{
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, Width, Height, Z, E_BLOCK_NETHER_PORTAL, Dir);
|
||||
a_ChunkInterface.SetBlock(Width, Height, Z, E_BLOCK_NETHER_PORTAL, Dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, X, Height, Width, E_BLOCK_NETHER_PORTAL, Dir);
|
||||
a_ChunkInterface.SetBlock(X, Height, Width, E_BLOCK_NETHER_PORTAL, Dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,13 +18,15 @@ public:
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
a_Pickups.Add(E_BLOCK_GRAVEL, 1, 0);
|
||||
|
||||
cFastRandom Random;
|
||||
if (Random.NextInt(30) == 0)
|
||||
{
|
||||
a_Pickups.Add(E_ITEM_FLINT, 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
a_Pickups.Add(E_BLOCK_GRAVEL, 1, 0);
|
||||
}
|
||||
}
|
||||
} ;
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "BlockLilypad.h"
|
||||
#include "BlockLever.h"
|
||||
#include "BlockMelon.h"
|
||||
#include "BlockMobSpawner.h"
|
||||
#include "BlockMushroom.h"
|
||||
#include "BlockMycelium.h"
|
||||
#include "BlockNetherWart.h"
|
||||
@ -244,6 +245,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
|
||||
case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType);
|
||||
case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType);
|
||||
case E_BLOCK_MELON_STEM: return new cBlockStemsHandler (a_BlockType);
|
||||
case E_BLOCK_MOB_SPAWNER: return new cBlockMobSpawnerHandler (a_BlockType);
|
||||
case E_BLOCK_MYCELIUM: return new cBlockMyceliumHandler (a_BlockType);
|
||||
case E_BLOCK_NETHER_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType);
|
||||
case E_BLOCK_NETHER_PORTAL: return new cBlockPortalHandler (a_BlockType);
|
||||
|
@ -146,9 +146,9 @@ public:
|
||||
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
|
||||
// Block entities
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
|
||||
// Spawn the wither:
|
||||
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
|
||||
@ -176,9 +176,9 @@ public:
|
||||
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
|
||||
// Block entities
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
|
||||
|
||||
// Spawn the wither:
|
||||
a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
|
||||
|
40
src/Blocks/BlockMobSpawner.h
Normal file
40
src/Blocks/BlockMobSpawner.h
Normal file
@ -0,0 +1,40 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlockHandler.h"
|
||||
#include "../World.h"
|
||||
#include "../Items/ItemHandler.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBlockMobSpawnerHandler :
|
||||
public cBlockHandler
|
||||
{
|
||||
public:
|
||||
cBlockMobSpawnerHandler(BLOCKTYPE a_BlockType)
|
||||
: cBlockHandler(a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
// No pickups
|
||||
}
|
||||
|
||||
|
||||
virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
|
||||
{
|
||||
cItemHandler * Handler = a_Player->GetEquippedItem().GetHandler();
|
||||
if (a_Player->IsGameModeCreative() || !Handler->CanHarvestBlock(E_BLOCK_MOB_SPAWNER))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cFastRandom Random;
|
||||
int Reward = 15 + Random.NextInt(15) + Random.NextInt(15);
|
||||
a_WorldInterface.SpawnExperienceOrb((double)a_BlockX, (double)a_BlockY + 1, (double)a_BlockZ, Reward);
|
||||
}
|
||||
} ;
|
@ -52,7 +52,7 @@ void cBlockPistonHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorld
|
||||
|
||||
if (a_ChunkInterface.GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION)
|
||||
{
|
||||
a_ChunkInterface.SetBlock(a_WorldInterface, newX, newY, newZ, E_BLOCK_AIR, 0);
|
||||
a_ChunkInterface.SetBlock(newX, newY, newZ, E_BLOCK_AIR, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,9 +37,9 @@ public:
|
||||
/** Sets the block at the specified coords to the specified value.
|
||||
Full processing, incl. updating neighbors, is performed.
|
||||
*/
|
||||
void SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
||||
void SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
||||
{
|
||||
m_ChunkMap->SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
|
||||
m_ChunkMap->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
|
||||
}
|
||||
|
||||
void SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData)
|
||||
|
@ -35,6 +35,9 @@ public:
|
||||
/** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */
|
||||
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0;
|
||||
|
||||
/** Spawns an experience orb at the given location with the given reward. It returns the UniqueID of the spawned experience orb. */
|
||||
virtual int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) = 0;
|
||||
|
||||
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
|
||||
virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) = 0;
|
||||
|
||||
|
@ -1287,12 +1287,12 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP
|
||||
|
||||
|
||||
|
||||
void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients)
|
||||
void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients)
|
||||
{
|
||||
cChunkInterface ChunkInterface(this);
|
||||
if (a_BlockType == E_BLOCK_AIR)
|
||||
{
|
||||
BlockHandler(GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnDestroyed(ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ);
|
||||
BlockHandler(GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnDestroyed(ChunkInterface, *m_World, a_BlockX, a_BlockY, a_BlockZ);
|
||||
}
|
||||
|
||||
int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ;
|
||||
@ -1305,7 +1305,7 @@ void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a
|
||||
Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta, a_SendToClients);
|
||||
m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, Chunk);
|
||||
}
|
||||
BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
|
||||
BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, *m_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
|
||||
}
|
||||
|
||||
|
||||
|
@ -151,7 +151,7 @@ public:
|
||||
NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
NIBBLETYPE GetBlockBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockMeta);
|
||||
void SetBlock (cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients = true);
|
||||
void SetBlock (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients = true);
|
||||
void QueueSetBlock (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Int64 a_Tick, BLOCKTYPE a_PreviousBlockType = E_BLOCK_AIR);
|
||||
bool GetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta);
|
||||
bool GetBlockInfo (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight);
|
||||
|
@ -1139,6 +1139,12 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo
|
||||
|
||||
FinishDigAnimation();
|
||||
|
||||
if (!m_Player->IsGameModeCreative() && (a_OldBlock == E_BLOCK_BEDROCK))
|
||||
{
|
||||
Kick("You can't break a bedrock!");
|
||||
return;
|
||||
}
|
||||
|
||||
cWorld * World = m_Player->GetWorld();
|
||||
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
|
||||
|
||||
@ -1466,8 +1472,20 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e
|
||||
cChunkInterface ChunkInterface(World->GetChunkMap());
|
||||
NewBlock->OnPlacedByPlayer(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta);
|
||||
|
||||
// Step sound with 0.8f pitch is used as block placement sound
|
||||
World->BroadcastSoundEffect(cBlockInfo::GetPlaceSound(BlockType), (double)a_BlockX, (double)a_BlockY, (double)a_BlockZ, 1.0f, 0.8f);
|
||||
AString PlaceSound = cBlockInfo::GetPlaceSound(BlockType);
|
||||
float Volume = 1.0f, Pitch = 0.8f;
|
||||
if (PlaceSound == "dig.metal")
|
||||
{
|
||||
Pitch = 1.2f;
|
||||
PlaceSound = "dig.stone";
|
||||
}
|
||||
else if (PlaceSound == "random.anvil_land")
|
||||
{
|
||||
Volume = 0.65f;
|
||||
}
|
||||
|
||||
World->BroadcastSoundEffect(PlaceSound, a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, Volume, Pitch);
|
||||
|
||||
cRoot::Get()->GetPluginManager()->CallHookPlayerPlacedBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta);
|
||||
}
|
||||
|
||||
|
@ -941,8 +941,9 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||
}
|
||||
NextSpeed.y += fallspeed;
|
||||
}
|
||||
|
||||
// Friction
|
||||
else
|
||||
{
|
||||
// Friction on ground
|
||||
if (NextSpeed.SqrLength() > 0.0004f)
|
||||
{
|
||||
NextSpeed.x *= 0.7f / (1 + a_Dt);
|
||||
@ -956,6 +957,7 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||
NextSpeed.z = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust X and Z speed for COBWEB temporary. This speed modification should be handled inside block handlers since we
|
||||
// might have different speed modifiers according to terrain.
|
||||
|
@ -582,6 +582,7 @@ bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType)
|
||||
case E_BLOCK_SNOW:
|
||||
case E_BLOCK_VINES:
|
||||
case E_BLOCK_PACKED_ICE:
|
||||
case E_BLOCK_MOB_SPAWNER:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -20,15 +20,17 @@ public:
|
||||
|
||||
virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override
|
||||
{
|
||||
if (a_Dir == BLOCK_FACE_NONE)
|
||||
if ((a_Dir == BLOCK_FACE_NONE) || (a_BlockY >= cChunkDef::Height))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
|
||||
if (IsBlockTypeOfDirt(Block))
|
||||
BLOCKTYPE UpperBlock = a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ);
|
||||
|
||||
if (((Block == E_BLOCK_DIRT) || (Block == E_BLOCK_GRASS)) && (UpperBlock == E_BLOCK_AIR))
|
||||
{
|
||||
a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FARMLAND, 0);
|
||||
a_World->BroadcastSoundEffect("dig.gravel", a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 1.0f, 0.8f);
|
||||
a_Player->UseEquippedItem();
|
||||
return true;
|
||||
}
|
||||
@ -45,4 +47,3 @@ public:
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -81,6 +81,7 @@ public:
|
||||
case E_BLOCK_STONE_BRICK_STAIRS:
|
||||
case E_BLOCK_NETHER_BRICK_STAIRS:
|
||||
case E_BLOCK_CAULDRON:
|
||||
case E_BLOCK_MOB_SPAWNER:
|
||||
{
|
||||
return PickaxeLevel() >= 1;
|
||||
}
|
||||
|
@ -1040,9 +1040,9 @@ void cProtocol172::SendExperienceOrb(const cExpOrb & a_ExpOrb)
|
||||
|
||||
cPacketizer Pkt(*this, 0x11);
|
||||
Pkt.WriteVarInt(a_ExpOrb.GetUniqueID());
|
||||
Pkt.WriteInt((int) a_ExpOrb.GetPosX());
|
||||
Pkt.WriteInt((int) a_ExpOrb.GetPosY());
|
||||
Pkt.WriteInt((int) a_ExpOrb.GetPosZ());
|
||||
Pkt.WriteFPInt(a_ExpOrb.GetPosX());
|
||||
Pkt.WriteFPInt(a_ExpOrb.GetPosY());
|
||||
Pkt.WriteFPInt(a_ExpOrb.GetPosZ());
|
||||
Pkt.WriteShort(a_ExpOrb.GetReward());
|
||||
}
|
||||
|
||||
|
@ -1727,7 +1727,7 @@ bool cWorld::SetAreaBiome(const cCuboid & a_Area, EMCSBiome a_Biome)
|
||||
|
||||
void cWorld::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients)
|
||||
{
|
||||
m_ChunkMap->SetBlock(*this, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_SendToClients);
|
||||
m_ChunkMap->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_SendToClients);
|
||||
}
|
||||
|
||||
|
||||
|
@ -469,7 +469,7 @@ public:
|
||||
int SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType, const cItem & a_Content = cItem(), int a_BlockHeight = 1);
|
||||
|
||||
/** Spawns an experience orb at the given location with the given reward. It returns the UniqueID of the spawned experience orb. */
|
||||
int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward);
|
||||
virtual int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) override;
|
||||
|
||||
/** Spawns a new primed TNT entity at the specified block coords and specified fuse duration. Initial velocity is given based on the relative coefficient provided */
|
||||
void SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTimeInSec = 80, double a_InitialVelocityCoeff = 1);
|
||||
|
Loading…
Reference in New Issue
Block a user