From 907ba15fe208f6a8ad37f35652ae3ceac6bb39e9 Mon Sep 17 00:00:00 2001 From: "admin@omencraft.com" Date: Mon, 7 Nov 2011 18:19:38 +0000 Subject: Added Sebi's changes to pistons and item drops. git-svn-id: http://mc-server.googlecode.com/svn/trunk@72 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/BlockID.h | 4 +- source/cBlockToPickup.cpp | 18 ++ source/cClientHandle.cpp | 33 +-- source/cPiston.cpp | 496 +++++++++------------------------------------- source/cPiston.h | 6 +- source/cWorld.cpp | 38 ++++ 6 files changed, 172 insertions(+), 423 deletions(-) (limited to 'source') diff --git a/source/BlockID.h b/source/BlockID.h index 01a491555..3bdc65cac 100644 --- a/source/BlockID.h +++ b/source/BlockID.h @@ -35,7 +35,7 @@ enum ENUM_BLOCK_ID E_BLOCK_STICKY_PISTON = 29, E_BLOCK_COBWEB = 30, E_BLOCK_TALL_GRASS = 31, - E_BLOCK_DEAD_BRUSH = 32, + E_BLOCK_DEAD_BUSH = 32, E_BLOCK_PISTON = 33, E_BLOCK_PISTON_EXTENSION = 34, E_BLOCK_WHITE_CLOTH = 35, @@ -358,7 +358,7 @@ enum ENUM_ITEM_ID E_ITEM_COOKIE = 357, E_ITEM_MAP = 358, E_ITEM_SHEARS = 359, - E_ITEM_MELON_SLICES = 360, + E_ITEM_MELON_SLICE = 360, E_ITEM_PUMPKIN_SEEDS = 361, E_ITEM_MELON_SEEDS = 362, E_ITEM_RAW_BEEF = 363, diff --git a/source/cBlockToPickup.cpp b/source/cBlockToPickup.cpp index 3638740a3..75ba77f9a 100644 --- a/source/cBlockToPickup.cpp +++ b/source/cBlockToPickup.cpp @@ -13,12 +13,24 @@ ENUM_ITEM_ID cBlockToPickup::ToPickup( unsigned char a_BlockID, ENUM_ITEM_ID a_U return E_ITEM_COBBLESTONE; case E_BLOCK_GRASS: return E_ITEM_DIRT; + case E_BLOCK_GLASS: + return E_ITEM_EMPTY; case E_BLOCK_DIRT: return E_ITEM_DIRT; case E_BLOCK_LOG: return E_ITEM_LOG; + case E_BLOCK_LEAVES: + if( a_UsedItemID == E_ITEM_SHEARS ) + return E_ITEM_LEAVES; + else + return E_ITEM_EMPTY; case E_BLOCK_COAL_ORE: return E_ITEM_COAL; + case E_BLOCK_LAPIS_ORE: + return E_ITEM_DYE; + case E_BLOCK_REDSTONE_ORE_GLOWING: + case E_BLOCK_REDSTONE_ORE: + return E_ITEM_REDSTONE_DUST; case E_BLOCK_DIAMOND_ORE: return E_ITEM_DIAMOND; case E_BLOCK_IRON_BLOCK: @@ -30,6 +42,12 @@ ENUM_ITEM_ID cBlockToPickup::ToPickup( unsigned char a_BlockID, ENUM_ITEM_ID a_U case E_BLOCK_SIGN_POST: case E_BLOCK_WALLSIGN: return E_ITEM_SIGN; + case E_BLOCK_REDSTONE_WIRE: + return E_ITEM_REDSTONE_DUST; + case E_BLOCK_REDSTONE_TORCH_OFF: + return E_ITEM_REDSTONE_TORCH_ON; + case E_BLOCK_MELON: + return E_ITEM_MELON_SLICE; default: return (ENUM_ITEM_ID)a_BlockID; } diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index c3ed6c3df..b428910d3 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -516,6 +516,16 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) PickupItem.m_ItemID = PickupID; PickupItem.m_ItemHealth = MetaData; PickupItem.m_ItemCount = 1; + if( OldBlock == E_BLOCK_LAPIS_ORE ) { + PickupItem.m_ItemHealth = 4; + PickupItem.m_ItemCount = rand()%5+4; + } + if( OldBlock == E_BLOCK_REDSTONE_ORE || OldBlock == E_BLOCK_REDSTONE_ORE_GLOWING ) { + PickupItem.m_ItemCount = rand()%2+4; + } + if( OldBlock == E_BLOCK_MELON ) { + PickupItem.m_ItemCount = rand()%8+3; + } } if(!cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_BLOCK_DIG, 2, PacketData, m_Player, &PickupItem ) ) { @@ -620,16 +630,19 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) case E_BLOCK_PLACE: { //LOG("TimeP: %f", m_Player->GetLastBlockActionTime() ); - //LOG("TimeN: %f", cRoot::Get()->GetWorld()->GetTime() ); - if ( cRoot::Get()->GetWorld()->GetTime() - m_Player->GetLastBlockActionTime() < 0.1 ) { //only allow block interactions every 0.1 seconds - LOGWARN("Player %s tried to interact with a block too quickly! (could indicate bot)", GetUsername() ); - m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time. - break; - } - m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time. + //LOG("TimeN: %f", cRoot::Get()->GetWorld()->GetTime() ); + if ( cRoot::Get()->GetWorld()->GetTime() - m_Player->GetLastBlockActionTime() < 0.1 ) { //only allow block interactions every 0.1 seconds + LOGWARN("Player %s tried to interact with a block too quickly! (could indicate bot)", GetUsername() ); + m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time. + break; + } + m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time. cPacket_BlockPlace* PacketData = reinterpret_cast(a_Packet); cItem & Equipped = m_Player->GetInventory().GetEquippedItem(); //if( (Equipped.m_ItemID != PacketData->m_ItemType) ) // Not valid + if ( ( m_Player->GetWorld()->GetBlock( PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ ) != E_BLOCK_AIR ) && (m_Player->GetGameMode() != 1) ) { //tried to place a block *into* another? + break; //happens when you place a block aiming at side of block like torch or stem + } if( (Equipped.m_ItemID != PacketData->m_ItemType) && (m_Player->GetGameMode() != 1) ) // Not valid { LOGWARN("Player %s tried to place a block that was not selected! (could indicate bot)", GetUsername() ); @@ -776,21 +789,15 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) } else { //printf("transparent not above me\n"); } - //PacketData->m_ItemType = E_BLOCK_REDSTONE_TORCH_ON; UpdateRedstone = true; AddedCurrent = true; - //cRedstone Redstone(m_Player->GetWorld()); - //Redstone.cRedstone::ChangeRedstoneTorch( PacketData->m_PosX, PacketData->m_PosY+1, PacketData->m_PosZ, true ); break; } case E_BLOCK_REDSTONE_TORCH_ON: { MetaData = cTorch::DirectionToMetaData( PacketData->m_Direction ); - //PacketData->m_ItemType = E_BLOCK_REDSTONE_TORCH_ON; UpdateRedstone = true; AddedCurrent = false; - //cRedstone Redstone(m_Player->GetWorld()); - //Redstone.cRedstone::ChangeRedstoneTorch( PacketData->m_PosX, PacketData->m_PosY+1, PacketData->m_PosZ, true ); break; } case E_ITEM_REDSTONE_DUST: diff --git a/source/cPiston.cpp b/source/cPiston.cpp index 05ad1be24..16df55089 100644 --- a/source/cPiston.cpp +++ b/source/cPiston.cpp @@ -1,429 +1,113 @@ #include "cPiston.h" +#include "cChunk.h" +#include "cPickup.h" +#include "cBlockToPickup.h" +#include "cItem.h" #include "cRoot.h" #include "cWorld.h" #include "BlockID.h" #include "packets/cPacket_BlockAction.h" #include "cServer.h" +extern bool g_BlockPistonBreakable[]; + +#define AddDir( 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; } + cPiston::cPiston( cWorld* a_World ) :m_World ( a_World ) { } -//Todo: All piston stuff below. -void cPiston::ExtendPiston( int pistx, int pisty, int pistz ) -{ - //cWorld* World = cRoot::Get()->GetWorld(); - char metadata = 0; - char extmetadata = 0; - int FirstFluidBlock = 0; - char piston; - - piston = m_World->GetBlock( pistx, pisty, pistz ); - - if ( piston == E_BLOCK_STICKY_PISTON ) { - extmetadata = 8; - }//if sticky piston than top nibble's bit is set to 1; - - if ( ( piston == E_BLOCK_STICKY_PISTON ) || ( piston == E_BLOCK_PISTON ) ) { - metadata = m_World->GetBlockMeta( pistx, pisty, pistz); - if ((int)metadata < 6) { //piston not extended - - //send blockaction packet - cPacket_BlockAction Action; - Action.m_PosX = (int)pistx; - Action.m_PosY = (short)pisty; - Action.m_PosZ = (int)pistz; - Action.m_Byte1 = 0; - - switch ((int)metadata) { - case 0: - FirstFluidBlock = FindFluidBlock ( pistx, pisty-1, pistz, pistx, pisty-16, pistz ); - if (FirstFluidBlock > 0) { - ChainMove ( pistx, pisty, pistz, pistx, pisty-FirstFluidBlock, pistz ); - } - Action.m_Byte2 = 0; - m_World->FastSetBlock( pistx, pisty, pistz, piston, (char)metadata + 8 ); - m_World->SetBlock( pistx, pisty-1, pistz, E_BLOCK_PISTON_EXTENSION, extmetadata ); - break; - case 1: - FirstFluidBlock = FindFluidBlock (pistx, pisty+1, pistz, pistx, pisty+16, pistz); - if (FirstFluidBlock > 0) { - ChainMove ( pistx, pisty, pistz, pistx, pisty+FirstFluidBlock, pistz ); - } - Action.m_Byte2 = 1; - m_World->FastSetBlock( pistx, pisty, pistz, piston, (char)metadata + 8 ); - m_World->SetBlock( pistx, pisty+1, pistz, E_BLOCK_PISTON_EXTENSION, extmetadata+1 ); - break; - case 2: - FirstFluidBlock = FindFluidBlock (pistx, pisty, pistz-1, pistx, pisty, pistz-16); - if (FirstFluidBlock > 0) { - ChainMove ( pistx, pisty, pistz, pistx, pisty, pistz-FirstFluidBlock ); - } - Action.m_Byte2 = 2; - m_World->FastSetBlock( pistx, pisty, pistz, piston, (char)metadata + 8 ); - m_World->SetBlock( pistx, pisty, pistz-1, E_BLOCK_PISTON_EXTENSION, extmetadata+2 ); - break; - case 3: - FirstFluidBlock = FindFluidBlock (pistx, pisty, pistz+1, pistx, pisty, pistz+16); - if (FirstFluidBlock > 0) { - ChainMove ( pistx, pisty, pistz, pistx, pisty, pistz+FirstFluidBlock ); - } - Action.m_Byte2 = 3; - m_World->FastSetBlock( pistx, pisty, pistz, piston, (char)metadata + 8 ); - m_World->SetBlock( pistx, pisty, pistz+1, E_BLOCK_PISTON_EXTENSION, extmetadata+3 ); - break; - case 4: - FirstFluidBlock = FindFluidBlock (pistx-1, pisty, pistz, pistx-16, pisty, pistz); - if (FirstFluidBlock > 0) { - ChainMove ( pistx, pisty, pistz, pistx-FirstFluidBlock, pisty, pistz ); - } - Action.m_Byte2 = 4; - m_World->FastSetBlock( pistx, pisty, pistz, piston, metadata + 8 ); - m_World->SetBlock( pistx-1, pisty, pistz, E_BLOCK_PISTON_EXTENSION, extmetadata+4 ); - break; - case 5: - FirstFluidBlock = FindFluidBlock (pistx+1, pisty, pistz, pistx+16, pisty, pistz); - if (FirstFluidBlock > 0) { - ChainMove ( pistx, pisty, pistz, pistx+FirstFluidBlock, pisty, pistz ); - } - Action.m_Byte2 = 5; - m_World->FastSetBlock( pistx, pisty, pistz, piston, metadata + 8 ); - m_World->SetBlock( pistx+1, pisty, pistz, E_BLOCK_PISTON_EXTENSION, extmetadata+5 ); - break; - } - cRoot::Get()->GetServer()->Broadcast( Action ); - } +unsigned short cPiston::FirstPassthroughBlock( int pistonX, int pistonY, int pistonZ, char pistonmeta ) { + unsigned short ret; + pistonmeta &= 7; + if(pistonmeta >= 6) { // just in case, it shouldn't happen but if it would, it'd case inf loop + printf("cPiston::FirstPassthroughBlock - piston has invalid meta data!\n"); + return 9001; } -} - -void cPiston::RetractPiston( int pistx, int pisty, int pistz ) -{ - char metadata = m_World->GetBlockMeta( pistx, pisty, pistz); - char tempmeta; - char tempblock; - - if ( (int)m_World->GetBlock( pistx, pisty, pistz ) == E_BLOCK_PISTON ) { - if (metadata > 5) { //piston retracted - metadata -= 8;//set the piston to retracted state. - - //send blockaction packet - cPacket_BlockAction Action; - Action.m_PosX = (int)pistx; - Action.m_PosY = (short)pisty; - Action.m_PosZ = (int)pistz; - Action.m_Byte1 = 1; - - switch (metadata) { - case 0: - Action.m_Byte2 = 0; - if ( m_World->GetBlock( pistx, pisty-1, pistz ) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx, pisty-1, pistz, 0, 0 ); - } - break; - - case 1: - Action.m_Byte2 = 1; - if ( m_World->GetBlock( pistx, pisty+1, pistz ) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx, pisty+1, pistz, 0, 0 ); - } - break; - - case 2: - Action.m_Byte2 = 2; - if ( m_World->GetBlock( pistx, pisty, pistz-1 ) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx, pisty, pistz-1, 0, 0 ); - } - break; - - case 3: - Action.m_Byte2 = 3; - if ( m_World->GetBlock( pistx, pisty, pistz+1 ) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx, pisty, pistz+1, 0, 0 ); - } - break; - - case 4: - Action.m_Byte2 = 4; - if ( m_World->GetBlock( pistx-1, pisty, pistz ) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx-1, pisty, pistz, 0, 0 ); - } - break; - - case 5: - Action.m_Byte2 = 5; - if ( m_World->GetBlock( pistx+1, pisty, pistz ) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx+1, pisty, pistz, 0, 0 ); - } - break; - - } - m_World->FastSetBlock( pistx, pisty, pistz, m_World->GetBlock( pistx, pisty, pistz ), metadata ); - cRoot::Get()->GetServer()->Broadcast( Action ); - } - } - - - if ( (int)m_World->GetBlock( pistx, pisty, pistz ) == E_BLOCK_STICKY_PISTON ) { - if (metadata > 5) { //piston retracted - metadata -= 8;//set the piston to retracted state. - - //send blockaction packet - cPacket_BlockAction Action; - Action.m_PosX = (int)pistx; - Action.m_PosY = (short)pisty; - Action.m_PosZ = (int)pistz; - Action.m_Byte1 = 1; - - switch (metadata) { - case 0: - Action.m_Byte2 = 0; - if ( m_World->GetBlock( pistx, pisty-1, pistz ) == E_BLOCK_PISTON_EXTENSION ) { - tempblock = m_World->GetBlock( pistx, pisty-2, pistz ); - tempmeta = m_World->GetBlockMeta( pistx, pisty-2, pistz ); - m_World->SetBlock( pistx, pisty-1, pistz, 0, 0 ); - m_World->SetBlock( pistx, pisty-1, pistz, tempblock, tempmeta ); - m_World->SetBlock( pistx, pisty-2, pistz, 0, 0 ); - } - break; - - case 1: - Action.m_Byte2 = 1; - if ( m_World->GetBlock( pistx, pisty+1, pistz ) == E_BLOCK_PISTON_EXTENSION ) { - tempblock = m_World->GetBlock( pistx, pisty+2, pistz ); - tempmeta = m_World->GetBlockMeta( pistx, pisty+2, pistz ); - m_World->SetBlock( pistx, pisty+1, pistz, 0, 0 ); - m_World->SetBlock( pistx, pisty+1, pistz, tempblock , tempmeta ); - m_World->SetBlock( pistx, pisty+2, pistz, 0, 0 ); - } - break; - case 2: - Action.m_Byte2 = 2; - if ( m_World->GetBlock( pistx, pisty, pistz-1) == E_BLOCK_PISTON_EXTENSION ) { - tempblock = m_World->GetBlock( pistx, pisty, pistz-2 ); - tempmeta = m_World->GetBlockMeta( pistx, pisty, pistz-2 ); - m_World->SetBlock( pistx, pisty, pistz-1, 0, 0 ); - m_World->SetBlock( pistx, pisty, pistz-1, tempblock, tempmeta ); - m_World->SetBlock( pistx, pisty, pistz-2, 0, 0 ); - } - break; - case 3: - Action.m_Byte2 = 3; - if ( m_World->GetBlock( pistx, pisty, pistz+1) == E_BLOCK_PISTON_EXTENSION ) { - tempblock = m_World->GetBlock( pistx, pisty, pistz+2 ); - tempmeta = m_World->GetBlockMeta( pistx, pisty, pistz+2 ); - m_World->SetBlock( pistx, pisty, pistz+1, 0, 0 ); - m_World->SetBlock( pistx, pisty, pistz+1, tempblock, tempmeta ); - m_World->SetBlock( pistx, pisty, pistz+2, 0, 0 ); - } - break; - case 4: - Action.m_Byte2 = 4; - if ( m_World->GetBlock( pistx-1, pisty, pistz) == E_BLOCK_PISTON_EXTENSION ) { - tempblock = m_World->GetBlock( pistx-2, pisty, pistz ); - tempmeta = m_World->GetBlockMeta( pistx-2, pisty, pistz ); - m_World->SetBlock( pistx-1, pisty, pistz, 0, 0 ); - m_World->SetBlock( pistx-1, pisty, pistz, tempblock, tempmeta ); - m_World->SetBlock( pistx-2, pisty, pistz, 0, 0 ); - } - break; - case 5: - Action.m_Byte2 = 5; - if ( m_World->GetBlock( pistx+1, pisty, pistz) == E_BLOCK_PISTON_EXTENSION ) { - tempblock = m_World->GetBlock( pistx+2, pisty, pistz ); - tempmeta = m_World->GetBlockMeta( pistx+2, pisty, pistz ); - m_World->SetBlock( pistx+1, pisty, pistz, 0, 0 ); - m_World->SetBlock( pistx+1, pisty, pistz, tempblock, tempmeta ); - m_World->SetBlock( pistx+2, pisty, pistz, 0, 0 ); - } - break; - } - m_World->FastSetBlock( pistx, pisty, pistz, m_World->GetBlock( pistx, pisty, pistz ), metadata ); - cRoot::Get()->GetServer()->Broadcast( Action ); - } + char currBlock; + for( ret = 0; ret < 24; ret++ ) { // push up to 24 blocks + AddDir( pistonX, pistonY, pistonZ, pistonmeta, 1 ) + currBlock = m_World->GetBlock( pistonX, pistonY, pistonZ ); + if(currBlock == E_BLOCK_BEDROCK || currBlock == E_BLOCK_OBSIDIAN || currBlock == E_BLOCK_PISTON_EXTENSION ) {return 9001;} + if(g_BlockPistonBreakable[currBlock]) {return ret;} } + return 9001; } -void cPiston::ChainMove ( int ax, int ay, int az, int bx, int by, int bz ) -{ - -char lastmeta; -char lastblock; - - if ( ( ax != bx ) && ( ay == by ) && ( az == bz ) ) { //move x - - if ( ax > bx ) { - - while ( ax > bx ) { - lastmeta = m_World->GetBlockMeta( bx, by, bz); - lastblock = m_World->GetBlock( bx, by, bz); - m_World->SetBlock( bx+1, by, bz, lastblock, lastmeta ); - bx += 1; - } - - } else { - - while ( ax < bx ) { - lastmeta = m_World->GetBlockMeta( bx, by, bz); - lastblock = m_World->GetBlock( bx, by, bz); - m_World->SetBlock( bx+1, by, bz, lastblock, lastmeta ); - bx -= 1; - } - - } - - m_World->SetBlock( ax, ay, az, 0, 0 ); - - } else if ( ( ax == bx ) && ( ay != by ) && ( az == bz ) ) { //move y - - if ( ay > by ) { - - while ( ay > by ) { - lastmeta = m_World->GetBlockMeta( bx, by, bz); - lastblock = m_World->GetBlock( bx, by, bz); - m_World->SetBlock( bx, by-1, bz, lastblock, lastmeta ); - by += 1 ; - } - - } else { - - while ( ay < by ) { - lastmeta = m_World->GetBlockMeta( bx, by, bz); - lastblock = m_World->GetBlock( bx, by, bz); - m_World->SetBlock( bx, by+1, bz, lastblock, lastmeta ); - by -= 1; - } - - } - - m_World->SetBlock( ax, ay, az, 0, 0 ); - - } else if ( ( ax == bx ) && ( ay == by ) && ( az != bz ) ) { //move z - - if ( az > bz ) { - - while ( az > bz ) { - lastmeta = m_World->GetBlockMeta( bx, by, bz ); - lastblock = m_World->GetBlock( bx, by, bz ); - m_World->SetBlock( bx, by, bz-1, lastblock, lastmeta ); - bz += 1; - } - - } else { - - while ( az < bz ) { - lastmeta = m_World->GetBlockMeta( bx, by, bz ); - lastblock = m_World->GetBlock( bx, by, bz ); - m_World->SetBlock( bx, by, bz+1, lastblock, lastmeta ); - bz -= 1; - } - - } - - m_World->SetBlock( ax, ay, az, 0, 0 ); - - } else { - - //LOG("Bad coords fed into cPiston::ChainMove"); - +void cPiston::ExtendPiston( int pistx, int pisty, int pistz ) { + char pistonBlock = m_World->GetBlock( pistx, pisty, pistz ); + char pistonMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); + char isSticky = (char)(pistonBlock == E_BLOCK_STICKY_PISTON) * 8; + unsigned short dist = FirstPassthroughBlock(pistx, pisty, pistz, pistonMeta); + if(dist>9000) return; // too many blocks + + AddDir( pistx, pisty, pistz, pistonMeta & 7, dist+1 ) + char currBlock = m_World->GetBlock( pistx, pisty, pistz ); + if( currBlock != E_BLOCK_AIR ) { + cItem PickupItem; + PickupItem.m_ItemID = cBlockToPickup::ToPickup( (ENUM_BLOCK_ID) currBlock, E_ITEM_EMPTY ); + PickupItem.m_ItemCount = 1; + cPickup* Pickup = new cPickup( pistx*32 + 16, pisty*32 + 16, pistz*32 + 16, PickupItem ); + Pickup->Initialize( m_World ); } - + int oldx = pistx, oldy = pisty, oldz = pistz; + char currBlockMeta; + for( int i = dist+1; i>0; i-- ) { + AddDir( pistx, pisty, pistz, pistonMeta & 7, -1 ) + currBlock = m_World->GetBlock( pistx, pisty, pistz ); + currBlockMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); + m_World->SetBlock( oldx, oldy, oldz, currBlock, currBlockMeta ); + oldx = pistx; + oldy = pisty; + oldz = pistz; + } + cPacket_BlockAction Action; + Action.m_PosX = (int)pistx; + Action.m_PosY = (short)pisty; + Action.m_PosZ = (int)pistz; + Action.m_Byte1 = 0; + Action.m_Byte2 = pistonMeta; + cRoot::Get()->GetServer()->Broadcast( Action ); + m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 8 ); + + int extx = pistx; + int exty = pisty; + int extz = pistz; + + AddDir( extx, exty, extz, pistonMeta&7, 1 ) + + m_World->SetBlock( extx, exty, extz, E_BLOCK_PISTON_EXTENSION, isSticky+pistonMeta&7 ); } - -int cPiston::FindFluidBlock ( int ax, int ay, int az, int bx, int by, int bz ) -{ - -char thisblock; -int cnt = 0; - if ( ( ax != bx ) && ( ay == by ) && ( az == bz ) ) { //check x - - if ( ax < bx ) { - while ( ax < bx ) { - thisblock = m_World->GetBlock( ax, ay, az); - if ( ((int)thisblock == 0) || ((int)thisblock == E_BLOCK_STATIONARY_WATER) || ((int)thisblock == E_BLOCK_WATER) || ((int)thisblock == E_BLOCK_STATIONARY_LAVA) || ((int)thisblock == E_BLOCK_LAVA) ) { - return cnt; - } - cnt++; - ax += 1; - } - - } else { - - while ( ax > bx ) { - thisblock = m_World->GetBlock( ax, ay, az); - if ( ((int)thisblock == 0) || ((int)thisblock == E_BLOCK_STATIONARY_WATER) || ((int)thisblock == E_BLOCK_WATER) || ((int)thisblock == E_BLOCK_STATIONARY_LAVA) || ((int)thisblock == E_BLOCK_LAVA) ) { - return cnt; - } - cnt++; - ax -= 1; - } - +void cPiston::RetractPiston( int pistx, int pisty, int pistz ) { + char pistonBlock = m_World->GetBlock( pistx, pisty, pistz ); + char pistonMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); + //send blockaction packet + cPacket_BlockAction Action; + Action.m_PosX = (int)pistx; + Action.m_PosY = (short)pisty; + Action.m_PosZ = (int)pistz; + Action.m_Byte1 = 1; + Action.m_Byte1 = pistonMeta & ~(8); + cRoot::Get()->GetServer()->Broadcast( Action ); + m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8) ); + + AddDir( pistx, pisty, pistz, pistonMeta & 7, 1 ) + if( m_World->GetBlock( pistx, pisty, pistz ) == E_BLOCK_PISTON_EXTENSION ) { + if( pistonBlock == E_BLOCK_STICKY_PISTON ) { + int tempx = pistx, tempy = pisty, tempz = pistz; + AddDir( tempx, tempy, tempz, pistonMeta&7, 1 ) + char tempblock = m_World->GetBlock( tempx, tempy, tempz ); + if(tempblock == E_BLOCK_OBSIDIAN || tempblock == E_BLOCK_BEDROCK || tempblock == E_BLOCK_PISTON_EXTENSION) {return;} + m_World->SetBlock( pistx, pisty, pistz, tempblock, m_World->GetBlockMeta( tempx, tempy, tempz ) ); + m_World->SetBlock( tempx, tempy, tempz, E_BLOCK_AIR, 0 ); + }else{ + m_World->SetBlock( pistx, pisty, pistz, E_BLOCK_AIR, 0 ); } - - return cnt; - - } else if ( ( ax == bx ) && ( ay != by ) && ( az == bz ) ) { //check y - - if ( ay < by ) { - - while ( ay < by ) { - thisblock = m_World->GetBlock( ax, ay, az); - if ( ((int)thisblock == 0) || ((int)thisblock == E_BLOCK_STATIONARY_WATER) || ((int)thisblock == E_BLOCK_WATER) || ((int)thisblock == E_BLOCK_STATIONARY_LAVA) || ((int)thisblock == E_BLOCK_LAVA) ) { - return cnt; - } - cnt++; - ay += 1; - } - - } else { - - while ( ay > by ) { - thisblock = m_World->GetBlock( ax, ay, az); - if ( ((int)thisblock == 0) || ((int)thisblock == E_BLOCK_STATIONARY_WATER) || ((int)thisblock == E_BLOCK_WATER) || ((int)thisblock == E_BLOCK_STATIONARY_LAVA) || ((int)thisblock == E_BLOCK_LAVA) ) { - return cnt; - } - cnt++; - ay -= 1; - } - - } - - return cnt; - - } else if ( ( ax == bx ) && ( ay == by ) && ( az != bz ) ) { //check z - - if ( az < bz ) { - - while ( az < bz ) { - thisblock = m_World->GetBlock( ax, ay, az); - if ( ((int)thisblock == 0) || ((int)thisblock == E_BLOCK_STATIONARY_WATER) || ((int)thisblock == E_BLOCK_WATER) || ((int)thisblock == E_BLOCK_STATIONARY_LAVA) || ((int)thisblock == E_BLOCK_LAVA) ) { - return cnt; - } - cnt++; - az += 1; - } - - } else { - - while ( az > bz ) { - thisblock = m_World->GetBlock( ax, ay, az); - if ( ((int)thisblock == 0) || ((int)thisblock == E_BLOCK_STATIONARY_WATER) || ((int)thisblock == E_BLOCK_WATER) || ((int)thisblock == E_BLOCK_STATIONARY_LAVA) || ((int)thisblock == E_BLOCK_LAVA) ) { - return cnt; - } - cnt++; - az -= 1; - } - - } - - return cnt; - - } else { - - return cnt; - } -} +} \ No newline at end of file diff --git a/source/cPiston.h b/source/cPiston.h index 9c4f38099..e976c24a3 100644 --- a/source/cPiston.h +++ b/source/cPiston.h @@ -35,9 +35,11 @@ static char RotationPitchToMetaData( float a_Rotation, float a_Pitch ) void ExtendPiston( int, int, int ); void RetractPiston( int, int, int ); -void ChainMove( int, int, int, int, int, int ); -int FindFluidBlock( int, int, int, int, int, int ); cWorld* m_World; +private: +void ChainMove( int, int, int, char, unsigned short * ); +unsigned short FirstPassthroughBlock( int, int, int, char ); + }; diff --git a/source/cWorld.cpp b/source/cWorld.cpp index 0601746e8..c80ccbe9f 100644 --- a/source/cWorld.cpp +++ b/source/cWorld.cpp @@ -56,6 +56,7 @@ char g_BlockLightValue[128]; char g_BlockSpreadLightFalloff[128]; bool g_BlockTransparent[128]; bool g_BlockOneHitDig[128]; +bool g_BlockPistonBreakable[128]; #define RECI_RAND_MAX (1.f/RAND_MAX) inline float fRadRand( float a_Radius ) @@ -197,6 +198,7 @@ cWorld::cWorld( const char* a_WorldName ) memset( g_BlockSpreadLightFalloff, 0xf, 128 ); // 0xf means total falloff memset( g_BlockTransparent, 0x0, 128 ); memset( g_BlockOneHitDig, 0x0, 128 ); + memset( g_BlockPistonBreakable, 0x0, 128 ); // Emissive blocks g_BlockLightValue[ E_BLOCK_TORCH ] = 14; @@ -246,6 +248,42 @@ cWorld::cWorld( const char* a_WorldName ) g_BlockOneHitDig[ E_BLOCK_REDSTONE_REPEATER_ON ] = true; g_BlockOneHitDig[ E_BLOCK_LOCKED_CHEST ] = true; + // Blocks that breaks when pushed by piston + g_BlockPistonBreakable[ E_BLOCK_AIR ] = true; + g_BlockPistonBreakable[ E_BLOCK_STATIONARY_WATER ] = true; + g_BlockPistonBreakable[ E_BLOCK_WATER ] = true; + g_BlockPistonBreakable[ E_BLOCK_STATIONARY_LAVA ] = true; + g_BlockPistonBreakable[ E_BLOCK_LAVA ] = true; + g_BlockPistonBreakable[ E_BLOCK_BED ] = true; + g_BlockPistonBreakable[ E_BLOCK_COBWEB ] = true; + g_BlockPistonBreakable[ E_BLOCK_TALL_GRASS ] = true; + g_BlockPistonBreakable[ E_BLOCK_YELLOW_FLOWER ] = true; + g_BlockPistonBreakable[ E_BLOCK_BROWN_MUSHROOM ] = true; + g_BlockPistonBreakable[ E_BLOCK_RED_ROSE ] = true; + g_BlockPistonBreakable[ E_BLOCK_RED_MUSHROOM ] = true; + g_BlockPistonBreakable[ E_BLOCK_DEAD_BUSH ] = true; + g_BlockPistonBreakable[ E_BLOCK_TORCH ] = true; + g_BlockPistonBreakable[ E_BLOCK_FIRE ] = true; + g_BlockPistonBreakable[ E_BLOCK_REDSTONE_WIRE ] = true; + g_BlockPistonBreakable[ E_BLOCK_CROPS ] = true; + g_BlockPistonBreakable[ E_BLOCK_LADDER ] = true; + g_BlockPistonBreakable[ E_BLOCK_WOODEN_DOOR ] = true; + g_BlockPistonBreakable[ E_BLOCK_IRON_DOOR ] = true; + g_BlockPistonBreakable[ E_BLOCK_LEVER ] = true; + g_BlockPistonBreakable[ E_BLOCK_STONE_BUTTON ] = true; + g_BlockPistonBreakable[ E_BLOCK_REDSTONE_TORCH_ON ] = true; + g_BlockPistonBreakable[ E_BLOCK_REDSTONE_TORCH_OFF ]= true; + g_BlockPistonBreakable[ E_BLOCK_SNOW ] = true; + g_BlockPistonBreakable[ E_BLOCK_REEDS ] = true; + g_BlockPistonBreakable[ E_BLOCK_PUMPKIN_STEM ] = true; + g_BlockPistonBreakable[ E_BLOCK_MELON_STEM ] = true; + g_BlockPistonBreakable[ E_BLOCK_MELON ] = true; + g_BlockPistonBreakable[ E_BLOCK_PUMPKIN ] = true; + g_BlockPistonBreakable[ E_BLOCK_JACK_O_LANTERN ] = true; + g_BlockPistonBreakable[ E_BLOCK_VINES ] = true; + g_BlockPistonBreakable[ E_BLOCK_STONE_PRESSURE_PLATE ] = true; + g_BlockPistonBreakable[ E_BLOCK_WOODEN_PRESSURE_PLATE ] = true; + } void cWorld::InitializeSpawn() -- cgit v1.2.3