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); }
public bool CanGrow(StructBlock block) { // Crops grow from 0x0 to 0x7 if (block.MetaData == 0x07) return false; return true; }
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); }
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); }
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); */ }
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); }
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); }
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); } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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; ContainerFactory.Open(player, block.Coords); }
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); }
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(); }
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); }
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); } }
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); }
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); }
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); }
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); }
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; }
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(); }
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); }
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; }