예제 #1
0
        private void OnRemove(Vec3i voxelPos, BlockFacing facing, int radius, IPlayer byPlayer)
        {
            if (SelectedRecipe.Voxels[voxelPos.X, voxelPos.Z])
            {
                return;
            }

            for (int dx = -(int)Math.Ceiling(radius / 2f); dx <= radius / 2; dx++)
            {
                for (int dz = -(int)Math.Ceiling(radius / 2f); dz <= radius / 2; dz++)
                {
                    Vec3i offPos = voxelPos.AddCopy(dx, 0, dz);

                    if (voxelPos.X >= 0 && voxelPos.X < 16 && voxelPos.Z >= 0 && voxelPos.Z < 16 && Voxels[offPos.X, offPos.Z])
                    {
                        Voxels[offPos.X, offPos.Z] = false;

                        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);
                    }
                }
            }
        }
예제 #2
0
        private void OnHit(Vec3i voxelPos)
        {
            if (AvailableVoxels <= 0)
            {
                return;
            }

            for (int dx = -1; dx <= 1; dx++)
            {
                for (int dz = -1; dz <= 1; dz++)
                {
                    Vec3i npos = voxelPos.AddCopy(dx, 0, dz);

                    if (npos.X >= 0 && npos.X < 16 && npos.Y >= 0 && npos.Y < 16 && npos.Z >= 0 && npos.Z < 16 && !Voxels[npos.X, npos.Y, npos.Z])
                    {
                        Voxels[npos.X, npos.Y, npos.Z] = true;
                        AvailableVoxels--;
                        if (AvailableVoxels <= 0)
                        {
                            return;
                        }
                    }
                }
            }
        }
예제 #3
0
        private bool OnRemove(Vec3i voxelPos, BlockFacing facing, int radius)
        {
            bool didremove = false;
            int  layer     = NextNotMatchingRecipeLayer();

            if (voxelPos.Y != layer)
            {
                return(didremove);
            }

            for (int dx = -(int)Math.Ceiling(radius / 2f); dx <= radius / 2; dx++)
            {
                for (int dz = -(int)Math.Ceiling(radius / 2f); dz <= radius / 2; dz++)
                {
                    Vec3i offPos = voxelPos.AddCopy(dx, 0, dz);

                    if (offPos.X >= 0 && offPos.X < 16 && offPos.Y >= 0 && offPos.Y <= 16 && offPos.Z >= 0 && offPos.Z < 16)
                    {
                        bool hadVoxel = Voxels[offPos.X, offPos.Y, offPos.Z];
                        didremove |= hadVoxel;

                        Voxels[offPos.X, offPos.Y, offPos.Z] = false;
                        if (hadVoxel)
                        {
                            AvailableVoxels++;
                        }
                    }
                }
            }

            return(didremove);
        }
        private bool OnRemove(Vec3i voxelPos, int radius)
        {
            // Required voxel, don't let the player break it
            if (SelectedRecipe == null || SelectedRecipe.Voxels[voxelPos.X, 0, voxelPos.Z])
            {
                return(false);
            }

            for (int dx = -(int)Math.Ceiling(radius / 2f); dx <= radius / 2; dx++)
            {
                for (int dz = -(int)Math.Ceiling(radius / 2f); dz <= radius / 2; dz++)
                {
                    Vec3i offPos = voxelPos.AddCopy(dx, 0, dz);

                    if (voxelPos.X >= 0 && voxelPos.X < 16 && voxelPos.Z >= 0 && voxelPos.Z < 16 && Voxels[offPos.X, offPos.Z])
                    {
                        Voxels[offPos.X, offPos.Z] = false;

                        lastRemovedLocalPos.Set(Pos.X + voxelPos.X / 16f, Pos.Y + voxelPos.Y / 16f, Pos.Z + voxelPos.Z / 16f);
                        return(true);
                    }
                }
            }



            return(false);
        }
예제 #5
0
        public List <Vec3i> RebuildNetwork(Vec3i pos_init, VoxelWire old_network)
        {
            if (!old_network.GotVoxelAtPos(pos_init))
            {
                return(new List <Vec3i>());
            }
            List <Vec3i> to_explore = new List <Vec3i>();
            List <Vec3i> explored   = new List <Vec3i>();

            to_explore.Add(pos_init);

            while (to_explore.Any())
            {
                Vec3i current_pos = to_explore.Last();
                foreach (BlockFacing facing in BlockFacing.ALLFACES)
                {
                    Vec3i offset_pos = current_pos.AddCopy(facing);
                    if (old_network.GotVoxelAtPos(offset_pos) && !explored.Contains(offset_pos))
                    {
                        to_explore.Add(offset_pos);
                    }
                }
                to_explore.Remove(current_pos);
                explored.Add(current_pos);
            }

            //At the end, the explored list contains connected voxels
            return(explored);
        }
예제 #6
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);
            }
        }
예제 #7
0
        public bool OnRemove(Vec3i voxelPos)
        {
            foreach (VoxelWire net in networks.Values)
            {
                if (net.RemoveVoxel(voxelPos))
                {
                    hasChanged = true;

                    //Simplest case, where the voxel was the only one left in the network
                    if (net.voxelpositions.Count == 0)
                    {
                        networks.Remove(net.id);
                        return(true);
                    }

                    //This is where the fun begins...network exploration!
                    //We first build a new network starting from one face
                    //We then check if voxels on other face are in the previous networks, if not, start a new network etc..
                    List <Vec3i> explored_pos = new List <Vec3i>();
                    foreach (BlockFacing face in BlockFacing.ALLFACES)
                    {
                        if (explored_pos.Contains(voxelPos.AddCopy(face)))
                        {
                            continue;
                        }

                        List <Vec3i> voxels = RebuildNetwork(voxelPos.AddCopy(face), net);
                        if (voxels.Count > 0)
                        {
                            int newId = getNewId();
                            networks.Add(newId, new VoxelWire(newId, voxels));
                            explored_pos.AddRange(voxels);
                        }
                    }
                    //remove the original network
                    networks.Remove(net.id);
                    return(true);
                }
            }

            return(false);
        }
예제 #8
0
        public bool OnAdd(Vec3i voxelPos)
        {
            //We first test if the voxel is already contained in a network
            foreach (VoxelWire net in networks.Values)
            {
                if (net.GotVoxelAtPos(voxelPos))
                {
                    return(false);
                }
            }


            //We explore adjacent voxels, looking for a network
            //if a network is found, we take the id. if another network is found with different id, we merge the networks.
            VoxelWire current_net = null;

            foreach (BlockFacing face in BlockFacing.ALLFACES)
            {
                Vec3i     pos2 = voxelPos.AddCopy(face);
                VoxelWire net  = GetWireAtPos(pos2);
                if (net != null)
                {
                    if (current_net == null)
                    {
                        net.AddVoxel(voxelPos);
                        current_net = net;
                    }
                    else if (current_net != null && net.id != current_net.id)
                    {
                        current_net.MergeWith(net);
                        networks.Remove(net.id);
                    }
                    else if (net.id == current_net.id)
                    {
                        net.AddVoxel(voxelPos);
                    }
                }
            }
            if (current_net == null)
            {
                //We create a new network
                int       new_id  = getNewId();
                VoxelWire network = new VoxelWire(new_id);
                network.AddVoxel(voxelPos);
                networks.Add(new_id, network);
            }

            hasChanged = true;
            return(true);
        }
예제 #9
0
        public bool canPlaceWireAt(Vec3i voxelPos)
        {
            if (voxelPos.Y == 0)
            {
                return(false);
            }
            if (wiring.gotWireAtPos(voxelPos.X, voxelPos.Y, voxelPos.Z))
            {
                return(false);
            }
            Cuboidi voxelBox = new Cuboidi(voxelPos, voxelPos.AddCopy(1, 1, 1));

            foreach (CircuitComponent comp in components)
            {
                if (comp.doesIntersect(voxelBox))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #10
0
        bool OnAdd(Vec3i voxelPos, int radius, int layer)
        {
            bool didadd = false;

            for (int dx = -(int)Math.Ceiling(radius / 2f); dx <= radius / 2; dx++)
            {
                for (int dz = -(int)Math.Ceiling(radius / 2f); dz <= radius / 2; dz++)
                {
                    Vec3i offPos = voxelPos.AddCopy(dx, 0, dz);
                    if (InBounds(offPos, layer) && offPos.Y == layer)
                    {
                        if (!Voxels[offPos.X, offPos.Y, offPos.Z])
                        {
                            AvailableVoxels--;
                            didadd = true;
                        }
                        Voxels[offPos.X, offPos.Y, offPos.Z] = true;
                    }
                }
            }

            return(didadd);
        }
예제 #11
0
        private bool OnAdd(Vec3i voxelPos, BlockFacing facing, int radius)
        {
            int layer = NextNotMatchingRecipeLayer();

            if (voxelPos.Y == layer && facing.IsVertical)
            {
                return(OnAdd(voxelPos, radius, layer));
            }

            if (Voxels[voxelPos.X, voxelPos.Y, voxelPos.Z])
            {
                Vec3i offPoss = voxelPos.AddCopy(facing);
                if (InBounds(offPoss, layer))
                {
                    return(OnAdd(offPoss, radius, layer));
                }
            }
            else
            {
                return(OnAdd(voxelPos, radius, layer));
            }

            return(false);
        }
        internal void OnUseOver(IPlayer byPlayer, Vec3i voxelPos, BlockFacing facing, bool mouseMode)
        {
            if (voxelPos == null)
            {
                // DidBeginUse = Math.Max(0, DidBeginUse - 1);
                return;
            }

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

            ItemSlot slot = byPlayer.InventoryManager.ActiveHotbarSlot;

            if (slot.Itemstack == null)
            {
                //      DidBeginUse = Math.Max(0, DidBeginUse - 1);
                return;
            }

            int toolMode = slot.Itemstack.Collectible.GetToolMode(slot, byPlayer, new BlockSelection()
            {
                Position = Pos
            });

            //float yaw = GameMath.Mod(byPlayer.Entity.Pos.Yaw, 2 * GameMath.PI);
            //BlockFacing towardsFace = BlockFacing.HorizontalFromAngle(yaw);


            //if (DidBeginUse > 0)
            {
                bool didRemove = mouseMode && OnRemove(voxelPos, toolMode);

                if (didRemove)
                {
                    for (int i = 0; i < BlockFacing.HORIZONTALS.Length; i++)
                    {
                        BlockFacing face  = BlockFacing.HORIZONTALS[i];
                        Vec3i       nnode = voxelPos.AddCopy(face);

                        if (!Voxels[nnode.X, nnode.Z])
                        {
                            continue;
                        }
                        if (SelectedRecipe.Voxels[nnode.X, 0, nnode.Z])
                        {
                            continue;
                        }

                        tryBfsRemove(nnode.X, nnode.Z);
                    }
                }

                if (mouseMode && (didRemove || Voxels[voxelPos.X, voxelPos.Z]))
                {
                    Api.World.PlaySoundAt(new AssetLocation("sounds/player/knap" + (Api.World.Rand.Next(2) > 0 ? 1 : 2)), lastRemovedLocalPos.X, lastRemovedLocalPos.Y, lastRemovedLocalPos.Z, byPlayer, true, 12, 1);
                }

                if (didRemove && Api.Side == EnumAppSide.Client)
                {
                    spawnParticles(lastRemovedLocalPos);
                }

                RegenMeshAndSelectionBoxes();
                Api.World.BlockAccessor.MarkBlockDirty(Pos);
                Api.World.BlockAccessor.MarkBlockEntityDirty(Pos);

                if (!HasAnyVoxel())
                {
                    Api.World.BlockAccessor.SetBlock(0, Pos);
                    return;
                }
            }

            CheckIfFinished(byPlayer);
            MarkDirty();
        }