public bool IsOpaque(BlockData.Blocks blockType) { byte opacity; _blocksOpacity.TryGetValue((byte)blockType, out opacity); return(opacity == 0xF); }
public byte Opacity(BlockData.Blocks blockType) { byte opacity; _blocksOpacity.TryGetValue((byte)blockType, out opacity); return(opacity); }
public short BurnEfficiency(BlockData.Blocks blockType) { short burnEfficiency; _blocksBurnEfficiency.TryGetValue((byte)blockType, out burnEfficiency); return(burnEfficiency); }
public byte Luminance(BlockData.Blocks blockType) { byte luminance; _blocksLuminance.TryGetValue((byte)blockType, out luminance); return(luminance); }
public bool IsIgnitable(BlockData.Blocks blockType) { short burnEfficiency; _blocksBurnEfficiency.TryGetValue((byte)blockType, out burnEfficiency); return(burnEfficiency > 0); }
public static void Open(Player player, UniversalCoords coords) { PersistentContainer container = Instance(player.World, coords); if (container == null) { return; } Chunk chunk = player.World.GetChunk(coords) as Chunk; if (chunk == null) { return; } BlockData.Blocks block = chunk.GetType(coords); switch (block) { case BlockData.Blocks.Furnace: case BlockData.Blocks.Burning_Furnace: player.CurrentInterface = new FurnaceInterface(player.World, coords); break; case BlockData.Blocks.Dispenser: player.CurrentInterface = new DispenserInterface(player.World, coords); break; case BlockData.Blocks.Chest: if (container is LargeChestContainer) { UniversalCoords[] doubleChestCoords = GetDoubleChestCoords(player.World, coords); if (doubleChestCoords == null) { return; } if (container.Coords == doubleChestCoords[0]) { player.CurrentInterface = new LargeChestInterface(player.World, doubleChestCoords[0], doubleChestCoords[1]); } else { player.CurrentInterface = new LargeChestInterface(player.World, doubleChestCoords[1], doubleChestCoords[0]); } } else { player.CurrentInterface = new SmallChestInterface(player.World, coords); } break; default: return; } player.CurrentInterface.Associate(player); container.AddInterface((PersistentContainerInterface)player.CurrentInterface); player.CurrentInterface.Open(); }
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(); }
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(); }
protected override byte GetDirection(LivingEntity living, StructBlock block, StructBlock targetBlock, BlockFace face) { Chunk chunk = GetBlockChunk(block); // Load the blocks surrounding the position (NSEW) not diagonals var nsewBlocks = new BlockData.Blocks[4]; var nsewBlockPositions = new UniversalCoords[4]; int nsewCount = 0; int secondChestIndex = -1; chunk.ForNSEW(block.Coords, uc => { byte? nearbyBlockId = block.World.GetBlockId(uc); if (nearbyBlockId == null) return; if (nearbyBlockId == (byte)BlockData.Blocks.Chest) secondChestIndex = nsewCount; nsewBlocks[nsewCount] = (BlockData.Blocks)nearbyBlockId; nsewBlockPositions[nsewCount] = uc; nsewCount++; }); byte direction = base.GetDirection(living, block, targetBlock, face); if (secondChestIndex != -1) { var secondChestCoords = nsewBlockPositions[secondChestIndex]; byte secondChestDirection = chunk.GetData(secondChestCoords); if (secondChestDirection != direction) { if (secondChestCoords.WorldX == block.Coords.WorldX) { if (direction != (byte)MetaData.Container.South && direction != (byte)MetaData.Container.North) direction = (byte)MetaData.Container.South; } else { if (direction != (byte)MetaData.Container.East && direction != (byte)MetaData.Container.West) direction = (byte)MetaData.Container.West; } } else { if (secondChestCoords.WorldX == block.Coords.WorldX && block.MetaData != (byte)MetaData.Container.North && block.MetaData != (byte)MetaData.Container.South) direction = (byte)MetaData.Container.South; else if (block.MetaData != (byte)MetaData.Container.West && block.MetaData != (byte)MetaData.Container.East) direction = (byte)MetaData.Container.West; } } return direction; }
public static void HandlePacketUpdateSign(Client client, UpdateSignPacket packet) { BlockData.Blocks blockId = (BlockData.Blocks)client.Owner.World.GetBlockId(packet.X, packet.Y, packet.Z); UniversalCoords coords = UniversalCoords.FromWorld(packet.X, packet.Y, packet.Z); if (blockId == BlockData.Blocks.Sign_Post) { BlockSignPost sign = (BlockSignPost)BlockHelper.Instance.CreateBlockInstance((byte)blockId); sign.SaveText(coords, client.Owner, packet.Lines); } }
public static UniversalCoords[] GetDoubleChestCoords(WorldManager world, UniversalCoords coords) { Chunk chunk = world.GetChunk(coords) as Chunk; if (chunk == null || !IsDoubleChest(chunk, coords)) { return(null); } // 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; byte?blockId; chunk.ForNSEW(coords, uc => { blockId = world.GetBlockId(uc) ?? 0; nsewBlocks[nsewCount] = (BlockData.Blocks)blockId; nsewBlockPositions[nsewCount] = uc; nsewCount++; }); UniversalCoords firstCoords; UniversalCoords secondCoords; if ((byte)nsewBlocks[0] == (byte)BlockData.Blocks.Chest) // North { firstCoords = nsewBlockPositions[0]; secondCoords = coords; } else if ((byte)nsewBlocks[2] == (byte)BlockData.Blocks.Chest) // East { firstCoords = nsewBlockPositions[2]; secondCoords = coords; } else if ((byte)nsewBlocks[1] == (byte)BlockData.Blocks.Chest) // South { firstCoords = coords; secondCoords = nsewBlockPositions[1]; } else// if ((byte)nsewBlocks[3] == (byte)BlockData.Blocks.Chest) // West { firstCoords = coords; secondCoords = nsewBlockPositions[3]; } return(new UniversalCoords[] { firstCoords, secondCoords }); }
public static UniversalCoords[] GetDoubleChestCoords(WorldManager world, UniversalCoords coords) { Chunk chunk = world.GetChunk(coords); if (chunk == null || !IsDoubleChest(chunk, coords)) return null; // 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; byte? blockId; chunk.ForNSEW(coords, uc => { blockId = world.GetBlockId(uc) ?? 0; nsewBlocks[nsewCount] = (BlockData.Blocks)blockId; nsewBlockPositions[nsewCount] = uc; nsewCount++; }); UniversalCoords firstCoords; UniversalCoords secondCoords; if ((byte)nsewBlocks[0] == (byte)BlockData.Blocks.Chest) // North { firstCoords = nsewBlockPositions[0]; secondCoords = coords; } else if ((byte)nsewBlocks[2] == (byte)BlockData.Blocks.Chest) // East { firstCoords = nsewBlockPositions[2]; secondCoords = coords; } else if ((byte)nsewBlocks[1] == (byte)BlockData.Blocks.Chest) // South { firstCoords = coords; secondCoords = nsewBlockPositions[1]; } else// if ((byte)nsewBlocks[3] == (byte)BlockData.Blocks.Chest) // West { firstCoords = coords; secondCoords = nsewBlockPositions[3]; } return new UniversalCoords[] { firstCoords, secondCoords }; }
public bool IsLiquid(BlockData.Blocks blockType) { return(_liquidBlocks.ContainsKey((byte)blockType)); }
public bool IsAir(BlockData.Blocks blockType) { return(_airBlocks.ContainsKey((byte)blockType)); }
public bool IsPlowed(BlockData.Blocks blockType) { return(_plowedBlocks.ContainsKey((byte)blockType)); }
public bool IsFertile(BlockData.Blocks blockType) { return(_fertileBlocks.ContainsKey((byte)blockType)); }
public bool IsGrowable(BlockData.Blocks blockType) { return(_growableBlocks.ContainsKey((byte)blockType)); }
protected override byte GetDirection(LivingEntity living, StructBlock block, StructBlock targetBlock, BlockFace face) { Chunk chunk = GetBlockChunk(block); // Load the blocks surrounding the position (NSEW) not diagonals var nsewBlocks = new BlockData.Blocks[4]; var nsewBlockPositions = new UniversalCoords[4]; int nsewCount = 0; int secondChestIndex = -1; chunk.ForNSEW(block.Coords, uc => { byte?nearbyBlockId = block.World.GetBlockId(uc); if (nearbyBlockId == null) { return; } if (nearbyBlockId == (byte)BlockData.Blocks.Chest) { secondChestIndex = nsewCount; } nsewBlocks[nsewCount] = (BlockData.Blocks)nearbyBlockId; nsewBlockPositions[nsewCount] = uc; nsewCount++; }); byte direction = base.GetDirection(living, block, targetBlock, face); if (secondChestIndex != -1) { var secondChestCoords = nsewBlockPositions[secondChestIndex]; byte secondChestDirection = chunk.GetData(secondChestCoords); if (secondChestDirection != direction) { if (secondChestCoords.WorldX == block.Coords.WorldX) { if (direction != (byte)MetaData.Container.South && direction != (byte)MetaData.Container.North) { direction = (byte)MetaData.Container.South; } } else { if (direction != (byte)MetaData.Container.East && direction != (byte)MetaData.Container.West) { direction = (byte)MetaData.Container.West; } } } else { if (secondChestCoords.WorldX == block.Coords.WorldX && block.MetaData != (byte)MetaData.Container.North && block.MetaData != (byte)MetaData.Container.South) { direction = (byte)MetaData.Container.South; } else if (block.MetaData != (byte)MetaData.Container.West && block.MetaData != (byte)MetaData.Container.East) { direction = (byte)MetaData.Container.West; } } } return(direction); }
public static void HandlePacketPlayerItemPlacement(Client client, PlayerBlockPlacementPacket packet) { Player player = client.Owner; // if(!Permissions.CanPlayerBuild(Username)) return; if (player.Inventory.Slots[player.Inventory.ActiveSlot].Type <= 255) { return; } UniversalCoords baseBlockCoords = UniversalCoords.FromWorld(packet.X, packet.Y, packet.Z); Chunk chunk = player.World.GetChunk(baseBlockCoords) as Chunk; if (chunk == null) { return; } BlockData.Blocks baseBlockType = chunk.GetType(baseBlockCoords); // Get block being built against. byte baseBlockData = chunk.GetData(baseBlockCoords); StructBlock baseBlock = new StructBlock(baseBlockCoords, (byte)baseBlockType, (byte)baseBlockData, player.World); // Placed Item Info short pType = player.Inventory.Slots[player.Inventory.ActiveSlot].Type; short pMetaData = player.Inventory.Slots[player.Inventory.ActiveSlot].Durability; UniversalCoords newBlockCoords = player.World.FromFace(baseBlockCoords, packet.Face); StructBlock newBlock; byte newBlockId = 0; switch (packet.Face) { case BlockFace.Held: return; // TODO: Process buckets, food, etc. } switch (baseBlockType) { case BlockData.Blocks.Air: case BlockData.Blocks.Water: case BlockData.Blocks.Lava: case BlockData.Blocks.Still_Water: case BlockData.Blocks.Still_Lava: return; } switch ((BlockData.Items)pType) { case BlockData.Items.Diamond_Hoe: case BlockData.Items.Gold_Hoe: case BlockData.Items.Iron_Hoe: case BlockData.Items.Stone_Hoe: case BlockData.Items.Wooden_Hoe: if (baseBlockType == BlockData.Blocks.Dirt || baseBlockType == BlockData.Blocks.Grass) { // Think the client has a Notch bug where hoe's durability is not updated properly. BlockHelper.Instance.CreateBlockInstance((byte)BlockData.Blocks.Soil).Spawn(baseBlock); } return; case BlockData.Items.Ink_Sack: if (pMetaData != 15) { return; } if (baseBlockType == BlockData.Blocks.Red_Mushroom || baseBlockType == BlockData.Blocks.Brown_Mushroom) { BlockBaseMushroom baseMushroom = (BlockBaseMushroom)BlockHelper.Instance.CreateBlockInstance((byte)baseBlockType); baseMushroom.Fertilize(player, baseBlock); } return; case BlockData.Items.Minecart: case BlockData.Items.Boat: case BlockData.Items.Storage_Minecart: case BlockData.Items.Powered_Minecart: // TODO: Create new object break; case BlockData.Items.Sign: if (packet.Face == BlockFace.Up) { newBlockId = (byte)BlockData.Blocks.Sign_Post; } else { newBlockId = (byte)BlockData.Blocks.Wall_Sign; } break; case BlockData.Items.Seeds: newBlockId = (byte)BlockData.Blocks.Crops; break; case BlockData.Items.Reeds: newBlockId = (byte)BlockData.Blocks.Reed; break; case BlockData.Items.Redstone: newBlockId = (byte)BlockData.Blocks.Redstone_Wire; break; case BlockData.Items.Iron_Door: newBlockId = (byte)BlockData.Blocks.Iron_Door; break; case BlockData.Items.Wooden_Door: newBlockId = (byte)BlockData.Blocks.Wooden_Door; break; } if (newBlockId != 0) { newBlock = new StructBlock(newBlockCoords, newBlockId, 0, player.World); BlockHelper.Instance.CreateBlockInstance(newBlockId).Place(player, newBlock, baseBlock, packet.Face); } }
public static void HandlePacketPlayerBlockPlacement(Client client, PlayerBlockPlacementPacket packet) { /* * Scenarios: * * 1) using an item against a block (e.g. stone and flint) * 2) placing a new block * 3) using a block: e.g. open/close door, open chest, open workbench, open furnace * * */ // if (!Permissions.CanPlayerBuild(Username)) return; // Using activeslot provides current item info wtihout having to maintain ActiveItem UniversalCoords coords = UniversalCoords.FromWorld(packet.X, packet.Y, packet.Z); if (packet.X == -1 && packet.Y == -1 && packet.Z == -1 && packet.Face == BlockFace.Held) { // TODO: Implement item usage - food etc return; } Player player = client.Owner; Chunk chunk = player.World.GetChunk(coords) as Chunk; if (chunk == null) { return; } BlockData.Blocks type = chunk.GetType(coords); // Get block being built against. byte metadata = chunk.GetData(coords); StructBlock facingBlock = new StructBlock(coords, (byte)type, metadata, player.World); UniversalCoords coordsFromFace = player.World.FromFace(coords, packet.Face); if (BlockHelper.Instance.CreateBlockInstance((byte)type) is IBlockInteractive) { (BlockHelper.Instance.CreateBlockInstance((byte)type) as IBlockInteractive).Interact(player, facingBlock); return; } if (player.Inventory.Slots[player.Inventory.ActiveSlot].Type <= 0 || player.Inventory.Slots[player.Inventory.ActiveSlot].Count < 1) { return; } // TODO: Neaten this out, or address via handler? if (player.Inventory.Slots[player.Inventory.ActiveSlot].Type > 255 || packet.Face == BlockFace.Held) // Client is using an Item. { HandlePacketPlayerItemPlacement(client, packet); return; } // Built Block Info byte bType = (byte)player.Inventory.Slots[player.Inventory.ActiveSlot].Type; byte bMetaData = (byte)player.Inventory.Slots[player.Inventory.ActiveSlot].Durability; StructBlock bBlock = new StructBlock(coordsFromFace, bType, bMetaData, player.World); BlockHelper.Instance.CreateBlockInstance(bType).Place(player, bBlock, facingBlock, packet.Face); }
public bool IsInteractive(BlockData.Blocks blockType) { return(_interactiveBlocks.ContainsKey((byte)blockType)); }
public bool CanGrow(IStructBlock block, IChunk iChunk) { Chunk chunk = iChunk as Chunk; if (chunk == null) { return(false); } // BlockMeta = 0x0 is a freshly planted cactus. // The data value is incremented at random intervals. // When it becomes 15, a new cactus block is created on top as long as the total height does not exceed 3. int maxHeight = 3; if (block.Coords.WorldY == 127) { return(false); } UniversalCoords oneUp = UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1, block.Coords.WorldZ); BlockData.Blocks blockId = chunk.GetType(oneUp); if (blockId != BlockData.Blocks.Air) { return(false); } // Calculating the cactus length below this block int cactusHeightBelow = 0; for (int i = block.Coords.WorldY - 1; i >= 0; i--) { blockId = chunk.GetType(UniversalCoords.FromWorld(block.Coords.WorldX, i, block.Coords.WorldZ)); if (blockId != BlockData.Blocks.Cactus) { break; } cactusHeightBelow++; } if ((cactusHeightBelow + 1) >= maxHeight) { return(false); } bool isAir = true; chunk.ForNSEW(oneUp, delegate(UniversalCoords uc) { byte?nearbyBlockId = block.WorldInterface.GetBlockId(uc); if (nearbyBlockId == null || nearbyBlockId != (byte)BlockData.Blocks.Air) { isAir = false; } }); if (!isAir) { return(false); } return(true); }
public override void Fertilize(EntityBase entity, StructBlock block) { Chunk chunk = GetBlockChunk(block); if (chunk == null) { return; } BlockData.Blocks blockBelow = chunk.GetType(block.Coords.BlockX, block.Coords.BlockY - 1, block.Coords.BlockZ); if (blockBelow != BlockData.Blocks.Dirt && blockBelow != BlockData.Blocks.Grass && blockBelow != BlockData.Blocks.Mycelium) { return; } int stemHeight = block.World.Server.Rand.Next(3) + 4; int capY = block.Coords.WorldY + stemHeight + 1; if (capY > 127) { return; } for (int dY = block.Coords.WorldY + 1; dY < capY - 1; dY++) { BlockData.Blocks blockUp = chunk.GetType(block.Coords.BlockX, dY, block.Coords.BlockZ); if (blockUp != BlockData.Blocks.Air && blockUp != BlockData.Blocks.Leaves) { return; } } int absdX, absdZ; byte?blockId; for (int dX = -3; dX < 4; dX++) { for (int dZ = -3; dZ < 4; dZ++) { absdX = Math.Abs(dX); absdZ = Math.Abs(dZ); if (absdX == 3 && absdZ == 3) { continue; } blockId = block.World.GetBlockId(block.Coords.WorldX + dX, capY, block.Coords.WorldZ + dZ); if (blockId == null || (blockId != (byte)BlockData.Blocks.Air && blockId != (byte)BlockData.Blocks.Leaves)) { return; } } } byte metaData = (byte)MetaData.HugeMushroom.NorthWeastSouthEast; for (int dY = block.Coords.WorldY; dY < capY; dY++) { if (chunk.GetType(block.Coords.BlockX, dY, block.Coords.BlockZ) != BlockData.Blocks.Leaves) { chunk.SetBlockAndData(block.Coords.BlockX, dY, block.Coords.BlockZ, (byte)BlockData.Blocks.BrownMushroomCap, metaData); } } for (int dX = -3; dX < 4; dX++) { for (int dZ = -3; dZ < 4; dZ++) { Chunk currentChunk = block.World.GetChunkFromWorld(block.Coords.WorldX + dX, block.Coords.WorldZ + dZ) as Chunk; if (currentChunk == null) { continue; } absdX = Math.Abs(dX); absdZ = Math.Abs(dZ); if (absdX == 3 && absdZ == 3) { continue; } BlockData.Blocks nearbyBlockId = currentChunk.GetType(block.Coords.BlockX + dX, capY, block.Coords.BlockZ + dZ); if (nearbyBlockId == BlockData.Blocks.Leaves) { continue; } if (absdX < 3 && absdZ < 3) { metaData = (byte)MetaData.HugeMushroom.Top; } else if ((dX == -3 && dZ == -2) || (dZ == -3 && dX == -2)) { metaData = (byte)MetaData.HugeMushroom.TopNorthWest; } else if ((dX == -3 && dZ == 2) || (dZ == 3 && dX == -2)) { metaData = (byte)MetaData.HugeMushroom.TopSouthWest; } else if ((dX == 3 && dZ == -2) || (dZ == -3 && dX == 2)) { metaData = (byte)MetaData.HugeMushroom.TopNorthEast; } else if ((dX == 3 && dZ == 2) || (dZ == 3 && dX == 2)) { metaData = (byte)MetaData.HugeMushroom.TopSouthEast; } else if (dX == -3 && absdZ < 2) { metaData = (byte)MetaData.HugeMushroom.TopWest; } else if (dX == 3 && absdZ < 2) { metaData = (byte)MetaData.HugeMushroom.TopEast; } else if (dZ == -3 && absdX < 2) { metaData = (byte)MetaData.HugeMushroom.TopNorth; } else if (dZ == 3 && absdX < 2) { metaData = (byte)MetaData.HugeMushroom.TopSouth; } currentChunk.SetBlockAndData(block.Coords.BlockX + dX, capY, block.Coords.BlockZ + dZ, (byte)BlockData.Blocks.BrownMushroomCap, metaData); } } }
public override void Place(EntityBase entity, StructBlock block, StructBlock targetBlock, BlockFace face) { Chunk chunk = GetBlockChunk(block); Chunk targetChunk = GetBlockChunk(targetBlock); if (chunk == null || targetChunk == null) return; // Load the blocks surrounding the position (NSEW) not diagonals BlockData.Blocks[] nsewBlocks = new BlockData.Blocks[4]; UniversalCoords[] nsewBlockPositions = new UniversalCoords[4]; int nsewCount = 0; chunk.ForNSEW(block.Coords, (uc) => { byte? nearbyBlockId = block.World.GetBlockId(uc); if(nearbyBlockId == null) return; nsewBlocks[nsewCount] = (BlockData.Blocks)nearbyBlockId; 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 && chunk.IsNSEWTo(p, (byte)BlockData.Blocks.Chest)) { // Cannot place next to a double chest return; } } base.Place(entity, block, targetBlock, face); }
public bool IsSolid(BlockData.Blocks blockType) { return(_solidBlocks.ContainsKey((byte)blockType)); }
public void SetType(int x, int y, int z, BlockData.Blocks value) { this[x, y, z] = (byte)value; }
public bool IsSingleHit(BlockData.Blocks blockType) { return(_singleHitBlocks.ContainsKey((byte)blockType)); }
public static ItemInventory GetInstance(BlockData.Blocks blockType) { return(GetInstance((short)blockType)); }
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]; PointI[] nsewBlockPositions = new PointI[4]; int nsewCount = 0; block.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++; }); // 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++) { PointI p = nsewBlockPositions[i]; if (nsewBlocks[i] == BlockData.Blocks.Chest && block.Chunk.IsNSEWTo(p.X & 0xf, p.Y, p.Z & 0xf, (byte)BlockData.Blocks.Chest)) { // Cannot place next to a double chest return; } } base.Place(entity, block, targetBlock, face); }
private void PacketHandler_PlayerBlockPlacement(object sender, PacketEventArgs<PlayerBlockPlacementPacket> e) { /* * Scenarios: * * 1) using an item against a block (e.g. stone and flint) * 2) placing a new block * 3) using a block: e.g. open/close door, open chest, open workbench, open furnace * * */ // if (!Permissions.CanPlayerBuild(Username)) return; // Using activeslot provides current item info wtihout having to maintain ActiveItem int x = e.Packet.X; int y = e.Packet.Y; int z = e.Packet.Z; BlockData.Blocks type = (BlockData.Blocks)World.GetBlockId(x, y, z); // Get block being built against. int bx, by, bz; World.FromFace(x, y, z, e.Packet.Face, out bx, out by, out bz); if (type == BlockData.Blocks.Chest) { if (!BlockData.Air.Contains((BlockData.Blocks)World.GetBlockId(bx, by, bz))) { // Cannot open a chest if no space is above it return; } Chunk chunk = World.GetBlockChunk(x, y, z); // Double chest? // TODO: simplify chunk API so that no bit shifting is required if (chunk.IsNSEWTo(x & 0xf, y, z & 0xf, (byte)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(x & 0xf, y, z & 0xf, (x1, y1, z1) => { nsewBlocks[nsewCount] = (BlockData.Blocks)World.GetBlockId(x1, y1, z1); nsewBlockPositions[nsewCount] = new PointI(x1, y1, z1); nsewCount++; }); if (nsewBlocks[0] == type) // North { CurrentInterface = new LargeChestInterface(World, nsewBlockPositions[0], new PointI(x, y, z)); } else if (nsewBlocks[2] == type) // East { CurrentInterface = new LargeChestInterface(World, nsewBlockPositions[2], new PointI(x, y, z)); } else if (nsewBlocks[1] == type) // South { CurrentInterface = new LargeChestInterface(World, new PointI(x, y, z), nsewBlockPositions[1]); } else if (nsewBlocks[3] == type) // West { CurrentInterface = new LargeChestInterface(World, new PointI(x, y, z), nsewBlockPositions[3]); } } else { CurrentInterface = new SmallChestInterface(World, x, y, z); } if (CurrentInterface != null) { CurrentInterface.Associate(this); CurrentInterface.Open(); } return; } else if (type == BlockData.Blocks.Workbench) { CurrentInterface = new WorkbenchInterface(); CurrentInterface.Associate(this); ((WorkbenchInterface)CurrentInterface).Open(bx, by, bz); return; } else if (type == BlockData.Blocks.Furnace || type == BlockData.Blocks.Burning_Furnace) { CurrentInterface = new FurnaceInterface(World, x, y, z); CurrentInterface.Associate(this); CurrentInterface.Open(); return; } if (Inventory.Slots[Inventory.ActiveSlot].Type <= 0 || Inventory.Slots[Inventory.ActiveSlot].Count < 1) return; // TODO: Neaten this out, or address via handler? if (Inventory.Slots[Inventory.ActiveSlot].Type > 255 || e.Packet.Face == BlockFace.Held) // Client is using an Item. { PacketHandler_PlayerItemPlacement(sender, e); return; } // Built Block Info byte bType = (byte)Inventory.Slots[Inventory.ActiveSlot].Type; byte bMetaData = (byte)Inventory.Slots[Inventory.ActiveSlot].Durability; switch (type) // Can't build against these blocks. { case BlockData.Blocks.Air: case BlockData.Blocks.Water: case BlockData.Blocks.Lava: case BlockData.Blocks.Still_Water: case BlockData.Blocks.Still_Lava: return; } switch ((BlockData.Blocks)bType) { case BlockData.Blocks.Cactus: { BlockData.Blocks uType = (BlockData.Blocks)World.GetBlockId(bx, by - 1, bz); if (uType != BlockData.Blocks.Sand && uType != BlockData.Blocks.Cactus) return; } break; case BlockData.Blocks.Crops: { BlockData.Blocks uType = (BlockData.Blocks)World.GetBlockId(bx, by - 1, bz); if (uType != BlockData.Blocks.Soil) return; } break; case BlockData.Blocks.Chest: // Load the blocks surrounding the position (NSEW) not diagonals Chunk chunk = World.GetBlockChunk(x, y, z); BlockData.Blocks[] nsewBlocks = new BlockData.Blocks[4]; PointI[] nsewBlockPositions = new PointI[4]; int nsewCount = 0; chunk.ForNSEW(bx & 0xf, by, bz & 0xf, (x1, y1, z1) => { nsewBlocks[nsewCount] = (BlockData.Blocks)World.GetBlockId(x1, y1, z1); nsewBlockPositions[nsewCount] = new PointI(x1, y1, z1); nsewCount++; }); // Count chests in list if (nsewBlocks.Where((b) => b == BlockData.Blocks.Chest).Count() > 1) { // Cannot place next to two chests return; } // A chest cannot be surrounded by two blocks on the same axis when placed //if (BlockData.IsSolid(nsewBlocks[0]) && BlockData.IsSolid(nsewBlocks[1])) //{ // return; //} //if (BlockData.IsSolid(nsewBlocks[2]) && BlockData.IsSolid(nsewBlocks[3])) //{ // return; //} for (int i = 0; i < 4; i++) { PointI p = nsewBlockPositions[i]; if (nsewBlocks[i] == BlockData.Blocks.Chest && chunk.IsNSEWTo(p.X & 0xf, p.Y, p.Z & 0xf, (byte)BlockData.Blocks.Chest)) { // Cannot place next to a double chest return; } } break; case BlockData.Blocks.Furnace: case BlockData.Blocks.Dispenser: switch (e.Packet.Face) //Bugged, as the client has a mind of its own for facing { case BlockFace.East: bMetaData = (byte)MetaData.Furnace.East; break; case BlockFace.West: bMetaData = (byte)MetaData.Furnace.West; break; case BlockFace.North: bMetaData = (byte)MetaData.Furnace.North; break; case BlockFace.South: bMetaData = (byte)MetaData.Furnace.South; break; default: switch (FacingDirection(4)) // Built on floor, set by facing dir { case "N": bMetaData = (byte)MetaData.Furnace.North; break; case "W": bMetaData = (byte)MetaData.Furnace.West; break; case "S": bMetaData = (byte)MetaData.Furnace.South; break; case "E": bMetaData = (byte)MetaData.Furnace.East; break; default: return; } break; } break; case BlockData.Blocks.Rails: // TODO: Rail Logic break; case BlockData.Blocks.Reed: // TODO: Check there is water nearby before placing. break; case BlockData.Blocks.Stair: // TODO : If (Block Y - 1 = Stair && Block Y = Air) Then DoubleStair // Else if (Buildblock = Stair) Then DoubleStair break; case BlockData.Blocks.Wooden_Stairs: case BlockData.Blocks.Cobblestone_Stairs: switch (FacingDirection(4)) { case "N": bMetaData = (byte)MetaData.Stairs.South; break; case "E": bMetaData = (byte)MetaData.Stairs.West; break; case "S": bMetaData = (byte)MetaData.Stairs.North; break; case "W": bMetaData = (byte)MetaData.Stairs.East; break; default: return; } break; case BlockData.Blocks.Torch: switch (e.Packet.Face) { case BlockFace.Down: return; case BlockFace.Up: bMetaData = (byte)MetaData.Torch.Standing; break; case BlockFace.West: bMetaData = (byte)MetaData.Torch.West; break; case BlockFace.East: bMetaData = (byte)MetaData.Torch.East; break; case BlockFace.North: bMetaData = (byte)MetaData.Torch.North; break; case BlockFace.South: bMetaData = (byte)MetaData.Torch.South; break; } break; case BlockData.Blocks.Sapling: // We can place a sapling only on the top of the dirt or soil block if (e.Packet.Face != BlockFace.Up || type != BlockData.Blocks.Dirt || type != BlockData.Blocks.Soil) return; break; } World.SetBlockAndData(bx, by, bz, bType, bMetaData); World.Update(bx, by, bz, false); if(GameMode == 0) Inventory.RemoveItem(Inventory.ActiveSlot); }
private void Burn(object state) { lock (_containerLock) { Chunk chunk = World.GetChunk(Coords) as Chunk; if (chunk == null) { StopBurning(); return; } if (_fuelTicksLeft <= 0) { if (HasIngredient() && HasFuel()) { if (!OutputSlot.IsVoid() && !GetSmeltingRecipe(InputSlot).Result.StacksWith(OutputSlot)) { StopBurning(); return; } _fuelTicksFull = GetFuelEfficiency(); _fuelTicksLeft = _fuelTicksFull; SendFurnaceProgressPacket(_progressTicks); RemoveFuel(); BlockData.Blocks blockId = chunk.GetType(Coords); if (blockId == BlockData.Blocks.Furnace) { chunk.SetType(Coords, BlockData.Blocks.Burning_Furnace); } } else { StopBurning(); } return; } _fuelTicksLeft--; if (InputSlot.IsVoid() || (!OutputSlot.IsVoid() && (!GetSmeltingRecipe(InputSlot).Result.StacksWith(OutputSlot) || OutputSlot.Count == 64))) { _progressTicks = 0; } else { if (_progressTicks >= FullProgress) { _progressTicks = 0; AddOutput(); RemoveIngredient(); } _progressTicks++; } double fuelTickCost = ((double)(_fuelTicksFull)) / FullFire; short fireLevel = (short)(_fuelTicksLeft / fuelTickCost); if (fireLevel % 10 == 0 || fireLevel == FullFire) { SendFurnaceFirePacket(fireLevel); } if (_progressTicks % 10 == 0 || _progressTicks == FullProgress) { SendFurnaceProgressPacket(_progressTicks); } } }
public static PersistentContainer Instance(WorldManager world, UniversalCoords coords) { PersistentContainer container; Chunk chunk = world.GetChunk(coords) as Chunk; if (chunk == null) { return(null); } BlockData.Blocks block = chunk.GetType(coords); if (!chunk.Containers.ContainsKey(coords.BlockPackedCoords)) { switch (block) { case BlockData.Blocks.Furnace: case BlockData.Blocks.Burning_Furnace: container = new FurnaceContainer(); container.Initialize(world, coords); (container as FurnaceContainer).StartBurning(); break; case BlockData.Blocks.Dispenser: container = new DispenserContainer(); container.Initialize(world, coords); break; case BlockData.Blocks.Chest: // Double chest? if (IsDoubleChest(chunk, coords)) { UniversalCoords[] doubleChestCoords = GetDoubleChestCoords(world, coords); if (doubleChestCoords == null) { return(null); } chunk.Containers.TryRemove(doubleChestCoords[0].BlockPackedCoords, out container); chunk.Containers.TryRemove(doubleChestCoords[1].BlockPackedCoords, out container); container = new LargeChestContainer(doubleChestCoords[1]); container.Initialize(world, doubleChestCoords[0]); chunk.Containers.TryAdd(doubleChestCoords[0].BlockPackedCoords, container); chunk.Containers.TryAdd(doubleChestCoords[1].BlockPackedCoords, container); } else { container = new SmallChestContainer(); container.Initialize(world, coords); } break; default: return(null); } chunk.Containers.TryAdd(coords.BlockPackedCoords, container); } else { chunk.Containers.TryGetValue(coords.BlockPackedCoords, out container); } return(container); }
public bool IsWaterProof(BlockData.Blocks blockType) { return(_waterProofBlocks.ContainsKey((byte)blockType)); }
public override void Fertilize(EntityBase entity, StructBlock block) { Chunk chunk = GetBlockChunk(block); if (chunk == null) { return; } BlockData.Blocks blockBelow = chunk.GetType(block.Coords.BlockX, block.Coords.BlockY - 1, block.Coords.BlockZ); if (blockBelow != BlockData.Blocks.Dirt && blockBelow != BlockData.Blocks.Grass && blockBelow != BlockData.Blocks.Mycelium) { return; } int stemHeight = block.World.Server.Rand.Next(3) + 4; int capY = block.Coords.WorldY + stemHeight + 1; if (capY > 127) { return; } BlockData.Blocks blockId; for (int dY = block.Coords.WorldY + 1; dY < capY - 1; dY++) { blockId = chunk.GetType(block.Coords.BlockX, dY, block.Coords.BlockZ); if (blockId != BlockData.Blocks.Air && blockId != BlockData.Blocks.Leaves) { return; } } int absdX, absdZ; byte?nullableBlockId; for (int dX = -2; dX < 3; dX++) { for (int dZ = -2; dZ < 3; dZ++) { for (int dY = block.Coords.WorldY + 1; dY <= capY; dY++) { absdX = Math.Abs(dX); absdZ = Math.Abs(dZ); if (absdX == 2 && absdZ == 2) { continue; } if (dY == capY && absdX > 1 && absdZ > 1) { continue; } if (dY < capY && absdX < 2 && absdZ < 2) { continue; } nullableBlockId = block.World.GetBlockId(block.Coords.WorldX + dX, dY, block.Coords.WorldZ + dZ); if (nullableBlockId == null || (nullableBlockId != (byte)BlockData.Blocks.Leaves && nullableBlockId != (byte)BlockData.Blocks.Air)) { return; } } } } byte metaData = (byte)MetaData.HugeMushroom.NorthWeastSouthEast; for (int dY = block.Coords.WorldY; dY < capY; dY++) { if (chunk.GetType(block.Coords.BlockX, dY, block.Coords.BlockZ) != BlockData.Blocks.Leaves) { chunk.SetBlockAndData(block.Coords.BlockX, dY, block.Coords.BlockZ, (byte)BlockData.Blocks.BrownMushroomCap, metaData); } } for (int dX = -2; dX < 3; dX++) { for (int dZ = -2; dZ < 3; dZ++) { Chunk currentChunk = block.World.GetChunkFromWorld(block.Coords.WorldX + dX, block.Coords.WorldZ + dZ) as Chunk; if (currentChunk == null) { continue; } for (int dY = capY - 3; dY <= capY; dY++) { absdX = Math.Abs(dX); absdZ = Math.Abs(dZ); if (absdX == 2 && absdZ == 2) { continue; } if (dY == capY && (absdX > 1 || absdZ > 1)) { continue; } if (dY < capY && absdX < 2 && absdZ < 2) { continue; } blockId = currentChunk.GetType(block.Coords.BlockX + dX, dY, block.Coords.BlockZ + dZ); if (blockId == BlockData.Blocks.Leaves) { continue; } if (dY == capY) { // Draw cap if (dX == 0 && dZ == 0) { metaData = (byte)MetaData.HugeMushroom.Top; } else if (dX == -1 && dZ == 0) { metaData = (byte)MetaData.HugeMushroom.TopWest; } else if (dX == 1 && dZ == 0) { metaData = (byte)MetaData.HugeMushroom.TopEast; } else if (dX == 0 && dZ == -1) { metaData = (byte)MetaData.HugeMushroom.TopNorth; } else if (dX == 0 && dZ == 1) { metaData = (byte)MetaData.HugeMushroom.TopSouth; } else if (dX == -1 && dZ == -1) { metaData = (byte)MetaData.HugeMushroom.TopNorthWest; } else if (dX == -1 && dZ == 1) { metaData = (byte)MetaData.HugeMushroom.TopSouthWest; } else if (dX == 1 && dZ == -1) { metaData = (byte)MetaData.HugeMushroom.TopNorthEast; } else if (dX == 1 && dZ == 1) { metaData = (byte)MetaData.HugeMushroom.TopSouthEast; } } else { // Draw sides if (dX == -2 && dZ == -1) { metaData = (byte)MetaData.HugeMushroom.TopNorthWest; } else if (dX == -2 && dZ == 0) { metaData = (byte)MetaData.HugeMushroom.TopWest; } else if (dX == -2 && dZ == 1) { metaData = (byte)MetaData.HugeMushroom.TopSouthWest; } else if (dX == 2 && dZ == -1) { metaData = (byte)MetaData.HugeMushroom.TopNorthEast; } else if (dX == 2 && dZ == 0) { metaData = (byte)MetaData.HugeMushroom.TopEast; } else if (dX == 2 && dZ == 1) { metaData = (byte)MetaData.HugeMushroom.TopSouthEast; } else if (dX == -1 && dZ == 2) { metaData = (byte)MetaData.HugeMushroom.TopSouthWest; } else if (dX == 0 && dZ == 2) { metaData = (byte)MetaData.HugeMushroom.TopSouth; } else if (dX == 1 && dZ == 2) { metaData = (byte)MetaData.HugeMushroom.TopSouthEast; } else if (dX == -1 && dZ == -2) { metaData = (byte)MetaData.HugeMushroom.TopNorthWest; } else if (dX == 0 && dZ == -2) { metaData = (byte)MetaData.HugeMushroom.TopNorth; } else if (dX == 1 && dZ == -2) { metaData = (byte)MetaData.HugeMushroom.TopNorthEast; } } currentChunk.SetBlockAndData(block.Coords.BlockX + dX, dY, block.Coords.BlockZ + dZ, (byte)BlockData.Blocks.RedMushroomCap, metaData); } } } }