예제 #1
0
        public void GenerateDropEntity(BlockDescriptor descriptor, IWorld world, IMultiplayerServer server, ItemStack item)
        {
            var entityManager = server.GetEntityManagerForWorld(world);
            var items = new ItemStack[0];
            var type = ToolType.None;
            var material = ToolMaterial.None;
            var held = ItemRepository.GetItemProvider(item.ID);

            if (held is ToolItem)
            {
                var tool = held as ToolItem;
                material = tool.Material;
                type = tool.ToolType;
            }

            if ((EffectiveTools & type) > 0)
            {
                if ((EffectiveToolMaterials & material) > 0)
                    items = GetDrop(descriptor, item);
            }

            foreach (var i in items)
            {
                if (i.Empty) continue;
                var entity = new ItemEntity(new Vector3(descriptor.Coordinates) + new Vector3(0.5), i);
                entityManager.SpawnEntity(entity);
            }
        }
예제 #2
0
 public override void BlockPlaced(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
 {
     var chunk = world.FindChunk(descriptor.Coordinates);
     user.Server.Scheduler.ScheduleEvent(chunk,
         DateTime.UtcNow.AddSeconds(MathHelper.Random.Next(MinGrowthTime, MaxGrowthTime)),
         s => TrySpread(descriptor.Coordinates, world, user.Server));
 }
예제 #3
0
 public bool ValidBedPosition(BlockDescriptor descriptor, IBlockRepository repository, IWorld world, bool checkNeighbor = true, bool checkSupport = false)
 {
     if (checkNeighbor)
     {
         var other = Coordinates3D.Zero;
         switch ((BedDirection)(descriptor.Metadata & 0x3))
         {
             case BedDirection.East:
                 other = Coordinates3D.East;
                 break;
             case BedDirection.West:
                 other = Coordinates3D.West;
                 break;
             case BedDirection.North:
                 other = Coordinates3D.North;
                 break;
             case BedDirection.South:
                 other = Coordinates3D.South;
                 break;
         }
         if ((descriptor.Metadata & (byte)BedType.Head) == (byte)BedType.Head)
             other = -other;
         if (world.GetBlockID(descriptor.Coordinates + other) != BedBlock.BlockID)
             return false;
     }
     if (checkSupport)
     {
         var supportingBlock = repository.GetBlockProvider(world.GetBlockID(descriptor.Coordinates + Coordinates3D.Down));
         if (!supportingBlock.Opaque)
             return false;
     }
     return true;
 }
예제 #4
0
 protected override ItemStack[] GetDrop(BlockDescriptor descriptor)
 {
     if (MathHelper.Random.Next(20) == 0) // 5% chance
         return new[] { new ItemStack(SaplingBlock.BlockID, 1, descriptor.Metadata) };
     else
         return new ItemStack[0];
 }
예제 #5
0
 public override void BlockPlaced(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
 {
     var chunk = world.FindChunk(descriptor.Coordinates);
     user.Server.Scheduler.ScheduleEvent("crops", chunk,
         TimeSpan.FromSeconds(MathHelper.Random.Next(30, 60)),
         (server) => GrowBlock(server, world, descriptor.Coordinates + MathHelper.BlockFaceToCoordinates(face)));
 }
예제 #6
0
 protected override ItemStack[] GetDrop(BlockDescriptor descriptor)
 {
     if (descriptor.Metadata >= 7)
         return new[] { new ItemStack(WheatItem.ItemID), new ItemStack(SeedsItem.ItemID, (sbyte)MathHelper.Random.Next(3)) };
     else
         return new[] { new ItemStack(SeedsItem.ItemID) };
 }
예제 #7
0
 public override void BlockUpdate(BlockDescriptor descriptor, BlockDescriptor source, IMultiplayerServer server, IWorld world)
 {
     bool upper = ((DoorItem.DoorFlags)descriptor.Metadata & DoorItem.DoorFlags.Upper) == DoorItem.DoorFlags.Upper;
     var other = upper ? Coordinates3D.Down : Coordinates3D.Up;
     if (world.GetBlockID(descriptor.Coordinates + other) != ID)
         world.SetBlockID(descriptor.Coordinates, 0);
 }
예제 #8
0
 public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
     VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
 {
     // This is similar to how wheat is rendered
     indicies = new int[5 * 6];
     var verticies = new VertexPositionNormalColorTexture[5 * 6];
     int[] _indicies;
     var center = new Vector3(-0.5f, -0.5f, -0.5f);
     CubeFace side;
     VertexPositionNormalColorTexture[] quad;
     for (int _side = 0; _side < 4; _side++)
     {
         side = (CubeFace)_side;
         quad = CreateQuad(side, center, Texture, 0, indiciesOffset, out _indicies, Color.White);
         if (side == CubeFace.NegativeX || side == CubeFace.PositiveX)
         {
             for (int i = 0; i < quad.Length; i++)
             {
                 quad[i].Position.X *= 14f / 16f;
                 quad[i].Position += offset;
             }
         }
         else
         {
             for (int i = 0; i < quad.Length; i++)
             {
                 quad[i].Position.Z *= 14f / 16f;
                 quad[i].Position += offset;
             }
         }
         Array.Copy(quad, 0, verticies, _side * 4, 4);
         Array.Copy(_indicies, 0, indicies, _side * 6, 6);
     }
     side = CubeFace.PositiveY;
     quad = CreateQuad(side, center, TopTexture, 0, indiciesOffset, out _indicies, Color.White);
     if (side == CubeFace.NegativeX || side == CubeFace.PositiveX)
     {
         for (int i = 0; i < quad.Length; i++)
         {
             quad[i].Position.X *= 14f / 16f;
             quad[i].Position += offset;
         }
     }
     else
     {
         for (int i = 0; i < quad.Length; i++)
         {
             quad[i].Position.Z *= 14f / 16f;
             quad[i].Position += offset;
         }
     }
     Array.Copy(quad, 0, verticies, (int)side * 4, 4);
     Array.Copy(_indicies, 0, indicies, (int)side * 6, 6);
     for (int i = 0; i < verticies.Length; i++)
     {
         verticies[i].Position.Y -= 1 / 16f;
         verticies[i].Position -= center;
     }
     return verticies;
 }
예제 #9
0
        public void DestroyCactus(BlockDescriptor descriptor, IMultiplayerServer server, IWorld world)
        {
            var toDrop = 0;

            // Search upwards
            for (int y = descriptor.Coordinates.Y; y < 127; y++)
            {
                var coordinates = new Coordinates3D(descriptor.Coordinates.X, y, descriptor.Coordinates.Z);
                if (world.GetBlockID(coordinates) == CactusBlock.BlockID)
                {
                    world.SetBlockID(coordinates, AirBlock.BlockID);
                    toDrop++;
                }
            }

            // Search downwards.
            for (int y = descriptor.Coordinates.Y - 1; y > 0; y--)
            {
                var coordinates = new Coordinates3D(descriptor.Coordinates.X, y, descriptor.Coordinates.Z);
                if (world.GetBlockID(coordinates) == CactusBlock.BlockID)
                {
                    world.SetBlockID(coordinates, AirBlock.BlockID);
                    toDrop++;
                }
            }

            var manager = server.GetEntityManagerForWorld(world);
            manager.SpawnEntity(
                new ItemEntity(descriptor.Coordinates + Coordinates3D.Up,
                    new ItemStack(CactusBlock.BlockID, (sbyte)toDrop)));
        }
예제 #10
0
        public void DoSpread(IMultiplayerServer server, IWorld world, BlockDescriptor descriptor)
        {
            foreach (var coord in SpreadableBlocks)
            {
                var check = descriptor.Coordinates + coord;
                if (world.GetBlockID(check) == AirBlock.BlockID)
                {
                    // Check if this is adjacent to a flammable block
                    foreach (var adj in AdjacentBlocks)
                    {
                        var provider = BlockRepository.GetBlockProvider(
                           world.GetBlockID(check + adj));
                        if (provider.Flammable)
                        {
                            if (provider.Hardness == 0)
                                check = check + adj;

                            // Spread to this block
                            world.SetBlockID(check, FireBlock.BlockID);
                            ScheduleUpdate(server, world, world.GetBlockData(check));
                            break;
                        }
                    }
                }
            }
        }
예제 #11
0
 public static bool ValidPlacement(BlockDescriptor descriptor, IWorld world)
 {
     var below = world.GetBlockID(descriptor.Coordinates + Coordinates3D.Down);
     if (below != SugarcaneBlock.BlockID && below != GrassBlock.BlockID && below != DirtBlock.BlockID)
         return false;
     var toCheck = new[]
     {
         Coordinates3D.Down + Coordinates3D.Left,
         Coordinates3D.Down + Coordinates3D.Right,
         Coordinates3D.Down + Coordinates3D.Backwards,
         Coordinates3D.Down + Coordinates3D.Forwards
     };
     if (below != BlockID)
     {
         bool foundWater = false;
         for (int i = 0; i < toCheck.Length; i++)
         {
             var id = world.GetBlockID(descriptor.Coordinates + toCheck[i]);
             if (id == WaterBlock.BlockID || id == StationaryWaterBlock.BlockID)
             {
                 foundWater = true;
                 break;
             }
         }
         return foundWater;
     }
     return true;
 }
예제 #12
0
        public bool ValidCactusPosition(BlockDescriptor descriptor, IBlockRepository repository, IWorld world, bool checkNeighbor = true, bool checkSupport = true)
        {
            if (checkNeighbor)
            {
                var adjacent = new Coordinates3D[]
                {
                    descriptor.Coordinates + Coordinates3D.North,
                    descriptor.Coordinates + Coordinates3D.East,
                    descriptor.Coordinates + Coordinates3D.South,
                    descriptor.Coordinates + Coordinates3D.West,
                };

                foreach (var coords in adjacent)
                    if (world.GetBlockID(coords) != AirBlock.BlockID)
                        return false;
            }

            if (checkSupport)
            {
                var supportingBlock = repository.GetBlockProvider(world.GetBlockID(descriptor.Coordinates + Coordinates3D.Down));
                if ((supportingBlock.ID != CactusBlock.BlockID) && (supportingBlock.ID != SandBlock.BlockID))
                    return false;
            }

            return true;
        }
예제 #13
0
        public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
            VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
        {
            int[] lighting = new int[6];
            for (int i = 0; i < 6; i++)
            {
                var coords = (descriptor.Coordinates + FaceCoords[i]);
                lighting[i] = GetLight(descriptor.Chunk, coords);
            }
            var centerized = new Vector3(7f / 16f, 0, 7f / 16f);
            var cube = CreateUniformCube(Vector3.Zero, Texture, VisibleFaces.All,
                indiciesOffset, out indicies, Color.White, lighting);
            for (int i = 0; i < cube.Length; i++)
            {
                cube[i].Position.X *= 1f / 8f;
                cube[i].Position.Z *= 1f / 8f;
                if (cube[i].Position.Y > 0)
                    cube[i].Position.Y *= 5f / 8f;
                switch ((TorchBlock.TorchDirection)descriptor.Metadata)
                {
                    case TorchBlock.TorchDirection.West:
                        if (cube[i].Position.Y == 0)
                            cube[i].Position.X += 8f / 16f;
                        else
                            cube[i].Position.X += 3f / 16f;
                        cube[i].Position.Y += 5f / 16f;
                        break;
                    case TorchBlock.TorchDirection.East:
                        if (cube[i].Position.Y == 0)
                            cube[i].Position.X -= 8f / 16f;
                        else
                            cube[i].Position.X -= 3f / 16f;
                        cube[i].Position.Y += 5f / 16f;
                        break;
                    case TorchBlock.TorchDirection.North:
                        if (cube[i].Position.Y == 0)
                            cube[i].Position.Z += 8f / 16f;
                        else
                            cube[i].Position.Z += 3f / 16f;
                        cube[i].Position.Y += 5f / 16f;
                        break;
                    case TorchBlock.TorchDirection.South:
                        if (cube[i].Position.Y == 0)
                            cube[i].Position.Z -= 8f / 16f;
                        else
                            cube[i].Position.Z -= 3f / 16f;
                        cube[i].Position.Y += 5f / 16f;
                        break;
                    case TorchBlock.TorchDirection.Ground:
                    default:
                        // nop
                        break;
                }

                cube[i].Position += offset;
                cube[i].Position += centerized;
            }
            return cube;
        }
예제 #14
0
 protected override ItemStack[] GetDrop(BlockDescriptor descriptor, ItemStack item)
 {
     //Gravel has a 10% chance of dropping flint.
     if (MathHelper.Random.Next(10) == 0)
         return new[] { new ItemStack(FlintItem.ItemID, 1, descriptor.Metadata) };
     else
         return new ItemStack[0];
 }
예제 #15
0
 public override void BlockUpdate(BlockDescriptor descriptor, BlockDescriptor source, IMultiplayerServer server, IWorld world)
 {
     if (world.GetBlockID(descriptor.Coordinates + Coordinates3D.Down) != FarmlandBlock.BlockID)
     {
         GenerateDropEntity(descriptor, world, server);
         world.SetBlockID(descriptor.Coordinates, 0);
     }
 }
예제 #16
0
        public override void BlockPlaced(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
        {
            double rotation = user.Entity.Yaw + 180 % 360;
            if (rotation < 0)
                rotation += 360;

            world.SetMetadata(descriptor.Coordinates, (byte)(rotation / 22.5));
        }
예제 #17
0
 public static VertexPositionNormalColorTexture[] RenderBlock(IBlockProvider provider, BlockDescriptor descriptor,
     VisibleFaces faces, Vector3 offset, int indiciesOffset, out int[] indicies)
 {
     var textureMap = provider.GetTextureMap(descriptor.Metadata);
     if (textureMap == null)
         textureMap = new Tuple<int, int>(0, 0); // TODO: handle this better
     return Renderers[descriptor.ID].Render(descriptor, offset, faces, textureMap, indiciesOffset, out indicies);
 }
예제 #18
0
 public override void BlockUpdate(BlockDescriptor descriptor, BlockDescriptor source, IMultiplayerServer server, IWorld world)
 {
     if (world.GetBlockID(descriptor.Coordinates + Coordinates3D.Down) == AirBlock.BlockID)
     {
         world.SetBlockID(descriptor.Coordinates, AirBlock.BlockID);
         server.GetEntityManagerForWorld(world).SpawnEntity(new FallingGravelEntity(descriptor.Coordinates));
     }
 }
예제 #19
0
 protected override ItemStack[] GetDrop(BlockDescriptor descriptor, ItemStack item)
 {
     var provider = ItemRepository.GetItemProvider(item.ID);
     if (provider is PickaxeItem)
         return new[] { new ItemStack(CobblestoneBlock.BlockID, 1, descriptor.Metadata) };
     else
         return new ItemStack[0];
 }
예제 #20
0
 public override bool BlockRightClicked(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
 {
     if (descriptor.Metadata == 5)
         world.SetBlockID(descriptor.Coordinates, AirBlock.BlockID);
     else
         world.SetMetadata(descriptor.Coordinates, (byte)(descriptor.Metadata + 1));
     return false;
 }
예제 #21
0
 public override void BlockPlaced(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
 {
     if (IsHydrated(descriptor.Coordinates, world))
     {
         world.SetMetadata(descriptor.Coordinates, 1);
     }
     user.Server.Scheduler.ScheduleEvent(DateTime.Now.AddSeconds(UpdateIntervalSeconds), (server) => HydrationCheckEvent(server, descriptor.Coordinates, world));
 }
예제 #22
0
 public override bool BlockRightClicked(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
 {
     bool upper = ((DoorItem.DoorFlags)descriptor.Metadata & DoorItem.DoorFlags.Upper) == DoorItem.DoorFlags.Upper;
     var other = upper ? Coordinates3D.Down : Coordinates3D.Up;
     var otherMeta = world.GetMetadata(descriptor.Coordinates + other);
     world.SetMetadata(descriptor.Coordinates, (byte)(descriptor.Metadata ^ (byte)DoorItem.DoorFlags.Open));
     world.SetMetadata(descriptor.Coordinates + other, (byte)(otherMeta ^ (byte)DoorItem.DoorFlags.Open));
     return false;
 }
예제 #23
0
        public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
                                                             Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
        {
            var overhead = new Vector3(0.5f, 0.5f, 0.5f);
            var centerized = new Vector3(7f / 16f, 0, 7f / 16f);
            var cube = CreateUniformCube(overhead, Texture, indiciesOffset, out indicies, Color.White);
            for (int i = 0; i < cube.Length; i++)
            {
                cube[i].Position.X *= 1f / 8f;
                cube[i].Position.Z *= 1f / 8f;
                if (cube[i].Position.Y > 0)
                    cube[i].Position.Y *= 5f / 8f;
                switch ((TorchBlock.TorchDirection)descriptor.Metadata)
                {
                    case TorchBlock.TorchDirection.West:
                        if (cube[i].Position.Y == 0)
                            cube[i].Position.X += 8f / 16f;
                        else
                            cube[i].Position.X += 3f / 16f;
                        cube[i].Position.Y += 5f / 16f;
                        break;
                    case TorchBlock.TorchDirection.East:
                        if (cube[i].Position.Y == 0)
                            cube[i].Position.X -= 8f / 16f;
                        else
                            cube[i].Position.X -= 3f / 16f;
                        cube[i].Position.Y += 5f / 16f;
                        break;
                    case TorchBlock.TorchDirection.North:
                        if (cube[i].Position.Y == 0)
                            cube[i].Position.Z += 8f / 16f;
                        else
                            cube[i].Position.Z += 3f / 16f;
                        cube[i].Position.Y += 5f / 16f;
                        break;
                    case TorchBlock.TorchDirection.South:
                        if (cube[i].Position.Y == 0)
                            cube[i].Position.Z -= 8f / 16f;
                        else
                            cube[i].Position.Z -= 3f / 16f;
                        cube[i].Position.Y += 5f / 16f;
                        break;
                    case TorchBlock.TorchDirection.Ground:
                    default:
                        // nop
                        break;
                }

                cube[i].Position += offset;
                cube[i].Position += centerized;
                cube[i].Position -= overhead;
            }
            return cube;
        }
예제 #24
0
 public override void BlockPlaced(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
 {
     if (IsHydrated(descriptor.Coordinates, world))
     {
         world.SetMetadata(descriptor.Coordinates, 1);
     }
     var chunk = world.FindChunk(descriptor.Coordinates);
     user.Server.Scheduler.ScheduleEvent("farmland", chunk,
         TimeSpan.FromSeconds(UpdateIntervalSeconds),
         server => HydrationCheckEvent(server, descriptor.Coordinates, world));
 }
예제 #25
0
 public virtual bool IsSupported(BlockDescriptor descriptor, IMultiplayerServer server, IWorld world)
 {
     var support = GetSupportDirection(descriptor);
     if (support != Coordinates3D.Zero)
     {
         var supportingBlock = server.BlockRepository.GetBlockProvider(world.GetBlockID(descriptor.Coordinates + support));
         if (!supportingBlock.Opaque)
             return false;
     }
     return true;
 }
예제 #26
0
        public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
            VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
        {
            var lighting = new int[6];
            for (int i = 0; i < 6; i++)
            {
                var coords = (descriptor.Coordinates + FaceCoords[i]);
                lighting[i] = GetLight(descriptor.Chunk, coords);
            }

            return CreateUniformCube(offset, Texture, faces, indiciesOffset, out indicies, Color.White, lighting);
        }
예제 #27
0
 public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
     VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
 {
     var cube = CreateUniformCube(Vector3.Zero, Texture, faces, indiciesOffset, out indicies, Color.White);
     var heightMultiplier = new Vector3(1, ((descriptor.Metadata + 1) / 16f), 1);
     for (int i = 0; i < cube.Length; i++)
     {
         if (cube[i].Position.Y > 0)
             cube[i].Position *= heightMultiplier;
         cube[i].Position += offset;
     }
     return cube;
 }
예제 #28
0
 protected override ItemStack[] GetDrop(BlockDescriptor descriptor, ItemStack item)
 {
     var provider = ItemRepository.GetItemProvider(item.ID);
     if (provider is ShearsItem)
         return base.GetDrop(descriptor, item);
     else
     {
         if (MathHelper.Random.Next(20) == 0) // 5% chance
         return new[] { new ItemStack(SaplingBlock.BlockID, 1, descriptor.Metadata) };
         else
             return new ItemStack[0];
     }
 }
예제 #29
0
 public override void BlockUpdate(BlockDescriptor descriptor, BlockDescriptor source, IMultiplayerServer server, IWorld world)
 {
     if (ID == StillID)
     {
         var outward = DetermineOutwardFlow(world, descriptor.Coordinates);
         var inward = DetermineInwardFlow(world, descriptor.Coordinates);
         if (outward.Length != 0 || inward != descriptor.Metadata)
         {
             world.SetBlockID(descriptor.Coordinates, FlowingID);
             ScheduleNextEvent(descriptor.Coordinates, world, server);
         }
     }
 }
예제 #30
0
        public override void BlockPlaced(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
        {
            if (ValidCactusPosition(descriptor, user.Server.BlockRepository, world))
                base.BlockPlaced(descriptor, face, world, user);
            else
            {
                world.SetBlockID(descriptor.Coordinates, AirBlock.BlockID);

                var manager = user.Server.GetEntityManagerForWorld(world);
                manager.SpawnEntity(
                    new ItemEntity(descriptor.Coordinates + Coordinates3D.Up,
                        new ItemStack(CactusBlock.BlockID, (sbyte)1)));
                // user.Inventory.PickUpStack() wasn't working?
            }
        }