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); } } } }
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; } } } } }
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); }
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); }
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); } }
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); }
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); }
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); }
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); }
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(); }