1
0

Bonemeal works on crops, melons, pumpkins, saplings and grass. Plant growing has been refactored into separate functions callable from Lua, too.

git-svn-id: http://mc-server.googlecode.com/svn/trunk@573 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com 2012-06-07 21:07:21 +00:00
parent f8167f3577
commit 876014b8e8
10 changed files with 286 additions and 6 deletions

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 06/06/12 21:50:56.
** Generated automatically by tolua++-1.0.92 on 06/07/12 23:02:08.
*/
#ifndef __cplusplus
@ -9884,6 +9884,49 @@ static int tolua_AllToLua_cWorld_GetBlockSkyLight00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetBlockTypeMeta of class cWorld */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlockTypeMeta00
static int tolua_AllToLua_cWorld_GetBlockTypeMeta00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
!tolua_isnumber(tolua_S,2,0,&tolua_err) ||
!tolua_isnumber(tolua_S,3,0,&tolua_err) ||
!tolua_isnumber(tolua_S,4,0,&tolua_err) ||
!tolua_isnumber(tolua_S,5,0,&tolua_err) ||
!tolua_isnumber(tolua_S,6,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,7,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0));
int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0));
int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0));
char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0));
unsigned char a_BlockMeta = ((unsigned char) tolua_tonumber(tolua_S,6,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockTypeMeta'", NULL);
#endif
{
self->GetBlockTypeMeta(a_BlockX,a_BlockY,a_BlockZ,a_BlockType,a_BlockMeta);
tolua_pushnumber(tolua_S,(lua_Number)a_BlockType);
tolua_pushnumber(tolua_S,(lua_Number)a_BlockMeta);
}
}
return 2;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'GetBlockTypeMeta'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: DigBlock of class cWorld */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_DigBlock00
static int tolua_AllToLua_cWorld_DigBlock00(lua_State* tolua_S)
@ -10208,6 +10251,82 @@ static int tolua_AllToLua_cWorld_GrowTreeByBiome00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* method: GrowPlant of class cWorld */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowPlant00
static int tolua_AllToLua_cWorld_GrowPlant00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
!tolua_isnumber(tolua_S,2,0,&tolua_err) ||
!tolua_isnumber(tolua_S,3,0,&tolua_err) ||
!tolua_isnumber(tolua_S,4,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,5,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0));
int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0));
int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowPlant'", NULL);
#endif
{
self->GrowPlant(a_BlockX,a_BlockY,a_BlockZ);
}
}
return 0;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'GrowPlant'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: GrowMelonPumpkin of class cWorld */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GrowMelonPumpkin00
static int tolua_AllToLua_cWorld_GrowMelonPumpkin00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
!tolua_isnumber(tolua_S,2,0,&tolua_err) ||
!tolua_isnumber(tolua_S,3,0,&tolua_err) ||
!tolua_isnumber(tolua_S,4,0,&tolua_err) ||
!tolua_isnumber(tolua_S,5,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,6,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0));
int a_BlockY = ((int) tolua_tonumber(tolua_S,3,0));
int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0));
char a_BlockType = ((char) tolua_tonumber(tolua_S,5,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GrowMelonPumpkin'", NULL);
#endif
{
self->GrowMelonPumpkin(a_BlockX,a_BlockY,a_BlockZ,a_BlockType);
}
}
return 0;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'GrowMelonPumpkin'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetBiomeAt of class cWorld */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBiomeAt00
static int tolua_AllToLua_cWorld_GetBiomeAt00(lua_State* tolua_S)
@ -18029,6 +18148,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"SetBlockMeta",tolua_AllToLua_cWorld_SetBlockMeta00);
tolua_function(tolua_S,"SetBlockMeta",tolua_AllToLua_cWorld_SetBlockMeta01);
tolua_function(tolua_S,"GetBlockSkyLight",tolua_AllToLua_cWorld_GetBlockSkyLight00);
tolua_function(tolua_S,"GetBlockTypeMeta",tolua_AllToLua_cWorld_GetBlockTypeMeta00);
tolua_function(tolua_S,"DigBlock",tolua_AllToLua_cWorld_DigBlock00);
tolua_function(tolua_S,"SendBlockTo",tolua_AllToLua_cWorld_SendBlockTo00);
tolua_function(tolua_S,"GetSpawnX",tolua_AllToLua_cWorld_GetSpawnX00);
@ -18038,6 +18158,8 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"GrowTree",tolua_AllToLua_cWorld_GrowTree00);
tolua_function(tolua_S,"GrowTreeFromSapling",tolua_AllToLua_cWorld_GrowTreeFromSapling00);
tolua_function(tolua_S,"GrowTreeByBiome",tolua_AllToLua_cWorld_GrowTreeByBiome00);
tolua_function(tolua_S,"GrowPlant",tolua_AllToLua_cWorld_GrowPlant00);
tolua_function(tolua_S,"GrowMelonPumpkin",tolua_AllToLua_cWorld_GrowMelonPumpkin00);
tolua_function(tolua_S,"GetBiomeAt",tolua_AllToLua_cWorld_GetBiomeAt00);
tolua_function(tolua_S,"GetName",tolua_AllToLua_cWorld_GetName00);
tolua_function(tolua_S,"SaveAllChunks",tolua_AllToLua_cWorld_SaveAllChunks00);

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 06/06/12 21:50:56.
** Generated automatically by tolua++-1.0.92 on 06/07/12 23:02:09.
*/
/* Exported function */

View File

@ -659,7 +659,15 @@ void cChunk::TickMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, int a_BlockIdx
FastSetBlock(m_BlockTickX, m_BlockTickY, m_BlockTickZ, a_BlockType, ++Meta);
return;
}
GrowMelonPumpkin(a_RelX, a_RelY, a_RelZ, a_BlockType, a_TickRandom);
}
void cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_TickRandom)
{
// Convert the stem BlockType into produce BlockType
BLOCKTYPE ProduceType;
switch (a_BlockType)

View File

@ -235,6 +235,9 @@ private:
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);
/// Grows a melon or a pumpkin next to the block specified (assumed to be the stem)
void GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_Random);
/// Same as GetBlock(), but relative coords needn't be in this chunk (uses m_ChunkMap in such a case); returns true on success; only usable in Tick()
bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta);

View File

@ -1084,6 +1084,23 @@ void cChunkMap::GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty)
void cChunkMap::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, MTRand & a_Rand)
{
int ChunkX, ChunkZ;
cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
cCSLock Lock(m_CSLayers);
cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ);
if (Chunk != NULL)
{
Chunk->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_Rand);
}
}
void cChunkMap::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ)
{
int ChunkX, ChunkZ;

View File

@ -151,6 +151,9 @@ public:
/// Returns the number of valid chunks and the number of dirty chunks
void GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty);
/// Grows a melon or a pumpkin next to the block specified (assumed to be the stem)
void GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, MTRand & a_Rand);
/// 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);

View File

@ -977,6 +977,7 @@ void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet)
cDoors::ChangeDoor(m_Player->GetWorld(), a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
break;
}
default:
{
break;
@ -1211,12 +1212,12 @@ void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet)
}
case E_ITEM_SIGN:
{
LOG("Sign Dir: %i", a_Packet->m_Direction);
LOGD("Sign Dir: %i", a_Packet->m_Direction);
if (a_Packet->m_Direction == 1)
{
LOG("Player Rotation: %f", m_Player->GetRotation());
LOGD("Player Rotation: %f", m_Player->GetRotation());
MetaData = cSign::RotationToMetaData(m_Player->GetRotation());
LOG("Sign rotation %i", MetaData);
LOGD("Sign rotation %i", MetaData);
a_Packet->m_ItemType = E_BLOCK_SIGN_POST;
}
else
@ -1261,6 +1262,15 @@ void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet)
a_Packet->m_ItemType = E_BLOCK_PUMPKIN_STEM;
break;
}
case E_ITEM_DYE:
{
// Handle bonemeal and dyes on sheep
if (HandleDyes(a_Packet))
{
return;
}
break;
}
default:
{
break;
@ -1557,6 +1567,26 @@ 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();
World->GrowPlant(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
}
return false;
}
bool cClientHandle::CheckBlockInteractionsRate(void)
{
ASSERT(m_Player != NULL);

View File

@ -204,6 +204,9 @@ private:
void HandleRespawn (void);
void HandleDisconnect (cPacket_Disconnect * a_Packet);
void HandleKeepAlive (cPacket_KeepAlive * a_Packet);
/// Handles rclk with a dye; returns true if normal rclk processing should continue
bool HandleDyes(cPacket_BlockPlace * a_Packet);
/// Returns true if the rate block interactions is within a reasonable limit (bot protection)
bool CheckBlockInteractionsRate(void);

View File

@ -844,6 +844,94 @@ void cWorld::GrowTreeImage(const sSetBlockVector & a_Blocks)
void cWorld::GrowPlant(int a_BlockX, int a_BlockY, int a_BlockZ)
{
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
switch (BlockType)
{
case E_BLOCK_CROPS:
{
if (BlockMeta < 7)
{
FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, 7);
}
break;
}
case E_BLOCK_MELON_STEM:
case E_BLOCK_PUMPKIN_STEM:
{
if (BlockMeta < 7)
{
FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, 7);
}
else
{
GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, BlockType);
}
break;
}
case E_BLOCK_SAPLING:
{
GrowTreeFromSapling(a_BlockX, a_BlockY, a_BlockZ, BlockMeta);
break;
}
case E_BLOCK_GRASS:
{
MTRand r1;
for (int i = 0; i < 60; i++)
{
int OfsX = (r1.randInt(3) + r1.randInt(3) + r1.randInt(3) + r1.randInt(3)) / 2 - 3;
int OfsY = r1.randInt(3) + r1.randInt(3) - 3;
int OfsZ = (r1.randInt(3) + r1.randInt(3) + r1.randInt(3) + r1.randInt(3)) / 2 - 3;
BLOCKTYPE Ground = GetBlock(a_BlockX + OfsX, a_BlockY + OfsY, a_BlockZ + OfsZ);
if (Ground != E_BLOCK_GRASS)
{
continue;
}
BLOCKTYPE Above = GetBlock(a_BlockX + OfsX, a_BlockY + OfsY + 1, a_BlockZ + OfsZ);
if (Above != E_BLOCK_AIR)
{
continue;
}
BLOCKTYPE SpawnType;
NIBBLETYPE SpawnMeta = 0;
switch (r1.randInt(10))
{
case 0: SpawnType = E_BLOCK_YELLOW_FLOWER; break;
case 1: SpawnType = E_BLOCK_RED_ROSE; break;
default:
{
SpawnType = E_BLOCK_TALL_GRASS;
SpawnMeta = E_META_TALL_GRASS_GRASS;
break;
}
} // switch (random spawn block)
FastSetBlock(a_BlockX + OfsX, a_BlockY + OfsY + 1, a_BlockZ + OfsZ, SpawnType, SpawnMeta);
} // for i - 50 times
break;
}
} // switch (BlockType)
}
void cWorld::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockType)
{
MTRand Rand;
m_ChunkMap->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, Rand);
}
int cWorld::GetBiomeAt (int a_BlockX, int a_BlockZ)
{
return m_ChunkMap->GetBiomeAt(a_BlockX, a_BlockZ);

View File

@ -243,6 +243,12 @@ public:
void GrowTreeByBiome (int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export
void GrowTreeImage(const sSetBlockVector & a_Blocks);
/// Grows the plant at the specified block to its ripe stage (bonemeal used)
void GrowPlant(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export
/// Grows a melon or a pumpkin next to the block specified (assumed to be the stem)
void GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockType); // tolua_export
int GetBiomeAt (int a_BlockX, int a_BlockZ); // tolua_export