From 36f7084e3fb4193676b14f302d0f961f2102e4ba Mon Sep 17 00:00:00 2001 From: "admin@omencraft.com" Date: Sun, 6 Nov 2011 09:23:20 +0000 Subject: [PATCH] Patch with diff file created by Sebi (implemented some stuff like lava physics, drops are deleted when in lava, water is now slower, lava gives actual damage etc.). Pistons now work mostly as they should. They do not yet show the motion animation and do not emit sound. They do extend, push, and retract as they should though. Right now the only way to activate a piston is to light redstone wire adjacent to it with a redstone torch. git-svn-id: http://mc-server.googlecode.com/svn/trunk@67 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- VC2010/MCServer.vcxproj | 2 + VC2010/MCServer.vcxproj.filters | 9 + makefile | 6 + source/cBlockEntity.h | 2 +- source/cChunk.cpp | 20 +- source/cClientHandle.cpp | 12 +- source/cLavaSimulator.cpp | 216 ++++++++++++++++ source/cLavaSimulator.h | 25 ++ source/cMonster.cpp | 18 +- source/cPickup.cpp | 17 +- source/cPiston.cpp | 419 +++++++++++++++----------------- source/cPlayer.cpp | 46 ++-- source/cRedstone.cpp | 3 - source/cWorld.cpp | 18 +- source/cWorld.h | 3 + 15 files changed, 540 insertions(+), 276 deletions(-) create mode 100644 source/cLavaSimulator.cpp create mode 100644 source/cLavaSimulator.h diff --git a/VC2010/MCServer.vcxproj b/VC2010/MCServer.vcxproj index 13f2193f2..d9253c701 100644 --- a/VC2010/MCServer.vcxproj +++ b/VC2010/MCServer.vcxproj @@ -244,6 +244,7 @@ + @@ -373,6 +374,7 @@ + diff --git a/VC2010/MCServer.vcxproj.filters b/VC2010/MCServer.vcxproj.filters index 96f1e0e40..70a4a6d3f 100644 --- a/VC2010/MCServer.vcxproj.filters +++ b/VC2010/MCServer.vcxproj.filters @@ -382,6 +382,9 @@ {4f551776-009b-4f05-8ab8-748b82279a67} + + {b0401fd9-4021-4ab7-bf61-c8de112b4196} + @@ -766,6 +769,9 @@ cPiston + + cLavaSimulator + @@ -1185,6 +1191,9 @@ cPiston + + cLavaSimulator + diff --git a/makefile b/makefile index 5f0ea966f..13eb768b6 100644 --- a/makefile +++ b/makefile @@ -223,6 +223,7 @@ MCServer : \ build/iniFile.o\ build/cSocket.o\ build/cWaterSimulator.o\ + build/cLavaSimulator.o\ build/cFileFormatUpdater.o\ build/cItem.o $(CC) $(LNK_OPTIONS) \ @@ -410,6 +411,7 @@ MCServer : \ build/iniFile.o\ build/cSocket.o\ build/cWaterSimulator.o\ + build/cLavaSimulator.o\ build/cFileFormatUpdater.o\ build/cItem.o\ -o MCServer @@ -600,6 +602,7 @@ clean : build/iniFile.o\ build/cSocket.o\ build/cWaterSimulator.o\ + build/cLavaSimulator.o\ build/cFileFormatUpdater.o\ build/cItem.o\ MCServer @@ -1380,6 +1383,9 @@ build/cSocket.o : source/cSocket.cpp build/cWaterSimulator.o : source/cWaterSimulator.cpp $(CC) $(CC_OPTIONS) source/cWaterSimulator.cpp -c $(INCLUDE) -o build/cWaterSimulator.o +build/cLavaSimulator.o : source/cLavaSimulator.cpp + $(CC) $(CC_OPTIONS) source/cLavaSimulator.cpp -c $(INCLUDE) -o build/cLavaSimulator.o + build/cFileFormatUpdater.o : source/cFileFormatUpdater.cpp $(CC) $(CC_OPTIONS) source/cFileFormatUpdater.cpp -c $(INCLUDE) -o build/cFileFormatUpdater.o diff --git a/source/cBlockEntity.h b/source/cBlockEntity.h index cbb6e7681..e955caff2 100644 --- a/source/cBlockEntity.h +++ b/source/cBlockEntity.h @@ -22,7 +22,7 @@ protected: public: virtual ~cBlockEntity() {}; virtual void Destroy() {}; - + int GetPosX() { return m_PosX; } int GetPosY() { return m_PosY; } int GetPosZ() { return m_PosZ; } diff --git a/source/cChunk.cpp b/source/cChunk.cpp index e9fd739eb..a8a579e96 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -337,7 +337,7 @@ void cChunk::Tick(float a_Dt) case E_BLOCK_GRASS: { char AboveBlock = GetBlock( Index+1 ); - if (!( (AboveBlock == 0) || (g_BlockOneHitDig[AboveBlock]) ) ) //changed to not allow grass if any one hit object is on top + if (!( (AboveBlock == 0) || (g_BlockOneHitDig[AboveBlock]) || (g_BlockTransparent[AboveBlock]) ) ) //changed to not allow grass if any one hit object is on top { FastSetBlock( m_BlockTickX, m_BlockTickY, m_BlockTickZ, E_BLOCK_DIRT, GetLight( m_BlockMeta, Index ) ); } @@ -687,13 +687,13 @@ void cChunk::SpreadLight(char* a_LightBuffer) float GetNoise( float x, float y, cNoise & a_Noise ) { - float oct1 = a_Noise.SSE_CubicNoise2D( x*cGenSettings::HeightFreq1, y*cGenSettings::HeightFreq1 )*cGenSettings::HeightAmp1; - float oct2 = a_Noise.SSE_CubicNoise2D( x*cGenSettings::HeightFreq2, y*cGenSettings::HeightFreq2 )*cGenSettings::HeightAmp2; - float oct3 = a_Noise.SSE_CubicNoise2D( x*cGenSettings::HeightFreq3, y*cGenSettings::HeightFreq3 )*cGenSettings::HeightAmp3; + float oct1 = a_Noise.CubicNoise2D( x*cGenSettings::HeightFreq1, y*cGenSettings::HeightFreq1 )*cGenSettings::HeightAmp1; + float oct2 = a_Noise.CubicNoise2D( x*cGenSettings::HeightFreq2, y*cGenSettings::HeightFreq2 )*cGenSettings::HeightAmp2; + float oct3 = a_Noise.CubicNoise2D( x*cGenSettings::HeightFreq3, y*cGenSettings::HeightFreq3 )*cGenSettings::HeightAmp3; - float height = a_Noise.SSE_CubicNoise2D( x*0.1f, y*0.1f )*2; + float height = a_Noise.CubicNoise2D( x*0.1f, y*0.1f )*2; - float flatness = ((a_Noise.SSE_CubicNoise2D( x*0.5f, y*0.5f ) + 1.f ) * 0.5f) * 1.1f; // 0 ... 1.5 + float flatness = ((a_Noise.CubicNoise2D( x*0.5f, y*0.5f ) + 1.f ) * 0.5f) * 1.1f; // 0 ... 1.5 flatness *= flatness * flatness; return (oct1 + oct2 + oct3) * flatness + height; @@ -845,8 +845,8 @@ void cChunk::GenerateTerrain() // int yy = TopY; int zz = z + m_PosZ*16; - float val1 = m_Noise.SSE_CubicNoise2D( xx*0.1f, zz*0.1f ); - float val2 = m_Noise.SSE_CubicNoise2D( xx*0.01f, zz*0.01f ); + float val1 = m_Noise.CubicNoise2D( xx*0.1f, zz*0.1f ); + float val2 = m_Noise.CubicNoise2D( xx*0.01f, zz*0.01f ); if( m_BlockType[index] == SandID ) { if( (val1 + val2 > 0.f) && (rand()%128) > 124 && m_BlockType[index] == E_BLOCK_SAND ) @@ -861,8 +861,8 @@ void cChunk::GenerateTerrain() } else if( m_BlockType[index] == GrassID ) { - float val3 = m_Noise.SSE_CubicNoise2D( xx*0.01f+10, zz*0.01f+10 ); - float val4 = m_Noise.SSE_CubicNoise2D( xx*0.05f+20, zz*0.05f+20 ); + float val3 = m_Noise.CubicNoise2D( xx*0.01f+10, zz*0.01f+10 ); + float val4 = m_Noise.CubicNoise2D( xx*0.05f+20, zz*0.05f+20 ); if( val1 + val2 > 0.2f && (rand()%128) > 124 ) m_World->GrowTree( xx, TopY, zz ); else if( val3 > 0.2f && (rand()%128) > 124 ) diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index 2238a3df0..515134683 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -523,7 +523,6 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) { if( World->DigBlock( PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ, PickupItem ) ) { - printf("OldBlock,E_BLOCK_REDSTONE_TORCH_ON: %i,%i\n", OldBlock, E_BLOCK_REDSTONE_TORCH_ON ); if (OldBlock == E_BLOCK_REDSTONE_TORCH_ON) { cRedstone Redstone(World); Redstone.cRedstone::ChangeRedstoneTorch( PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ, false ); @@ -767,9 +766,9 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) //if( GetBlock( X, Y+1, Z ) == E_BLOCK_AIR ) if( g_BlockTransparent[ (int)m_Player->GetWorld()->GetBlock( PacketData->m_PosX, PacketData->m_PosY+2, PacketData->m_PosZ ) ] == true ) {//if block above is transparent - printf("transparent above me\n"); + //printf("transparent above me\n"); } else { - printf("transparent not above me\n"); + //printf("transparent not above me\n"); } cRedstone Redstone(m_Player->GetWorld()); @@ -1051,11 +1050,10 @@ void cClientHandle::Tick(float a_Dt) // Send health Send( cPacket_UpdateHealth( (short)m_Player->GetHealth() ) ); - //quick bugfix to prevent players from spawning in ground - //m_Player->TeleportTo( m_Player->GetPosX(), m_Player->GetPosY()+1, m_Player->GetPosZ() ); - World->UnlockEntities(); - m_Player->TeleportTo( m_Player->GetPosX(), m_Player->GetPosY()+1, m_Player->GetPosZ() ); + + //quick bugfix to prevent players from spawning in ground + m_Player->TeleportTo( m_Player->GetPosX(), m_Player->GetPosY()+2, m_Player->GetPosZ() ); } } diff --git a/source/cLavaSimulator.cpp b/source/cLavaSimulator.cpp new file mode 100644 index 000000000..e8dbb4126 --- /dev/null +++ b/source/cLavaSimulator.cpp @@ -0,0 +1,216 @@ +#include "cLavaSimulator.h" +#include "cWorld.h" +#include "Vector3i.h" +#include "BlockID.h" +#include + +class cLavaSimulator::LavaData +{ +public: + LavaData( cWorld* a_World ) + : m_ActiveLava( new std::vector< Vector3i >() ) + , m_Buffer( new std::vector< Vector3i >() ) + , m_World( a_World ) + {} + + std::vector< Vector3i > GetLowestPoints( int a_X, int a_Y, int a_Z ) + { + std::vector< Vector3i > Points; + if( m_World->GetBlock(a_X, a_Y-1, a_Z) == E_BLOCK_AIR ) + { + Points.push_back( Vector3i( a_X, a_Y-1, a_Z ) ); + return Points; + } + + Vector3i LowerPoints [] = { + Vector3i( a_X-1, a_Y-1, a_Z ), + Vector3i( a_X+1, a_Y-1, a_Z ), + Vector3i( a_X, a_Y-1, a_Z-1 ), + Vector3i( a_X, a_Y-1, a_Z+1 ), + }; + bool bLavaFound = false; + for( int i = 0; i < 4; ++i ) + { + char Block1 = m_World->GetBlock( LowerPoints[i].x, LowerPoints[i].y, LowerPoints[i].z ); + char Block2 = m_World->GetBlock( LowerPoints[i].x, a_Y, LowerPoints[i].z ); + if( Block1 == E_BLOCK_AIR && Block2 == E_BLOCK_AIR ) + { + Points.push_back( LowerPoints[i] ); + LowerPoints[i].y = a_Y; + Points.push_back( LowerPoints[i] ); + } + else if( (Block2 == E_BLOCK_LAVA || Block2 == E_BLOCK_STATIONARY_LAVA ) && ( Block1 == E_BLOCK_AIR || Block1 == E_BLOCK_LAVA || Block1 == E_BLOCK_STATIONARY_LAVA ) ) + { + bLavaFound = true; + } + } + + if( Points.size() == 0 && !bLavaFound ) + { + Vector3i LevelPoints [] = { + Vector3i( a_X-1, a_Y, a_Z ), + Vector3i( a_X+1, a_Y, a_Z ), + Vector3i( a_X, a_Y, a_Z-1 ), + Vector3i( a_X, a_Y, a_Z+1 ), + }; + for( int i = 0; i < 4; ++i ) + { + char Block = m_World->GetBlock( LevelPoints[i].x, a_Y, LevelPoints[i].z ); + if( Block == E_BLOCK_AIR || Block == E_BLOCK_LAVA || Block == E_BLOCK_STATIONARY_LAVA ) + Points.push_back( LevelPoints[i] ); + } + } + return Points; + } + + std::vector< Vector3i >* m_ActiveLava; + std::vector< Vector3i >* m_Buffer; + cWorld* m_World; +}; + +cLavaSimulator::cLavaSimulator( cWorld* a_World ) + : m_World( a_World ) + , m_Data( new LavaData( a_World ) ) +{ +} + +cLavaSimulator::~cLavaSimulator() +{ +} + +void cLavaSimulator::WakeUp( int a_X, int a_Y, int a_Z ) +{ + AddBlock( a_X, a_Y, a_Z ); + AddBlock( a_X-1, a_Y, a_Z ); + AddBlock( a_X+1, a_Y, a_Z ); + AddBlock( a_X, a_Y-1, a_Z ); + AddBlock( a_X, a_Y+1, a_Z ); + AddBlock( a_X, a_Y, a_Z-1 ); + AddBlock( a_X, a_Y, a_Z+1 ); +} + +void cLavaSimulator::AddBlock( int a_X, int a_Y, int a_Z ) +{ + // Check for duplicates + std::vector< Vector3i > & ActiveLava = *m_Data->m_ActiveLava; + for( std::vector< Vector3i >::iterator itr = ActiveLava.begin(); itr != ActiveLava.end(); ++itr ) + { + Vector3i & pos = *itr; + if( pos.x == a_X && pos.y == a_Y && pos.z == a_Z ) + return; + } + + ActiveLava.push_back( Vector3i( a_X, a_Y, a_Z ) ); +} + +char cLavaSimulator::GetHighestLevelAround( int a_X, int a_Y, int a_Z ) +{ + char Max = 8; +#define __HIGHLEVEL_CHECK__( x, y, z ) \ + if( IsLavaBlock( m_World->GetBlock( x, y, z ) ) ) \ + { \ + char Meta; \ + if( (Meta = m_World->GetBlockMeta( x, y, z ) ) < Max ) Max = Meta; \ + else if( Meta == 8 ) Max = 0; \ + if( Max == 0 ) return 0; \ + } + + __HIGHLEVEL_CHECK__( a_X-1, a_Y, a_Z ); + __HIGHLEVEL_CHECK__( a_X+1, a_Y, a_Z ); + __HIGHLEVEL_CHECK__( a_X, a_Y, a_Z-1 ); + __HIGHLEVEL_CHECK__( a_X, a_Y, a_Z+1 ); + + return Max; +} + +void cLavaSimulator::Simulate( float a_Dt ) +{ + m_Timer += a_Dt; + + std::swap( m_Data->m_ActiveLava, m_Data->m_Buffer ); // Swap so blocks can be added to empty ActiveLava array + m_Data->m_ActiveLava->clear(); + + std::vector< Vector3i > & LavaBlocks = *m_Data->m_Buffer; + for( std::vector< Vector3i >::iterator itr = LavaBlocks.begin(); itr != LavaBlocks.end(); ++itr ) + { + Vector3i & pos = *itr; + char BlockID = m_World->GetBlock( pos.x, pos.y, pos.z ); + if( IsLavaBlock( BlockID ) ) // only care about lava + { + bool bIsFed = false; + char Meta = m_World->GetBlockMeta( pos.x, pos.y, pos.z ); + char Feed = Meta; + if( Meta == 8 ) // Falling lava + { + if( IsLavaBlock( m_World->GetBlock(pos.x, pos.y+1, pos.z) ) ) // Block above is lava + { + bIsFed = true; + Meta = 0; // Make it a full block + } + } + else if( Meta <= 2 ) + { + bIsFed = true; + } + else + { + if( (Feed = GetHighestLevelAround( pos.x, pos.y, pos.z )) < Meta ) + bIsFed = true; + } + + + if( bIsFed ) + { + char DownID = m_World->GetBlock( pos.x, pos.y-1, pos.z ); + if( DownID == E_BLOCK_AIR || IsLavaBlock( DownID ) ) // free for Lava + { + m_World->FastSetBlock( pos.x, pos.y-1, pos.z, E_BLOCK_LAVA, 8 ); // falling + AddBlock( pos.x, pos.y-1, pos.z ); + } + else // Not falling Lava + { + if( Feed+2 < Meta ) + { + m_World->FastSetBlock( pos.x, pos.y, pos.z, E_BLOCK_LAVA, Feed+2 ); + AddBlock( pos.x, pos.y, pos.z ); + } + else if( Meta < 6 ) // 7 is only 1 unit high, so it cannot spread, lower than 7 can though. + { + std::vector< Vector3i > Points = m_Data->GetLowestPoints( pos.x, pos.y, pos.z ); + for( std::vector< Vector3i >::iterator itr = Points.begin(); itr != Points.end(); ++itr ) + { + Vector3i & p = *itr; + char BlockID = m_World->GetBlock( p.x, p.y, p.z ); + if( !IsLavaBlock( BlockID ) ) + { + if( p.y == pos.y ) + m_World->FastSetBlock(p.x, p.y, p.z, E_BLOCK_LAVA, Meta+2); + else + m_World->FastSetBlock(p.x, p.y, p.z, E_BLOCK_LAVA, 8); + AddBlock( p.x, p.y, p.z ); + } + else // it's Lava + { + char PointMeta = m_World->GetBlockMeta( p.x, p.y, p.z ); + if( PointMeta > Meta+2 ) + { + AddBlock( p.x, p.y, p.z ); + } + } + } + } + } + } + else // not fed + { + m_World->FastSetBlock( pos.x, pos.y, pos.z, E_BLOCK_AIR, 0 ); + WakeUp( pos.x, pos.y, pos.z ); + } + } + } +} + +bool cLavaSimulator::IsLavaBlock( char a_BlockID ) +{ + return a_BlockID == E_BLOCK_LAVA || a_BlockID == E_BLOCK_STATIONARY_LAVA; +} diff --git a/source/cLavaSimulator.h b/source/cLavaSimulator.h new file mode 100644 index 000000000..f1c59b939 --- /dev/null +++ b/source/cLavaSimulator.h @@ -0,0 +1,25 @@ +#pragma once + +class Vector3i; +class cWorld; +class cLavaSimulator +{ +public: + cLavaSimulator( cWorld* a_World ); + ~cLavaSimulator(); + + void Simulate( float a_Dt ); + void WakeUp( int a_X, int a_Y, int a_Z ); + +private: + void AddBlock( int a_X, int a_Y, int a_Z); + char GetHighestLevelAround( int a_X, int a_Y, int a_Z ); + + bool IsLavaBlock( char a_BlockID ); + + float m_Timer; + cWorld* m_World; + + class LavaData; + LavaData* m_Data; +}; diff --git a/source/cMonster.cpp b/source/cMonster.cpp index 99a74a86f..0eeac1409 100644 --- a/source/cMonster.cpp +++ b/source/cMonster.cpp @@ -474,22 +474,22 @@ void cMonster::InStateIdle(float a_Dt) { void cMonster::InStateBurning(float a_Dt) { m_FireDamageInterval += a_Dt; char block = GetWorld()->GetBlock( (int)m_Pos->x, (int)m_Pos->y, (int)m_Pos->z ); - char bblock = GetWorld()->GetBlock( (int)m_Pos->x, (int)m_Pos->y -1, (int)m_Pos->z ); + char bblock = GetWorld()->GetBlock( (int)m_Pos->x, (int)m_Pos->y +1, (int)m_Pos->z ); if(m_FireDamageInterval > 1) { m_FireDamageInterval = 0; - int rem = rand()%3 + 1; //Burn most of the time - if(rem >= 2) { - //printf("OUCH burning!!!\n"); - TakeDamage(1, this); - } + TakeDamage(1, this); + m_BurnPeriod++; if(block == E_BLOCK_LAVA || block == E_BLOCK_STATIONARY_LAVA || block == E_BLOCK_FIRE - || bblock == E_BLOCK_LAVA || bblock == E_BLOCK_STATIONARY_LAVA || bblock == E_BLOCK_FIRE) + || bblock == E_BLOCK_LAVA || bblock == E_BLOCK_STATIONARY_LAVA || bblock == E_BLOCK_FIRE) { m_BurnPeriod = 0; + TakeDamage(6, this); + }else{ + TakeDamage(1, this); + } - if(m_BurnPeriod > 5) { - + if(m_BurnPeriod > 8) { cChunk* InChunk = GetWorld()->GetChunkUnreliable( m_ChunkX, m_ChunkY, m_ChunkZ ); m_EMMetaState = NORMAL; cPacket_Metadata md(NORMAL, GetUniqueID()); diff --git a/source/cPickup.cpp b/source/cPickup.cpp index c712d9919..10427f5b3 100644 --- a/source/cPickup.cpp +++ b/source/cPickup.cpp @@ -125,7 +125,8 @@ void cPickup::Tick(float a_Dt) return; } - HandlePhysics( a_Dt ); + if(!m_bCollected) + HandlePhysics( a_Dt ); if( !m_bReplicated || m_bDirtyPosition ) { @@ -148,14 +149,18 @@ void cPickup::HandlePhysics(float a_Dt) if( m_bOnGround ) // check if it's still on the ground { cWorld* World = GetWorld(); - int BlockX = (int)m_Pos->x; - if( m_Pos->x < 0 ) BlockX--; - int BlockZ = (int)m_Pos->z; - if( m_Pos->z < 0 ) BlockZ--; + int BlockX = (m_Pos->x)<0 ? (int)m_Pos->x-1 : (int)m_Pos->x; + int BlockZ = (m_Pos->z)<0 ? (int)m_Pos->z-1 : (int)m_Pos->z; if( World->GetBlock( BlockX, (int)m_Pos->y -1, BlockZ ) == E_BLOCK_AIR ) { m_bOnGround = false; } + char block = World->GetBlock( BlockX, (int)m_Pos->y - (int)m_bOnGround, BlockZ ); + if( block == E_BLOCK_STATIONARY_LAVA || block == E_BLOCK_LAVA ) { + m_bCollected = true; + m_Timer = 0; + return; + } if( World->GetBlock( BlockX, (int)m_Pos->y, BlockZ ) != E_BLOCK_AIR ) // If in ground itself, push it out { m_bOnGround = true; @@ -211,7 +216,7 @@ void cPickup::HandlePhysics(float a_Dt) bool cPickup::CollectedBy( cPlayer* a_Dest ) { if(m_bCollected) return false; // It's already collected! - if(m_Timer < 1000.f) return false; // Not old enough + if(m_Timer < 800.f) return false; // Not old enough if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_COLLECT_ITEM, 2, this, a_Dest ) ) return false; diff --git a/source/cPiston.cpp b/source/cPiston.cpp index af424fc3d..e6adbcc5c 100644 --- a/source/cPiston.cpp +++ b/source/cPiston.cpp @@ -14,76 +14,67 @@ void cPiston::ExtendPiston( int pistx, int pisty, int pistz ) //cWorld* World = cRoot::Get()->GetWorld(); char metadata = 0; char extmetadata = 0; - int FirstFluidBlock = 0; + int FirstFluidBlock = 0; char piston; piston = m_World->GetBlock( pistx, pisty, pistz ); - printf("psPiston1\n"); - if ( piston == E_BLOCK_STICKY_PISTON ) { - printf("psPiston2\n"); extmetadata = 8; - }//if sticky piston than top nibble bit is set to 1; - + }//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); - printf("psPiston3\n"); - printf("metadata %c\n",metadata); - if (metadata < 5) { //piston not extended - - printf("metadata %c\n",metadata); - metadata -= 8; //removing 8 from retracts it - switch (metadata) { + if ((int)metadata < 6) { //piston not extended + switch ((int)metadata) { case 0: - FirstFluidBlock = FindFluidBlock ( pistx, pisty, pistz, pistx, pisty-16, pistz ); + FirstFluidBlock = FindFluidBlock ( pistx, pisty-1, pistz, pistx, pisty-16, pistz ); if (FirstFluidBlock > 0) { ChainMove ( pistx, pisty, pistz, pistx, pisty-FirstFluidBlock, pistz ); } m_World->FastSetBlock( pistx, pisty, pistz, piston, (char)metadata + 8 ); - m_World->FastSetBlock( pistx, pisty-1, pistz, E_BLOCK_PISTON_EXTENSION, extmetadata ); + m_World->SetBlock( pistx, pisty-1, pistz, E_BLOCK_PISTON_EXTENSION, extmetadata ); break; case 1: - FirstFluidBlock = FindFluidBlock (pistx, pisty, pistz, pistx, pisty+16, pistz); - if (FirstFluidBlock > 0) { - ChainMove ( pistx, pisty, pistz, pistx, pisty+FirstFluidBlock, pistz ); - } + FirstFluidBlock = FindFluidBlock (pistx, pisty+1, pistz, pistx, pisty+16, pistz); + if (FirstFluidBlock > 0) { + ChainMove ( pistx, pisty, pistz, pistx, pisty+FirstFluidBlock, pistz ); + } m_World->FastSetBlock( pistx, pisty, pistz, piston, (char)metadata + 8 ); - m_World->FastSetBlock( pistx, pisty+1, pistz, E_BLOCK_PISTON_EXTENSION, extmetadata+1 ); + m_World->SetBlock( pistx, pisty+1, pistz, E_BLOCK_PISTON_EXTENSION, extmetadata+1 ); break; case 2: - FirstFluidBlock = FindFluidBlock (pistx, pisty, pistz, pistx, pisty, pistz-16); - if (FirstFluidBlock > 0) { - ChainMove ( pistx, pisty, pistz, pistx, pisty, pistz-FirstFluidBlock ); - } + FirstFluidBlock = FindFluidBlock (pistx, pisty, pistz-1, pistx, pisty, pistz-16); + if (FirstFluidBlock > 0) { + ChainMove ( pistx, pisty, pistz, pistx, pisty, pistz-FirstFluidBlock ); + } m_World->FastSetBlock( pistx, pisty, pistz, piston, (char)metadata + 8 ); - m_World->FastSetBlock( pistx, pisty, pistz-1, E_BLOCK_PISTON_EXTENSION, extmetadata+2 ); + m_World->SetBlock( pistx, pisty, pistz-1, E_BLOCK_PISTON_EXTENSION, extmetadata+2 ); break; case 3: - FirstFluidBlock = FindFluidBlock (pistx, pisty, pistz, pistx, pisty, pistz+16); - if (FirstFluidBlock > 0) { - ChainMove ( pistx, pisty, pistz, pistx, pisty, pistz+FirstFluidBlock ); - } - m_World->FastSetBlock( pistx, pisty, pistz, piston, (char)metadata + 8 ); - m_World->FastSetBlock( pistx, pisty, pistz+1, E_BLOCK_PISTON_EXTENSION, extmetadata+3 ); + FirstFluidBlock = FindFluidBlock (pistx, pisty, pistz+1, pistx, pisty, pistz+16); + if (FirstFluidBlock > 0) { + ChainMove ( pistx, pisty, pistz, pistx, pisty, pistz+FirstFluidBlock ); + } + 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, pisty, pistz, pistx-16, pisty, pistz); - if (FirstFluidBlock > 0) { - ChainMove ( pistx, pisty, pistz, pistx-FirstFluidBlock, pisty, pistz ); - } - m_World->FastSetBlock( pistx, pisty, pistz, piston, metadata + 8 ); - m_World->FastSetBlock( pistx, pisty+1, pistz, E_BLOCK_PISTON_EXTENSION, extmetadata+4 ); + FirstFluidBlock = FindFluidBlock (pistx-1, pisty, pistz, pistx-16, pisty, pistz); + if (FirstFluidBlock > 0) { + ChainMove ( pistx, pisty, pistz, pistx-FirstFluidBlock, pisty, pistz ); + } + 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, pisty, pistz, pistx+16, pisty, pistz); - if (FirstFluidBlock > 0) { - ChainMove ( pistx, pisty, pistz, pistx+FirstFluidBlock, pisty, pistz ); - } - m_World->FastSetBlock( pistx, pisty, pistz, piston, metadata + 8 ); - m_World->FastSetBlock( pistx, pisty+1, pistz, E_BLOCK_PISTON_EXTENSION, extmetadata+5 ); + FirstFluidBlock = FindFluidBlock (pistx+1, pisty, pistz, pistx+16, pisty, pistz); + if (FirstFluidBlock > 0) { + ChainMove ( pistx, pisty, pistz, pistx+FirstFluidBlock, pisty, pistz ); + } + m_World->FastSetBlock( pistx, pisty, pistz, piston, metadata + 8 ); + m_World->SetBlock( pistx+1, pisty, pistz, E_BLOCK_PISTON_EXTENSION, extmetadata+5 ); break; } } @@ -93,9 +84,11 @@ void cPiston::ExtendPiston( int pistx, int pisty, int pistz ) 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 + if (metadata > 5) { //piston retracted metadata -= 8;//set the piston to retracted state. m_World->FastSetBlock( pistx, pisty, pistz, m_World->GetBlock( pistx, pisty, pistz ), metadata ); @@ -108,90 +101,102 @@ void cPiston::RetractPiston( int pistx, int pisty, int pistz ) case 1: if ( m_World->GetBlock( pistx, pisty+1, pistz ) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx, pisty+1, pistz, 0, 0 ); + m_World->SetBlock( pistx, pisty+1, pistz, 0, 0 ); } break; case 2: if ( m_World->GetBlock( pistx, pisty, pistz-1 ) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx, pisty, pistz-1, 0, 0 ); + m_World->SetBlock( pistx, pisty, pistz-1, 0, 0 ); } break; case 3: if ( m_World->GetBlock( pistx, pisty, pistz+1 ) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx, pisty, pistz+1, 0, 0 ); + m_World->SetBlock( pistx, pisty, pistz+1, 0, 0 ); } break; case 4: if ( m_World->GetBlock( pistx-1, pisty, pistz ) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx-1, pisty, pistz, 0, 0 ); + m_World->SetBlock( pistx-1, pisty, pistz, 0, 0 ); } break; case 5: if ( m_World->GetBlock( pistx+1, pisty, pistz ) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx+1, pisty, pistz, 0, 0 ); + m_World->SetBlock( pistx+1, pisty, pistz, 0, 0 ); } break; } } - } + } - if ( (int)m_World->GetBlock( pistx, pisty, pistz ) == E_BLOCK_PISTON ) { - if (metadata > 5) { //piston retracted - metadata -= 8;//set the piston to retracted state. + 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. + m_World->FastSetBlock( pistx, pisty, pistz, m_World->GetBlock( pistx, pisty, pistz ), metadata ); + switch (metadata) { + case 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; - m_World->FastSetBlock( pistx, pisty, pistz, m_World->GetBlock( pistx, pisty, pistz ), metadata ); - switch (metadata) { - case 0: - if ( m_World->GetBlock( pistx, pisty-1, pistz ) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx, pisty-1, pistz, m_World->GetBlock( pistx, pisty-2, pistz ), m_World->GetBlockMeta( pistx, pisty-2, pistz ) ); - m_World->SetBlock( pistx, pisty-2, pistz, 0, 0 ); - } - break; - - case 1: - if ( m_World->GetBlock( pistx, pisty+1, pistz ) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx, pisty-1, pistz, m_World->GetBlock( pistx, pisty-2, pistz ), m_World->GetBlockMeta( pistx, pisty-2, pistz ) ); - m_World->SetBlock( pistx, pisty-2, pistz, 0, 0 ); - } - break; - - case 2: - if ( m_World->GetBlock( pistx, pisty, pistz-1) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx, pisty, pistz-1, m_World->GetBlock( pistx, pisty, pistz-2 ), m_World->GetBlockMeta( pistx, pisty, pistz-2 ) ); - m_World->SetBlock( pistx, pisty, pistz-2, 0, 0 ); - } - break; - - case 3: - if ( m_World->GetBlock( pistx, pisty, pistz+1) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx, pisty, pistz+1, m_World->GetBlock( pistx, pisty, pistz+2 ), m_World->GetBlockMeta( pistx, pisty, pistz+2 ) ); - m_World->SetBlock( pistx, pisty, pistz+2, 0, 0 ); - } - break; - - case 4: - if ( m_World->GetBlock( pistx-1, pisty, pistz) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx-1, pisty, pistz, m_World->GetBlock( pistx-2, pisty, pistz ), m_World->GetBlockMeta( pistx-2, pisty, pistz ) ); - m_World->SetBlock( pistx-2, pisty, pistz, 0, 0 ); - } - break; - - case 5: - if ( m_World->GetBlock( pistx+1, pisty, pistz) == E_BLOCK_PISTON_EXTENSION ) { - m_World->SetBlock( pistx+1, pisty, pistz, m_World->GetBlock( pistx+2, pisty, pistz ), m_World->GetBlockMeta( pistx+2, pisty, pistz ) ); - m_World->SetBlock( pistx+2, pisty, pistz, 0, 0 ); - } - break; - - } - } - } + case 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: + 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: + 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: + 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: + 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; + } + } + } } void cPiston::ChainMove ( int ax, int ay, int az, int bx, int by, int bz ) @@ -202,27 +207,23 @@ char lastblock; if ( ( ax != bx ) && ( ay == by ) && ( az == bz ) ) { //move x - if ( ax < bx ) { + if ( ax > bx ) { while ( ax > bx ) { - - lastmeta = m_World->GetBlockMeta( bx+1, by, bz); - lastblock = m_World->GetBlockMeta( bx+1, by, bz); - m_World->SetBlock( bx, by, bz, lastblock, lastmeta ); - bx+1; - + 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-1, by, bz); - lastblock = m_World->GetBlockMeta( bx-1, by, bz); - m_World->SetBlock( bx, by, bz, lastblock, lastmeta ); - bx-1; - - } + 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; + } } @@ -230,57 +231,49 @@ char lastblock; } else if ( ( ax == bx ) && ( ay != by ) && ( az == bz ) ) { //move y - if ( ay < by ) { + if ( ay > by ) { - while ( 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 ; + } - lastmeta = m_World->GetBlockMeta( bx, by+1, bz); - lastblock = m_World->GetBlockMeta( bx, by+1, bz); - m_World->SetBlock( bx, by, 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; + } - } else { - - while ( ay < by ) { - - lastmeta = m_World->GetBlockMeta( bx, by-1, bz); - lastblock = m_World->GetBlockMeta( bx, by-1, bz); - m_World->SetBlock( bx, by, 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 ) { + if ( az > bz ) { - while ( 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; + } - lastmeta = m_World->GetBlockMeta( bx, by, bz+1 ); - lastblock = m_World->GetBlockMeta( bx, by, bz+1 ); - m_World->SetBlock( bx, by, bz, 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; + } - } else { - - while ( az < bz ) { - - lastmeta = m_World->GetBlockMeta( bx, by, bz-1 ); - lastblock = m_World->GetBlockMeta( bx, by, bz-1 ); - m_World->SetBlock( bx, by, bz, lastblock, lastmeta ); - bz-1; - - } - - } + } m_World->SetBlock( ax, ay, az, 0, 0 ); @@ -299,104 +292,92 @@ 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 ) && ( ay == by ) && ( az == bz ) ) { //check x - if ( ax < bx ) { - - while ( ax < bx ) { - - thisblock = m_World->GetBlock( ax, ay, az); - if ( (thisblock == 0) || (thisblock == E_BLOCK_STATIONARY_WATER) || (thisblock == E_BLOCK_WATER) || (thisblock == E_BLOCK_STATIONARY_LAVA) || (thisblock == E_BLOCK_LAVA) ) { - return cnt; + 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; - } + ax += 1; + } - } else { + } else { - while ( ax > bx ) { - - thisblock = m_World->GetBlock( ax, ay, az); - if ( (thisblock == 0) || (thisblock == E_BLOCK_STATIONARY_WATER) || (thisblock == E_BLOCK_WATER) || (thisblock == E_BLOCK_STATIONARY_LAVA) || (thisblock == E_BLOCK_LAVA) ) { - return cnt; + 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; + ax -= 1; + } - } + } - } + return cnt; - m_World->SetBlock( ax, ay, az, 0, 0 ); + } else if ( ( ax == bx ) && ( ay != by ) && ( az == bz ) ) { //check y - } else if ( ( ax == bx ) && ( ay != by ) && ( az == bz ) ) { //check y + if ( ay < by ) { - if ( ay < by ) { - - while ( ay < by ) { - - thisblock = m_World->GetBlock( bx, by, bz); - if ( (thisblock == 0) || (thisblock == E_BLOCK_STATIONARY_WATER) || (thisblock == E_BLOCK_WATER) || (thisblock == E_BLOCK_STATIONARY_LAVA) || (thisblock == E_BLOCK_LAVA) ) { - return cnt; + 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; + ay += 1; + } - } + } else { - } else { - - while ( ay > by ) { - - thisblock = m_World->GetBlock( bx, by, bz); - if ( (thisblock == 0) || (thisblock == E_BLOCK_STATIONARY_WATER) || (thisblock == E_BLOCK_WATER) || (thisblock == E_BLOCK_STATIONARY_LAVA) || (thisblock == E_BLOCK_LAVA) ) { - return cnt; + 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; + ay -= 1; + } - } + } - } + return cnt; - m_World->SetBlock( ax, ay, az, 0, 0 ); + } else if ( ( ax == bx ) && ( ay == by ) && ( az != bz ) ) { //check z - } else if ( ( ax == bx ) && ( ay == by ) && ( az != bz ) ) { //check z + if ( az < bz ) { - if ( az < bz ) { - - while ( az < bz ) { - - thisblock = m_World->GetBlock( ax, ay, az); - if ( (thisblock == 0) || (thisblock == E_BLOCK_STATIONARY_WATER) || (thisblock == E_BLOCK_WATER) || (thisblock == E_BLOCK_STATIONARY_LAVA) || (thisblock == E_BLOCK_LAVA) ) { - return cnt; + 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; + az += 1; + } - } + } else { - } else { - - while ( az > bz ) { - - thisblock = m_World->GetBlock( ax, ay, az); - if ( (thisblock == 0) || (thisblock == E_BLOCK_STATIONARY_WATER) || (thisblock == E_BLOCK_WATER) || (thisblock == E_BLOCK_STATIONARY_LAVA) || (thisblock == E_BLOCK_LAVA) ) { - return cnt; + 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; + az -= 1; + } - } + } - } + return cnt; - } else { - - return cnt; - - } + } else { + return cnt; + } } diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp index 85eec3e2d..62098eb0b 100644 --- a/source/cPlayer.cpp +++ b/source/cPlayer.cpp @@ -40,7 +40,7 @@ #include #define sprintf_s(dst, size, format, ...) sprintf(dst, format, __VA_ARGS__ ) #endif - +#define float2int(x) ((x)<0 ? ((int)(x))-1 : (int)(x)) extern std::vector< std::string > StringSplit( std::string str, std::string delim); CLASS_DEFINITION( cPlayer, cPawn ); @@ -81,7 +81,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const char* a_PlayerName) m_TimeLastTeleportPacket = cWorld::GetTime(); m_TimeLastPickupCheck = cWorld::GetTime(); - + m_pState->PlayerName = a_PlayerName; m_bDirtyPosition = true; // So chunks are streamed to player at spawn @@ -104,6 +104,7 @@ cPlayer::~cPlayer(void) { SaveToDisk(); m_ClientHandle = 0; + CloseWindow(); if( m_Inventory ) { @@ -149,6 +150,7 @@ void cPlayer::Tick(float a_Dt) InChunk->Broadcast( EntityLook, m_ClientHandle ); m_bDirtyOrientation = false; } + if(m_bDirtyPosition ) { cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_MOVE, 1, this ); @@ -229,22 +231,21 @@ void cPlayer::Tick(float a_Dt) void cPlayer::InStateBurning(float a_Dt) { m_FireDamageInterval += a_Dt; - char block = GetWorld()->GetBlock( (int)m_Pos->x, (int)m_Pos->y, (int)m_Pos->z ); - char bblock = GetWorld()->GetBlock( (int)m_Pos->x, (int)m_Pos->y -1, (int)m_Pos->z ); - if(m_FireDamageInterval > 1000) { + char block = GetWorld()->GetBlock( float2int(m_Pos->x), float2int(m_Pos->y), float2int(m_Pos->z) ); + char bblock = GetWorld()->GetBlock( float2int(m_Pos->x), float2int(m_Pos->y)+1, float2int(m_Pos->z) ); + if(m_FireDamageInterval > 800) { m_FireDamageInterval = 0; - int rem = rand()%3 + 1; //Burn most of the time - if(rem >= 2) { - //printf("OUCH burning!!!\n"); - TakeDamage(1, this); - } + m_BurnPeriod++; if(block == E_BLOCK_LAVA || block == E_BLOCK_STATIONARY_LAVA || block == E_BLOCK_FIRE - || bblock == E_BLOCK_LAVA || bblock == E_BLOCK_STATIONARY_LAVA || bblock == E_BLOCK_FIRE) + || bblock == E_BLOCK_LAVA || bblock == E_BLOCK_STATIONARY_LAVA || bblock == E_BLOCK_FIRE) { m_BurnPeriod = 0; - - if(m_BurnPeriod > 5) { + TakeDamage(6, this); + }else{ + TakeDamage(1, this); + } + if(m_BurnPeriod > 7) { cChunk* InChunk = GetWorld()->GetChunkUnreliable( m_ChunkX, m_ChunkY, m_ChunkZ ); e_EPMetaState = NORMAL; @@ -261,14 +262,22 @@ void cPlayer::InStateBurning(float a_Dt) { //----Change Entity MetaData void cPlayer::CheckMetaDataBurn() { - char block = GetWorld()->GetBlock( (int)m_Pos->x, (int)m_Pos->y, (int)m_Pos->z ); - char bblock = GetWorld()->GetBlock( (int)m_Pos->x, (int)m_Pos->y -1, (int)m_Pos->z ); - if(m_bBurnable && e_EPMetaState != BURNING && (block == E_BLOCK_LAVA || block == E_BLOCK_STATIONARY_LAVA || block == E_BLOCK_FIRE + char block = GetWorld()->GetBlock( float2int(m_Pos->x), float2int(m_Pos->y), float2int(m_Pos->z) ); + char bblock = GetWorld()->GetBlock( float2int(m_Pos->x), float2int(m_Pos->y)+1, float2int(m_Pos->z) ); + if(e_EPMetaState == BURNING && (block == E_BLOCK_WATER || block == E_BLOCK_STATIONARY_WATER + || bblock == E_BLOCK_WATER || bblock == E_BLOCK_STATIONARY_WATER)) { + cChunk* InChunk = GetWorld()->GetChunkUnreliable( m_ChunkX, m_ChunkY, m_ChunkZ ); + if(!InChunk) + return; + e_EPMetaState = NORMAL; + cPacket_Metadata md(NORMAL,GetUniqueID()); + InChunk->Broadcast(md); + }else if(m_bBurnable && e_EPMetaState != BURNING && (block == E_BLOCK_LAVA || block == E_BLOCK_STATIONARY_LAVA || block == E_BLOCK_FIRE || bblock == E_BLOCK_LAVA || bblock == E_BLOCK_STATIONARY_LAVA || bblock == E_BLOCK_FIRE)) { cChunk* InChunk = GetWorld()->GetChunkUnreliable( m_ChunkX, m_ChunkY, m_ChunkZ ); if(!InChunk) return; - printf("I should burn"); + printf("I should burn\n"); e_EPMetaState = BURNING; cPacket_Metadata md(BURNING,GetUniqueID()); InChunk->Broadcast(md); @@ -282,7 +291,7 @@ void cPlayer::SetTouchGround( bool a_bTouchGround ) if( !m_bTouchGround ) { cWorld* World = GetWorld(); - char BlockID = World->GetBlock( (int)m_Pos->x, (int)m_Pos->y, (int)m_Pos->z ); + char BlockID = World->GetBlock( float2int(m_Pos->x), float2int(m_Pos->y), float2int(m_Pos->z) ); if( BlockID != E_BLOCK_AIR ) { m_bTouchGround = true; @@ -371,6 +380,7 @@ void cPlayer::Respawn() //Packet.m_CreativeMode = (char)GetWorld()->GetGameMode(); Packet.m_CreativeMode = (char)m_GameMode; //Set GameMode packet based on Player's GameMode; //Send Packet + e_EPMetaState = NORMAL; m_ClientHandle->Send( Packet ); TeleportTo( GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ() ); SetVisible( true ); diff --git a/source/cRedstone.cpp b/source/cRedstone.cpp index 111c012e2..77a3400fc 100644 --- a/source/cRedstone.cpp +++ b/source/cRedstone.cpp @@ -64,13 +64,10 @@ void cRedstone::ChangeRedstoneTorch( int fillx, int filly, int fillz, bool added void cRedstone::LightRedstone( int fillx, int filly, int fillz, char metadata) { if ( ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_STICKY_PISTON ) || ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_PISTON ) ) { - printf("rsPiston 1\n"); cPiston Piston(m_World); if (metadata > 0) { - printf("rsPiston 2\n"); Piston.ExtendPiston(fillx, filly, fillz); } else { - printf("rsPiston 3\n"); Piston.RetractPiston(fillx, filly, fillz); } } else if ( ( (int)m_World->GetBlock( fillx, filly, fillz ) == E_BLOCK_REDSTONE_WIRE) && ( (int)m_World->GetBlockMeta( fillx, filly, fillz) != metadata ) ) { diff --git a/source/cWorld.cpp b/source/cWorld.cpp index c67998064..0601746e8 100644 --- a/source/cWorld.cpp +++ b/source/cWorld.cpp @@ -13,6 +13,7 @@ #include "../iniFile/iniFile.h" #include "cChunkMap.h" #include "cWaterSimulator.h" +#include "cLavaSimulator.h" #include "cChicken.h" #include "cSpider.h" #include "cCow.h" //cow @@ -47,6 +48,8 @@ #include #endif + + float cWorld::m_Time = 0.f; char g_BlockLightValue[128]; @@ -94,6 +97,7 @@ cWorld::~cWorld() UnlockEntities(); delete m_WaterSimulator; + delete m_LavaSimulator; UnloadUnusedChunks(); delete m_ChunkMap; @@ -114,9 +118,9 @@ cWorld::cWorld( const char* a_WorldName ) cMakeDir::MakeDir(m_pState->WorldName.c_str()); srand( (unsigned int) time(0) ); - m_SpawnX = (double)((rand()%10000)-5000); + m_SpawnX = (double)((rand()%1000)-500); m_SpawnY = 128; - m_SpawnZ = (double)((rand()%10000)-5000); + m_SpawnZ = (double)((rand()%1000)-500); m_WorldSeed = rand(); m_GameMode = 0; @@ -187,6 +191,7 @@ cWorld::cWorld( const char* a_WorldName ) m_ChunksCriticalSection = new cCriticalSection(); m_WaterSimulator = new cWaterSimulator( this ); + m_LavaSimulator = new cLavaSimulator( this ); memset( g_BlockLightValue, 0x0, 128 ); memset( g_BlockSpreadLightFalloff, 0xf, 128 ); // 0xf means total falloff @@ -263,6 +268,8 @@ void cWorld::Tick(float a_Dt) { m_Time+=a_Dt/1000.f; + CurrentTick++; + bool bSendTime = false; m_WorldTimeFraction+=a_Dt/1000.f; while( m_WorldTimeFraction > 1.f ) @@ -302,7 +309,10 @@ void cWorld::Tick(float a_Dt) } m_ChunkMap->Tick(a_Dt); - m_WaterSimulator->Simulate(a_Dt); + if( CurrentTick % 6 == 0 ) + m_WaterSimulator->Simulate(a_Dt); + if( CurrentTick % 12 == 0 ) + m_LavaSimulator->Simulate(a_Dt); UnlockChunks(); if( m_Time - m_LastSave > 60*5 ) // Save each 5 minutes @@ -499,6 +509,7 @@ cChunk* cWorld::GetChunkOfBlock( int a_X, int a_Y, int a_Z ) void cWorld::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta ) { m_WaterSimulator->WakeUp( a_X, a_Y, a_Z ); + m_LavaSimulator->WakeUp( a_X, a_Y, a_Z ); int ChunkX, ChunkY, ChunkZ; AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkY, ChunkZ ); @@ -556,6 +567,7 @@ bool cWorld::DigBlock( int a_X, int a_Y, int a_Z, cItem & a_PickupItem ) { DestChunk->SetBlock(PosX, PosY, PosZ, 0, 0 ); m_WaterSimulator->WakeUp( a_X, a_Y, a_Z ); + m_LavaSimulator->WakeUp( a_X, a_Y, a_Z ); if( !a_PickupItem.IsEmpty() ) { diff --git a/source/cWorld.h b/source/cWorld.h index 10f73fae3..e8ad0f517 100644 --- a/source/cWorld.h +++ b/source/cWorld.h @@ -9,6 +9,7 @@ enum ENUM_ITEM_ID; #include class cWaterSimulator; +class cLavaSimulator; class cChunkMap; class cItem; class cCriticalSection; @@ -140,10 +141,12 @@ private: float m_LastSave; static float m_Time; // Time in seconds long long m_WorldTime; // Time in seconds*20, this is sent to clients (is wrapped) + unsigned long long CurrentTick; int m_GameMode; float m_WorldTimeFraction; // When this > 1.f m_WorldTime is incremented by 20 cWaterSimulator* m_WaterSimulator; + cLavaSimulator* m_LavaSimulator; cCriticalSection* m_ClientHandleCriticalSection; cCriticalSection* m_EntitiesCriticalSection;