summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source/BlockID.cpp7
-rw-r--r--source/Blocks/BlockDropSpenser.h2
-rw-r--r--source/Blocks/BlockHandler.cpp8
-rw-r--r--source/Entities/Entity.cpp105
-rw-r--r--source/Entities/Minecart.cpp27
-rw-r--r--source/Entities/Minecart.h14
-rw-r--r--source/Entities/Pickup.cpp3
-rw-r--r--source/Entities/Player.cpp2
-rw-r--r--source/Items/ItemShears.h1
-rw-r--r--source/Simulator/SandSimulator.cpp2
-rw-r--r--source/UI/SlotArea.cpp2
-rw-r--r--source/World.cpp40
12 files changed, 135 insertions, 78 deletions
diff --git a/source/BlockID.cpp b/source/BlockID.cpp
index 38b0b6ad4..c3bd3c750 100644
--- a/source/BlockID.cpp
+++ b/source/BlockID.cpp
@@ -778,10 +778,11 @@ public:
g_BlockIsSolid[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE] = false;
g_BlockIsSolid[E_BLOCK_MELON_STEM] = false;
g_BlockIsSolid[E_BLOCK_NETHER_PORTAL] = false;
- g_BlockIsSolid[E_BLOCK_PISTON_MOVED_BLOCK] = false;
- g_BlockIsSolid[E_BLOCK_POTATOES] = false;
- g_BlockIsSolid[E_BLOCK_PUMPKIN_STEM] = false;
+ g_BlockIsSolid[E_BLOCK_PISTON] = false;
+ g_BlockIsSolid[E_BLOCK_PISTON_EXTENSION] = false;
g_BlockIsSolid[E_BLOCK_RAIL] = false;
+ g_BlockIsSolid[E_BLOCK_REDSTONE_REPEATER_OFF] = false;
+ g_BlockIsSolid[E_BLOCK_REDSTONE_REPEATER_ON] = false;
g_BlockIsSolid[E_BLOCK_REDSTONE_TORCH_OFF] = false;
g_BlockIsSolid[E_BLOCK_REDSTONE_TORCH_ON] = false;
g_BlockIsSolid[E_BLOCK_REDSTONE_WIRE] = false;
diff --git a/source/Blocks/BlockDropSpenser.h b/source/Blocks/BlockDropSpenser.h
index e5572da8a..b7f20825d 100644
--- a/source/Blocks/BlockDropSpenser.h
+++ b/source/Blocks/BlockDropSpenser.h
@@ -31,7 +31,7 @@ public:
a_BlockType = m_BlockType;
// FIXME: Do not use cPiston class for dispenser placement!
- a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), 0);
+ a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetRotation(), a_Player->GetPitch());
return true;
}
} ;
diff --git a/source/Blocks/BlockHandler.cpp b/source/Blocks/BlockHandler.cpp
index 451ad6b91..3e97d1e9d 100644
--- a/source/Blocks/BlockHandler.cpp
+++ b/source/Blocks/BlockHandler.cpp
@@ -354,6 +354,14 @@ void cBlockHandler::DropBlock(cWorld * a_World, cEntity * a_Digger, int a_BlockX
if (!Pickups.empty())
{
+ // Add random offset to the spawn position:
+ // Commented out until bug with pickups not spawning properly is fixed, see World.cpp
+ /*
+ int MicroX = (int)(a_BlockX * 32) + (r1.randInt(16) + r1.randInt(16) - 16);
+ int MicroY = (int)(a_BlockY * 32) + (r1.randInt(16) + r1.randInt(16) - 16);
+ int MicroZ = (int)(a_BlockZ * 32) + (r1.randInt(16) + r1.randInt(16) - 16);
+ */
+
a_World->SpawnItemPickups(Pickups, a_BlockX, a_BlockY, a_BlockZ);
}
}
diff --git a/source/Entities/Entity.cpp b/source/Entities/Entity.cpp
index cb6799d33..d9272b39d 100644
--- a/source/Entities/Entity.cpp
+++ b/source/Entities/Entity.cpp
@@ -1,4 +1,3 @@
-
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Entity.h"
@@ -13,6 +12,7 @@
#include "../Simulator/FluidSimulator.h"
#include "../PluginManager.h"
#include "../Tracer.h"
+#include "Minecart.h"
@@ -564,8 +564,43 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
else
{
// Push out entity.
+ BLOCKTYPE GotBlock;
+
+ static const struct
+ {
+ int x, y, z;
+ } gCrossCoords[] =
+ {
+ { 1, 0, 0},
+ {-1, 0, 0},
+ { 0, 0, 1},
+ { 0, 0, -1},
+ } ;
+
+ bool IsNoAirSurrounding = true;
+ for (int i = 0; i < ARRAYCOUNT(gCrossCoords); i++)
+ {
+ if (!NextChunk->UnboundedRelGetBlockType(RelBlockX + gCrossCoords[i].x, BlockY, RelBlockZ + gCrossCoords[i].z, GotBlock))
+ {
+ // The pickup is too close to an unloaded chunk, bail out of any physics handling
+ return;
+ }
+ if (!g_BlockIsSolid[GotBlock])
+ {
+ NextPos.x += gCrossCoords[i].x;
+ NextPos.z += gCrossCoords[i].z;
+ IsNoAirSurrounding = false;
+ break;
+ }
+ } // for i - gCrossCoords[]
+
+ if (IsNoAirSurrounding)
+ {
+ NextPos.y += 0.5;
+ }
+
m_bOnGround = true;
- NextPos.y += 0.2;
+
LOGD("Entity #%d (%s) is inside a block at {%d, %d, %d}",
m_UniqueID, GetClass(), BlockX, BlockY, BlockZ
);
@@ -578,6 +613,11 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
{
fallspeed = m_Gravity * a_Dt / 3; // Fall 3x slower in water.
}
+ else if ((IsBlockRail(BlockBelow)) && (IsMinecart())) // Rails aren't solid, except for Minecarts
+ {
+ fallspeed = 0;
+ m_bOnGround = true;
+ }
else if (BlockIn == E_BLOCK_COBWEB)
{
NextSpeed.y *= 0.05; // Reduce overall falling speed
@@ -592,27 +632,40 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
}
else
{
- // TODO: This condition belongs to minecarts, without it, they derails too much.
- // But it shouldn't be here for other entities. We need a complete minecart physics overhaul.
- if (
- (BlockBelow != E_BLOCK_RAIL) &&
- (BlockBelow != E_BLOCK_DETECTOR_RAIL) &&
- (BlockBelow != E_BLOCK_POWERED_RAIL) &&
- (BlockBelow != E_BLOCK_ACTIVATOR_RAIL)
- )
+ if (IsMinecart())
{
- // Friction
- if (NextSpeed.SqrLength() > 0.0004f)
+ if (!IsBlockRail(BlockBelow))
{
- NextSpeed.x *= 0.6666;
- if (fabs(NextSpeed.x) < 0.05)
+ // Friction if minecart is off track, otherwise, Minecart.cpp handles this
+ if (NextSpeed.SqrLength() > 0.0004f)
{
- NextSpeed.x = 0;
+ NextSpeed.x *= 0.7f / (1 + a_Dt);
+ if (fabs(NextSpeed.x) < 0.05)
+ {
+ NextSpeed.x = 0;
+ }
+ NextSpeed.z *= 0.7f / (1 + a_Dt);
+ if (fabs(NextSpeed.z) < 0.05)
+ {
+ NextSpeed.z = 0;
+ }
}
- NextSpeed.z *= 0.6666;
- if (fabs(NextSpeed.z) < 0.05)
+ }
+ else
+ {
+ // Friction
+ if (NextSpeed.SqrLength() > 0.0004f)
{
- NextSpeed.z = 0;
+ NextSpeed.x *= 0.7f / (1 + a_Dt);
+ if (fabs(NextSpeed.x) < 0.05)
+ {
+ NextSpeed.x = 0;
+ }
+ NextSpeed.z *= 0.7f / (1 + a_Dt);
+ if (fabs(NextSpeed.z) < 0.05)
+ {
+ NextSpeed.z = 0;
+ }
}
}
}
@@ -634,19 +687,19 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
switch(WaterDir)
{
case X_PLUS:
- m_WaterSpeed.x = 1.f;
+ m_WaterSpeed.x = 0.2f;
m_bOnGround = false;
break;
case X_MINUS:
- m_WaterSpeed.x = -1.f;
+ m_WaterSpeed.x = -0.2f;
m_bOnGround = false;
break;
case Z_PLUS:
- m_WaterSpeed.z = 1.f;
+ m_WaterSpeed.z = 0.2f;
m_bOnGround = false;
break;
case Z_MINUS:
- m_WaterSpeed.z = -1.f;
+ m_WaterSpeed.z = -0.2f;
m_bOnGround = false;
break;
@@ -677,7 +730,6 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
{
if( Ret == 1 )
{
-
if( Tracer.HitNormal.x != 0.f ) NextSpeed.x = 0.f;
if( Tracer.HitNormal.y != 0.f ) NextSpeed.y = 0.f;
if( Tracer.HitNormal.z != 0.f ) NextSpeed.z = 0.f;
@@ -688,11 +740,14 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
}
}
NextPos.Set(Tracer.RealHit.x,Tracer.RealHit.y,Tracer.RealHit.z);
- NextPos.x += Tracer.HitNormal.x * 0.5f;
- NextPos.z += Tracer.HitNormal.z * 0.5f;
+ NextPos.x += Tracer.HitNormal.x * 0.3f;
+ NextPos.y += Tracer.HitNormal.y * 0.05f; // Any larger produces entity vibration-upon-the-spot
+ NextPos.z += Tracer.HitNormal.z * 0.3f;
}
else
+ {
NextPos += (NextSpeed * a_Dt);
+ }
}
else
{
diff --git a/source/Entities/Minecart.cpp b/source/Entities/Minecart.cpp
index 0c0b7b58a..a2f1e5593 100644
--- a/source/Entities/Minecart.cpp
+++ b/source/Entities/Minecart.cpp
@@ -54,20 +54,24 @@ void cMinecart::HandlePhysics(float a_Dt, cChunk & a_Chunk)
if ((GetPosY() > 0) && (GetPosY() < cChunkDef::Height))
{
BLOCKTYPE BelowType = GetWorld()->GetBlock(floor(GetPosX()), floor(GetPosY() -1 ), floor(GetPosZ()));
+ BLOCKTYPE InsideType = GetWorld()->GetBlock(floor(GetPosX()), floor(GetPosY()), floor(GetPosZ()));
- if (
- (BelowType == E_BLOCK_RAIL) ||
- (BelowType == E_BLOCK_POWERED_RAIL) ||
- (BelowType == E_BLOCK_DETECTOR_RAIL) ||
- (BelowType == E_BLOCK_ACTIVATOR_RAIL)
- )
+ if (IsBlockRail(BelowType))
{
HandleRailPhysics(a_Dt, a_Chunk);
}
else
{
- super::HandlePhysics(a_Dt, a_Chunk);
- BroadcastMovementUpdate();
+ if (IsBlockRail(InsideType))
+ {
+ SetPosY(ceil(GetPosY()));
+ HandleRailPhysics(a_Dt, a_Chunk);
+ }
+ else
+ {
+ super::HandlePhysics(a_Dt, a_Chunk);
+ BroadcastMovementUpdate();
+ }
}
}
else
@@ -105,9 +109,6 @@ void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk)
SpeedY = 0; // Don't move vertically as on ground
SpeedX = 0; // Correct diagonal movement from curved rails
- // Set Y as current Y rounded up to bypass friction
- SetPosY(floor(GetPosY()));
-
if (SpeedZ != 0) // Don't do anything if cart is stationary
{
if (SpeedZ > 0)
@@ -130,8 +131,6 @@ void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk)
SpeedY = 0;
SpeedZ = 0;
- SetPosY(floor(GetPosY()));
-
if (SpeedX != 0)
{
if (SpeedX > 0)
@@ -347,7 +346,7 @@ void cMinecart::DoTakeDamage(TakeDamageInfo & TDI)
{
super::DoTakeDamage(TDI);
- if (GetHealth() == 0)
+ if (GetHealth() <= 0)
{
Destroy(true);
}
diff --git a/source/Entities/Minecart.h b/source/Entities/Minecart.h
index f98b02bb5..0ca6586db 100644
--- a/source/Entities/Minecart.h
+++ b/source/Entities/Minecart.h
@@ -16,6 +16,20 @@
+inline bool IsBlockRail(BLOCKTYPE a_BlockType)
+ {
+ return (
+ (a_BlockType == E_BLOCK_RAIL) ||
+ (a_BlockType == E_BLOCK_ACTIVATOR_RAIL) ||
+ (a_BlockType == E_BLOCK_DETECTOR_RAIL) ||
+ (a_BlockType == E_BLOCK_POWERED_RAIL)
+ ) ;
+ }
+
+
+
+
+
class cMinecart :
public cEntity
{
diff --git a/source/Entities/Pickup.cpp b/source/Entities/Pickup.cpp
index 9b388366a..db7be8b04 100644
--- a/source/Entities/Pickup.cpp
+++ b/source/Entities/Pickup.cpp
@@ -25,7 +25,7 @@
cPickup::cPickup(int a_MicroPosX, int a_MicroPosY, int a_MicroPosZ, const cItem & a_Item, float a_SpeedX /* = 0.f */, float a_SpeedY /* = 0.f */, float a_SpeedZ /* = 0.f */)
- : cEntity(etPickup, ((double)(a_MicroPosX)) / 32, ((double)(a_MicroPosY)) / 32, ((double)(a_MicroPosZ)) / 32, 0.2, 0.2)
+ : cEntity(etPickup, (((double)(a_MicroPosX)) / 32) + 0.1 /*Accomodate player vomiting*/, ((double)(a_MicroPosY)) / 32, ((double)(a_MicroPosZ)) / 32, 0.2, 0.2)
, m_Timer( 0.f )
, m_Item(a_Item)
, m_bCollected( false )
@@ -33,7 +33,6 @@ cPickup::cPickup(int a_MicroPosX, int a_MicroPosY, int a_MicroPosZ, const cItem
m_MaxHealth = 5;
m_Health = 5;
SetSpeed(a_SpeedX, a_SpeedY, a_SpeedZ);
- m_Gravity = -3.0;
}
diff --git a/source/Entities/Player.cpp b/source/Entities/Player.cpp
index 751920759..04d285b01 100644
--- a/source/Entities/Player.cpp
+++ b/source/Entities/Player.cpp
@@ -1184,7 +1184,7 @@ void cPlayer::TossItem(
double vX = 0, vY = 0, vZ = 0;
EulerToVector(-GetRotation(), GetPitch(), vZ, vX, vY);
vY = -vY * 2 + 1.f;
- m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY() + 1.6f, GetPosZ(), vX * 2, vY * 2, vZ * 2);
+ m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY() + 1.6f, GetPosZ(), vX * 3, vY * 3, vZ * 3);
}
diff --git a/source/Items/ItemShears.h b/source/Items/ItemShears.h
index 663fa0170..6a17607ee 100644
--- a/source/Items/ItemShears.h
+++ b/source/Items/ItemShears.h
@@ -38,7 +38,6 @@ public:
a_Player->UseEquippedItem();
return true;
}
- // TODO: cobweb, vines
return false;
}
diff --git a/source/Simulator/SandSimulator.cpp b/source/Simulator/SandSimulator.cpp
index f4f0cdc80..87fb83357 100644
--- a/source/Simulator/SandSimulator.cpp
+++ b/source/Simulator/SandSimulator.cpp
@@ -258,7 +258,7 @@ void cSandSimulator::FinishFalling(
// Create a pickup instead:
cItems Pickups;
Pickups.Add((ENUM_ITEM_ID)a_FallingBlockType, 1, a_FallingBlockMeta);
- a_World->SpawnItemPickups(Pickups, (double)a_BlockX + 0.5, (double)a_BlockY + 0.5, (double)a_BlockZ + 0.5, 0);
+ a_World->SpawnItemPickups(Pickups, (double)a_BlockX + 0.5, (double)a_BlockY + 0.5, (double)a_BlockZ + 0.5);
}
diff --git a/source/UI/SlotArea.cpp b/source/UI/SlotArea.cpp
index 9213d4ff8..0a37e82b0 100644
--- a/source/UI/SlotArea.cpp
+++ b/source/UI/SlotArea.cpp
@@ -793,7 +793,7 @@ void cSlotAreaTemporary::TossItems(cPlayer & a_Player, int a_Begin, int a_End)
double vX = 0, vY = 0, vZ = 0;
EulerToVector(-a_Player.GetRotation(), a_Player.GetPitch(), vZ, vX, vY);
vY = -vY * 2 + 1.f;
- a_Player.GetWorld()->SpawnItemPickups(Drops, a_Player.GetPosX(), a_Player.GetPosY() + 1.6f, a_Player.GetPosZ(), vX * 2, vY * 2, vZ * 2);
+ a_Player.GetWorld()->SpawnItemPickups(Drops, a_Player.GetPosX(), a_Player.GetPosY() + 1.6f, a_Player.GetPosZ(), vX * 3, vY * 3, vZ * 3);
}
diff --git a/source/World.cpp b/source/World.cpp
index edcbb48f2..882cf90d2 100644
--- a/source/World.cpp
+++ b/source/World.cpp
@@ -1514,22 +1514,13 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double
for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr)
{
float SpeedX = (float)(a_FlyAwaySpeed * (r1.randInt(1000) - 500));
- float SpeedY = (float)(a_FlyAwaySpeed * r1.randInt(1000));
+ float SpeedY = 1;
float SpeedZ = (float)(a_FlyAwaySpeed * (r1.randInt(1000) - 500));
-
- // Add random offset to the spawn position:
- int MicroX = (int)(a_BlockX * 32) + (r1.randInt(16) + r1.randInt(16) - 16);
- int MicroY = (int)(a_BlockY * 32) + (r1.randInt(16) + r1.randInt(16) - 16);
- int MicroZ = (int)(a_BlockZ * 32) + (r1.randInt(16) + r1.randInt(16) - 16);
-
- // TODO 2013_05_12 _X: Because spawning pickups with nonzero speed causes them to bug (FS #338),
- // I decided to temporarily reset the speed to zero to fix it, until we have proper pickup physics
- SpeedX = SpeedY = SpeedZ = 0;
-
- // TODO 2013_05_12 _X: It seems that pickups bug out even with zero speed, trying mid-block position:
- MicroX = (int)(floor(a_BlockX) * 32) + 16;
- MicroY = (int)(floor(a_BlockY) * 32) + 16;
- MicroZ = (int)(floor(a_BlockZ) * 32) + 16;
+
+ // Pickup doesn't spawn on client without a mid block position. Perhaps the doubles are causing issues?
+ int MicroX = (int)(floor(a_BlockX) * 32) + 16;
+ int MicroY = (int)(floor(a_BlockY) * 32) + 16;
+ int MicroZ = (int)(floor(a_BlockZ) * 32) + 16;
cPickup * Pickup = new cPickup(
MicroX, MicroY, MicroZ,
@@ -1545,23 +1536,14 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double
void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ)
{
- // TODO 2013_05_12 _X: Because spawning pickups with nonzero speed causes them to bug (FS #338),
- // I decided to temporarily reset the speed to zero to fix it, until we have proper pickup physics
- a_SpeedX = a_SpeedY = a_SpeedZ = 0;
-
MTRand r1;
for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr)
{
- // Add random offset to the spawn position:
- int MicroX = (int)(a_BlockX * 32) + (r1.randInt(16) + r1.randInt(16) - 16);
- int MicroY = (int)(a_BlockY * 32) + (r1.randInt(16) + r1.randInt(16) - 16);
- int MicroZ = (int)(a_BlockZ * 32) + (r1.randInt(16) + r1.randInt(16) - 16);
-
- // TODO 2013_05_12 _X: It seems that pickups bug out even with zero speed, trying mid-block position:
- MicroX = (int)(floor(a_BlockX) * 32) + 16;
- MicroY = (int)(floor(a_BlockY) * 32) + 16;
- MicroZ = (int)(floor(a_BlockZ) * 32) + 16;
-
+ // Pickup doesn't spawn on client without a mid block position. Perhaps the doubles are causing issues?
+ int MicroX = (int)(floor(a_BlockX) * 32) + 16;
+ int MicroY = (int)(floor(a_BlockY) * 32) + 16;
+ int MicroZ = (int)(floor(a_BlockZ) * 32) + 16;
+
cPickup * Pickup = new cPickup(
MicroX, MicroY, MicroZ,
*itr, (float)a_SpeedX, (float)a_SpeedY, (float)a_SpeedZ