public WaypointsTraverser(EntityAgent entity) : base(entity) { if (entity?.Properties.Server?.Attributes?.GetTreeAttribute("pathfinder") != null) { minTurnAnglePerSec = (float)entity.Properties.Server.Attributes.GetTreeAttribute("pathfinder").GetDecimal("minTurnAnglePerSec", 250); maxTurnAnglePerSec = (float)entity.Properties.Server.Attributes.GetTreeAttribute("pathfinder").GetDecimal("maxTurnAnglePerSec", 450); } else { minTurnAnglePerSec = 250; maxTurnAnglePerSec = 450; } psys = entity.World.Api.ModLoader.GetModSystem <PathfindSystem>(); asyncPathfinder = entity.World.Api.ModLoader.GetModSystem <PathfindingAsync>(); }
private void onCmdAStar(IServerPlayer player, int groupId, CmdArgs args) { string subcmd = args.PopWord(); BlockPos plrPos = player.Entity.ServerPos.XYZ.AsBlockPos; PathfindSystem pfs = sapi.ModLoader.GetModSystem <PathfindSystem>(); Cuboidf narrow = new Cuboidf(-0.4f, 0, -0.4f, 0.4f, 1.5f, 0.4f); Cuboidf narrower = new Cuboidf(-0.2f, 0, -0.2f, 0.2f, 1.5f, 0.2f); Cuboidf wide = new Cuboidf(-0.6f, 0, -0.6f, 0.6f, 1.5f, 0.6f); Cuboidf collbox = narrow; int maxFallHeight = 3; float stepHeight = 1.01f; switch (subcmd) { case "start": start = plrPos.Copy(); sapi.World.HighlightBlocks(player, 26, new List <BlockPos>() { start }, new List <int>() { ColorUtil.ColorFromRgba(255, 255, 0, 128) }, EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary); break; case "end": end = plrPos.Copy(); sapi.World.HighlightBlocks(player, 27, new List <BlockPos>() { end }, new List <int>() { ColorUtil.ColorFromRgba(255, 0, 255, 128) }, EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary); break; case "bench": if (start == null || end == null) { return; } Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < 15; i++) { List <PathNode> nodes = pfs.FindPath(start, end, maxFallHeight, stepHeight, collbox); } sw.Stop(); float timeMs = (float)sw.ElapsedMilliseconds / 15f; player.SendMessage(groupId, string.Format("15 searches average: {0} ms", (int)timeMs), EnumChatType.Notification); return; case "clear": start = null; end = null; sapi.World.HighlightBlocks(player, 2, new List <BlockPos>(), EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary); sapi.World.HighlightBlocks(player, 26, new List <BlockPos>(), EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary); sapi.World.HighlightBlocks(player, 27, new List <BlockPos>(), EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary); break; } if (start == null || end == null) { sapi.World.HighlightBlocks(player, 2, new List <BlockPos>(), EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary); } if (start != null && end != null) { Stopwatch sw = new Stopwatch(); sw.Start(); List <PathNode> nodes = pfs.FindPath(start, end, maxFallHeight, stepHeight, collbox); sw.Stop(); int timeMs = (int)sw.ElapsedMilliseconds; player.SendMessage(groupId, string.Format("Search took {0} ms, {1} nodes checked", timeMs, pfs.astar.NodesChecked), EnumChatType.Notification); if (nodes == null) { player.SendMessage(groupId, "No path found", EnumChatType.CommandError); sapi.World.HighlightBlocks(player, 2, new List <BlockPos>(), EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary); sapi.World.HighlightBlocks(player, 3, new List <BlockPos>(), EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary); return; } List <BlockPos> poses = new List <BlockPos>(); foreach (var node in nodes) { poses.Add(node); } sapi.World.HighlightBlocks(player, 2, poses, new List <int>() { ColorUtil.ColorFromRgba(128, 128, 128, 30) }, EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary); List <Vec3d> wps = pfs.ToWaypoints(nodes); poses = new List <BlockPos>(); foreach (var node in wps) { poses.Add(node.AsBlockPos); } sapi.World.HighlightBlocks(player, 3, poses, new List <int>() { ColorUtil.ColorFromRgba(128, 0, 0, 100) }, EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary); } }