public FloatyWaypointManagement(ClientMain game, WaypointUtils utils) : base(game) { capi = game.Api as ICoreClientAPI; this.utils = utils; capi.Input.RegisterHotKey("editfloatywaypoint", "Edit Floaty Waypoint", GlKeys.R, HotkeyType.GUIOrOtherControls); capi.Input.SetHotKeyHandler("editfloatywaypoint", (k) => { foreach (var val in WaypointElements) { if (val.isAligned) { val.OpenEditDialog(); return(true); } } return(false); }); Update(); }
public void CmdShape(int groupId, CmdArgs args) { BlockPos pos = capi.World.Player.CurrentBlockSelection?.Position ?? capi.World.Player.Entity.Pos.AsBlockPos; string arg = args.PopWord(); int radius = (int)args.PopInt(4); int thickness = (int)args.PopInt(1); bool at = (bool)args.PopBool(false); int attach = at ? radius + 1 : 0; WaypointUtils wUtil = capi.ModLoader.GetModSystem <WaypointUtils>(); BlockPos wp1Pos, wp2Pos; switch (arg) { case "sphere": for (int x = -radius; x <= radius; x++) { for (int y = -radius; y <= radius; y++) { for (int z = -radius; z <= radius; z++) { BlockPos iPos = new BlockPos(pos.X + x, pos.Y + y + attach, pos.Z + z); int r = x * x + y * y + z * z; if (r <= (radius * radius) && r > (radius - thickness) * (radius - thickness) && iPos.Y > 0) { highlighted.Add(iPos); } } } } MakeHighlights(highlighted); break; case "dome": for (int x = -radius; x <= radius; x++) { for (int y = -radius; y <= radius; y++) { for (int z = -radius; z <= radius; z++) { if (y < 0) { continue; } BlockPos iPos = new BlockPos(pos.X + x, pos.Y + y + attach, pos.Z + z); int r = x * x + y * y + z * z; if (r <= (radius * radius) && r > (radius - thickness) * (radius - thickness) && iPos.Y > 0) { highlighted.Add(iPos); } } } } MakeHighlights(highlighted); break; case "cube": for (int x = -radius; x <= radius; x++) { for (int y = -radius; y <= radius; y++) { for (int z = -radius; z <= radius; z++) { int r = thickness; if (x < r && y < r && z < r && x > -r && y > -r && z > -r) { continue; } BlockPos iPos = new BlockPos(pos.X + x, pos.Y + y + attach - 1, pos.Z + z); if (iPos.Y > 0) { highlighted.Add(iPos); } } } } MakeHighlights(highlighted); break; case "path": if (radius > wUtil.Waypoints.Count || thickness > wUtil.Waypoints.Count) { break; } wp1Pos = wUtil.Waypoints[radius]?.Position?.AsBlockPos.AddCopy(0, at ? -1 : 0, 0); wp2Pos = wUtil.Waypoints[thickness]?.Position?.AsBlockPos.AddCopy(0, at ? -1 : 0, 0); if (wp1Pos != null && wp2Pos != null) { highlighted = new HashSet <BlockPos>(highlighted.Concat(PlotLine3d(wp1Pos, wp2Pos))); } MakeHighlights(highlighted); break; case "astarpath": AStarClient aStar = new AStarClient(capi); if (radius > wUtil.Waypoints.Count || thickness > wUtil.Waypoints.Count) { break; } wp1Pos = wUtil.Waypoints[radius]?.Position?.AsBlockPos; wp2Pos = wUtil.Waypoints[thickness]?.Position?.AsBlockPos; if (wp1Pos != null && wp2Pos != null) { var path = aStar.FindPath(wp1Pos, wp2Pos, 2, 1.0f, new Cuboidf(new Vec3f(0, 0, 0), new Vec3f(0, 2, 0)), int.MaxValue); if (at && path != null) { foreach (var val in path) { val.Down(); } } if (path != null) { highlighted = new HashSet <BlockPos>(highlighted.Concat(path)); } } MakeHighlights(highlighted); break; case "circle": for (int x = -radius; x <= radius; x++) { for (int z = -radius; z <= radius; z++) { BlockPos iPos = new BlockPos(pos.X + x, pos.Y, pos.Z + z); int r = x * x + z * z; if (r <= (radius * radius) && r > (radius - thickness) * (radius - thickness) && iPos.Y > 0) { highlighted.Add(iPos); } } } MakeHighlights(highlighted); break; case "extrude": var tmp = new HashSet <BlockPos>(); var dir = thickness == 0 ? new Vec3i(0, 1, 0) : thickness == 1 ? new Vec3i(1, 0, 0) : thickness == 2 ? new Vec3i(0, 0, 1) : thickness == 3 ? new Vec3i(1, 1, 1) : new Vec3i(0, 0, 0); foreach (var val in highlighted) { for (int i = 0; i < radius; i++) { tmp.Add(val.AddCopy(dir * i)); } } highlighted = new HashSet <BlockPos>(highlighted.Concat(tmp).ToList()); MakeHighlights(highlighted); break; case "toflatten": HashSet <BlockPos> temp = new HashSet <BlockPos>(highlighted); foreach (var val in highlighted) { if (capi.World.BlockAccessor.GetBlock(val).Id == 0) { temp.Remove(val); } } highlighted = temp; MakeHighlights(highlighted); break; case "save": using (TextWriter tw = new StreamWriter("shape" + radius + ".json")) { tw.Write(JsonConvert.SerializeObject(highlighted, Formatting.None)); tw.Close(); } break; case "load": using (TextReader tr = new StreamReader("shape" + radius + ".json")) { highlighted = JsonConvert.DeserializeObject <HashSet <BlockPos> >(tr.ReadToEnd()); tr.Close(); } MakeHighlights(highlighted); break; case "clear": capi.World.HighlightBlocks(capi.World.Player, 514, new List <BlockPos>(), EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Cubes); highlighted.Clear(); break; default: break; } }
public CommandFloatyWaypoints(ICoreClientAPI capi, WaypointUtils utils) : base(capi) { Command = "wpcfg"; RegisterSubCommand("deathdebug", new SubCommand((player, groupId, args) => { Config.DebugDeathWaypoints = args.PopBool() ?? !Config.DebugDeathWaypoints; capi.ShowChatMessage(string.Format("Death waypoint debbuging set to {0}", Config.DebugDeathWaypoints)); }, "Debug sending of death waypoint string, true/false.")); RegisterSubCommand("dotrange", new SubCommand((player, groupId, args) => { double?dr = args.PopDouble(); Config.DotRange = dr != null ? (double)dr : Config.DotRange; capi.ShowChatMessage("Dot Range Set To " + Config.DotRange + " Meters."); }, "Sets the dot range of floaty waypoints, any decimal value.")); RegisterSubCommand("titlerange", new SubCommand((player, groupId, args) => { double?tr = args.PopDouble(); Config.TitleRange = tr != null ? (double)tr : Config.TitleRange; capi.ShowChatMessage("Title Range Set To " + Config.TitleRange + " Meters."); }, "Sets the title range of floaty waypoints, any decimal value.")); RegisterSubCommand("perblockwaypoints", new SubCommand((player, groupId, args) => { bool?pb = args.PopBool(); Config.PerBlockWaypoints = pb != null ? (bool)pb : !Config.PerBlockWaypoints; capi.ShowChatMessage("Per Block Waypoints Set To " + Config.PerBlockWaypoints + "."); }, "Whether or not floaty waypoints are clamped to block positions, true/false.")); RegisterSubCommand("pdw", new SubCommand((player, groupId, args) => { utils.PurgeWaypointsByStrings("Player Death Waypoint", "*Player Death Waypoint*"); }, "Purges death waypoints.")); RegisterSubCommand("plt", new SubCommand((player, groupId, args) => { utils.PurgeWaypointsByStrings("Limits Test"); }, "Purges waypoints created by the testlimits debug command.")); RegisterSubCommand("open", new SubCommand((player, groupId, args) => { utils.ViewWaypoints(new KeyCombination()); }, "Opens floaty waypoints uis.")); RegisterSubCommand("waypointprefix", new SubCommand((player, groupId, args) => { bool?wp = args.PopBool(); Config.WaypointPrefix = wp != null ? (bool)wp : !Config.WaypointPrefix; capi.ShowChatMessage("Waypoint Prefix Set To " + Config.WaypointPrefix + "."); }, "Whether or not waypoints are prefixed with \"Waypoint:\", true/false")); RegisterSubCommand("waypointid", new SubCommand((player, groupId, args) => { bool?wi = args.PopBool(); Config.WaypointID = wi != null ? (bool)wi : !Config.WaypointID; capi.ShowChatMessage("Waypoint ID Set To " + Config.WaypointID + "."); }, "Whether or not floaty waypoints are prefixed with their ID, true/false")); RegisterSubCommand("purge", new SubCommand((player, groupId, args) => { string s = args.PopWord(); if (s == "reallyreallyconfirm") { utils.Purge(); } else { capi.ShowChatMessage(Lang.Get("Are you sure you want to do that? It will remove ALL your waypoints, type \"reallyreallyconfirm\" to confirm.")); } }, "Deletes ALL your waypoints.")); RegisterSubCommand("enableall", new SubCommand((player, groupId, args) => { Config.DisabledColors.Clear(); }, "Enables all waypoint colors.")); RegisterSubCommand("save", new SubCommand((player, groupId, args) => { ConfigLoader.SaveConfig(capi); }, "Force save configuration file.")); RegisterSubCommand("export", new SubCommand((player, groupId, args) => { string filePath = Path.Combine(GamePaths.DataPath, args.PopWord() ?? "waypoints"); lock (MassFileExportSystem.toExport) { MassFileExportSystem.toExport.Push(new ExportableJsonObject(utils.WaypointsRel, filePath)); } }, "Exports waypoints as a JSON file located in your game data folder.")); RegisterSubCommand("import", new SubCommand((player, groupId, args) => { string path1 = Path.Combine(GamePaths.DataPath, args.PopWord() ?? "waypoints") + ".json"; if (File.Exists(path1)) { using (TextReader reader = new StreamReader(path1)) { DummyWaypoint[] relative = JsonConvert.DeserializeObject <DummyWaypoint[]>(reader.ReadToEnd(), new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }); VSHUDTaskSystem.Actions.Enqueue(new Vintagestory.API.Common.Action(() => { for (int j = 0; j < relative.Length; j++) { var val = relative[j]; if (utils.WaypointsRel.Any(w => val.Position.AsBlockPos.X == w.Position.AsBlockPos.X && val.Position.AsBlockPos.Y == w.Position.AsBlockPos.Y && val.Position.AsBlockPos.Z == w.Position.AsBlockPos.Z )) { continue; } string str = string.Format(CultureInfo.InvariantCulture, "/waypoint addati {0} ={1} ={2} ={3} {4} #{5} {6}", val.Icon, val.Position.X, val.Position.Y, val.Position.Z, val.Pinned, ColorUtil.Int2Hex(val.Color), val.Title); capi.SendChatMessage(str); } capi.SendMyWaypoints(); })); reader.Close(); } } }, "Imports waypoints from a JSON file located in your game data folder, default name waypoints.json, if not, provide filename excluding .json.")); RegisterSubCommand("testlimits", new SubCommand((player, groupId, args) => { int amount = args.PopInt() ?? 30; int maxY = args.PopInt() ?? 10; double radius = (args.PopInt() ?? 1000); VSHUDTaskSystem.Actions.Enqueue(new Vintagestory.API.Common.Action(() => { for (int i = 0; i < amount; i++) { double x = (capi.World.Rand.NextDouble() - 0.5) * radius, z = (capi.World.Rand.NextDouble() - 0.5) * radius, y = capi.World.BlockAccessor.GetRainMapHeightAt((int)x, (int)z); double r = x * x + z * z; if (r <= (radius * 0.5) * (radius * 0.5)) { Vec3d pos = capi.World.Player.Entity.Pos.XYZ.AddCopy(new Vec3d(x, y, z)); bool deathWaypoint = capi.World.Rand.NextDouble() > 0.8; string icon = deathWaypoint ? "rocks" : WaypointUtils.iconKeys[(int)(capi.World.Rand.NextDouble() * (WaypointUtils.iconKeys.Length - 1))]; string title = deathWaypoint ? "Limits Test Player Death Waypoint" : "Limits Test Waypoint"; string str = string.Format(CultureInfo.InvariantCulture, "/waypoint addati {0} ={1} ={2} ={3} {4} #{5} {6}", icon, pos.X, pos.Y, pos.Z, deathWaypoint, ColorStuff.RandomHexColorVClamp(capi, 0.5, 0.8), title); capi.SendChatMessage(str); } else { i--; } } capi.SendMyWaypoints(); })); }, "Creates and uploads many waypoints to the server to debug the limits of VSHUD's floaty waypoint rendering system, inputs 3 integers (amount, maxY, radius).")); RegisterSubCommand("pillars", new SubCommand((player, groupId, args) => { Config.ShowPillars = args.PopBool() ?? !Config.ShowPillars; capi.ShowChatMessage("Waypoint Pillars Set To " + Config.ShowPillars + "."); }, "Toggles the rendering of the pillars that accompany the floaty waypoint UIs. True/False")); RegisterSubCommand("shuffle", new SubCommand((player, groupId, args) => { lock (FloatyWaypointManagement.WaypointElements) { if (FloatyWaypointManagement.WaypointElements != null && FloatyWaypointManagement.WaypointElements.Count > 1) { HudElementWaypoint[] wps = new HudElementWaypoint[FloatyWaypointManagement.WaypointElements.Count]; FloatyWaypointManagement.WaypointElements.TryPopRange(wps); wps.Shuffle(new LCGRandom(468963)); FloatyWaypointManagement.WaypointElements.PushRange(wps); } } }, "Shuffles the internal floaty waypoint UI stack to debug if changes are handled correctly.")); RegisterSubCommand("echo", new SubCommand((player, groupId, args) => { Config.Echo = (bool)args.PopBool(!Config.Echo); capi.ShowChatMessage(string.Format("Waypoint creation echoing set to {0}.", Config.Echo)); }, "Toggles the logging to chat of waypoint creation/deletion. Useful if you have a mod that creates many waypoints. True/False")); }
public void CmdMeasuringTape(int groupId, CmdArgs args) { WaypointUtils wUtil = capi.ModLoader.GetModSystem <WaypointUtils>(); 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; } }