private void InitializeSpawn() { Spawn = new PointI(Settings.Default.SpawnX, Settings.Default.SpawnY, Settings.Default.SpawnZ); for (int i = 127; i > 0; i--) { if (GetBlockOrLoad(Spawn.X, i, Spawn.Z) != 0) { Spawn = new PointI(Spawn.X, i + 4, Spawn.Z); break; } } }
private void Pos2Command(string[] tokens) { Point2 = new PointI((int)Position.X, (int)Position.Y, (int)Position.Z); SendMessage("§7First position set."); }
private void Pos1Command(string[] tokens) { Point1 = new PointI((int)Position.X, (int)Position.Y, (int)Position.Z); SendMessage("§7Second position set."); }
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); }
public bool ContainsKey(PointI key) { return Chunks.ContainsKey(key); }
public BoundingBox[] GetCollidingBoundingBoxes(EntityBase entity, BoundingBox boundingBox) { List<BoundingBox > collidingBoundingBoxes = new List<BoundingBox>(); PointI minimumBlockXYZ = new PointI((int)Math.Floor(boundingBox.Minimum.X), (int)Math.Floor(boundingBox.Minimum.Y), (int)Math.Floor(boundingBox.Minimum.Z)); PointI maximumBlockXYZ = new PointI((int)Math.Floor(boundingBox.Maximum.X + 1.0D), (int)Math.Floor(boundingBox.Maximum.Y + 1.0D), (int)Math.Floor(boundingBox.Maximum.Z + 1.0D)); for (int x = minimumBlockXYZ.X; x < maximumBlockXYZ.X; x++) { for (int z = minimumBlockXYZ.Z; z < maximumBlockXYZ.Z; z++) { for (int y = minimumBlockXYZ.Y - 1; y < maximumBlockXYZ.Y; y++) { byte block = this.GetBlockId(x, y, z); // TODO: this needs to move into block logic BoundingBox blockBox = new BoundingBox( new Vector3(x, y, z), new Vector3(x + 1, y + 1, z + 1) ); if (blockBox.IntersectsWith(boundingBox)) { collidingBoundingBoxes.Add(blockBox); } } } } foreach (var e in GetEntitiesWithinBoundingBoxExcludingEntity(entity, boundingBox.Expand(new Vector3(0.25, 0.25, 0.25)))) { collidingBoundingBoxes.Add(e.BoundingBox); // TODO: determine if overridable collision boxes between two entities is necessary BoundingBox? collisionBox = entity.GetCollisionBox(e); if (collisionBox != null && collisionBox.Value != e.BoundingBox && collisionBox.Value.IntersectsWith(boundingBox)) { collidingBoundingBoxes.Add(collisionBox.Value); } } return collidingBoundingBoxes.ToArray(); }