private void UpdateBlock(bool remove, BlockPos pos)
        {
            if (remove)
            {
                if (DoRemoveBlock)
                {
                    World.BlockAccessor.SetBlock(0, pos);
                    World.BlockAccessor.MarkBlockDirty(pos, () => OnChunkRetesselated(true));
                }
            }
            else
            {
                World.BlockAccessor.SetBlock(Block.BlockId, pos);
                World.BlockAccessor.MarkBlockDirty(pos, () => OnChunkRetesselated(false));

                if (blockEntityAttributes != null)
                {
                    BlockEntity be = World.BlockAccessor.GetBlockEntity(pos);

                    blockEntityAttributes.SetInt("posx", pos.X);
                    blockEntityAttributes.SetInt("posy", pos.Y);
                    blockEntityAttributes.SetInt("posz", pos.Z);

                    if (be != null)
                    {
                        be.FromTreeAttributes(blockEntityAttributes, World);
                    }
                }
            }

            NotifyNeighborsOfBlockChange(pos);
        }
예제 #2
0
        private void PlaceFarmland(ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, ITreeAttribute treeAttributes)
        {
            int      id  = slot.Itemstack.Attributes.GetInt("farmId");
            BlockPos pos = blockSel.Position.AddCopy(blockSel.Face);

            byEntity.World.BlockAccessor.SetBlock(id, pos);
            BlockEntity blockEntity = byEntity.World.BlockAccessor.GetBlockEntity(pos);

            if (blockEntity is BlockEntityFarmland)
            {
                treeAttributes.SetInt("posx", pos.X);
                treeAttributes.SetInt("posy", pos.Y);
                treeAttributes.SetInt("posz", pos.Z);
                blockEntity.FromTreeAttributes(treeAttributes, byEntity.World);
                blockEntity.MarkDirty();
            }
            slot.Itemstack.Attributes.RemoveAttribute("farmland");
            slot.Itemstack.Attributes.RemoveAttribute("farmId");
        }
예제 #3
0
        public void MirrorArea(BlockPos startPos, BlockPos endPos, BlockFacing dir, bool selectNewArea, bool growNewArea)
        {
            BlockPos curPos = startPos.Copy();

            BlockPos offset = new BlockPos(
                (endPos.X - startPos.X) * dir.Normali.X,
                (endPos.Y - startPos.Y) * dir.Normali.Y,
                (endPos.Z - startPos.Z) * dir.Normali.Z
                );

            BlockPos pos = new BlockPos();
            Block    block;

            Dictionary <BlockPos, ITreeAttribute> blockEntityData = new Dictionary <BlockPos, ITreeAttribute>();

            while (curPos.X < endPos.X)
            {
                curPos.Y = startPos.Y;

                while (curPos.Y < endPos.Y)
                {
                    curPos.Z = startPos.Z;

                    while (curPos.Z < endPos.Z)
                    {
                        int blockId = workspace.revertableBlockAccess.GetBlockId(curPos);

                        if (dir.Axis == EnumAxis.Y)
                        {
                            block = sapi.World.GetBlock(sapi.World.Blocks[blockId].GetVerticallyFlippedBlockCode());
                        }
                        else
                        {
                            block = sapi.World.GetBlock(sapi.World.Blocks[blockId].GetHorizontallyFlippedBlockCode(dir.Axis));
                        }

                        // Mirrored position inside the same area
                        int mX = dir.Axis == EnumAxis.X ? startPos.X + (endPos.X - curPos.X) - 1 : curPos.X;
                        int mY = dir.Axis == EnumAxis.Y ? startPos.Y + (endPos.Y - curPos.Y) - 1 : curPos.Y;
                        int mZ = dir.Axis == EnumAxis.Z ? startPos.Z + (endPos.Z - curPos.Z) - 1 : curPos.Z;

                        pos.Set(mX + offset.X, mY + offset.Y, mZ + offset.Z);

                        BlockEntity be = workspace.revertableBlockAccess.GetBlockEntity(curPos);
                        if (be != null)
                        {
                            TreeAttribute tree = new TreeAttribute();
                            be.ToTreeAttributes(tree);
                            blockEntityData[pos.Copy()] = tree;
                        }


                        workspace.revertableBlockAccess.SetBlock(block.BlockId, pos);

                        curPos.Z++;
                    }
                    curPos.Y++;
                }
                curPos.X++;
            }

            workspace.revertableBlockAccess.Commit();
            Good("Marked area mirrored " + dir);

            // restore block entity data
            foreach (var val in blockEntityData)
            {
                BlockEntity be = workspace.revertableBlockAccess.GetBlockEntity(val.Key);
                if (be != null)
                {
                    ITreeAttribute tree = val.Value;

                    tree.SetInt("posx", val.Key.X);
                    tree.SetInt("posy", val.Key.Y);
                    tree.SetInt("posz", val.Key.Z);

                    if (be is IBlockEntityRotatable)
                    {
                        (be as IBlockEntityRotatable).OnTransformed(tree, 0, dir.Axis);
                    }

                    be.FromTreeAttributes(tree, this.sapi.World);
                }
            }

            if (selectNewArea)
            {
                workspace.StartMarker.Add(offset);
                workspace.EndMarker.Add(offset);
                ResendBlockHighlights();
            }

            if (growNewArea)
            {
                workspace.StartMarker.Set(
                    startPos.X + (offset.X < 0 ? offset.X : 0),
                    startPos.Y + (offset.Y < 0 ? offset.Y : 0),
                    startPos.Z + (offset.Z < 0 ? offset.Z : 0)
                    );

                workspace.EndMarker.Set(
                    endPos.X + (offset.X > 0 ? offset.X : 0),
                    endPos.Y + (offset.Y > 0 ? offset.Y : 0),
                    endPos.Z + (offset.Z > 0 ? offset.Z : 0)
                    );

                ResendBlockHighlights();
            }
        }
예제 #4
0
        public int MoveArea(int dx, int dy, int dz, BlockPos start, BlockPos end)
        {
            int updated = 0;

            BlockPos startPos = new BlockPos(Math.Min(start.X, end.X), Math.Min(start.Y, end.Y), Math.Min(start.Z, end.Z));
            BlockPos endPos   = new BlockPos(Math.Max(start.X, end.X), Math.Max(start.Y, end.Y), Math.Max(start.Z, end.Z));
            BlockPos curPos   = startPos.Copy();

            int wx = endPos.X - startPos.X;
            int wy = endPos.Y - startPos.Y;
            int wz = endPos.Z - startPos.Z;

            int   quantityBlocks = dx * dy * dz;
            Block block          = sapi.World.Blocks[0];

            if (!MayPlace(block, quantityBlocks))
            {
                return(0);
            }


            BlockPos newPos  = new BlockPos();
            BlockPos prevPos = new BlockPos();

            Dictionary <BlockPos, ITreeAttribute> blockEntityData = new Dictionary <BlockPos, ITreeAttribute>();

            // Clear area
            while (curPos.X < endPos.X)
            {
                curPos.Y = startPos.Y;
                while (curPos.Y < endPos.Y)
                {
                    curPos.Z = startPos.Z;
                    while (curPos.Z < endPos.Z)
                    {
                        BlockEntity be = workspace.revertableBlockAccess.GetBlockEntity(curPos);
                        if (be != null)
                        {
                            TreeAttribute tree = new TreeAttribute();
                            be.ToTreeAttributes(tree);
                            blockEntityData[curPos.AddCopy(dx, dy, dz)] = tree;
                        }

                        workspace.revertableBlockAccess.SetBlock(0, curPos);

                        curPos.Z++;
                    }

                    curPos.Y++;
                }

                curPos.X++;
            }


            curPos = startPos.Copy();

            // move selection
            while (curPos.X < endPos.X)
            {
                curPos.Y = startPos.Y;
                while (curPos.Y < endPos.Y)
                {
                    curPos.Z = startPos.Z;
                    while (curPos.Z < endPos.Z)
                    {
                        newPos.Set(curPos.X + dx, curPos.Y + dy, curPos.Z + dz);
                        int prevBlockId = workspace.revertableBlockAccess.GetBlockId(curPos);
                        workspace.revertableBlockAccess.SetBlock(prevBlockId, newPos);

                        curPos.Z++;
                    }

                    curPos.Y++;
                }

                curPos.X++;
            }

            workspace.revertableBlockAccess.Commit();

            // restore block entity data
            foreach (var val in blockEntityData)
            {
                BlockEntity be = workspace.revertableBlockAccess.GetBlockEntity(val.Key);
                if (be != null)
                {
                    val.Value.SetInt("posx", val.Key.X);
                    val.Value.SetInt("posy", val.Key.Y);
                    val.Value.SetInt("posz", val.Key.Z);

                    be.FromTreeAttributes(val.Value, this.sapi.World);
                }
            }

            return(updated);
        }
예제 #5
0
        public void RepeatArea(BlockPos startPos, BlockPos endPos, BlockFacing dir, int repeats, bool selectNewArea, bool growNewArea)
        {
            int curRepeats = 0;

            Dictionary <BlockPos, TreeAttribute> blockEntityData = new Dictionary <BlockPos, TreeAttribute>();

            BlockPos offset = null;

            while (curRepeats++ < repeats)
            {
                BlockPos curPos = startPos.Copy();

                offset = new BlockPos(
                    (endPos.X - startPos.X) * dir.Normali.X * curRepeats,
                    (endPos.Y - startPos.Y) * dir.Normali.Y * curRepeats,
                    (endPos.Z - startPos.Z) * dir.Normali.Z * curRepeats
                    );
                BlockPos pos = new BlockPos();

                while (curPos.X < endPos.X)
                {
                    curPos.Y = startPos.Y;

                    while (curPos.Y < endPos.Y)
                    {
                        curPos.Z = startPos.Z;

                        while (curPos.Z < endPos.Z)
                        {
                            int blockId = workspace.revertableBlockAccess.GetBlockId(curPos);

                            if (workspace.world.Blocks[blockId].EntityClass != null)
                            {
                                TreeAttribute tree = new TreeAttribute();
                                workspace.revertableBlockAccess.GetBlockEntity(curPos)?.ToTreeAttributes(tree);
                                blockEntityData[curPos + offset] = tree;
                            }

                            pos.Set(curPos.X + offset.X, curPos.Y + offset.Y, curPos.Z + offset.Z);

                            workspace.revertableBlockAccess.SetBlock(blockId, pos);


                            curPos.Z++;
                        }
                        curPos.Y++;
                    }
                    curPos.X++;
                }
            }


            workspace.revertableBlockAccess.Commit();

            foreach (var val in blockEntityData)
            {
                BlockEntity be = workspace.revertableBlockAccess.GetBlockEntity(val.Key);
                val.Value.SetInt("posx", val.Key.X);
                val.Value.SetInt("posy", val.Key.Y);
                val.Value.SetInt("posz", val.Key.Z);

                be?.FromTreeAttributes(val.Value, workspace.world);
            }

            if (repeats > 1)
            {
                Good("Marked area repeated " + repeats + ((repeats > 1) ? " times" : " time"));
            }


            if (selectNewArea)
            {
                workspace.StartMarker.Add(offset);
                workspace.EndMarker.Add(offset);
                ResendBlockHighlights();
            }

            if (growNewArea)
            {
                workspace.StartMarker.Set(
                    startPos.X + (offset.X < 0 ? offset.X : 0),
                    startPos.Y + (offset.Y < 0 ? offset.Y : 0),
                    startPos.Z + (offset.Z < 0 ? offset.Z : 0)
                    );

                workspace.EndMarker.Set(
                    endPos.X + (offset.X > 0 ? offset.X : 0),
                    endPos.Y + (offset.Y > 0 ? offset.Y : 0),
                    endPos.Z + (offset.Z > 0 ? offset.Z : 0)
                    );

                ResendBlockHighlights();
            }
        }