Implement map text (#28705)
This commit is contained in:
20
Content.Client/MapText/MapTextComponent.cs
Normal file
20
Content.Client/MapText/MapTextComponent.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using Content.Shared.MapText;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
|
||||||
|
namespace Content.Client.MapText;
|
||||||
|
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed partial class MapTextComponent : SharedMapTextComponent
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The font that gets cached on component init or state changes
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public VectorFont? CachedFont;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The text currently being displayed. This is either <see cref="SharedMapTextComponent.Text"/> or the
|
||||||
|
/// localized text <see cref="SharedMapTextComponent.LocText"/> or
|
||||||
|
/// </summary>
|
||||||
|
public string CachedText = string.Empty;
|
||||||
|
}
|
||||||
85
Content.Client/MapText/MapTextOverlay.cs
Normal file
85
Content.Client/MapText/MapTextOverlay.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Content.Shared.MapText;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.ResourceManagement;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Client.UserInterface.RichText;
|
||||||
|
using Robust.Shared;
|
||||||
|
using Robust.Shared.Configuration;
|
||||||
|
using Robust.Shared.Enums;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Client.MapText;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draws map text as an overlay
|
||||||
|
/// </summary>
|
||||||
|
public sealed class MapTextOverlay : Overlay
|
||||||
|
{
|
||||||
|
private readonly IConfigurationManager _configManager;
|
||||||
|
private readonly IEntityManager _entManager;
|
||||||
|
private readonly IUserInterfaceManager _uiManager;
|
||||||
|
private readonly SharedTransformSystem _transform;
|
||||||
|
public override OverlaySpace Space => OverlaySpace.ScreenSpace;
|
||||||
|
|
||||||
|
public MapTextOverlay(
|
||||||
|
IConfigurationManager configManager,
|
||||||
|
IEntityManager entManager,
|
||||||
|
IUserInterfaceManager uiManager,
|
||||||
|
SharedTransformSystem transform,
|
||||||
|
IResourceCache resourceCache,
|
||||||
|
IPrototypeManager prototypeManager)
|
||||||
|
{
|
||||||
|
_configManager = configManager;
|
||||||
|
_entManager = entManager;
|
||||||
|
_uiManager = uiManager;
|
||||||
|
_transform = transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(in OverlayDrawArgs args)
|
||||||
|
{
|
||||||
|
if (args.ViewportControl == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
args.DrawingHandle.SetTransform(Matrix3x2.Identity);
|
||||||
|
|
||||||
|
var scale = _configManager.GetCVar(CVars.DisplayUIScale);
|
||||||
|
|
||||||
|
if (scale == 0f)
|
||||||
|
scale = _uiManager.DefaultUIScale;
|
||||||
|
|
||||||
|
DrawWorld(args.ScreenHandle, args, scale);
|
||||||
|
|
||||||
|
args.DrawingHandle.UseShader(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawWorld(DrawingHandleScreen handle, OverlayDrawArgs args, float scale)
|
||||||
|
{
|
||||||
|
if ( args.ViewportControl == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var matrix = args.ViewportControl.GetWorldToScreenMatrix();
|
||||||
|
var query = _entManager.AllEntityQueryEnumerator<MapTextComponent>();
|
||||||
|
|
||||||
|
// Enlarge bounds to try prevent pop-in due to large text.
|
||||||
|
var bounds = args.WorldBounds.Enlarged(2);
|
||||||
|
|
||||||
|
while(query.MoveNext(out var uid, out var mapText))
|
||||||
|
{
|
||||||
|
var mapPos = _transform.GetMapCoordinates(uid);
|
||||||
|
|
||||||
|
if (mapPos.MapId != args.MapId)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!bounds.Contains(mapPos.Position))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (mapText.CachedFont == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var pos = Vector2.Transform(mapPos.Position, matrix) + mapText.Offset;
|
||||||
|
var dimensions = handle.GetDimensions(mapText.CachedFont, mapText.CachedText, scale);
|
||||||
|
handle.DrawString(mapText.CachedFont, pos - dimensions / 2f, mapText.CachedText, scale, mapText.Color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
81
Content.Client/MapText/MapTextSystem.cs
Normal file
81
Content.Client/MapText/MapTextSystem.cs
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
using Content.Shared.MapText;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.ResourceManagement;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Client.UserInterface.RichText;
|
||||||
|
using Robust.Shared.Configuration;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Client.MapText;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public sealed class MapTextSystem : SharedMapTextSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
||||||
|
[Dependency] private readonly IUserInterfaceManager _uiManager = default!;
|
||||||
|
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||||
|
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
[Dependency] private readonly IOverlayManager _overlayManager = default!;
|
||||||
|
|
||||||
|
private MapTextOverlay _overlay = default!;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
SubscribeLocalEvent<MapTextComponent, ComponentStartup>(OnComponentStartup);
|
||||||
|
SubscribeLocalEvent<MapTextComponent, ComponentHandleState>(HandleCompState);
|
||||||
|
|
||||||
|
_overlay = new MapTextOverlay(_configManager, EntityManager, _uiManager, _transform, _resourceCache, _prototypeManager);
|
||||||
|
_overlayManager.AddOverlay(_overlay);
|
||||||
|
|
||||||
|
// TODO move font prototype to robust.shared, then use ProtoId<FontPrototype>
|
||||||
|
DebugTools.Assert(_prototypeManager.HasIndex<FontPrototype>(SharedMapTextComponent.DefaultFont));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnComponentStartup(Entity<MapTextComponent> ent, ref ComponentStartup args)
|
||||||
|
{
|
||||||
|
CacheText(ent.Comp);
|
||||||
|
// TODO move font prototype to robust.shared, then use ProtoId<FontPrototype>
|
||||||
|
DebugTools.Assert(_prototypeManager.HasIndex<FontPrototype>(ent.Comp.FontId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleCompState(Entity<MapTextComponent> ent, ref ComponentHandleState args)
|
||||||
|
{
|
||||||
|
if (args.Current is not MapTextComponentState state)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ent.Comp.Text = state.Text;
|
||||||
|
ent.Comp.LocText = state.LocText;
|
||||||
|
ent.Comp.Color = state.Color;
|
||||||
|
ent.Comp.FontId = state.FontId;
|
||||||
|
ent.Comp.FontSize = state.FontSize;
|
||||||
|
ent.Comp.Offset = state.Offset;
|
||||||
|
|
||||||
|
CacheText(ent.Comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CacheText(MapTextComponent component)
|
||||||
|
{
|
||||||
|
component.CachedFont = null;
|
||||||
|
|
||||||
|
component.CachedText = string.IsNullOrWhiteSpace(component.Text)
|
||||||
|
? Loc.GetString(component.LocText)
|
||||||
|
: component.Text;
|
||||||
|
|
||||||
|
if (!_prototypeManager.TryIndex<FontPrototype>(component.FontId, out var fontPrototype))
|
||||||
|
{
|
||||||
|
component.CachedText = Loc.GetString("map-text-font-error");
|
||||||
|
component.Color = Color.Red;
|
||||||
|
|
||||||
|
if(_prototypeManager.TryIndex<FontPrototype>(SharedMapTextComponent.DefaultFont, out var @default))
|
||||||
|
component.CachedFont = new VectorFont(_resourceCache.GetResource<FontResource>(@default.Path), 14);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fontResource = _resourceCache.GetResource<FontResource>(fontPrototype.Path);
|
||||||
|
component.CachedFont = new VectorFont(fontResource, component.FontSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
6
Content.Server/MapText/MapTextComponent.cs
Normal file
6
Content.Server/MapText/MapTextComponent.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
using Content.Shared.MapText;
|
||||||
|
|
||||||
|
namespace Content.Server.MapText;
|
||||||
|
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed partial class MapTextComponent : SharedMapTextComponent;
|
||||||
28
Content.Server/MapText/MapTextSystem.cs
Normal file
28
Content.Server/MapText/MapTextSystem.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using Content.Shared.MapText;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Server.MapText;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public sealed class MapTextSystem : SharedMapTextSystem
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<MapTextComponent, ComponentGetState>(GetCompState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetCompState(Entity<MapTextComponent> ent, ref ComponentGetState args)
|
||||||
|
{
|
||||||
|
args.State = new MapTextComponentState
|
||||||
|
{
|
||||||
|
Text = ent.Comp.Text,
|
||||||
|
LocText = ent.Comp.LocText,
|
||||||
|
Color = ent.Comp.Color,
|
||||||
|
FontId = ent.Comp.FontId,
|
||||||
|
FontSize = ent.Comp.FontSize,
|
||||||
|
Offset = ent.Comp.Offset
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
51
Content.Shared/MapText/SharedMapTextComponent.cs
Normal file
51
Content.Shared/MapText/SharedMapTextComponent.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.MapText;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is used for displaying text in world space
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
[NetworkedComponent, Access(typeof(SharedMapTextSystem))]
|
||||||
|
public abstract partial class SharedMapTextComponent : Component
|
||||||
|
{
|
||||||
|
public const string DefaultFont = "Default";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The text to display. This will override <see cref="LocText"/>.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public string? Text;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The localized-id of the text that should be displayed.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public LocId LocText = "map-text-default";
|
||||||
|
// TODO VV: LocId editing
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public Color Color = Color.White;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public string FontId = DefaultFont;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public int FontSize = 12;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public Vector2 Offset = Vector2.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class MapTextComponentState : ComponentState
|
||||||
|
{
|
||||||
|
public string? Text { get; init;}
|
||||||
|
public LocId LocText { get; init;}
|
||||||
|
public Color Color { get; init;}
|
||||||
|
public string FontId { get; init; } = default!;
|
||||||
|
public int FontSize { get; init;}
|
||||||
|
public Vector2 Offset { get; init;}
|
||||||
|
}
|
||||||
6
Content.Shared/MapText/SharedMapTextSystem.cs
Normal file
6
Content.Shared/MapText/SharedMapTextSystem.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Content.Shared.MapText;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This handles registering the map text overlay, caching the text font and handling component state
|
||||||
|
/// </summary>
|
||||||
|
public abstract class SharedMapTextSystem : EntitySystem;
|
||||||
2
Resources/Locale/en-US/mapping/map-text-component.ftl
Normal file
2
Resources/Locale/en-US/mapping/map-text-component.ftl
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
map-text-default = Use VV to change the displayed text
|
||||||
|
map-text-font-error = "Error - invalid font"
|
||||||
11
Resources/Prototypes/Entities/Markers/map_text.yml
Normal file
11
Resources/Prototypes/Entities/Markers/map_text.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
- type: entity
|
||||||
|
id: MapText
|
||||||
|
parent: MarkerBase
|
||||||
|
name: map text
|
||||||
|
placement:
|
||||||
|
mode: PlaceFree
|
||||||
|
components:
|
||||||
|
- type: MapText
|
||||||
|
- type: Sprite
|
||||||
|
state: pink
|
||||||
|
|
||||||
Reference in New Issue
Block a user