diff --git a/Projects/Scripts/Commands/Generic/Commands/Commands.cs b/Projects/Scripts/Commands/Generic/Commands/Commands.cs index 73a5f4cba..9f05b2624 100644 --- a/Projects/Scripts/Commands/Generic/Commands/Commands.cs +++ b/Projects/Scripts/Commands/Generic/Commands/Commands.cs @@ -59,6 +59,7 @@ namespace Server.Commands.Generic Register(new FactionKickCommand(FactionKickType.Unban)); Register(new BringToPackCommand()); Register(new TraceLockdownCommand()); + Register(new LocationCommand()); } public static void Register(BaseCommand command) @@ -751,7 +752,7 @@ namespace Server.Commands.Generic { AccessLevel = AccessLevel.GameMaster; Supports = CommandSupport.AllNPCs | CommandSupport.AllItems; - Commands = new[] { "Delete", "Remove" }; + Commands = new[] { "Delete", "Remove", "Rm" }; ObjectTypes = ObjectTypes.Both; Usage = "Delete"; Description = "Deletes a targeted item or mobile. Does not delete players."; diff --git a/Projects/Scripts/Commands/LocationCommand.cs b/Projects/Scripts/Commands/LocationCommand.cs new file mode 100644 index 000000000..5f215b692 --- /dev/null +++ b/Projects/Scripts/Commands/LocationCommand.cs @@ -0,0 +1,52 @@ +using Server.Commands.Generic; +using Server.Items; +using Server.Targeting; +using System.Globalization; +using System.Linq; + +namespace Server.Commands +{ + public class LocationCommand : BaseCommand + { + public LocationCommand() : base() + { + AccessLevel = AccessLevel.Counselor; + Commands = new[] { "Location", "Loc", "Pos" }; + ObjectTypes = ObjectTypes.All; + Supports = CommandSupport.Single | CommandSupport.Multi; + Usage = "Location [itemIds ...]"; + Description = "Retrieves the positional coordinates of a target. Displaying a message above the item, " + + "mobile, or environment. Environment targets will also have a graphic temporarily displayed " + + "on the tile. This graphic can be changed to the provided list of itemIds."; + } + + public override void Execute(CommandEventArgs e, object obj) + { + int[] graphics = new[] { 0x17AF, 0X17B0, 0X17B1, 0X17B2 }; + if (e.Arguments.Length > 0) + graphics = e.Arguments + .Select(x => int.TryParse(x, out int result) + ? result : int.TryParse(x.Substring(2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out result) + ? result : (int?)null) + .Where(x => x.HasValue) + .Select(x => x.Value) + .ToArray(); + if (obj is IPoint3D point) + { + var label = $"(x:{point.X}, y:{point.Y}, z:{point.Z})"; + if (obj is LandTarget || obj is StaticTarget) + { + var item = EffectItem.Create(new Point3D(point), e.Mobile.Map, EffectItem.DefaultDuration); + foreach (int graphic in graphics) + Effects.SendLocationParticles(item, graphic, 10, 50, 2023); + item.LabelTo(e.Mobile, label); + } + else if (obj is Mobile entity) entity.SayTo(e.Mobile, label); + else if (obj is Item item) item.LabelTo(e.Mobile, label); + AddResponse($"Location: {label}"); + } + else + LogFailure("That is not locatable."); + } + } +}