public override void OnBuild(WorldEdit worldEdit, int oldBlockId, BlockSelection blockSel, ItemStack withItemStack) { if (startPos == null) { return; } BlockPos destPos = blockSel.Position.AddCopy(blockSel.Face.Opposite); Block block = blockAccessRev.GetBlock(blockSel.Position); if (PlaceMode) { block = blockAccessRev.GetBlock(0); } worldEdit.sapi.World.BlockAccessor.SetBlock(oldBlockId, blockSel.Position); if (!worldEdit.MayPlace(block, startPos.ManhattenDistance(destPos))) { return; } GameMath.BresenHamPlotLine3d(startPos.X, startPos.Y, startPos.Z, destPos.X, destPos.Y, destPos.Z, (pos) => blockAccessRev.SetBlock(block.BlockId, pos, withItemStack)); if (LineMode == EnumLineStartPoint.LineStrip) { startPos = destPos.Copy(); } blockAccessRev.SetHistoryStateBlock(blockSel.Position.X, blockSel.Position.Y, blockSel.Position.Z, oldBlockId, blockAccessRev.GetBlockId(blockSel.Position)); blockAccessRev.Commit(); }
private BlockPos BfsSearchPath(IWorldAccessor world, Queue <BlockPos> uncheckedPositions, BlockPos target, Block ourBlock) { BlockPos pos, npos = new BlockPos(); while (uncheckedPositions.Count > 0) { pos = uncheckedPositions.Dequeue(); int curDist = pos.ManhattenDistance(target); for (int i = 0; i < BlockFacing.HORIZONTALS.Length; i++) { BlockFacing facing = BlockFacing.HORIZONTALS[i]; npos.Set(pos.X + facing.Normali.X, target.Y, pos.Z + facing.Normali.Z); if (npos.ManhattenDistance(target) > curDist) { continue; } if (npos.Equals(target)) { return(pos); } Block block = world.BlockAccessor.GetBlock(npos); if (!block.IsLiquid() && block.Replaceable < ReplacableThreshold) { continue; } uncheckedPositions.Enqueue(npos.Copy()); } } return(null); }
public List <PosAndDist> FindDownwardPaths(IWorldAccessor world, BlockPos pos, Block ourBlock) { List <PosAndDist> paths = new List <PosAndDist>(); Queue <BlockPos> uncheckedPositions = new Queue <BlockPos>(); int shortestPath = 99; for (int i = 0; i < downPaths.Length; i++) { Vec2i offset = downPaths[i]; Block block = world.BlockAccessor.GetBlock(pos.X + offset.X, pos.Y - 1, pos.Z + offset.Y); Block aboveblock = world.BlockAccessor.GetBlock(pos.X + offset.X, pos.Y, pos.Z + offset.Y); if (aboveblock.LiquidLevel < ourBlock.LiquidLevel && block.Replaceable >= ReplacableThreshold && aboveblock.Replaceable >= ReplacableThreshold) { uncheckedPositions.Enqueue(new BlockPos(pos.X + offset.X, pos.Y, pos.Z + offset.Y)); BlockPos foundPos = BfsSearchPath(world, uncheckedPositions, pos, ourBlock); if (foundPos != null) { PosAndDist pad = new PosAndDist() { pos = foundPos, dist = pos.ManhattenDistance(pos.X + offset.X, pos.Y, pos.Z + offset.Y) }; if (pad.dist == 1 && ourBlock.LiquidLevel < 7) { paths.Clear(); paths.Add(pad); return(paths); } paths.Add(pad); shortestPath = Math.Min(shortestPath, pad.dist); } } } // Now we remove all suboptimal paths for (int i = 0; i < paths.Count; i++) { if (paths[i].dist > shortestPath) { paths.RemoveAt(i); i--; } } return(paths); }
public override void OnBlockPlaced(IWorldAccessor world, BlockPos blockPos, ref EnumHandling handled) { if (world.Side != EnumAppSide.Server) { return; } pastCost.Clear(); costPos.Clear(); BlockPos pos = blockPos; int sD = 16; targetPos = pos + new BlockPos(-2, 0, 8); int sR = sD / 2; var grid = new CubeGrid(sD, sD, sD); if (!isInBounds(world, targetPos) || !isPassable(world, targetPos) || !isWalkable(world, targetPos) || isDangerous(world, targetPos)) { return; } for (int x = pos.X - sR; x <= pos.X + sR; x++) { for (int y = pos.Y - sR; y <= pos.Y + sR; y++) { for (int z = pos.Z - sR; z <= pos.Z + sR; z++) { BlockPos currentPos = new BlockPos(x, y, z); if (isInBounds(world, currentPos) && isPassable(world, currentPos) && isWalkable(world, currentPos) && !isDangerous(world, currentPos)) { costPos.Add(currentPos); pastCost.Add(currentPos, currentPos.ManhattenDistance(targetPos)); grid.air.Add(currentPos); } else { grid.walls.Add(currentPos); } } } } var astar = new AStarSearch(world, grid, pastCost, pos, targetPos); DrawGrid(world, astar, pos, sR); world.BlockAccessor.SetBlock(1, pos); world.BlockAccessor.SetBlock(903, targetPos); return; }
public void CmdMeasuringTape(int groupId, CmdArgs args) { WaypointUtilSystem wUtil = capi.ModLoader.GetModSystem <WaypointUtilSystem>(); string arg = args.PopWord(); switch (arg) { case "start": if (capi.World.Player.CurrentBlockSelection != null) { start = capi.World.Player.CurrentBlockSelection.Position; //capi.ShowChatMessage("Okay, start set to: " + start); MakeHighlights(); } else { capi.ShowChatMessage("Please look at a block."); } break; case "end": if (capi.World.Player.CurrentBlockSelection != null) { end = capi.World.Player.CurrentBlockSelection.Position; //capi.ShowChatMessage("Okay, end set to: " + end); MakeHighlights(); } else { capi.ShowChatMessage("Please look at a block."); } break; case "startwp": int?swpID = args.PopInt(); if (swpID != null) { start = wUtil.Waypoints[(int)swpID].Position.AsBlockPos; MakeHighlights(); } else { capi.ShowChatMessage("Please enter a waypoint id."); } break; case "endwp": int?ewpID = args.PopInt(); if (ewpID != null) { end = wUtil.Waypoints[(int)ewpID].Position.AsBlockPos; MakeHighlights(); } else { capi.ShowChatMessage("Please enter a waypoint id."); } break; case "calc": string type = args.PopWord(); switch (type) { case "block": capi.ShowChatMessage("Block Distance: " + Math.Round(start.DistanceTo(end) + 1)); break; case "euclidian": capi.ShowChatMessage("Euclidian Distance: " + start.DistanceTo(end)); break; case "manhattan": capi.ShowChatMessage("Manhattan Distance: " + start.ManhattenDistance(end)); break; case "horizontal": capi.ShowChatMessage("Horizontal Distance: " + Math.Sqrt(start.HorDistanceSqTo(end.X, end.Z))); break; case "horizontalmanhattan": capi.ShowChatMessage("Horizontal Manhattan Distance: " + start.HorizontalManhattenDistance(end)); break; default: capi.ShowChatMessage("Syntax: .measure calc [block|euclidian|manhattan|horizontal|horizontalmanhattan]"); break; } break; default: capi.ShowChatMessage("Syntax: .measure [start|end|calc]"); break; } }
/// <summary> /// Returns the temperature at the given location based on it's distance from the lava. /// </summary> /// <param name="lavaPos"></param> /// <param name="airBlockPos"></param> /// <returns></returns> private int GetTemperatureAtLocation(BlockPos lavaPos, BlockPos airBlockPos) { int distance = lavaPos.ManhattenDistance(airBlockPos); return(temperature - (distance * tempLossPerMeter)); }