Пример #1
0
 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;
         }
     }
 }
Пример #2
0
 private void Pos2Command(string[] tokens)
 {
     Point2 = new PointI((int)Position.X, (int)Position.Y, (int)Position.Z);
     SendMessage("§7First position set.");
 }
Пример #3
0
 private void Pos1Command(string[] tokens)
 {
     Point1 = new PointI((int)Position.X, (int)Position.Y, (int)Position.Z);
     SendMessage("§7Second position set.");
 }
Пример #4
0
        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);
        }
Пример #5
0
 public bool ContainsKey(PointI key)
 {
     return Chunks.ContainsKey(key);
 }
Пример #6
0
        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();
        }