implements PLN-0008

This commit is contained in:
Nilton Constantino 2026-06-21 08:31:14 +01:00
parent f8a8adb80e
commit 28147da443
No known key found for this signature in database
4 changed files with 128 additions and 1 deletions

View File

@ -12,6 +12,10 @@ namespace Editor.GON.StageEditor
public static readonly Color PreviewFill = new(1f, 1f, 1f, 0.18f);
public static readonly Color PreviewStroke = new(1f, 1f, 1f, 0.9f);
public static readonly Color SelectionStroke = new(1f, 0.85f, 0.25f, 1f);
public static readonly Color WorldSyncFootprint = new(1f, 0.1f, 0.95f, 0.42f);
public static readonly Color WorldSyncAnchor = new(0.05f, 0.9f, 1f, 0.48f);
public static readonly Color WorldSyncLift = new(1f, 0.16f, 0.14f, 0.48f);
public static readonly Color WorldSyncSocket = new(1f, 0.9f, 0.12f, 0.9f);
public static Color FromHtml(string html)
{

View File

@ -7,6 +7,7 @@ namespace Editor.GON.StageEditor
public StageLogicalLayer activeLayer = StageLogicalLayer.Structural;
public StagePaletteEntry activePaletteEntry;
public StageObjectDefinition selectedObject;
public bool showWorldSyncUnderlay = true;
public event Action Changed;
@ -37,6 +38,12 @@ namespace Editor.GON.StageEditor
NotifyChanged();
}
public void SetWorldSyncUnderlayVisible(bool visible)
{
showWorldSyncUnderlay = visible;
NotifyChanged();
}
public void NotifyChanged()
{
Changed?.Invoke();

View File

@ -169,6 +169,13 @@ namespace Editor.GON.StageEditor
}
sync.EnsureDefaults();
var underlay = new Toggle("Show Underlay")
{
value = state.showWorldSyncUnderlay
};
underlay.RegisterValueChangedCallback(evt => state.SetWorldSyncUnderlayVisible(evt.newValue));
Add(underlay);
AddReadOnlyLine("World Stage", string.IsNullOrEmpty(sync.worldStageDisplayName)
? sync.worldStageId
: sync.worldStageDisplayName);

View File

@ -1,4 +1,5 @@
using System;
using Intrepid.Gameplay.Journey;
using UnityEngine;
using UnityEngine.UIElements;
@ -495,6 +496,8 @@ namespace Editor.GON.StageEditor
DrawInfiniteGrid(p);
DrawWorldSyncUnderlay(p);
DrawLowerFloors(p);
DrawCells(p, floor, 1f);
@ -504,6 +507,51 @@ namespace Editor.GON.StageEditor
DrawHoverCell(p);
DrawPreview(p);
}
private void DrawWorldSyncUnderlay(Painter2D p)
{
var sync = stage.worldSync;
if (!state.showWorldSyncUnderlay || sync is null || !sync.HasSync)
{
return;
}
sync.EnsureDefaults();
var cellsPerWorldTile = sync.worldTileSize / Mathf.Max(0.01f, stage.cellSize);
if (cellsPerWorldTile <= 0f)
{
return;
}
foreach (var tile in sync.worldTiles)
{
DrawHatching(p, WorldTileRect(tile, cellsPerWorldTile), StageEditorColors.WorldSyncFootprint);
}
foreach (var endpoint in sync.expectedEndpoints)
{
if (endpoint is null)
{
continue;
}
var rect = WorldTileRect(endpoint.worldTile, cellsPerWorldTile);
switch (endpoint.kind)
{
case JEndpointKind.Anchor:
DrawHatching(p, rect.Expanded(-3f), StageEditorColors.WorldSyncAnchor);
break;
case JEndpointKind.Lift:
DrawHatching(p, rect.Expanded(-6f), StageEditorColors.WorldSyncLift);
break;
case JEndpointKind.Socket:
DrawSocketFaceHint(p, rect, endpoint.socketFace);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
private void DrawLowerFloors(Painter2D p)
{
@ -919,6 +967,15 @@ namespace Editor.GON.StageEditor
rect.height * cellPixels);
}
private Rect WorldTileRect(JWorldTile tile, float cellsPerWorldTile)
{
return new Rect(
pan.x + tile.x * cellsPerWorldTile * cellPixels,
pan.y + tile.y * cellsPerWorldTile * cellPixels,
cellsPerWorldTile * cellPixels,
cellsPerWorldTile * cellPixels);
}
private Rect GetResizeHandleRect(StageObjectDefinition obj)
{
var rect = GridRect(obj.Bounds);
@ -960,6 +1017,58 @@ namespace Editor.GON.StageEditor
p.LineTo(b);
p.Stroke();
}
private void DrawHatching(Painter2D p, Rect rect, Color color)
{
if (rect.width <= 0f || rect.height <= 0f)
{
return;
}
StrokeRect(p, rect, color.WithAlpha(Mathf.Min(0.85f, color.a + 0.12f)), 1.5f);
var spacing = Mathf.Clamp(cellPixels * 2f, 10f, 28f);
var width = Mathf.Clamp(cellPixels * 0.08f, 1.25f, 3f);
for (var d = -rect.height; d < rect.width; d += spacing)
{
var start = d < 0f
? new Vector2(rect.xMin, rect.yMin - d)
: new Vector2(rect.xMin + d, rect.yMin);
var end = d + rect.height < rect.width
? new Vector2(rect.xMin + d + rect.height, rect.yMax)
: new Vector2(rect.xMax, rect.yMin + rect.width - d);
DrawLine(p, start, end, color, width);
}
}
private void DrawSocketFaceHint(Painter2D p, Rect rect, JSocketFace face)
{
var color = StageEditorColors.WorldSyncSocket;
var inset = Mathf.Clamp(cellPixels * 0.25f, 4f, 14f);
var width = Mathf.Clamp(cellPixels * 0.16f, 3f, 8f);
switch (face)
{
case JSocketFace.North:
DrawLine(p, new Vector2(rect.xMin + inset, rect.yMin), new Vector2(rect.xMax - inset, rect.yMin),
color, width);
break;
case JSocketFace.South:
DrawLine(p, new Vector2(rect.xMin + inset, rect.yMax), new Vector2(rect.xMax - inset, rect.yMax),
color, width);
break;
case JSocketFace.East:
DrawLine(p, new Vector2(rect.xMax, rect.yMin + inset), new Vector2(rect.xMax, rect.yMax - inset),
color, width);
break;
case JSocketFace.West:
DrawLine(p, new Vector2(rect.xMin, rect.yMin + inset), new Vector2(rect.xMin, rect.yMax - inset),
color, width);
break;
default:
throw new ArgumentOutOfRangeException(nameof(face), face, null);
}
}
}
internal static class StageEditorRectExtensions
@ -975,4 +1084,4 @@ namespace Editor.GON.StageEditor
return color;
}
}
}
}