Esempio n. 1
0
        public virtual void ItemUsedOnBlock(Coordinates3D coordinates, ItemStack item, BlockFace face, IWorld world,
                                            IRemoteClient user)
        {
            var old = world.GetBlockData(coordinates);

            if (!Overwritable.Any(b => b == old.Id))
            {
                coordinates += MathHelper.BlockFaceToCoordinates(face);
                old          = world.GetBlockData(coordinates);
                if (!Overwritable.Any(b => b == old.Id))
                {
                    return;
                }
            }

            // Test for entities
            if (BoundingBox.HasValue)
            {
                var em       = user.Server.GetEntityManagerForWorld(world);
                var entities = em.EntitiesInRange(coordinates.AsVector3(), 3);
                var box      = new BoundingBox(BoundingBox.Value.Min + (Vector3)coordinates.AsVector3(),
                                               BoundingBox.Value.Max + (Vector3)coordinates.AsVector3());
                foreach (var entity in entities)
                {
                    var aabb = entity as IAABBEntity;
                    if (aabb != null && !(entity is ItemEntity))
                    {
                        if (aabb.BoundingBox.Intersects(box))
                        {
                            return;
                        }
                    }
                    var player = entity as PlayerEntity;                     // Players do not implement IAABBEntity
                    if (player != null)
                    {
                        if (new BoundingBox(player.Position, player.Position + player.Size.AsVector3())
                            .Intersects(box))
                        {
                            return;
                        }
                    }
                }
            }

            // Place block
            world.SetBlockId(coordinates, Id);
            world.SetMetadata(coordinates, (byte)item.Metadata);

            BlockPlaced(world.GetBlockData(coordinates), face, world, user);

            if (!IsSupported(world.GetBlockData(coordinates), user.Server, world))
            {
                world.SetBlockData(coordinates, old);
            }
            else
            {
                item.Count--;
                user.Inventory[user.SelectedSlot] = item;
            }
        }
Esempio n. 2
0
        public bool TestTerrainCollisionCylinder(IAABBEntity entity, out Vector3 collisionPoint)
        {
            collisionPoint = Vector3.Zero;
            var testBox      = GetAABBVelocityBox(entity);
            var testCylinder = new BoundingCylinder(testBox.Min, testBox.Max,
                                                    entity.BoundingBox.Min.DistanceTo(entity.BoundingBox.Max));

            var collision = false;

            for (var x = (int)Math.Floor(testBox.Min.X); x <= (int)Math.Ceiling(testBox.Max.X); x++)
            {
                for (var z = (int)Math.Floor(testBox.Min.Z); z <= (int)Math.Ceiling(testBox.Max.Z); z++)
                {
                    for (var y = (int)Math.Floor(testBox.Min.Y); y <= (int)Math.Ceiling(testBox.Max.Y); y++)
                    {
                        var coords = new Coordinates3D(x, y, z);
                        if (!World.IsValidPosition(coords))
                        {
                            continue;
                        }

                        var _box = BlockPhysicsProvider.GetBoundingBox(World, coords);
                        if (_box == null)
                        {
                            continue;
                        }

                        var box = _box.Value.OffsetBy(coords.AsVector3());
                        if (testCylinder.Intersects(box))
                        {
                            if (testBox.Intersects(box))
                            {
                                collision = true;
                                AdjustVelocityForCollision(entity, box);
                                testBox      = GetAABBVelocityBox(entity);
                                testCylinder = new BoundingCylinder(testBox.Min, testBox.Max,
                                                                    entity.BoundingBox.Min.DistanceTo(entity.BoundingBox.Max));
                                collisionPoint = coords.AsVector3();
                            }
                        }
                    }
                }
            }

            return(collision);
        }
        public static void HandleUpdateSignPacket(IPacket _packet, IRemoteClient _client, IMultiPlayerServer server)
        {
            var packet = (UpdateSignPacket)_packet;
            var client = (RemoteClient)_client;
            var coords = new Coordinates3D(packet.X, packet.Y, packet.Z);

            if (client.Entity.Position.DistanceTo(coords.AsVector3()) < 10)             // TODO: Reach
            {
                var block = client.World.GetBlockId(coords);
                if (block == UprightSignBlock.BlockId || block == WallSignBlock.BlockId)
                {
                    client.World.SetTileEntity(coords, new NbtCompound(new[]
                    {
                        new NbtString("Text1", packet.Text[0]),
                        new NbtString("Text2", packet.Text[1]),
                        new NbtString("Text3", packet.Text[2]),
                        new NbtString("Text4", packet.Text[3])
                    }));
                    // TODO: Some utility methods for things like "clients with given chunk loaded"
                    server.Clients.Where(c => ((RemoteClient)c).LoggedIn && c.World == _client.World).ToList()
                    .ForEach(c => c.QueuePacket(packet));
                }
            }
        }
Esempio n. 4
0
        public bool TestTerrainCollisionZ(IAABBEntity entity, out Vector3 collisionPoint)
        {
            // Things we need to do:
            // 1 - expand bounding box to include the destination and everything within
            // 2 - collect all blocks within that area
            // 3 - test bounding boxes in direction of motion

            collisionPoint = Vector3.Zero;

            if (entity.Velocity.Z == 0)
            {
                return(false);
            }

            bool negative;

            BoundingBox testBox;

            if (entity.Velocity.Z < 0)
            {
                testBox = new BoundingBox(
                    new Vector3(
                        entity.BoundingBox.Min.X,
                        entity.BoundingBox.Min.Y,
                        entity.BoundingBox.Min.Z + entity.Velocity.Z),
                    entity.BoundingBox.Max);
                negative = true;
            }
            else
            {
                testBox = new BoundingBox(
                    entity.BoundingBox.Min,
                    new Vector3(
                        entity.BoundingBox.Max.X,
                        entity.BoundingBox.Max.Y,
                        entity.BoundingBox.Max.Z + entity.Velocity.Z));
                negative = false;
            }

            double?collisionExtent = null;

            for (var x = (int)Math.Floor(testBox.Min.X); x <= (int)Math.Ceiling(testBox.Max.X); x++)
            {
                for (var z = (int)Math.Floor(testBox.Min.Z); z <= (int)Math.Ceiling(testBox.Max.Z); z++)
                {
                    for (var y = (int)Math.Floor(testBox.Min.Y); y <= (int)Math.Ceiling(testBox.Max.Y); y++)
                    {
                        var coords = new Coordinates3D(x, y, z);
                        if (!World.IsValidPosition(coords))
                        {
                            continue;
                        }

                        var _box = BlockPhysicsProvider.GetBoundingBox(World, coords);
                        if (_box == null)
                        {
                            continue;
                        }

                        var box = _box.Value.OffsetBy(coords.AsVector3());
                        if (testBox.Intersects(box))
                        {
                            if (negative)
                            {
                                if (collisionExtent == null || collisionExtent.Value < box.Max.Z)
                                {
                                    collisionExtent = box.Max.Z;
                                    collisionPoint  = coords.AsVector3();
                                }
                            }
                            else
                            {
                                if (collisionExtent == null || collisionExtent.Value > box.Min.Z)
                                {
                                    collisionExtent = box.Min.Z;
                                    collisionPoint  = coords.AsVector3();
                                }
                            }
                        }
                    }
                }
            }

            if (collisionExtent != null)             // Collision detected, adjust accordingly
            {
                var    extent = collisionExtent.Value;
                double diff;
                if (negative)
                {
                    diff = -(entity.BoundingBox.Min.Z - extent);
                }
                else
                {
                    diff = extent - entity.BoundingBox.Max.Z;
                }
                entity.Velocity = new Vector3(entity.Velocity.X, entity.Velocity.Y, (float)diff);
                return(true);
            }

            return(false);
        }