Skip to content

Commit

Permalink
Basic Maptext (#2108)
Browse files Browse the repository at this point in the history
Co-authored-by: amylizzle <[email protected]>
Co-authored-by: wixoa <[email protected]>
  • Loading branch information
3 people authored Jan 19, 2025
1 parent 75b5cf2 commit 3976b02
Show file tree
Hide file tree
Showing 9 changed files with 224 additions and 38 deletions.
10 changes: 5 additions & 5 deletions DMCompiler/DMStandard/Types/Atoms/_Atom.dm
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@
var/gender = NEUTER
var/density = FALSE

var/maptext as opendream_unimplemented
var/maptext = null

var/list/filters = null
var/appearance
var/appearance_flags = 0
var/maptext_width as opendream_unimplemented
var/maptext_height as opendream_unimplemented
var/maptext_x = 32 as opendream_unimplemented
var/maptext_y = 32 as opendream_unimplemented
var/maptext_width = 32
var/maptext_height = 32
var/maptext_x = 0
var/maptext_y = 0
var/step_x as opendream_unimplemented
var/step_y as opendream_unimplemented
var/render_source
Expand Down
10 changes: 5 additions & 5 deletions DMCompiler/DMStandard/Types/Image.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
var/list/filters = list()
var/layer = FLOAT_LAYER
var/luminosity = 0 as opendream_unimplemented
var/maptext = "i" as opendream_unimplemented
var/maptext_width = 32 as opendream_unimplemented
var/maptext_height = 32 as opendream_unimplemented
var/maptext_x = 0 as opendream_unimplemented
var/maptext_y = 0 as opendream_unimplemented
var/maptext = null
var/maptext_width = 32
var/maptext_height = 32
var/maptext_x = 0
var/maptext_y = 0
var/mouse_over_pointer = 0 as opendream_unimplemented
var/mouse_drag_pointer = 0 as opendream_unimplemented
var/mouse_drop_pointer = 1 as opendream_unimplemented
Expand Down
32 changes: 14 additions & 18 deletions OpenDreamClient/Rendering/DreamIcon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ public void Dispose() {
TextureRenderOffset = Vector2.Zero;
return frame;
} else {
if(textureOverride is not null)
return FullRenderTexture(viewOverlay, handle, iconMetaData, frame).Texture; //no caching in the presence of overrides
CachedTexture = FullRenderTexture(viewOverlay, handle, iconMetaData, frame);
}

Expand Down Expand Up @@ -323,11 +325,9 @@ private void UpdateAnimation() {
_animatedAppearance.IconState = endAppearance.IconState;
if (endAppearance.Invisibility != _appearance.Invisibility)
_animatedAppearance.Invisibility = endAppearance.Invisibility;
if (endAppearance.Maptext != _appearance.Maptext)
_animatedAppearance.Maptext = endAppearance.Maptext;

/* TODO maptext
if (endAppearance.MapText != _appearance.MapText)
appearance.MapText = endAppearance.MapText;
*/
/* TODO suffix
if (endAppearance.Suffix != _appearance.Suffix)
appearance.Suffix = endAppearance.Suffix;
Expand Down Expand Up @@ -383,34 +383,30 @@ private void UpdateAnimation() {
}
*/

/* TODO maptext
if (endAppearance.MapTextWidth != _appearance.MapTextWidth) {
appearance.MapTextWidth = (ushort)Math.Clamp(((1-factor) * _appearance.MapTextWidth) + (factor * endAppearance.MapTextWidth), 0, 65535);
}
if (endAppearance.MaptextSize != _appearance.MaptextSize) {
Vector2 startingOffset = _appearance.MaptextSize;
Vector2 newMaptextSize = Vector2.Lerp(startingOffset, endAppearance.MaptextSize, factor);

if (endAppearance.MapTextHeight != _appearance.MapTextHeight) {
appearance.MapTextHeight = (ushort)Math.Clamp(((1-factor) * _appearance.MapTextHeight) + (factor * endAppearance.MapTextHeight), 0, 65535);
_animatedAppearance.MaptextSize = (Vector2i)newMaptextSize;
}

if (endAppearance.MapTextX != _appearance.MapTextX) {
appearance.MapTextX = (short)Math.Clamp(((1-factor) * _appearance.MapTextX) + (factor * endAppearance.MapTextX), -32768, 32767);
}
if (endAppearance.MaptextOffset != _appearance.MaptextOffset) {
Vector2 startingOffset = _appearance.MaptextOffset;
Vector2 newMaptextOffset = Vector2.Lerp(startingOffset, endAppearance.MaptextOffset, factor);

if (endAppearance.MapTextY != _appearance.MapTextY) {
appearance.MapTextY = (short)Math.Clamp(((1-factor) * _appearance.MapTextY) + (factor * endAppearance.MapTextY), -32768, 32767);
_animatedAppearance.MaptextOffset = (Vector2i)newMaptextOffset;
}
*/

if (endAppearance.PixelOffset != _appearance.PixelOffset) {
Vector2 startingOffset = _appearance.PixelOffset;
Vector2 newPixelOffset = Vector2.Lerp(startingOffset, endAppearance.PixelOffset, 1.0f-factor);
Vector2 newPixelOffset = Vector2.Lerp(startingOffset, endAppearance.PixelOffset, factor);

_animatedAppearance.PixelOffset = (Vector2i)newPixelOffset;
}

if (endAppearance.PixelOffset2 != _appearance.PixelOffset2) {
Vector2 startingOffset = _appearance.PixelOffset2;
Vector2 newPixelOffset = Vector2.Lerp(startingOffset, endAppearance.PixelOffset2, 1.0f-factor);
Vector2 newPixelOffset = Vector2.Lerp(startingOffset, endAppearance.PixelOffset2, factor);

_animatedAppearance.PixelOffset2 = (Vector2i)newPixelOffset;
}
Expand Down
68 changes: 66 additions & 2 deletions OpenDreamClient/Rendering/DreamViewOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using OpenDreamClient.Interface;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Enums;
using Robust.Shared.Map;
using OpenDreamShared.Dream;
using Robust.Shared.Console;
Expand All @@ -13,6 +12,8 @@
using Robust.Shared.Profiling;
using Vector3 = Robust.Shared.Maths.Vector3;
using Matrix3x2 = System.Numerics.Matrix3x2;
using Robust.Client.ResourceManagement;
using Robust.Shared.Enums;

namespace OpenDreamClient.Rendering;

Expand Down Expand Up @@ -40,6 +41,9 @@ internal sealed class DreamViewOverlay : Overlay {
[Dependency] private readonly IClyde _clyde = default!;
[Dependency] private readonly IPrototypeManager _protoManager = default!;
[Dependency] private readonly ProfManager _prof = default!;
[Dependency] private readonly IResourceCache _resourceCache = default!;

private readonly Font _defaultMaptextFont;

private readonly ISawmill _sawmill = Logger.GetSawmill("opendream.view");

Expand Down Expand Up @@ -83,6 +87,7 @@ public DreamViewOverlay(RenderTargetPool renderTargetPool, TransformSystem trans
_appearanceSystem = appearanceSystem;
_screenOverlaySystem = screenOverlaySystem;
_clientImagesSystem = clientImagesSystem;
_defaultMaptextFont = new VectorFont(_resourceCache.GetResource<FontResource>("/Fonts/NotoSans-Regular.ttf"),8);

_spriteQuery = _entityManager.GetEntityQuery<DMISpriteComponent>();
_xformQuery = _entityManager.GetEntityQuery<TransformComponent>();
Expand Down Expand Up @@ -338,7 +343,35 @@ private void ProcessIconComponents(DreamIcon icon, Vector2 position, EntityUid u
// TODO: vis_flags
}

//TODO maptext - note colour + transform apply
//maptext is basically just an image of rendered text added as an overlay
if(icon.Appearance.Maptext != null){ //if has maptext
RendererMetaData maptext = RentRendererMetaData();
maptext.MainIcon = icon;
maptext.Position = current.Position;
maptext.Uid = current.Uid;
maptext.ClickUid = current.Uid;
maptext.IsScreen = current.IsScreen;
tieBreaker++;
maptext.TieBreaker = tieBreaker;
maptext.Plane = current.Plane;
maptext.Layer = current.Layer;
maptext.RenderSource = null;
maptext.RenderTarget = null;
maptext.MouseOpacity = current.MouseOpacity;
maptext.TransformToApply = current.TransformToApply;
maptext.ColorToApply = current.ColorToApply;
maptext.ColorMatrixToApply = current.ColorMatrixToApply;
maptext.AlphaToApply = current.AlphaToApply;
maptext.BlendMode = current.BlendMode;

maptext.AppearanceFlags = current.AppearanceFlags;
maptext.AppearanceFlags &= ~AppearanceFlags.PlaneMaster; //doesn't make sense for maptext

maptext.Maptext = icon.Appearance.Maptext;
maptext.MaptextSize = icon.Appearance.MaptextSize;
maptext.Position += icon.Appearance.MaptextOffset/(float)EyeManager.PixelsPerMeter;
result.Add(maptext);
}

//TODO particles - colour and transform don't apply?

Expand Down Expand Up @@ -400,6 +433,11 @@ public void DrawIcon(DrawingHandleWorld handle, Vector2i renderTargetSize, Rende
positionOffset -= ((ktSize/EyeManager.PixelsPerMeter) - Vector2.One) * new Vector2(0.5f); //correct for KT group texture offset
}

//Maptext
if(iconMetaData.Maptext != null){
iconMetaData.TextureOverride = GetTextureFromMaptext(iconMetaData.Maptext, iconMetaData.MaptextSize!.Value.X, iconMetaData.MaptextSize!.Value.Y, handle);
}

var frame = iconMetaData.GetTexture(this, handle);
var pixelPosition = (iconMetaData.Position + positionOffset) * EyeManager.PixelsPerMeter;

Expand Down Expand Up @@ -756,6 +794,28 @@ private Texture ProcessKeepTogether(DrawingHandleWorld handle, RendererMetaData
return ktTexture.Texture;
}

public Texture GetTextureFromMaptext(string maptext, int width, int height, DrawingHandleWorld handle) {
if(width == 0) width = 32;
if(height == 0) height = 32;
IRenderTexture tempTexture = _renderTargetPool.Rent(new Vector2i(width, height));
handle.RenderInRenderTarget(tempTexture, () => {
handle.SetTransform(CreateRenderTargetFlipMatrix(tempTexture.Size, Vector2.Zero));
float scale = 1;
var font = _defaultMaptextFont;
var baseLine = new Vector2(0, 0);
foreach (var rune in maptext.EnumerateRunes()){
var metric = font.GetCharMetrics(rune, scale);
Vector2 mod = new Vector2(0);
if(metric.HasValue)
mod.Y += metric.Value.BearingY - (metric.Value.Height - metric.Value.BearingY);

baseLine.X += font.DrawChar(handle, rune, baseLine+mod, scale, Color.White);
}
}, Color.Transparent);
_renderTargetPool.ReturnAtEndOfFrame(tempTexture);
return tempTexture.Texture;
}

/// <summary>
/// Creates a transformation matrix that counteracts RT's
/// <see cref="DrawingHandleBase.RenderInRenderTarget(IRenderTarget,Action,System.Nullable{Robust.Shared.Maths.Color})"/> quirks
Expand Down Expand Up @@ -812,6 +872,8 @@ internal sealed class RendererMetaData : IComparable<RendererMetaData> {
public BlendMode BlendMode;
public MouseOpacity MouseOpacity;
public Texture? TextureOverride;
public string? Maptext;
public Vector2i? MaptextSize;

public bool IsPlaneMaster => (AppearanceFlags & AppearanceFlags.PlaneMaster) != 0;
public bool HasRenderSource => !string.IsNullOrEmpty(RenderSource);
Expand Down Expand Up @@ -841,6 +903,8 @@ public void Reset() {
BlendMode = BlendMode.Default;
MouseOpacity = MouseOpacity.Transparent;
TextureOverride = null;
Maptext = null;
MaptextSize = null;
}

public Texture? GetTexture(DreamViewOverlay viewOverlay, DrawingHandleWorld handle) {
Expand Down
35 changes: 35 additions & 0 deletions OpenDreamRuntime/AtomManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ public bool IsValidAppearanceVar(string name) {
case "verbs":
case "overlays":
case "underlays":
case "maptext":
case "maptext_width":
case "maptext_height":
case "maptext_x":
case "maptext_y":
return true;

// Get/SetAppearanceVar doesn't handle filters right now
Expand Down Expand Up @@ -391,6 +396,24 @@ public void SetAppearanceVar(MutableAppearance appearance, string varName, Dream
appearance.Verbs.Add(verb.VerbId!.Value);
}

break;
case "maptext":
if(value == DreamValue.Null)
appearance.Maptext = null;
else
value.TryGetValueAsString(out appearance.Maptext);
break;
case "maptext_height":
value.TryGetValueAsInteger(out appearance.MaptextSize.Y);
break;
case "maptext_width":
value.TryGetValueAsInteger(out appearance.MaptextSize.X);
break;
case "maptext_x":
value.TryGetValueAsInteger(out appearance.MaptextOffset.X);
break;
case "maptext_y":
value.TryGetValueAsInteger(out appearance.MaptextOffset.Y);
break;
case "appearance":
throw new Exception("Cannot assign the appearance var on an appearance");
Expand Down Expand Up @@ -484,6 +507,18 @@ public DreamValue GetAppearanceVar(ImmutableAppearance appearance, string varNam
transform[1], transform[3], transform[5]);

return new(matrix);
case "maptext":
return (appearance.Maptext != null)
? new DreamValue(appearance.Maptext)
: DreamValue.Null;
case "maptext_height":
return new(appearance.MaptextSize.Y);
case "maptext_width":
return new(appearance.MaptextSize.X);
case "maptext_x":
return new(appearance.MaptextOffset.X);
case "maptext_y":
return new(appearance.MaptextOffset.Y);
case "appearance":
MutableAppearance appearanceCopy = appearance.ToMutable(); // Return a copy
return new(appearanceCopy);
Expand Down
31 changes: 23 additions & 8 deletions OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,16 @@ public static DreamValue NativeProc_animate(NativeProc.Bundle bundle, DreamObjec
/* TODO these are not yet implemented
if(!pixelZ.IsNull)
pixelZ = new(pixelZ.UnsafeGetValueAsFloat() + obj.GetVariable("pixel_z").UnsafeGetValueAsFloat()); //TODO change to appearance when pixel_z is implemented
*/
if(!maptextWidth.IsNull)
maptextWidth = new(maptextWidth.UnsafeGetValueAsFloat() + obj.GetVariable("maptext_width").UnsafeGetValueAsFloat()); //TODO change to appearance when maptext_width is implemented
maptextWidth = new(maptextWidth.UnsafeGetValueAsFloat() + appearance.MaptextSize.X);
if(!maptextHeight.IsNull)
maptextHeight = new(maptextHeight.UnsafeGetValueAsFloat() + obj.GetVariable("maptext_height").UnsafeGetValueAsFloat()); //TODO change to appearance when maptext_height is implemented
maptextHeight = new(maptextHeight.UnsafeGetValueAsFloat() + appearance.MaptextSize.Y);
if(!maptextX.IsNull)
maptextX = new(maptextX.UnsafeGetValueAsFloat() + obj.GetVariable("maptext_x").UnsafeGetValueAsFloat()); //TODO change to appearance when maptext_x is implemented
maptextX = new(maptextX.UnsafeGetValueAsFloat() + appearance.MaptextOffset.X);
if(!maptextY.IsNull)
maptextY = new(maptextY.UnsafeGetValueAsFloat() + obj.GetVariable("maptext_y").UnsafeGetValueAsFloat()); //TODO change to appearance when maptext_y is implemented
maptextY = new(maptextY.UnsafeGetValueAsFloat() + appearance.MaptextOffset.Y);
/*
if(!luminosity.IsNull)
luminosity = new(luminosity.UnsafeGetValueAsFloat() + obj.GetVariable("luminosity").UnsafeGetValueAsFloat()); //TODO change to appearance when luminosity is implemented
*/
Expand Down Expand Up @@ -274,17 +276,30 @@ public static DreamValue NativeProc_animate(NativeProc.Bundle bundle, DreamObjec
}
*/

/* TODO maptext
if (!maptextX.IsNull) {
obj.SetVariableValue("maptext_x", maptextX);
maptextX.TryGetValueAsInteger(out appearance.MapTextOffset.X);
maptextX.TryGetValueAsInteger(out appearance.MaptextOffset.X);
}

if (!maptextY.IsNull) {
obj.SetVariableValue("maptext_y", maptextY);
maptextY.TryGetValueAsInteger(out appearance.MapTextOffset.Y);
maptextY.TryGetValueAsInteger(out appearance.MaptextOffset.Y);
}

if (!maptextWidth.IsNull) {
obj.SetVariableValue("maptext_width", maptextWidth);
maptextX.TryGetValueAsInteger(out appearance.MaptextSize.X);
}

if (!maptextHeight.IsNull) {
obj.SetVariableValue("maptext_y", maptextHeight);
maptextY.TryGetValueAsInteger(out appearance.MaptextSize.Y);
}

if(!maptext.IsNull){
obj.SetVariableValue("maptext", maptext);
maptext.TryGetValueAsString(out appearance.Maptext);
}
*/

if (!dir.IsNull) {
obj.SetVariableValue("dir", dir);
Expand Down
Loading

0 comments on commit 3976b02

Please sign in to comment.