Autocomplete more map commands (#5797)

* Autocomplete more map commands

Also added some extra helper features.

* Finish

* Fix bug, avoid IocResolves

* grid is grid

* file filename clash

* turn hint into option

* a

---------

Co-authored-by: ElectroJr <leonsfriedrich@gmail.com>
This commit is contained in:
metalgearsloth
2025-09-18 12:38:17 +10:00
committed by GitHub
parent 10e4766809
commit 917878d05f
7 changed files with 78 additions and 17 deletions

View File

@@ -0,0 +1,3 @@
generic-map = map
generic-grid = grid
generic-mapid = map Id

View File

@@ -577,3 +577,5 @@ cmd-localization_set_culture-desc = Set DefaultCulture for the client Localizati
cmd-localization_set_culture-help = Usage: localization_set_culture <cultureName>
cmd-localization_set_culture-culture-name = <cultureName>
cmd-localization_set_culture-changed = Localization changed to { $code } ({ $nativeName } / { $englishName })
cmd-addmap-hint-2 = runMapInit [true / false]

View File

@@ -1,3 +1,4 @@
using System.Diagnostics.Contracts;
using Robust.Client.Graphics;
using Robust.Client.Map;
using Robust.Client.ResourceManagement;
@@ -9,13 +10,14 @@ namespace Robust.Client.GameObjects;
public sealed class MapSystem : SharedMapSystem
{
protected override MapId GetNextMapId()
[Pure]
internal override MapId GetNextMapId()
{
// Client-side map entities use negative map Ids to avoid conflict with server-side maps.
var id = new MapId(--LastMapId);
var id = new MapId(LastMapId - 1);
while (MapExists(id) || UsedIds.Contains(id))
{
id = new MapId(--LastMapId);
id = new MapId(id.Value - 1);
}
return id;
}

View File

@@ -1,3 +1,4 @@
using System.Diagnostics.Contracts;
using System.Linq;
using Robust.Server.GameStates;
using Robust.Shared;
@@ -18,13 +19,15 @@ namespace Robust.Server.GameObjects
private bool _deleteEmptyGrids;
protected override MapId GetNextMapId()
[Pure]
internal override MapId GetNextMapId()
{
var id = new MapId(++LastMapId);
var id = new MapId(LastMapId + 1);
while (MapExists(id) || UsedIds.Contains(id))
{
id = new MapId(++LastMapId);
id = new MapId(id.Value + 1);
}
return id;
}

View File

@@ -33,9 +33,23 @@ sealed class AddMapCommand : LocalizedEntityCommands
shell.WriteError($"Map with ID {mapId} already exists!");
}
public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
{
switch (args.Length)
{
case 1:
var mapId = _mapSystem.GetNextMapId();
return CompletionResult.FromHintOptions([ new CompletionOption($"{mapId}")], LocalizationManager.GetString("generic-mapid"));
case 2:
return CompletionResult.FromHint(LocalizationManager.GetString("cmd-addmap-hint-2"));
default:
return CompletionResult.Empty;
}
}
}
sealed class RemoveMapCommand : LocalizedCommands
sealed class RemoveMapCommand : LocalizedEntityCommands
{
[Dependency] private readonly IEntitySystemManager _systems = default!;
@@ -62,6 +76,14 @@ sealed class RemoveMapCommand : LocalizedCommands
mapSystem.DeleteMap(mapId);
shell.WriteLine($"Map {mapId.Value} was removed.");
}
public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
{
if (args.Length != 1)
return CompletionResult.Empty;
return CompletionResult.FromHintOptions(CompletionHelper.MapIds(args[0], entManager: EntityManager), LocalizationManager.GetString("generic-map"));
}
}
sealed class RemoveGridCommand : LocalizedEntityCommands
@@ -88,6 +110,14 @@ sealed class RemoveGridCommand : LocalizedEntityCommands
EntityManager.DeleteEntity(gridId);
shell.WriteLine($"Grid {gridId} was removed.");
}
public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
{
if (args.Length != 1)
return CompletionResult.Empty;
return CompletionResult.FromHintOptions(CompletionHelper.Components<MapGridComponent>(args[0], entManager: EntityManager), LocalizationManager.GetString("generic-grid"));
}
}
internal sealed class RunMapInitCommand : LocalizedEntityCommands
@@ -153,7 +183,8 @@ internal sealed class ListMapsCommand : LocalizedEntityCommands
string.Join(",", _map.GetAllGrids(mapId).Select(grid => grid.Owner)));
}
shell.WriteLine(msg.ToString());
// Trim the newline
shell.WriteLine(msg.ToString()[..^1]);
}
}
@@ -183,6 +214,6 @@ internal sealed class ListGridsCommand : LocalizedEntityCommands
uid, xform.MapID, uid, worldPos.X, worldPos.Y);
}
shell.WriteLine(msg.ToString());
shell.WriteLine(msg.ToString()[..^1]);
}
}

View File

@@ -208,11 +208,16 @@ public static class CompletionHelper
return sorted ? playerOptions.OrderBy(o => o.Value) : playerOptions;
}
public static IEnumerable<CompletionOption> MapIds(string text, IEntityManager entManager)
{
return GetComponents<MapComponent>(text, entManager: entManager).Select(o => new CompletionOption(o.Component.MapId.ToString(), o.EntityName));
}
public static IEnumerable<CompletionOption> MapIds(IEntityManager? entManager = null)
{
IoCManager.Resolve(ref entManager);
return entManager.EntityQuery<MapComponent>(true).Select(o => new CompletionOption(o.MapId.ToString()));
return entManager.EntityQuery<MapComponent, MetaDataComponent>(true).Select(o => new CompletionOption(o.Item1.MapId.ToString(), o.Item2.EntityName));
}
public static IEnumerable<CompletionOption> MapUids(IEntityManager? entManager = null)
@@ -245,23 +250,29 @@ public static class CompletionHelper
}
}
public static IEnumerable<CompletionOption> Components<T>(string text, IEntityManager? entManager = null, int limit = 20) where T : IComponent
private static IEnumerable<(T Component, string NetString, string EntityName)> GetComponents<T>(string text, IEntityManager entManager, int limit = 20)
where T : IComponent
{
if (text != string.Empty && !NetEntity.TryParse(text, out _))
yield break;
IoCManager.Resolve(ref entManager);
var query = entManager.AllEntityQueryEnumerator<T, MetaDataComponent>();
var i = 0;
while (i < limit && query.MoveNext(out _, out var metadata))
while (i < limit && query.MoveNext(out var comp, out var metadata))
{
var netString = metadata.NetEntity.ToString();
if (!netString.StartsWith(text))
continue;
i++;
yield return new CompletionOption(netString, metadata.EntityName);
yield return (comp, netString, metadata.EntityName);
}
}
public static IEnumerable<CompletionOption> Components<T>(string text, IEntityManager? entManager = null, int limit = 20) where T : IComponent
{
IoCManager.Resolve(ref entManager);
return GetComponents<T>(text, entManager, limit).Select(o => new CompletionOption(o.NetString, o.EntityName));
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
@@ -111,7 +112,15 @@ public abstract partial class SharedMapSystem
args.State = new MapComponentState(component.MapId, component.LightingEnabled, component.MapPaused, component.MapInitialized);
}
protected abstract MapId GetNextMapId();
protected MapId TakeNextMapId()
{
var id = GetNextMapId();
LastMapId = id.Value;
return id;
}
[Pure]
internal abstract MapId GetNextMapId();
private void OnComponentAdd(EntityUid uid, MapComponent component, ComponentAdd args)
{
@@ -139,7 +148,7 @@ public abstract partial class SharedMapSystem
return;
}
map.Comp.MapId = id ?? GetNextMapId();
map.Comp.MapId = id ?? TakeNextMapId();
if (IsClientSide(map) != map.Comp.MapId.IsClientSide)
throw new Exception($"Attempting to assign a client-side map id to a networked entity or vice-versa");
@@ -209,7 +218,7 @@ public abstract partial class SharedMapSystem
/// </summary>
public EntityUid CreateMap(out MapId mapId, bool runMapInit = true)
{
mapId = GetNextMapId();
mapId = TakeNextMapId();
var uid = CreateMap(mapId, runMapInit);
return uid;
}