예제 #1
0
파일: BlockChest.cs 프로젝트: Smjert/c-raft
        public override void Place(EntityBase entity, StructBlock block, StructBlock targetBlock, BlockFace face)
        {
            // Load the blocks surrounding the position (NSEW) not diagonals
            BlockData.Blocks[] nsewBlocks = new BlockData.Blocks[4];
            UniversalCoords[] nsewBlockPositions = new UniversalCoords[4];
            int nsewCount = 0;
            block.Chunk.ForNSEW(block.Coords, (uc) =>
            {
                nsewBlocks[nsewCount] = (BlockData.Blocks)block.World.GetBlockId(uc);
                nsewBlockPositions[nsewCount] = uc;
                nsewCount++;
            });

            // Count chests in list
            if (nsewBlocks.Where((b) => b == BlockData.Blocks.Chest).Count() > 1)
            {
                // Cannot place next to two chests
                return;
            }

            for (int i = 0; i < 4; i++)
            {
                UniversalCoords p = nsewBlockPositions[i];
                if (nsewBlocks[i] == BlockData.Blocks.Chest && block.Chunk.IsNSEWTo(p, (byte)BlockData.Blocks.Chest))
                {
                    // Cannot place next to a double chest
                    return;
                }
            }
            base.Place(entity, block, targetBlock, face);
        }
예제 #2
0
파일: BlockCrops.cs 프로젝트: Smjert/c-raft
 public bool CanGrow(StructBlock block)
 {
     // Crops grow from 0x0 to 0x7
     if (block.MetaData == 0x07)
         return false;
     return true;
 }
예제 #3
0
        public override void Place(EntityBase entity, StructBlock block, StructBlock targetBlock, BlockFace face)
        {
            Player player = (entity as Player);
            if (player == null)
                return;
            if (face == BlockFace.Down)
                return;

            switch (face)
            {
                case BlockFace.Down: return;
                case BlockFace.Up: block.MetaData = (byte)MetaData.Torch.Standing;
                    break;
                case BlockFace.West: block.MetaData = (byte)MetaData.Torch.West;
                    break;
                case BlockFace.East: block.MetaData = (byte)MetaData.Torch.East;
                    break;
                case BlockFace.North: block.MetaData = (byte)MetaData.Torch.North;
                    break;
                case BlockFace.South: block.MetaData = (byte)MetaData.Torch.South;
                    break;
            }

            base.Place(entity, block, targetBlock, face);
        }
        public override void Place(EntityBase entity, StructBlock block, StructBlock targetBlock, BlockFace targetSide)
        {
            Player player = entity as Player;
            if (player == null)
                return;

            // TODO: Bugged - should depend on the player's Yaw/Pitch
            switch (player.Client.FacingDirection(4))
            {
                case "N":
                    block.MetaData = (byte)MetaData.Stairs.South;
                    break;
                case "E":
                    block.MetaData = (byte)MetaData.Stairs.West;
                    break;
                case "S":
                    block.MetaData = (byte)MetaData.Stairs.North;
                    break;
                case "W":
                    block.MetaData = (byte)MetaData.Stairs.East;
                    break;
                default:
                    return;
            }
            base.Place(entity, block, targetBlock, targetSide);
        }
예제 #5
0
        protected override bool CanBePlacedOn(EntityBase who, StructBlock block, StructBlock targetBlock, BlockFace targetSide)
        {
            Chunk chunk = GetBlockChunk(block);
            if (chunk == null)
                return false;

            bool isDoubleChestNearby = false;
            int chestCount = 0;
            chunk.ForNSEW(block.Coords, uc =>
            {
                byte? nearbyBlockId = block.World.GetBlockId(uc);

                if (nearbyBlockId == null)
                    return;

                // Cannot place next to a double chest
                if (nearbyBlockId == (byte)BlockData.Blocks.Chest)
                {
                    chestCount++;
                     if (chunk.IsNSEWTo(uc, (byte)BlockData.Blocks.Chest))
                        isDoubleChestNearby = true;
                }
            });

            if (isDoubleChestNearby || chestCount > 1)
                return false;
            return base.CanBePlacedOn(who, block, targetBlock, targetSide);
        }
예제 #6
0
        public void Grow(StructBlock block)
        {
            // Too high
            /*            if (Y > 120)
                return;

            // Grow a trunk. Replace only the BlockAir
            for (int i = Y; i < Y + 5; i++)
            {
                if (Chunk.World.GetBlockId(X, i, Z) == (byte)BlockData.Blocks.Air)
                    WorldMgr.GetChunk(X, Z, false, true).ReplaceBlock(this, BlockData.Blocks.Log, BlockMeta);
                else
                    break;
            }

            // Grow leaves
            for (int i = Y + 2; i < Y + 5; i++)
                for (int j = X - 2; j <= X + 2; j++)
                    for (int k = Z - 2; k <= Z + 2; k++)
                        if (!WorldMgr.ChunkExists(j, k) || !(WorldMgr.GetBlock(j, i, k) is BlockAir))
                            continue;
                        else
                            WorldMgr.GetChunk(j, k, false, true).ReplaceBlock(this, BlockData.Blocks.Leaves, BlockMeta);

            for (int i = X - 1; i <= X + 1; i++)
                for (int j = Z - 1; j <= Z + 1; j++)
                    if (!WorldMgr.ChunkExists(i, j) || !(WorldMgr.GetBlock(i, Y + 5, j) is BlockAir))
                        continue;
                    else
                        WorldMgr.GetChunk(i, j, false, true).ReplaceBlock(this, BlockData.Blocks.Leaves, BlockMeta);

            foreach (Client c in WorldMgr.Server.GetNearbyPlayers(WorldMgr, X, Y, Z))
                c.SendBlockRegion(X - 3, Y, Z - 3, 7, 7, 7);
             */
        }
예제 #7
0
파일: BlockSand.cs 프로젝트: Smjert/c-raft
 protected void StartPhysics(StructBlock block)
 {
     Remove(block);
     FallingSand fsBlock = new FallingSand(block.World, new Location(block.Coords.WorldX + 0.5, block.Coords.WorldY + 0.5, block.Coords.WorldZ + 0.5));
     fsBlock.Start();
     block.World.PhysicsBlocks.TryAdd(fsBlock.EntityId, fsBlock);
 }
예제 #8
0
 protected override void DropItems(EntityBase entity, StructBlock block)
 {
     LootTable = new List<ItemStack>();
     if (block.World.Server.Rand.Next(5) == 0)
         LootTable.Add(new ItemStack((short)BlockData.Blocks.Sapling, 1));
     base.DropItems(entity, block);
 }
예제 #9
0
        public void Grow(StructBlock block)
        {
            if (!CanGrow(block))
                return;

            for (int i = block.Coords.WorldY; i < block.Coords.WorldY + 4; i++)
            {
                block.World.SetBlockAndData(block.Coords.WorldX, i, block.Coords.WorldZ, (byte)BlockData.Blocks.Log, block.MetaData);
                if (block.World.GetBlockId(block.Coords.WorldX, i + 1, block.Coords.WorldZ) != (byte)BlockData.Blocks.Air)
                    break;
            }

            // Grow leaves
            for (int i = block.Coords.WorldY + 2; i < block.Coords.WorldY + 5; i++)
                for (int j = block.Coords.WorldX - 2; j <= block.Coords.WorldX + 2; j++)
                    for (int k = block.Coords.WorldZ - 2; k <= block.Coords.WorldZ + 2; k++)
                        if (!block.World.ChunkExists(j >> 4, k >> 4) || (block.World.GetBlockId(j, i, k) != (byte)BlockData.Blocks.Air))
                            continue;
                        else
                            block.World.SetBlockAndData(j, i, k, (byte)BlockData.Blocks.Leaves,
                                                        block.MetaData);

            for (int i = block.Coords.WorldX - 1; i <= block.Coords.WorldX + 1; i++)
                for (int j = block.Coords.WorldZ - 1; j <= block.Coords.WorldZ + 1; j++)
                    if (!block.World.ChunkExists(i >> 4, j >> 4) || (block.World.GetBlockId(i, block.Coords.WorldY + 5, j) != (byte)BlockData.Blocks.Air))
                        continue;
                    else
                        block.World.SetBlockAndData(i, block.Coords.WorldY + 5, j, (byte)BlockData.Blocks.Leaves,
                                                    block.MetaData);
            AbsWorldCoords absCoords = new AbsWorldCoords(block.Coords);
            foreach (Net.Client c in block.World.Server.GetNearbyPlayers(block.World, absCoords))
            {
                c.SendBlockRegion(block.Coords.WorldX - 3, block.Coords.WorldY, block.Coords.WorldZ - 3, 7, 7, 7);
            }
        }
예제 #10
0
 protected void StartPhysics(StructBlock block)
 {
     Remove(block);
     FallingGravel fgBlock = new FallingGravel(block.World, new AbsWorldCoords(block.Coords.WorldX + 0.5, block.Coords.WorldY + 0.5, block.Coords.WorldZ + 0.5));
     fgBlock.Start();
     block.World.PhysicsBlocks.TryAdd(fgBlock.EntityId, fgBlock);
 }
예제 #11
0
 protected override void UpdateWorld(StructBlock block, bool isDestroyed = false)
 {
     base.UpdateWorld(block, isDestroyed);
     if (!isDestroyed && block.Coords.WorldY > 1)
         if (block.World.GetBlockId(block.Coords.WorldX, block.Coords.WorldY - 1, block.Coords.WorldZ) == (byte)BlockData.Blocks.Air)
             StartPhysics(block);
 }
예제 #12
0
 public override void Place(EntityBase entity, StructBlock block, StructBlock targetBlock, BlockFace face)
 {
     LivingEntity living = (entity as LivingEntity);
     if (living == null)
         return;
     block.MetaData = GetDirection(living, block, targetBlock, face);
     base.Place(entity, block, targetBlock, face);
 }
예제 #13
0
 protected override void DropItems(EntityBase entity, StructBlock block, List<ItemStack> overridedLoot = null)
 {
     // SnowBlock requires 9 snowballs to craft and drops 4-6 snowballs upon destruction.
     // No tools required.
     overridedLoot = new List<ItemStack>();
     overridedLoot.Add(new ItemStack((short)BlockData.Items.Snowball, (sbyte)(4 + block.World.Server.Rand.Next(2))));
     base.DropItems(entity, block, overridedLoot);
 }
예제 #14
0
 public override void NotifyDestroy(EntityBase entity, StructBlock sourceBlock, StructBlock targetBlock)
 {
     if ((targetBlock.Coords.WorldY - sourceBlock.Coords.WorldY) == 1 &&
         targetBlock.Coords.WorldX == sourceBlock.Coords.WorldX &&
         targetBlock.Coords.WorldZ == sourceBlock.Coords.WorldZ)
         Destroy(targetBlock);
     base.NotifyDestroy(entity, sourceBlock, targetBlock);
 }
예제 #15
0
 protected override void DropItems(EntityBase entity, StructBlock block, List<ItemStack> overridedLoot = null)
 {
     overridedLoot = new List<ItemStack>();
     int amount = block.World.Server.Rand.Next(10) - 7;
     if (amount > 0)
         overridedLoot.Add(new ItemStack((short)BlockData.Blocks.Red_Mushroom, (sbyte)amount));
     base.DropItems(entity, block, overridedLoot);
 }
예제 #16
0
 protected override void DropItems(EntityBase entity, StructBlock block)
 {
     LootTable = new List<ItemStack>();
     int amount = block.World.Server.Rand.Next(10) - 7;
     if (amount > 0)
         LootTable.Add(new ItemStack((short)BlockData.Blocks.Brown_Mushroom, (sbyte)amount));
     base.DropItems(entity, block);
 }
예제 #17
0
        public void Interact(EntityBase entity, StructBlock block)
        {
            Player player = entity as Player;
            if (player == null)
                return;
            if (player.CurrentInterface != null)
                return;

            byte? blockId = block.World.GetBlockId(block.Coords);

            if (blockId == null || !BlockHelper.Instance((byte)blockId).IsAir)
            {
                // Cannot open a chest if no space is above it
                return;
            }

            Chunk chunk = GetBlockChunk(block);

            // Double chest?
            if (chunk.IsNSEWTo(block.Coords, block.Type))
            {
                // Is this chest the "North or East", or the "South or West"
                BlockData.Blocks[] nsewBlocks = new BlockData.Blocks[4];
                UniversalCoords[] nsewBlockPositions = new UniversalCoords[4];
                int nsewCount = 0;
                chunk.ForNSEW(block.Coords, (uc) =>
                {
                    nsewBlocks[nsewCount] = (BlockData.Blocks)block.World.GetBlockId(uc);
                    nsewBlockPositions[nsewCount] = uc;
                    nsewCount++;
                });

                if ((byte)nsewBlocks[0] == block.Type) // North
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, nsewBlockPositions[0], block.Coords);
                }
                else if ((byte)nsewBlocks[2] == block.Type) // East
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, nsewBlockPositions[2], block.Coords);
                }
                else if ((byte)nsewBlocks[1] == block.Type) // South
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, block.Coords, nsewBlockPositions[1]);
                }
                else if ((byte)nsewBlocks[3] == block.Type) // West
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, block.Coords, nsewBlockPositions[3]);
                }
            }
            else
            {
                player.CurrentInterface = new SmallChestInterface(block.World, block.Coords);
            }

            player.CurrentInterface.Associate(player);
            player.CurrentInterface.Open();
        }
예제 #18
0
 public void Interact(EntityBase entity, StructBlock block)
 {
     Player player = entity as Player;
     if (player == null)
         return;
     if (player.CurrentInterface != null)
         return;
     ContainerFactory.Open(player, block.Coords);
 }
예제 #19
0
파일: BlockLava.cs 프로젝트: dekema2/c-raft
 public override void Touch(EntityBase entity, StructBlock block, BlockFace face)
 {
     LivingEntity living = entity as LivingEntity;
     if (living != null)
     {
         living.TouchedLava();
     }
     base.Touch(entity, block, face);
 }
예제 #20
0
        public void Interact(EntityBase entity, StructBlock block)
        {
            Player player = entity as Player;
            if (player == null)
                return;
            if (player.CurrentInterface != null)
                return;

            if (!block.World.BlockHelper.Instance(block.World.GetBlockId(block.X, block.Y, block.Z)).IsAir)
            {
                // Cannot open a chest if no space is above it
                return;
            }

            Chunk chunk = player.World.GetBlockChunk(block.X, block.Y, block.Z);

            // Double chest?
            // TODO: simplify chunk API so that no bit shifting is required
            if (chunk.IsNSEWTo(block.X & 0xf, block.Y, block.Z & 0xf, block.Type))
            {
                // Is this chest the "North or East", or the "South or West"
                BlockData.Blocks[] nsewBlocks = new BlockData.Blocks[4];
                PointI[] nsewBlockPositions = new PointI[4];
                int nsewCount = 0;
                chunk.ForNSEW(block.X & 0xf, block.Y, block.Z & 0xf, (x1, y1, z1) =>
                {
                    nsewBlocks[nsewCount] = (BlockData.Blocks)block.World.GetBlockId(x1, y1, z1);
                    nsewBlockPositions[nsewCount] = new PointI(x1, y1, z1);
                    nsewCount++;
                });

                if ((byte)nsewBlocks[0] == block.Type) // North
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, nsewBlockPositions[0], new PointI(block.X, block.Y, block.Z));
                }
                else if ((byte)nsewBlocks[2] == block.Type) // East
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, nsewBlockPositions[2], new PointI(block.X, block.Y, block.Z));
                }
                else if ((byte)nsewBlocks[1] == block.Type) // South
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, new PointI(block.X, block.Y, block.Z), nsewBlockPositions[1]);
                }
                else if ((byte)nsewBlocks[3] == block.Type) // West
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, new PointI(block.X, block.Y, block.Z), nsewBlockPositions[3]);
                }
            }
            else
            {
                player.CurrentInterface = new SmallChestInterface(block.World, block.X, block.Y, block.Z);
            }

            player.CurrentInterface.Associate(player);
            player.CurrentInterface.Open();
        }
예제 #21
0
 public override void Place(EntityBase entity, StructBlock block, StructBlock targetBlock, BlockFace face)
 {
     if (face == BlockFace.Down)
         return;
     byte? blockId = targetBlock.World.GetBlockId(UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY - 1, block.Coords.WorldZ));
     // We can place the tall grass only on the fertile blocks - dirt, soil, grass)
     if (blockId == null || !BlockHelper.Instance((byte)blockId).IsFertile)
         return;
     base.Place(entity, block, targetBlock, face);
 }
예제 #22
0
파일: BlockGrass.cs 프로젝트: Smjert/c-raft
        public void Grow(StructBlock block)
        {
            if (!CanGrow(block))
                return;

            if (block.World.Server.Rand.Next(10) == 0)
            {
                block.World.SetBlockAndData(block.Coords, (byte)BlockData.Blocks.Dirt, 0);
            }
        }
예제 #23
0
 protected override bool CanBePlacedOn(EntityBase who, StructBlock block, StructBlock targetBlock, BlockFace targetSide)
 {
     if (block.Coords.WorldY > 125)
         return false;
     UniversalCoords blockAbove = UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1,
                                                            block.Coords.WorldZ);
     if (block.World.GetBlockId(blockAbove) != (byte)BlockData.Blocks.Air)
         return false;
     return base.CanBePlacedOn(who, block, targetBlock, targetSide);
 }
예제 #24
0
 public override void NotifyDestroy(EntityBase entity, StructBlock sourceBlock, StructBlock targetBlock)
 {
     if (targetBlock.Coords.WorldY > sourceBlock.Coords.WorldY && targetBlock.MetaData == (byte)MetaData.Torch.Standing ||
         targetBlock.Coords.WorldX > sourceBlock.Coords.WorldX && targetBlock.MetaData == (byte)MetaData.Torch.South ||
         targetBlock.Coords.WorldX < sourceBlock.Coords.WorldX && targetBlock.MetaData == (byte)MetaData.Torch.North ||
         targetBlock.Coords.WorldZ > sourceBlock.Coords.WorldZ && targetBlock.MetaData == (byte)MetaData.Torch.West ||
         targetBlock.Coords.WorldZ < sourceBlock.Coords.WorldZ && targetBlock.MetaData == (byte)MetaData.Torch.East)
         Destroy(targetBlock);
     base.NotifyDestroy(entity, sourceBlock, targetBlock);
 }
예제 #25
0
 public override void Place(EntityBase entity, StructBlock block, StructBlock targetBlock, BlockFace face)
 {
     if (face == BlockFace.Down)
         return;
     byte blockId = targetBlock.World.GetBlockId(block.X, block.Y-1, block.Z);
     // We can place the tall grass only on the fertile blocks - dirt, soil, grass)
     if (!targetBlock.World.BlockHelper.Instance(blockId).IsFertile)
         return;
     base.Place(entity, block, targetBlock, face);
 }
예제 #26
0
 public void Interact(EntityBase entity, StructBlock block)
 {
     Player player = entity as Player;
     if (player == null)
         return;
     if (player.CurrentInterface != null)
         return;
     player.CurrentInterface = new WorkbenchInterface();
     player.CurrentInterface.Associate(player);
     ((WorkbenchInterface)player.CurrentInterface).Open(block.Coords);
 }
예제 #27
0
 public bool CanGrow(StructBlock block, Chunk chunk)
 {
     if (chunk == null || block.Coords.WorldY > 120)
         return false;
     /*UniversalCoords oneUp = UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1,
                                                       block.Coords.WorldZ);
     byte lightUp = block.World.GetBlockData(oneUp);
     if (lightUp < 9)
         return false;*/
     return true;
 }
예제 #28
0
 public void Interact(EntityBase entity, StructBlock block)
 {
     Player player = entity as Player;
     if (player == null)
         return;
     if (player.CurrentInterface != null)
         return;
     player.CurrentInterface = new FurnaceInterface(block.World, block.Coords);
     player.CurrentInterface.Associate(player);
     player.CurrentInterface.Open();
 }
예제 #29
0
 public void Interact(EntityBase entity, StructBlock block)
 {
     if (block.Coords.WorldY < 127)
     {
         // Cannot open a chest if no space is above it
         byte? blockId = block.World.GetBlockId(block.Coords.WorldX, block.Coords.WorldY + 1, block.Coords.WorldZ);
         if (blockId == null || !BlockHelper.IsAir((byte)blockId))
             return;
     }
     base.Interact(entity, block);
 }
예제 #30
-1
        public bool CanGrow(StructBlock block, Chunk chunk)
        {
            if (chunk == null)
                return false;

            // Can't grow above the sky
            if (block.Coords.WorldY == 127)
                return false;

            // Can grow only if the block above is free
            byte blockId = (byte)chunk.GetType(UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1, block.Coords.WorldZ));
            if (blockId != (byte)BlockData.Blocks.Air)
                return false;

            // MetaData = 0x0 is a freshly planted reed (sugar cane).
            // The data value is incremented randomly.
            // When it becomes 15, a new reed block is created on top as long as the total height does not exceed 3.

            // Calculating the reed length below this block
            int reedHeightBelow = 0;
            for (int i = block.Coords.WorldY - 1; i >= 0; i--)
            {
                if (chunk.GetType(block.Coords.BlockX, i, block.Coords.BlockZ) != BlockData.Blocks.Reed)
                    break;
                reedHeightBelow++;
            }

            // If the total reed height is bigger than the maximal height - it'll not grow
            if ((reedHeightBelow + 1) >= MaxHeight)
                return false;

            // Checking if there are water next to the basement block
            bool isWater = false;

            chunk.ForNSEW(UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY - reedHeightBelow - 1, block.Coords.WorldZ),
                delegate(UniversalCoords uc)
                {
                    byte? blockIdBelow = block.World.GetBlockId(uc);
                    if (blockIdBelow != null && (blockIdBelow == (byte)BlockData.Blocks.Water || blockIdBelow == (byte)BlockData.Blocks.Still_Water))
                    {
                        isWater = true;
                    }
                });

            if (!isWater && reedHeightBelow < MaxHeight)
            {
                UniversalCoords baseBlock = UniversalCoords.FromWorld(block.Coords.WorldX,
                                                                      block.Coords.WorldY - reedHeightBelow,
                                                                      block.Coords.WorldZ);
                BlockHelper.Instance(block.Type).Destroy(new StructBlock(baseBlock, block.Type, block.MetaData, block.World));
                return false;
            }

            return true;
        }