diff --git a/TrueCraft.API/Entities/IPhysicsEntity.cs b/TrueCraft.API/Entities/IPhysicsEntity.cs
index e913c2f..65fc35e 100644
--- a/TrueCraft.API/Entities/IPhysicsEntity.cs
+++ b/TrueCraft.API/Entities/IPhysicsEntity.cs
@@ -11,6 +11,7 @@ namespace TrueCraft.API.Entities
Vector3 Velocity { get; set; }
float AccelerationDueToGravity { get; }
float Drag { get; }
+ float TerminalVelocity { get; }
bool BeginUpdate();
void EndUpdate(Vector3 newPosition);
diff --git a/TrueCraft.API/Vector3.cs b/TrueCraft.API/Vector3.cs
index 289acee..aa3aaf9 100644
--- a/TrueCraft.API/Vector3.cs
+++ b/TrueCraft.API/Vector3.cs
@@ -54,6 +54,20 @@ namespace TrueCraft.API
return new Vector3(Math.Floor(X), Math.Floor(Y), Math.Floor(Z));
}
+ ///
+ /// Clamps the vector to within the specified value.
+ ///
+ /// Value.
+ public void Clamp(double value)
+ {
+ if (Math.Abs(X) > value)
+ X = value * (X < 0 ? -1 : 1);
+ if (Math.Abs(Y) > value)
+ Y = value * (Y < 0 ? -1 : 1);
+ if (Math.Abs(Z) > value)
+ Z = value * (Z < 0 ? -1 : 1);
+ }
+
///
/// Calculates the distance between two Vector3 objects.
///
diff --git a/TrueCraft.Core/Entities/Entity.cs b/TrueCraft.Core/Entities/Entity.cs
index 0a234aa..3681fb9 100644
--- a/TrueCraft.Core/Entities/Entity.cs
+++ b/TrueCraft.Core/Entities/Entity.cs
@@ -99,6 +99,9 @@ namespace TrueCraft.Core.Entities
public virtual void Update(IEntityManager entityManager)
{
+ // TODO: Losing health and all that jazz
+ if (Position.Y < -50)
+ entityManager.DespawnEntity(this);
}
protected bool EnablePropertyChange { get; set; }
diff --git a/TrueCraft.Core/Entities/ItemEntity.cs b/TrueCraft.Core/Entities/ItemEntity.cs
index 65a15c2..fa31d1c 100644
--- a/TrueCraft.Core/Entities/ItemEntity.cs
+++ b/TrueCraft.Core/Entities/ItemEntity.cs
@@ -123,16 +123,22 @@ namespace TrueCraft.Core.Entities
OnPropertyChanged("Metadata");
}*/
}
+ base.Update(entityManager);
}
public float AccelerationDueToGravity
{
- get { return 0.08f; }
+ get { return 0.4f; }
}
public float Drag
{
- get { return 0.98f; }
+ get { return 0.2f; }
+ }
+
+ public float TerminalVelocity
+ {
+ get { return 1.96f; }
}
}
}
diff --git a/TrueCraft.Core/Logic/BlockProvider.cs b/TrueCraft.Core/Logic/BlockProvider.cs
index 480a151..38a7163 100644
--- a/TrueCraft.Core/Logic/BlockProvider.cs
+++ b/TrueCraft.Core/Logic/BlockProvider.cs
@@ -35,7 +35,11 @@ namespace TrueCraft.Core.Logic
var entityManager = server.GetEntityManagerForWorld(world);
var items = GetDrop(descriptor);
foreach (var item in items)
- entityManager.SpawnEntity(new ItemEntity(new Vector3(descriptor.Coordinates) + new Vector3(0.5), item));
+ {
+ var entity = new ItemEntity(new Vector3(descriptor.Coordinates) + new Vector3(0.5), item);
+ entity.Velocity += new Vector3(MathHelper.Random.NextDouble());
+ entityManager.SpawnEntity(entity);
+ }
}
public virtual bool IsSupported(BlockDescriptor descriptor, IMultiplayerServer server, IWorld world)
diff --git a/TrueCraft/EntityManager.cs b/TrueCraft/EntityManager.cs
index b2bf84d..59779e4 100644
--- a/TrueCraft/EntityManager.cs
+++ b/TrueCraft/EntityManager.cs
@@ -177,6 +177,17 @@ namespace TrueCraft
spawnedClient = (RemoteClient)GetClientForEntity(entity as PlayerEntity);
client.KnownEntities.Add(entity);
client.QueuePacket(entity.SpawnPacket);
+ if (entity is IPhysicsEntity)
+ {
+ var pentity = entity as IPhysicsEntity;
+ client.QueuePacket(new EntityVelocityPacket
+ {
+ EntityID = entity.EntityID,
+ XVelocity = (short)(pentity.Velocity.X * 320),
+ YVelocity = (short)(pentity.Velocity.Y * 320),
+ ZVelocity = (short)(pentity.Velocity.Z * 320),
+ });
+ }
if (entity.SendMetadataToClients)
client.QueuePacket(new EntityMetadataPacket(entity.EntityID, entity.Metadata));
if (spawnedClient != null)
@@ -265,6 +276,8 @@ namespace TrueCraft
while (PendingDespawns.Count != 0)
{
while (!PendingDespawns.TryTake(out entity));
+ if (entity is IPhysicsEntity)
+ PhysicsEngine.RemoveEntity((IPhysicsEntity)entity);
for (int i = 0, ServerClientsCount = Server.Clients.Count; i < ServerClientsCount; i++)
{
var client = (RemoteClient)Server.Clients[i];
diff --git a/TrueCraft/PhysicsEngine.cs b/TrueCraft/PhysicsEngine.cs
index 42ed0a8..f419af7 100644
--- a/TrueCraft/PhysicsEngine.cs
+++ b/TrueCraft/PhysicsEngine.cs
@@ -40,7 +40,8 @@ namespace TrueCraft
{
if (!Entities.Contains(entity))
return;
- Entities.Remove(entity);
+ lock (EntityLock)
+ Entities.Remove(entity);
}
private BoundingBox TempBoundingBox;
@@ -57,6 +58,7 @@ namespace TrueCraft
{
entity.Velocity *= entity.Drag * multipler;
entity.Velocity -= new Vector3(0, entity.AccelerationDueToGravity * multipler, 0);
+ entity.Velocity.Clamp(entity.TerminalVelocity);
if (entity is IAABBEntity)
CheckWithTerrain((IAABBEntity)entity, World);
entity.EndUpdate(entity.Position + entity.Velocity);
@@ -69,7 +71,7 @@ namespace TrueCraft
private void CheckWithTerrain(IAABBEntity entity, IWorld world)
{
Vector3 collisionPoint, collisionDirection;
- if (entity.Position.Y + entity.Velocity.Y >= 0 && entity.Position.Y + entity.Velocity.Y <= 255) // Don't do checks outside the map
+ if (entity.Position.Y > 0 && entity.Position.Y <= 127) // Don't do checks outside the map
{
bool fireEvent = entity.Velocity != Vector3.Zero;
// Do terrain collisions
@@ -80,7 +82,7 @@ namespace TrueCraft
}
if (AdjustVelocityY(entity, world, out collisionPoint, out collisionDirection))
{
- entity.Velocity *= new Vector3(0.2, 1, 0.2); // TODO: More sophisticated friction
+ entity.Velocity *= new Vector3(0.1, 1, 0.1); // TODO: More sophisticated friction
if (fireEvent)
entity.TerrainCollision(collisionPoint, collisionDirection);
}
@@ -114,22 +116,19 @@ namespace TrueCraft
if (entity.Velocity.X < 0)
{
TempBoundingBox = new BoundingBox(
- new Vector3(entity.BoundingBox.Min.X + entity.Velocity.X, entity.BoundingBox.Min.Y, entity.BoundingBox.Min.Z) - (entity.Size / 2),
- new Vector3(entity.BoundingBox.Max.X, entity.BoundingBox.Max.Y, entity.BoundingBox.Max.Z) - (entity.Size / 2)
- );
+ new Vector3(entity.BoundingBox.Min.X + entity.Velocity.X, entity.BoundingBox.Min.Y, entity.BoundingBox.Min.Z),
+ entity.BoundingBox.Max);
maxX = (int)(TempBoundingBox.Max.X);
- minX = (int)(TempBoundingBox.Min.X + entity.Velocity.X);
+ minX = (int)(TempBoundingBox.Min.X + entity.Velocity.X) - 1;
}
else
{
TempBoundingBox = new BoundingBox(
- entity.BoundingBox.Min - (entity.Size / 2),
- new Vector3(
- entity.BoundingBox.Max.X + entity.Velocity.X, entity.BoundingBox.Max.Y, entity.BoundingBox.Max.Z) - (entity.Size / 2)
- );
+ entity.BoundingBox.Min,
+ new Vector3(entity.BoundingBox.Max.X + entity.Velocity.X, entity.BoundingBox.Max.Y, entity.BoundingBox.Max.Z));
minX = (int)(entity.BoundingBox.Min.X);
- maxX = (int)(entity.BoundingBox.Max.X + entity.Velocity.X);
+ maxX = (int)(entity.BoundingBox.Max.X + entity.Velocity.X) + 1;
}
// Do terrain checks
@@ -141,8 +140,8 @@ namespace TrueCraft
{
for (int z = minZ; z <= maxZ; z++)
{
- var position = new Vector3(x, y, z);
- var boundingBox = BlockPhysicsProvider.GetBoundingBox(world, (Coordinates3D)position);
+ var position = new Coordinates3D(x, y, z);
+ var boundingBox = BlockPhysicsProvider.GetBoundingBox(world, position);
if (boundingBox == null)
continue;
blockBox = boundingBox.Value.OffsetBy(position);
@@ -213,22 +212,19 @@ namespace TrueCraft
if (entity.Velocity.Y < 0)
{
TempBoundingBox = new BoundingBox(
- new Vector3(entity.BoundingBox.Min.X, entity.BoundingBox.Min.Y + entity.Velocity.Y, entity.BoundingBox.Min.Z) - (entity.Size / 2),
- new Vector3(entity.BoundingBox.Max.X, entity.BoundingBox.Max.Y, entity.BoundingBox.Max.Z) - (entity.Size / 2)
- );
+ new Vector3(entity.BoundingBox.Min.X, entity.BoundingBox.Min.Y + entity.Velocity.Y, entity.BoundingBox.Min.Z),
+ entity.BoundingBox.Max);
maxY = (int)(TempBoundingBox.Max.Y);
- minY = (int)(TempBoundingBox.Min.Y + entity.Velocity.Y);
+ minY = (int)(TempBoundingBox.Min.Y + entity.Velocity.Y) - 1;
}
else
{
TempBoundingBox = new BoundingBox(
- entity.BoundingBox.Min - (entity.Size / 2),
- new Vector3(
- entity.BoundingBox.Max.X, entity.BoundingBox.Max.Y + entity.Velocity.Y, entity.BoundingBox.Max.Z) - (entity.Size / 2)
- );
+ entity.BoundingBox.Min,
+ new Vector3(entity.BoundingBox.Max.X, entity.BoundingBox.Max.Y + entity.Velocity.Y, entity.BoundingBox.Max.Z));
minY = (int)(entity.BoundingBox.Min.Y);
- maxY = (int)(entity.BoundingBox.Max.Y + entity.Velocity.Y);
+ maxY = (int)(entity.BoundingBox.Max.Y + entity.Velocity.Y) + 1;
}
// Clamp Y into map boundaries
@@ -250,8 +246,10 @@ namespace TrueCraft
{
for (int z = minZ; z <= maxZ; z++)
{
- var position = new Vector3(x, y, z);
- var boundingBox = BlockPhysicsProvider.GetBoundingBox(world, (Coordinates3D)position);
+ var position = new Coordinates3D(x, y, z);
+ if (!World.IsValidPosition(position))
+ continue;
+ var boundingBox = BlockPhysicsProvider.GetBoundingBox(world, position);
if (boundingBox == null)
continue;
blockBox = boundingBox.Value.OffsetBy(position);
@@ -323,22 +321,20 @@ namespace TrueCraft
if (entity.Velocity.Z < 0)
{
TempBoundingBox = new BoundingBox(
- new Vector3(entity.BoundingBox.Min.X, entity.BoundingBox.Min.Y, entity.BoundingBox.Min.Z + entity.Velocity.Z) - (entity.Size / 2),
- new Vector3(entity.BoundingBox.Max.X, entity.BoundingBox.Max.Y, entity.BoundingBox.Max.Z) - (entity.Size / 2)
- );
+ new Vector3(entity.BoundingBox.Min.X, entity.BoundingBox.Min.Y, entity.BoundingBox.Min.Z + entity.Velocity.Z),
+ entity.BoundingBox.Max);
maxZ = (int)(TempBoundingBox.Max.Z);
- minZ = (int)(TempBoundingBox.Min.Z + entity.Velocity.Z);
+ minZ = (int)(TempBoundingBox.Min.Z + entity.Velocity.Z) - 1;
}
else
{
TempBoundingBox = new BoundingBox(
- entity.BoundingBox.Min - (entity.Size / 2),
- new Vector3(
- entity.BoundingBox.Max.X, entity.BoundingBox.Max.Y, entity.BoundingBox.Max.Z + entity.Velocity.Z) - (entity.Size / 2)
+ entity.BoundingBox.Min,
+ new Vector3(entity.BoundingBox.Max.X, entity.BoundingBox.Max.Y, entity.BoundingBox.Max.Z + entity.Velocity.Z)
);
minZ = (int)(entity.BoundingBox.Min.Z);
- maxZ = (int)(entity.BoundingBox.Max.Z + entity.Velocity.Z);
+ maxZ = (int)(entity.BoundingBox.Max.Z + entity.Velocity.Z) + 1;
}
// Do terrain checks
@@ -350,8 +346,8 @@ namespace TrueCraft
{
for (int z = minZ; z <= maxZ; z++)
{
- var position = new Vector3(x, y, z);
- var boundingBox = BlockPhysicsProvider.GetBoundingBox(world, (Coordinates3D)position);
+ var position = new Coordinates3D(x, y, z);
+ var boundingBox = BlockPhysicsProvider.GetBoundingBox(world, position);
if (boundingBox == null)
continue;
blockBox = boundingBox.Value.OffsetBy(position);
diff --git a/TrueCraft/Program.cs b/TrueCraft/Program.cs
index 23d450b..6eccf90 100644
--- a/TrueCraft/Program.cs
+++ b/TrueCraft/Program.cs
@@ -24,7 +24,6 @@ namespace TrueCraft
server.AddLogProvider(new ConsoleLogProvider(LogCategory.Notice | LogCategory.Warning | LogCategory.Error | LogCategory.Debug));
#if DEBUG
server.AddLogProvider(new FileLogProvider(new StreamWriter("packets.log", false), LogCategory.Packets));
- server.EnableClientLogging = true;
#endif
CommandManager = new CommandManager();
server.ChatMessageReceived += HandleChatMessageReceived;