internal void UpdateVoxel(IPlayer byPlayer, Vec3i voxelPos, BlockFacing facing, bool isBreak)
        {
            Vec3i addAtPos = voxelPos.Clone().Add(facing);

            if (!isBreak)
            {
                if (addAtPos.X >= 0 && addAtPos.X < 16 && addAtPos.Y >= 0 && addAtPos.Y < 16 && addAtPos.Z >= 0 && addAtPos.Z < 16)
                {
                    Voxels[addAtPos.X, addAtPos.Y, addAtPos.Z] = true;
                }
            }
            else
            {
                Voxels[voxelPos.X, voxelPos.Y, voxelPos.Z] = false;
            }



            if (api.Side == EnumAppSide.Client)
            {
                RegenMesh();
            }

            RegenSelectionBoxes();
            MarkDirty(true);

            // Send a custom network packet for server side, because
            // serverside blockselection index is inaccurate
            if (api.Side == EnumAppSide.Client)
            {
                SendUseOverPacket(byPlayer, voxelPos, facing, isBreak);
            }
        }
示例#2
0
        private Vec3i getClosestBfs(Vec3i voxelPos, BlockFacing towardsFace, int maxDist)
        {
            Queue <Vec3i>   nodesToVisit = new Queue <Vec3i>();
            HashSet <Vec3i> nodesVisited = new HashSet <Vec3i>();

            nodesToVisit.Enqueue(voxelPos);

            while (nodesToVisit.Count > 0)
            {
                Vec3i node = nodesToVisit.Dequeue();

                for (int i = 0; i < BlockFacing.HORIZONTALS.Length; i++)
                {
                    BlockFacing face  = BlockFacing.HORIZONTALS[i];
                    Vec3i       nnode = node.Clone().Add(face);

                    if (nnode.X < 0 || nnode.X >= 16 || nnode.Y < 0 || nnode.Y >= 6 || nnode.Z < 0 || nnode.Z >= 16)
                    {
                        continue;
                    }
                    if (nodesVisited.Contains(nnode))
                    {
                        continue;
                    }
                    nodesVisited.Add(nnode);

                    double x   = nnode.X - voxelPos.X;
                    double z   = nnode.Z - voxelPos.Z;
                    double len = GameMath.Sqrt(x * x + z * z);

                    if (len > maxDist)
                    {
                        continue;
                    }

                    x /= len;
                    z /= len;

                    if (towardsFace == null || Math.Abs((float)Math.Acos(towardsFace.Normalf.X * x + towardsFace.Normalf.Z * z)) < 25 * GameMath.DEG2RAD)
                    {
                        if (Voxels[nnode.X, nnode.Y, nnode.Z] == (byte)EnumVoxelMaterial.Empty)
                        {
                            return(nnode);
                        }
                    }

                    if (Voxels[nnode.X, nnode.Y, nnode.Z] == (byte)EnumVoxelMaterial.Metal)
                    {
                        nodesToVisit.Enqueue(nnode);
                    }
                }
            }

            return(null);
        }
示例#3
0
        public void OnUseOver(IPlayer byPlayer, Vec3i voxelHitPos, Vec3i voxelBoxPos, BlockFacing facing, ItemStack itemStack, bool mouseBreakMode)
        {
            Item heldItem = itemStack?.Item;

            if (heldItem?.Code?.ToString() == "signals:el_wire")
            {
                if (mouseBreakMode)
                {
                    if (wiring.OnRemove(voxelHitPos))
                    {
                        AvailableWireVoxels++;
                        if (AvailableWireVoxels >= 25)
                        {
                            byPlayer.InventoryManager.TryGiveItemstack(new ItemStack(heldItem));
                            AvailableWireVoxels = 0;
                        }
                    }
                    return;
                }


                if (canPlaceWireAt(voxelHitPos.AddCopy(facing)))
                {
                    if (AvailableWireVoxels == 0)
                    {
                        AvailableWireVoxels = 25;
                        //slot.TakeOut(1);
                        //slot.MarkDirty();
                    }
                    wiring.OnAdd(voxelHitPos.AddCopy(facing));
                    AvailableWireVoxels--;
                }
                return;
            }


            CircuitComponent comp = SignalsUtils.GetCircuitComponentFromItem(api, heldItem);

            if (comp != null)
            {
                comp.Pos       = voxelBoxPos.Clone();
                comp.myCircuit = this;
                comp.Initialize(api, this);
                components.Add(comp);
            }
        }
示例#4
0
        internal void UpdateVoxel(IPlayer byPlayer, ItemSlot itemslot, Vec3i voxelPos, BlockFacing facing, bool isBreak)
        {
            int mode = ChiselMode(byPlayer);

            if (mode == 5)
            {
                IClientWorldAccessor clientWorld = (IClientWorldAccessor)api.World;

                string prevName = blockName;
                GuiDialogBlockEntityTextInput dlg = new GuiDialogBlockEntityTextInput(Lang.Get("Block name"), pos, blockName, api as ICoreClientAPI);
                dlg.OnTextChanged = (text) => blockName = text;
                dlg.OnCloseCancel = () => blockName = prevName;
                dlg.TryOpen();
            }

            bool wasChanged = false;

            if (mode == 4)
            {
                RotateModel(byPlayer, isBreak);
                wasChanged = true;
            }
            else
            {
                int   size     = ChiselSize(byPlayer);
                Vec3i addAtPos = voxelPos.Clone().Add(size * facing.Normali.X, size * facing.Normali.Y, size * facing.Normali.Z);

                if (isBreak)
                {
                    wasChanged = SetVoxel(voxelPos, false, byPlayer);
                }
                else
                {
                    if (addAtPos.X >= 0 && addAtPos.X < 16 && addAtPos.Y >= 0 && addAtPos.Y < 16 && addAtPos.Z >= 0 && addAtPos.Z < 16)
                    {
                        wasChanged = SetVoxel(addAtPos, true, byPlayer);
                    }
                }
            }


            if (!wasChanged)
            {
                return;
            }

            if (api.Side == EnumAppSide.Client)
            {
                RegenMesh();
            }

            RegenSelectionBoxes(byPlayer);
            MarkDirty(true);

            // Send a custom network packet for server side, because
            // serverside blockselection index is inaccurate
            if (api.Side == EnumAppSide.Client)
            {
                SendUseOverPacket(byPlayer, voxelPos, facing, isBreak);
            }

            double posx = pos.X + voxelPos.X / 16f;
            double posy = pos.Y + voxelPos.Y / 16f;
            double posz = pos.Z + voxelPos.Z / 16f;

            api.World.PlaySoundAt(new AssetLocation("sounds/player/knap" + (api.World.Rand.Next(2) > 0 ? 1 : 2)), posx, posy, posz, byPlayer, true, 12, 1);

            if (byPlayer.WorldData.CurrentGameMode != EnumGameMode.Creative)
            {
                itemslot.Itemstack?.Collectible.DamageItem(api.World, byPlayer.Entity, itemslot);
            }


            if (VoxelCuboids.Count == 0)
            {
                api.World.BlockAccessor.SetBlock(0, pos);
                return;
            }
        }
示例#5
0
        public virtual void OnHit(Vec3i voxelPos)
        {
            if (Voxels[voxelPos.X, voxelPos.Y, voxelPos.Z] != (byte)EnumVoxelMaterial.Metal)
            {
                return;
            }

            if (voxelPos.Y > 0)
            {
                int voxelsMoved = 0;

                for (int dx = -1; dx <= 1; dx++)
                {
                    for (int dz = -1; dz <= 1; dz++)
                    {
                        if (dx == 0 && dz == 0)
                        {
                            continue;
                        }
                        if (voxelPos.X + dx < 0 || voxelPos.X + dx >= 16 || voxelPos.Z + dz < 0 || voxelPos.Z + dz >= 16)
                        {
                            continue;
                        }

                        if (Voxels[voxelPos.X + dx, voxelPos.Y, voxelPos.Z + dz] == (byte)EnumVoxelMaterial.Metal)
                        {
                            voxelsMoved += moveVoxelDownwards(voxelPos.Clone().Add(dx, 0, dz), null, 1) ? 1 : 0;
                        }
                    }
                }

                if (Voxels[voxelPos.X, voxelPos.Y, voxelPos.Z] == (byte)EnumVoxelMaterial.Metal)
                {
                    voxelsMoved += moveVoxelDownwards(voxelPos.Clone(), null, 1) ? 1 : 0;
                }


                if (voxelsMoved == 0)
                {
                    Vec3i emptySpot = null;

                    for (int dx = -1; dx <= 1; dx++)
                    {
                        for (int dz = -1; dz <= 1; dz++)
                        {
                            if (dx == 0 && dz == 0)
                            {
                                continue;
                            }
                            if (voxelPos.X + 2 * dx < 0 || voxelPos.X + 2 * dx >= 16 || voxelPos.Z + 2 * dz < 0 || voxelPos.Z + 2 * dz >= 16)
                            {
                                continue;
                            }

                            bool spotEmpty = Voxels[voxelPos.X + 2 * dx, voxelPos.Y, voxelPos.Z + 2 * dz] == (byte)EnumVoxelMaterial.Empty;

                            if (Voxels[voxelPos.X + dx, voxelPos.Y, voxelPos.Z + dz] == (byte)EnumVoxelMaterial.Metal && spotEmpty)
                            {
                                Voxels[voxelPos.X + dx, voxelPos.Y, voxelPos.Z + dz] = (byte)EnumVoxelMaterial.Empty;

                                if (Voxels[voxelPos.X + 2 * dx, voxelPos.Y - 1, voxelPos.Z + 2 * dz] == (byte)EnumVoxelMaterial.Empty)
                                {
                                    Voxels[voxelPos.X + 2 * dx, voxelPos.Y - 1, voxelPos.Z + 2 * dz] = (byte)EnumVoxelMaterial.Metal;
                                }
                                else
                                {
                                    Voxels[voxelPos.X + 2 * dx, voxelPos.Y, voxelPos.Z + 2 * dz] = (byte)EnumVoxelMaterial.Metal;
                                }
                            }
                            else
                            {
                                if (spotEmpty)
                                {
                                    emptySpot = voxelPos.Clone().Add(dx, 0, dz);
                                }
                            }
                        }
                    }

                    if (emptySpot != null && Voxels[voxelPos.X, voxelPos.Y, voxelPos.Z] == (byte)EnumVoxelMaterial.Metal)
                    {
                        Voxels[voxelPos.X, voxelPos.Y, voxelPos.Z] = (byte)EnumVoxelMaterial.Empty;

                        if (Voxels[emptySpot.X, emptySpot.Y - 1, emptySpot.Z] == (byte)EnumVoxelMaterial.Empty)
                        {
                            Voxels[emptySpot.X, emptySpot.Y - 1, emptySpot.Z] = (byte)EnumVoxelMaterial.Metal;
                        }
                        else
                        {
                            Voxels[emptySpot.X, emptySpot.Y, emptySpot.Z] = (byte)EnumVoxelMaterial.Metal;
                        }
                    }
                }
            }
        }
示例#6
0
        public virtual void OnUpset(Vec3i voxelPos, BlockFacing towardsFace)
        {
            if (Voxels[voxelPos.X, voxelPos.Y, voxelPos.Z] != (byte)EnumVoxelMaterial.Metal)
            {
                return;
            }

            Vec3i npos      = voxelPos.Clone().Add(towardsFace);
            Vec3i opFaceDir = towardsFace.Opposite.Normali;

            if (npos.X < 0 || npos.X >= 16 || npos.Y < 0 || npos.Y >= 6 || npos.Z < 0 || npos.Z >= 16)
            {
                return;
            }

            if (voxelPos.Y > 0)
            {
                if (Voxels[npos.X, npos.Y, npos.Z] == (byte)EnumVoxelMaterial.Empty && Voxels[npos.X, npos.Y - 1, npos.Z] != (byte)EnumVoxelMaterial.Empty)
                {
                    if (npos.X < 0 || npos.X >= 16 || npos.Y < 0 || npos.Y >= 6 || npos.Z < 0 || npos.Z >= 16)
                    {
                        return;
                    }

                    Voxels[npos.X, npos.Y, npos.Z]             = (byte)EnumVoxelMaterial.Metal;
                    Voxels[voxelPos.X, voxelPos.Y, voxelPos.Z] = 0;
                    return;
                }
                else
                {
                    npos.Y++;

                    if (npos.Y < 6 && Voxels[npos.X, npos.Y, npos.Z] == (byte)EnumVoxelMaterial.Empty && Voxels[npos.X, npos.Y - 1, npos.Z] != (byte)EnumVoxelMaterial.Empty && Voxels[voxelPos.X + opFaceDir.X, voxelPos.Y, voxelPos.Z + opFaceDir.Z] == (byte)EnumVoxelMaterial.Empty)
                    {
                        Voxels[npos.X, npos.Y, npos.Z]             = (byte)EnumVoxelMaterial.Metal;
                        Voxels[voxelPos.X, voxelPos.Y, voxelPos.Z] = (byte)EnumVoxelMaterial.Empty;
                        return;
                    }

                    if (!moveVoxelDownwards(voxelPos.Clone(), towardsFace, 1))
                    {
                        moveVoxelDownwards(voxelPos.Clone(), towardsFace, 2);
                    }
                }
                return;
            }


            npos.Y++;

            if (npos.X < 0 || npos.X >= 16 || npos.Y < 0 || npos.Y >= 6 || npos.Z < 0 || npos.Z >= 16)
            {
                return;
            }
            if (voxelPos.X + opFaceDir.X < 0 || voxelPos.X + opFaceDir.X >= 16 || voxelPos.Z + opFaceDir.Z < 0 || voxelPos.Z + opFaceDir.Z >= 16)
            {
                return;
            }

            if (npos.Y < 6 && Voxels[npos.X, npos.Y, npos.Z] == (byte)EnumVoxelMaterial.Empty && Voxels[npos.X, npos.Y - 1, npos.Z] != (byte)EnumVoxelMaterial.Empty && Voxels[voxelPos.X + opFaceDir.X, voxelPos.Y, voxelPos.Z + opFaceDir.Z] == (byte)EnumVoxelMaterial.Empty)
            {
                Voxels[npos.X, npos.Y, npos.Z]             = (byte)EnumVoxelMaterial.Metal;
                Voxels[voxelPos.X, voxelPos.Y, voxelPos.Z] = (byte)EnumVoxelMaterial.Empty;
                return;
            }
        }
示例#7
0
        internal void UpdateVoxel(IPlayer byPlayer, ItemSlot itemslot, Vec3i voxelPos, BlockFacing facing, bool isBreak)
        {
            if (!Api.World.Claims.TryAccess(byPlayer, Pos, EnumBlockAccessFlags.Use))
            {
                MarkDirty(true, byPlayer);
                return;
            }


            EnumChiselMode mode = GetChiselMode(byPlayer);

            bool wasChanged = false;

            byte[] lightHsv = this.LightHsv;

            switch (mode)
            {
            case EnumChiselMode.Rename:
                IClientWorldAccessor clientWorld = (IClientWorldAccessor)Api.World;

                string prevName = BlockName;
                GuiDialogBlockEntityTextInput dlg = new GuiDialogBlockEntityTextInput(Lang.Get("Block name"), Pos, BlockName, Api as ICoreClientAPI, 500);
                dlg.OnTextChanged = (text) => BlockName = text;
                dlg.OnCloseCancel = () => BlockName = prevName;
                dlg.TryOpen();
                break;

            case EnumChiselMode.Flip:
                FlipVoxels(Block.SuggestedHVOrientation(byPlayer, new BlockSelection()
                {
                    Position = Pos.Copy(), HitPosition = new Vec3d(voxelPos.X / 16.0, voxelPos.Y / 16.0, voxelPos.Z / 16.0)
                })[0]);
                wasChanged = true;
                break;

            case EnumChiselMode.Rotate:
                RotateModel(isBreak ? 90 : -90, null);
                wasChanged = true;
                break;


            default:
                int   size     = GetChiselSize(byPlayer);
                Vec3i addAtPos = voxelPos.Clone().Add(size * facing.Normali.X, size * facing.Normali.Y, size * facing.Normali.Z);

                if (isBreak)
                {
                    wasChanged = SetVoxel(voxelPos, false, byPlayer, nowmaterialIndex);
                }
                else
                {
                    if (addAtPos.X >= 0 && addAtPos.X < 16 && addAtPos.Y >= 0 && addAtPos.Y < 16 && addAtPos.Z >= 0 && addAtPos.Z < 16)
                    {
                        wasChanged = SetVoxel(addAtPos, true, byPlayer, nowmaterialIndex);
                    }
                }

                break;
            }


            if (!wasChanged)
            {
                return;
            }

            if (Api.Side == EnumAppSide.Client)
            {
                RegenMesh();
            }

            RegenSelectionBoxes(byPlayer);
            MarkDirty(true, byPlayer);

            // Send a custom network packet for server side, because
            // serverside blockselection index is inaccurate
            if (Api.Side == EnumAppSide.Client)
            {
                SendUseOverPacket(byPlayer, voxelPos, facing, isBreak);
            }

            double posx = Pos.X + voxelPos.X / 16f;
            double posy = Pos.Y + voxelPos.Y / 16f;
            double posz = Pos.Z + voxelPos.Z / 16f;

            Api.World.PlaySoundAt(new AssetLocation("sounds/player/knap" + (Api.World.Rand.Next(2) > 0 ? 1 : 2)), posx, posy, posz, byPlayer, true, 12, 1);

            if (byPlayer.WorldData.CurrentGameMode != EnumGameMode.Creative && Api.World.Rand.Next(3) == 0)
            {
                itemslot.Itemstack?.Collectible.DamageItem(Api.World, byPlayer.Entity, itemslot);
            }


            if (VoxelCuboids.Count == 0)
            {
                Api.World.BlockAccessor.SetBlock(0, Pos);
                Api.World.BlockAccessor.RemoveBlockLight(LightHsv, Pos);
                return;
            }
        }