mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a440d705f | ||
|
|
5849474022 | ||
|
|
b7d67c0ece | ||
|
|
b04cf71bc0 | ||
|
|
ea87df649a | ||
|
|
dab7a9112f | ||
|
|
d3dc89832a | ||
|
|
3ade9ca447 | ||
|
|
149e9a2613 | ||
|
|
d164148ce2 | ||
|
|
d898b52449 | ||
|
|
dcf7a1e580 | ||
|
|
65c6bb74eb | ||
|
|
d6d88bea91 | ||
|
|
d6467f768a |
@@ -1,4 +1,4 @@
|
||||
<Project>
|
||||
|
||||
<!-- This file automatically reset by Tools/version.py -->
|
||||
<!-- This file automatically reset by Tools/version.py -->
|
||||
|
||||
|
||||
@@ -54,6 +54,52 @@ END TEMPLATE-->
|
||||
*None yet*
|
||||
|
||||
|
||||
## 148.2.0
|
||||
|
||||
### New features
|
||||
|
||||
* `SpinBox.LineEditControl` exposes the underlying `LineEdit`.
|
||||
* Add VV attributes to various fields across overlay and sessions.
|
||||
* Add IsPaused to EntityManager to check if an entity is paused.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
* Fix SetActiveTheme not updating the theme.
|
||||
|
||||
|
||||
## 148.1.0
|
||||
|
||||
### New features
|
||||
|
||||
* Added IgnoreUIChecksComponent that lets entities ignore bound user interface range checks which would normally close the UI.
|
||||
* Add support for F16-F24 keybinds.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
* Fix gamestate bug where PVS is disabled.
|
||||
|
||||
### Other
|
||||
|
||||
* EntityQuery.HasComponent override for nullable entity uids.
|
||||
|
||||
|
||||
## 148.0.0
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Several NuGet dependencies are now private assets.
|
||||
* Added `IViewportControl.PixelToMap()` and `PixelToMapEvent`. These are variants of the existing screen-to-map functions that should account for distortion effects.
|
||||
|
||||
### New features
|
||||
|
||||
* Added several new rich-text tags, including italic and bold-italic.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
* Fixed log messages for unknown components not working due to threaded IoC issues.
|
||||
* Replay recordings no longer record invalid prototype uploads.
|
||||
|
||||
|
||||
## 147.0.0
|
||||
|
||||
### Breaking changes
|
||||
@@ -204,7 +250,7 @@ END TEMPLATE-->
|
||||
* `IHttpClientHolder` holds a shared `HttpClient` for use by content. It has Happy Eyeballs fixed and an appropriate `User-Agent`.
|
||||
* Added `DataNode.ToString()`. Makes it easier to save yaml files and debug code.
|
||||
* Added some cvars to modify discord rich presence icons.
|
||||
* .ogg files now read the `Artist` and `Title` tags and make them available via new fields in `AudioStream`.
|
||||
* .ogg files now read the `Artist` and `Title` tags and make them available via new fields in `AudioStream`.
|
||||
* The default fragment shaders now have access to the local light level (`lowp vec3 lightSample`).
|
||||
* Added `IPrototypeManager.ValidateAllPrototypesSerializable()`, which can be used to check that all currently loaded prototypes can be serialised & deserialised.
|
||||
|
||||
@@ -213,7 +259,7 @@ END TEMPLATE-->
|
||||
* Fix certain debug commands and tools crashing on non-SS14 RobustToolbox games due to a missing font.
|
||||
* Discord rich presence strings are now truncated if they are too long.
|
||||
* Fixed a couple of broadphase/entity-lookup update bugs that were affecting containers and entities attached to other (non-grid/map) entities.
|
||||
* Fixed `INetChannel.Disconnect()` not properly disconnecting clients in integration tests.
|
||||
* Fixed `INetChannel.Disconnect()` not properly disconnecting clients in integration tests.
|
||||
|
||||
### Other
|
||||
|
||||
|
||||
@@ -18,6 +18,15 @@ input-key-F12 = F12
|
||||
input-key-F13 = F13
|
||||
input-key-F14 = F14
|
||||
input-key-F15 = F15
|
||||
input-key-F16 = F16
|
||||
input-key-F17 = F17
|
||||
input-key-F18 = F18
|
||||
input-key-F19 = F19
|
||||
input-key-F20 = F20
|
||||
input-key-F21 = F21
|
||||
input-key-F22 = F22
|
||||
input-key-F23 = F23
|
||||
input-key-F24 = F24
|
||||
input-key-Pause = Pause
|
||||
input-key-Left = Left
|
||||
input-key-Up = Up
|
||||
|
||||
@@ -630,7 +630,7 @@ namespace Robust.Client.Console.Commands
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var mousePos = _eye.ScreenToMap(_input.MouseScreenPosition);
|
||||
var mousePos = _eye.PixelToMap(_input.MouseScreenPosition);
|
||||
|
||||
if (!_map.TryFindGridAt(mousePos, out var gridUid, out var grid))
|
||||
{
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace Robust.Client.Debugging
|
||||
}
|
||||
|
||||
var mouseSpot = _inputManager.MouseScreenPosition;
|
||||
var spot = _eyeManager.ScreenToMap(mouseSpot);
|
||||
var spot = _eyeManager.PixelToMap(mouseSpot);
|
||||
|
||||
if (!_mapManager.TryFindGridAt(spot, out var gridUid, out var grid))
|
||||
{
|
||||
|
||||
@@ -371,7 +371,7 @@ namespace Robust.Client.Debugging
|
||||
if ((_debugPhysicsSystem.Flags & PhysicsDebugFlags.ShapeInfo) != 0x0)
|
||||
{
|
||||
var hoverBodies = new List<PhysicsComponent>();
|
||||
var bounds = Box2.UnitCentered.Translated(_eyeManager.ScreenToMap(mousePos.Position).Position);
|
||||
var bounds = Box2.UnitCentered.Translated(_eyeManager.PixelToMap(mousePos.Position).Position);
|
||||
|
||||
foreach (var physBody in _physicsSystem.GetCollidingEntities(mapId, bounds))
|
||||
{
|
||||
@@ -404,7 +404,7 @@ namespace Robust.Client.Debugging
|
||||
|
||||
if ((_debugPhysicsSystem.Flags & PhysicsDebugFlags.Distance) != 0x0)
|
||||
{
|
||||
var mapPos = _eyeManager.ScreenToMap(mousePos);
|
||||
var mapPos = _eyeManager.PixelToMap(mousePos);
|
||||
|
||||
if (mapPos.MapId != args.MapId)
|
||||
return;
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Robust.Client.Graphics
|
||||
[Dependency] private readonly IClyde _displayManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IUserInterfaceManager _uiManager = default!;
|
||||
private ISawmill _logMill = default!;
|
||||
|
||||
// We default to this when we get set to a null eye.
|
||||
private readonly FixedEye _defaultEye = new();
|
||||
@@ -53,6 +54,7 @@ namespace Robust.Client.Graphics
|
||||
void IEyeManager.Initialize()
|
||||
{
|
||||
MainViewport = _uiManager.MainViewport;
|
||||
_logMill = IoCManager.Resolve<ILogManager>().RootSawmill;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -129,14 +131,14 @@ namespace Robust.Client.Graphics
|
||||
/// <inheritdoc />
|
||||
public ScreenCoordinates CoordinatesToScreen(EntityCoordinates point)
|
||||
{
|
||||
return MapToScreen(point.ToMap(_entityManager));
|
||||
return MapToScreen(point.ToMap(_entityManager, _entityManager.System<SharedTransformSystem>()));
|
||||
}
|
||||
|
||||
public ScreenCoordinates MapToScreen(MapCoordinates point)
|
||||
{
|
||||
if (CurrentEye.Position.MapId != point.MapId)
|
||||
{
|
||||
Logger.Error($"Attempted to convert map coordinates ({point}) to screen coordinates with an eye on another map ({CurrentEye.Position.MapId})");
|
||||
_logMill.Error($"Attempted to convert map coordinates ({point}) to screen coordinates with an eye on another map ({CurrentEye.Position.MapId})");
|
||||
return new(default, WindowId.Invalid);
|
||||
}
|
||||
|
||||
@@ -146,12 +148,10 @@ namespace Robust.Client.Graphics
|
||||
/// <inheritdoc />
|
||||
public MapCoordinates ScreenToMap(ScreenCoordinates point)
|
||||
{
|
||||
var (pos, window) = point;
|
||||
|
||||
if (_uiManager.MouseGetControl(point) is not IViewportControl viewport)
|
||||
return default;
|
||||
|
||||
return viewport.ScreenToMap(pos);
|
||||
return viewport.ScreenToMap(point.Position);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -159,6 +159,21 @@ namespace Robust.Client.Graphics
|
||||
{
|
||||
return MainViewport.ScreenToMap(point);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MapCoordinates PixelToMap(ScreenCoordinates point)
|
||||
{
|
||||
if (_uiManager.MouseGetControl(point) is not IViewportControl viewport)
|
||||
return default;
|
||||
|
||||
return viewport.PixelToMap(point.Position);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MapCoordinates PixelToMap(Vector2 point)
|
||||
{
|
||||
return MainViewport.PixelToMap(point);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CurrentEyeChangedEvent : EntityEventArgs
|
||||
|
||||
@@ -79,6 +79,16 @@ namespace Robust.Client.Graphics
|
||||
/// <returns>Corresponding point in the world.</returns>
|
||||
MapCoordinates ScreenToMap(Vector2 point);
|
||||
|
||||
/// <summary>
|
||||
/// Similar to <see cref="ScreenToMap(ScreenCoordinates)"/>, except it should compensate for the effects of shaders on viewports.
|
||||
/// </summary>
|
||||
MapCoordinates PixelToMap(ScreenCoordinates point);
|
||||
|
||||
/// <summary>
|
||||
/// Similar to <see cref="ScreenToMap(Vector2)"/>, except it should compensate for the effects of shaders on viewports.
|
||||
/// </summary>
|
||||
MapCoordinates PixelToMap(Vector2 point);
|
||||
|
||||
void ClearCurrentEye();
|
||||
void Initialize();
|
||||
}
|
||||
|
||||
@@ -207,6 +207,15 @@ namespace Robust.Client.Graphics.Clyde
|
||||
{GlfwKey.F13, Key.F13},
|
||||
{GlfwKey.F14, Key.F14},
|
||||
{GlfwKey.F15, Key.F15},
|
||||
{GlfwKey.F16, Key.F16},
|
||||
{GlfwKey.F17, Key.F17},
|
||||
{GlfwKey.F18, Key.F18},
|
||||
{GlfwKey.F19, Key.F19},
|
||||
{GlfwKey.F20, Key.F20},
|
||||
{GlfwKey.F21, Key.F21},
|
||||
{GlfwKey.F22, Key.F22},
|
||||
{GlfwKey.F23, Key.F23},
|
||||
{GlfwKey.F24, Key.F24},
|
||||
{GlfwKey.Pause, Key.Pause},
|
||||
{GlfwKey.World1, Key.World1},
|
||||
};
|
||||
|
||||
@@ -191,6 +191,15 @@ internal partial class Clyde
|
||||
MapKey(SDL_SCANCODE_F13, Key.F13);
|
||||
MapKey(SDL_SCANCODE_F14, Key.F14);
|
||||
MapKey(SDL_SCANCODE_F15, Key.F15);
|
||||
MapKey(SDL_SCANCODE_F16, Key.F16);
|
||||
MapKey(SDL_SCANCODE_F17, Key.F17);
|
||||
MapKey(SDL_SCANCODE_F18, Key.F18);
|
||||
MapKey(SDL_SCANCODE_F19, Key.F19);
|
||||
MapKey(SDL_SCANCODE_F20, Key.F20);
|
||||
MapKey(SDL_SCANCODE_F21, Key.F21);
|
||||
MapKey(SDL_SCANCODE_F22, Key.F22);
|
||||
MapKey(SDL_SCANCODE_F23, Key.F23);
|
||||
MapKey(SDL_SCANCODE_F24, Key.F24);
|
||||
MapKey(SDL_SCANCODE_PAUSE, Key.Pause);
|
||||
|
||||
KeyMapReverse = new Dictionary<Key, SDL_Scancode>();
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
@@ -11,6 +12,7 @@ namespace Robust.Client.Graphics
|
||||
{
|
||||
[Dependency] private readonly ILogManager _logMan = default!;
|
||||
|
||||
[ViewVariables]
|
||||
private readonly Dictionary<Type, Overlay> _overlays = new Dictionary<Type, Overlay>();
|
||||
private ISawmill _logger = default!;
|
||||
|
||||
|
||||
@@ -161,6 +161,15 @@ namespace Robust.Client.Input
|
||||
F13,
|
||||
F14,
|
||||
F15,
|
||||
F16,
|
||||
F17,
|
||||
F18,
|
||||
F19,
|
||||
F20,
|
||||
F21,
|
||||
F22,
|
||||
F23,
|
||||
F24,
|
||||
Pause,
|
||||
World1,
|
||||
}
|
||||
|
||||
@@ -532,7 +532,7 @@ namespace Robust.Client.Placement
|
||||
return false;
|
||||
}
|
||||
coordinates = EntityCoordinates.FromMap(MapManager,
|
||||
EyeManager.ScreenToMap(InputManager.MouseScreenPosition));
|
||||
EyeManager.PixelToMap(InputManager.MouseScreenPosition));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace Robust.Client.Placement
|
||||
public IEnumerable<EntityCoordinates> LineCoordinates()
|
||||
{
|
||||
var mouseScreen = pManager.InputManager.MouseScreenPosition;
|
||||
var mousePos = pManager.EyeManager.ScreenToMap(mouseScreen);
|
||||
var mousePos = pManager.EyeManager.PixelToMap(mouseScreen);
|
||||
|
||||
if (mousePos.MapId == MapId.Nullspace)
|
||||
yield break;
|
||||
@@ -165,7 +165,7 @@ namespace Robust.Client.Placement
|
||||
public IEnumerable<EntityCoordinates> GridCoordinates()
|
||||
{
|
||||
var mouseScreen = pManager.InputManager.MouseScreenPosition;
|
||||
var mousePos = pManager.EyeManager.ScreenToMap(mouseScreen);
|
||||
var mousePos = pManager.EyeManager.PixelToMap(mouseScreen);
|
||||
|
||||
if (mousePos.MapId == MapId.Nullspace)
|
||||
yield break;
|
||||
@@ -254,7 +254,7 @@ namespace Robust.Client.Placement
|
||||
|
||||
protected EntityCoordinates ScreenToCursorGrid(ScreenCoordinates coords)
|
||||
{
|
||||
var mapCoords = pManager.EyeManager.ScreenToMap(coords.Position);
|
||||
var mapCoords = pManager.EyeManager.PixelToMap(coords.Position);
|
||||
if (!pManager.MapManager.TryFindGridAt(mapCoords, out var gridUid, out var grid))
|
||||
{
|
||||
return EntityCoordinates.FromMap(pManager.MapManager, mapCoords);
|
||||
|
||||
@@ -3,14 +3,18 @@ using System.Collections.Generic;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Client.Player
|
||||
{
|
||||
public interface IPlayerManager : Shared.Players.ISharedPlayerManager
|
||||
{
|
||||
new IEnumerable<ICommonSession> Sessions { get; }
|
||||
|
||||
[ViewVariables]
|
||||
IReadOnlyDictionary<NetUserId, ICommonSession> SessionsDict { get; }
|
||||
|
||||
[ViewVariables]
|
||||
LocalPlayer? LocalPlayer { get; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,6 +2,7 @@ using Robust.Shared.Enums;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Client.Player
|
||||
{
|
||||
@@ -17,11 +18,14 @@ namespace Robust.Client.Player
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public EntityUid? AttachedEntity { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public NetUserId UserId { get; }
|
||||
|
||||
[ViewVariables]
|
||||
internal string Name { get; set; } = "<Unknown>";
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -31,9 +35,11 @@ namespace Robust.Client.Player
|
||||
set => this.Name = value;
|
||||
}
|
||||
|
||||
[ViewVariables]
|
||||
internal short Ping { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public INetChannel ConnectedClient { get; internal set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -7,6 +7,7 @@ using Robust.Shared.Network;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Threading.Tasks;
|
||||
using Robust.Client.Upload.Commands;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Replays;
|
||||
@@ -250,36 +251,56 @@ public sealed partial class ReplayLoadManager
|
||||
continue;
|
||||
|
||||
message.Messages.RemoveSwap(i);
|
||||
var changed = new Dictionary<Type, HashSet<string>>();
|
||||
_protoMan.LoadString(protoUpload.PrototypeData, true, changed);
|
||||
|
||||
foreach (var (kind, ids) in changed)
|
||||
try
|
||||
{
|
||||
var protos = prototypes[kind];
|
||||
var count = protos.Count;
|
||||
protos.UnionWith(ids);
|
||||
if (!ignoreDuplicates && ids.Count + count != protos.Count)
|
||||
{
|
||||
// An existing prototype was overwritten. Much like for resource uploading, supporting this
|
||||
// requires tracking the last-modified time of prototypes and either resetting or applying
|
||||
// prototype changes when jumping around in time. This also requires reworking how the initial
|
||||
// implicit state data is generated, because we can't simply cache it anymore.
|
||||
// Also, does reloading prototypes in release mode modify existing entities?
|
||||
|
||||
var msg = $"Overwriting an existing prototype! Kind: {kind.Name}. Ids: {string.Join(", ", ids)}";
|
||||
if (_confMan.GetCVar(CVars.ReplayIgnoreErrors))
|
||||
_sawmill.Error(msg);
|
||||
else
|
||||
throw new NotSupportedException(msg);
|
||||
}
|
||||
LoadPrototype(protoUpload.PrototypeData, prototypes, ignoreDuplicates);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e is NotSupportedException || !_confMan.GetCVar(CVars.ReplayIgnoreErrors))
|
||||
throw;
|
||||
|
||||
_protoMan.ResolveResults();
|
||||
_protoMan.ReloadPrototypes(changed);
|
||||
_locMan.ReloadLocalizations();
|
||||
var msg = $"Caught exception while parsing uploaded prototypes in a replay. Exception: {e}";
|
||||
_sawmill.Error(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadPrototype(
|
||||
string data,
|
||||
Dictionary<Type, HashSet<string>> prototypes,
|
||||
bool ignoreDuplicates)
|
||||
{
|
||||
var changed = new Dictionary<Type, HashSet<string>>();
|
||||
_protoMan.LoadString(data, true, changed);
|
||||
|
||||
foreach (var (kind, ids) in changed)
|
||||
{
|
||||
var protos = prototypes[kind];
|
||||
var count = protos.Count;
|
||||
protos.UnionWith(ids);
|
||||
if (!ignoreDuplicates && ids.Count + count != protos.Count)
|
||||
{
|
||||
// An existing prototype was overwritten. Much like for resource uploading, supporting this
|
||||
// requires tracking the last-modified time of prototypes and either resetting or applying
|
||||
// prototype changes when jumping around in time. This also requires reworking how the initial
|
||||
// implicit state data is generated, because we can't simply cache it anymore.
|
||||
// Also, does reloading prototypes in release mode modify existing entities?
|
||||
|
||||
var msg = $"Overwriting an existing prototype! Kind: {kind.Name}. Ids: {string.Join(", ", ids)}";
|
||||
if (_confMan.GetCVar(CVars.ReplayIgnoreErrors))
|
||||
_sawmill.Error(msg);
|
||||
else
|
||||
throw new NotSupportedException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
_protoMan.ResolveResults();
|
||||
_protoMan.ReloadPrototypes(changed);
|
||||
_locMan.ReloadLocalizations();
|
||||
}
|
||||
|
||||
private void UpdateDeletions(NetListAsArray<EntityUid> entityDeletions,
|
||||
Dictionary<EntityUid, EntityState> entStates, HashSet<EntityUid> detached)
|
||||
{
|
||||
|
||||
@@ -10,25 +10,26 @@
|
||||
<RobustILLink>true</RobustILLink>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DiscordRichPresence" Version="1.0.175" />
|
||||
<PackageReference Include="DiscordRichPresence" Version="1.0.175" PrivateAssets="compile" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="6.0.9" />
|
||||
<PackageReference Include="SQLitePCLRaw.provider.sqlite3" Version="2.1.2" Condition="'$(UseSystemSqlite)' == 'True'" />
|
||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.2" Condition="'$(UseSystemSqlite)' != 'True'" />
|
||||
<PackageReference Include="SpaceWizards.NFluidsynth" Version="0.1.1" />
|
||||
<PackageReference Include="NVorbis" Version="0.10.1" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="6.0.9" PrivateAssets="compile" />
|
||||
<PackageReference Include="SQLitePCLRaw.provider.sqlite3" Version="2.1.2" Condition="'$(UseSystemSqlite)' == 'True'" PrivateAssets="compile" />
|
||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.2" Condition="'$(UseSystemSqlite)' != 'True'" PrivateAssets="compile" />
|
||||
<PackageReference Include="SpaceWizards.NFluidsynth" Version="0.1.1" PrivateAssets="compile" />
|
||||
<PackageReference Include="NVorbis" Version="0.10.1" PrivateAssets="compile" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
|
||||
<PackageReference Include="OpenToolkit.Graphics" Version="4.0.0-pre9.1" />
|
||||
<PackageReference Include="OpenTK.OpenAL" Version="4.7.5" />
|
||||
<PackageReference Include="SpaceWizards.SharpFont" Version="1.0.1" />
|
||||
<PackageReference Include="OpenToolkit.Graphics" Version="4.0.0-pre9.1" PrivateAssets="compile" />
|
||||
<PackageReference Include="OpenTK.OpenAL" Version="4.7.5" PrivateAssets="compile" />
|
||||
<PackageReference Include="SpaceWizards.SharpFont" Version="1.0.1" PrivateAssets="compile" />
|
||||
<PackageReference Include="Robust.Natives" Version="0.1.1" />
|
||||
<PackageReference Include="TerraFX.Interop.Windows" Version="10.0.20348-rc2" />
|
||||
<PackageReference Condition="'$(FullRelease)' != 'True'" Include="JetBrains.Profiler.Api" Version="1.2.0" />
|
||||
<PackageReference Include="TerraFX.Interop.Windows" Version="10.0.20348-rc2" PrivateAssets="compile" />
|
||||
<PackageReference Condition="'$(FullRelease)' != 'True'" Include="JetBrains.Profiler.Api" Version="1.2.0" PrivateAssets="compile" />
|
||||
<PackageReference Include="SpaceWizards.Sodium" Version="0.2.1" PrivateAssets="compile" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(EnableClientScripting)' == 'True'">
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="4.0.1" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.0.1" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.0.1" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="4.0.1" PrivateAssets="compile" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.0.1" PrivateAssets="compile" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.0.1" PrivateAssets="compile" />
|
||||
|
||||
<ProjectReference Include="..\Robust.Shared.Scripting\Robust.Shared.Scripting.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace Robust.Client.UserInterface.Controls
|
||||
|
||||
public void AddMessage(FormattedMessage message)
|
||||
{
|
||||
var entry = new RichTextEntry(message, this, _tagManager);
|
||||
var entry = new RichTextEntry(message, this, _tagManager, null);
|
||||
|
||||
entry.Update(_getFont(), _getContentBox().Width, UIScale);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Numerics;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface.RichText;
|
||||
@@ -21,18 +22,18 @@ namespace Robust.Client.UserInterface.Controls
|
||||
IoCManager.InjectDependencies(this);
|
||||
}
|
||||
|
||||
public void SetMessage(FormattedMessage message)
|
||||
public void SetMessage(FormattedMessage message, Type[]? tagsAllowed = null, Color? defaultColor = null)
|
||||
{
|
||||
_message = message;
|
||||
_entry = new RichTextEntry(_message, this, _tagManager);
|
||||
_entry = new RichTextEntry(_message, this, _tagManager, tagsAllowed, defaultColor);
|
||||
InvalidateMeasure();
|
||||
}
|
||||
|
||||
public void SetMessage(string message)
|
||||
public void SetMessage(string message, Type[]? tagsAllowed = null, Color? defaultColor = null)
|
||||
{
|
||||
var msg = new FormattedMessage();
|
||||
msg.AddText(message);
|
||||
SetMessage(msg);
|
||||
SetMessage(msg, tagsAllowed, defaultColor);
|
||||
}
|
||||
|
||||
public string? GetMessage() => _message?.ToMarkup();
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Robust.Client.UserInterface.Controls
|
||||
public const string LeftButtonStyle = "spinbox-left";
|
||||
public const string RightButtonStyle = "spinbox-right";
|
||||
public const string MiddleButtonStyle = "spinbox-middle";
|
||||
private LineEdit _lineEdit;
|
||||
public LineEdit LineEditControl { get; }
|
||||
private List<Button> _leftButtons = new();
|
||||
private List<Button> _rightButtons = new();
|
||||
private int _stepSize = 1;
|
||||
@@ -35,7 +35,7 @@ namespace Robust.Client.UserInterface.Controls
|
||||
return;
|
||||
}
|
||||
_value = value;
|
||||
_lineEdit.Text = value.ToString();
|
||||
LineEditControl.Text = value.ToString();
|
||||
ValueChanged?.Invoke(new ValueChangedEventArgs(value));
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ namespace Robust.Client.UserInterface.Controls
|
||||
return;
|
||||
}
|
||||
_value = value;
|
||||
_lineEdit.Text = value.ToString();
|
||||
LineEditControl.Text = value.ToString();
|
||||
}
|
||||
|
||||
public event Action<ValueChangedEventArgs>? ValueChanged;
|
||||
@@ -62,17 +62,17 @@ namespace Robust.Client.UserInterface.Controls
|
||||
Orientation = LayoutOrientation.Horizontal;
|
||||
MouseFilter = MouseFilterMode.Pass;
|
||||
|
||||
_lineEdit = new LineEdit
|
||||
LineEditControl = new LineEdit
|
||||
{
|
||||
MinSize = new Vector2(40, 0),
|
||||
HorizontalExpand = true
|
||||
};
|
||||
AddChild(_lineEdit);
|
||||
AddChild(LineEditControl);
|
||||
|
||||
Value = 0;
|
||||
|
||||
_lineEdit.IsValid = (str) => int.TryParse(str, out var i) && (IsValid == null || IsValid(i));
|
||||
_lineEdit.OnTextChanged += (args) =>
|
||||
LineEditControl.IsValid = (str) => int.TryParse(str, out var i) && (IsValid == null || IsValid(i));
|
||||
LineEditControl.OnTextChanged += (args) =>
|
||||
{
|
||||
if (int.TryParse(args.Text, out int i))
|
||||
Value = i;
|
||||
@@ -143,8 +143,8 @@ namespace Robust.Client.UserInterface.Controls
|
||||
/// </summary>
|
||||
public bool LineEditDisabled
|
||||
{
|
||||
get => !_lineEdit.Editable;
|
||||
set => _lineEdit.Editable = !value;
|
||||
get => !LineEditControl.Editable;
|
||||
set => LineEditControl.Editable = !value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -185,7 +185,7 @@ namespace Robust.Client.UserInterface.Controls
|
||||
{
|
||||
base.MouseWheel(args);
|
||||
|
||||
if (!_lineEdit.HasKeyboardFocus())
|
||||
if (!LineEditControl.HasKeyboardFocus())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace Robust.Client.UserInterface.CustomControls.DebugMonitorControls
|
||||
EntityCoordinates mouseGridPos;
|
||||
TileRef tile;
|
||||
|
||||
var mouseWorldMap = _eyeManager.ScreenToMap(mouseScreenPos);
|
||||
var mouseWorldMap = _eyeManager.PixelToMap(mouseScreenPos);
|
||||
if (mouseWorldMap == MapCoordinates.Nullspace)
|
||||
return;
|
||||
|
||||
|
||||
@@ -24,6 +24,11 @@ namespace Robust.Client.UserInterface.CustomControls
|
||||
/// </param>
|
||||
MapCoordinates ScreenToMap(Vector2 coords);
|
||||
|
||||
/// <summary>
|
||||
/// Similar to <see cref="ScreenToMap(Vector2)"/>, except it should compensate for the effects of shaders on viewports.
|
||||
/// </summary>
|
||||
MapCoordinates PixelToMap(Vector2 point);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a point on the map to screen coordinates.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.GameObjects;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Robust.Client.UserInterface.CustomControls;
|
||||
|
||||
/// <summary>
|
||||
/// An event used to reverse distortion effects applied by shaders.
|
||||
/// Used to find the map position that visible pixels originate from so that severe distortion shaders do not make interaction nigh-impossible.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct PixelToMapEvent(Vector2 LocalPosition, IViewportControl Control, IClydeViewport Viewport)
|
||||
{
|
||||
/// <summary>
|
||||
/// The local position of the pixel within the <see cref="Control"/> that we are trying to convert to a map position.
|
||||
/// </summary>
|
||||
public readonly Vector2 LocalPosition = LocalPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The original (or WIP) location of the pixel within the <see cref="Control"/> that we are trying to convert to a map position.
|
||||
/// Used as the output of the event.
|
||||
/// </summary>
|
||||
public Vector2 VisiblePosition = LocalPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The control the pixel we are considering is located within.
|
||||
/// </summary>
|
||||
public readonly IViewportControl Control = Control;
|
||||
|
||||
/// <summary>
|
||||
/// The viewport being displayed by the control we are considering.
|
||||
/// </summary>
|
||||
public readonly IClydeViewport Viewport = Viewport;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
@@ -13,8 +14,9 @@ namespace Robust.Client.UserInterface.CustomControls
|
||||
[Virtual]
|
||||
public class ViewportContainer : Control, IViewportControl
|
||||
{
|
||||
private readonly IClyde _displayManager;
|
||||
private readonly IInputManager _inputManager;
|
||||
[Dependency] private readonly IClyde _displayManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IInputManager _inputManager = default!;
|
||||
|
||||
public IClydeViewport? Viewport { get; set; }
|
||||
|
||||
@@ -36,8 +38,7 @@ namespace Robust.Client.UserInterface.CustomControls
|
||||
|
||||
public ViewportContainer()
|
||||
{
|
||||
_displayManager = IoCManager.Resolve<IClyde>();
|
||||
_inputManager = IoCManager.Resolve<IInputManager>();
|
||||
IoCManager.InjectDependencies(this);
|
||||
MouseFilter = MouseFilterMode.Stop;
|
||||
Resized();
|
||||
}
|
||||
@@ -99,8 +100,7 @@ namespace Robust.Client.UserInterface.CustomControls
|
||||
// -- Handlers: In --
|
||||
|
||||
// -- Utils / S2M-M2S Base --
|
||||
|
||||
public MapCoordinates LocalPixelToMap(Vector2 point)
|
||||
public MapCoordinates LocalCoordsToMap(Vector2 point)
|
||||
{
|
||||
if (Viewport == null)
|
||||
return default;
|
||||
@@ -111,6 +111,19 @@ namespace Robust.Client.UserInterface.CustomControls
|
||||
return Viewport.LocalToWorld(point);
|
||||
}
|
||||
|
||||
public MapCoordinates LocalPixelToMap(Vector2 point)
|
||||
{
|
||||
if (Viewport == null)
|
||||
return default;
|
||||
|
||||
// pre-scaler
|
||||
point *= _viewportResolution;
|
||||
var ev = new PixelToMapEvent(point, this, Viewport);
|
||||
_entityManager.EventBus.RaiseEvent(EventSource.Local, ref ev);
|
||||
|
||||
return Viewport.LocalToWorld(ev.VisiblePosition);
|
||||
}
|
||||
|
||||
public Vector2 WorldToLocalPixel(Vector2 point)
|
||||
{
|
||||
if (Viewport?.Eye == null)
|
||||
@@ -127,6 +140,12 @@ namespace Robust.Client.UserInterface.CustomControls
|
||||
// -- Utils / S2M-M2S Extended --
|
||||
|
||||
public MapCoordinates ScreenToMap(Vector2 point)
|
||||
{
|
||||
return LocalCoordsToMap(point - GlobalPixelPosition);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public MapCoordinates PixelToMap(Vector2 point)
|
||||
{
|
||||
return LocalPixelToMap(point - GlobalPixelPosition);
|
||||
}
|
||||
|
||||
29
Robust.Client/UserInterface/RichText/BoldItalicTag.cs
Normal file
29
Robust.Client/UserInterface/RichText/BoldItalicTag.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Client.UserInterface.RichText;
|
||||
|
||||
public sealed class BoldItalicTag : IMarkupTag
|
||||
{
|
||||
public const string BoldItalicFont = "DefaultBoldItalic";
|
||||
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
public string Name => "bolditalic";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void PushDrawContext(MarkupNode node, MarkupDrawingContext context)
|
||||
{
|
||||
var font = FontTag.CreateFont(context.Font, node, _resourceCache, _prototypeManager, BoldItalicFont);
|
||||
context.Font.Push(font);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void PopDrawContext(MarkupNode node, MarkupDrawingContext context)
|
||||
{
|
||||
context.Font.Pop();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Linq;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -14,12 +15,18 @@ public sealed class BoldTag : IMarkupTag
|
||||
|
||||
public string Name => "bold";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void PushDrawContext(MarkupNode node, MarkupDrawingContext context)
|
||||
{
|
||||
var font = FontTag.CreateFont(context.Font, node, _resourceCache, _prototypeManager, BoldFont);
|
||||
var font = FontTag.CreateFont(context.Font, node, _resourceCache, _prototypeManager,
|
||||
context.Tags.Any(static x => x is ItalicTag)
|
||||
? BoldItalicTag.BoldItalicFont
|
||||
: BoldFont
|
||||
);
|
||||
context.Font.Push(font);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void PopDrawContext(MarkupNode node, MarkupDrawingContext context)
|
||||
{
|
||||
context.Font.Pop();
|
||||
|
||||
11
Robust.Client/UserInterface/RichText/BulletTag.cs
Normal file
11
Robust.Client/UserInterface/RichText/BulletTag.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Client.UserInterface.RichText;
|
||||
|
||||
public sealed class BulletTag : IMarkupTag
|
||||
{
|
||||
public string Name => "bullet";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string TextBefore(MarkupNode _) => " · ";
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace Robust.Client.UserInterface.RichText;
|
||||
/// </summary>
|
||||
public sealed class ColorTag : IMarkupTag
|
||||
{
|
||||
private static readonly Color DefaultColor = new(200, 200, 200);
|
||||
public static readonly Color DefaultColor = new(200, 200, 200);
|
||||
|
||||
public string Name => "color";
|
||||
|
||||
|
||||
@@ -14,12 +14,14 @@ namespace Robust.Client.UserInterface.RichText;
|
||||
public sealed class FontTag : IMarkupTag
|
||||
{
|
||||
public const string DefaultFont = "Default";
|
||||
public const int DefaultSize = 12;
|
||||
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
public string Name => "font";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void PushDrawContext(MarkupNode node, MarkupDrawingContext context)
|
||||
{
|
||||
string fontId = node.Value.StringValue ?? DefaultFont;
|
||||
@@ -28,6 +30,7 @@ public sealed class FontTag : IMarkupTag
|
||||
context.Font.Push(font);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void PopDrawContext(MarkupNode node, MarkupDrawingContext context)
|
||||
{
|
||||
context.Font.Pop();
|
||||
@@ -44,7 +47,7 @@ public sealed class FontTag : IMarkupTag
|
||||
IPrototypeManager prototypeManager,
|
||||
string fontId)
|
||||
{
|
||||
var size = 12;
|
||||
var size = DefaultSize;
|
||||
|
||||
if (contextFontStack.TryPeek(out var previousFont))
|
||||
{
|
||||
|
||||
36
Robust.Client/UserInterface/RichText/HeadingTag.cs
Normal file
36
Robust.Client/UserInterface/RichText/HeadingTag.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Client.UserInterface.RichText;
|
||||
|
||||
public sealed class HeadingTag : IMarkupTag
|
||||
{
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
public string Name => "head";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void PushDrawContext(MarkupNode node, MarkupDrawingContext context)
|
||||
{
|
||||
if (!node.Value.TryGetLong(out var levelParam))
|
||||
return;
|
||||
|
||||
var level = Math.Min(Math.Max((int)levelParam, 1), 3);
|
||||
node.Attributes["size"] = new MarkupParameter(
|
||||
(int)Math.Ceiling(FontTag.DefaultSize * 2 / Math.Sqrt(level))
|
||||
);
|
||||
|
||||
var font = FontTag.CreateFont(context.Font, node, _resourceCache, _prototypeManager, BoldTag.BoldFont);
|
||||
context.Font.Push(font);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void PopDrawContext(MarkupNode node, MarkupDrawingContext context)
|
||||
{
|
||||
context.Font.Pop();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Linq;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -11,14 +12,21 @@ public sealed class ItalicTag : IMarkupTag
|
||||
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
public string Name => "italic";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void PushDrawContext(MarkupNode node, MarkupDrawingContext context)
|
||||
{
|
||||
var font = FontTag.CreateFont(context.Font, node, _resourceCache, _prototypeManager, ItalicFont);
|
||||
var font = FontTag.CreateFont(context.Font, node, _resourceCache, _prototypeManager,
|
||||
context.Tags.Any(static x => x is BoldTag)
|
||||
? BoldItalicTag.BoldItalicFont
|
||||
: ItalicFont
|
||||
);
|
||||
context.Font.Push(font);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void PopDrawContext(MarkupNode node, MarkupDrawingContext context)
|
||||
{
|
||||
context.Font.Pop();
|
||||
|
||||
@@ -8,22 +8,26 @@ public sealed class MarkupDrawingContext
|
||||
{
|
||||
public readonly Stack<Color> Color;
|
||||
public readonly Stack<Font> Font;
|
||||
public readonly List<IMarkupTag> Tags;
|
||||
|
||||
public MarkupDrawingContext()
|
||||
{
|
||||
Color = new Stack<Color>();
|
||||
Font = new Stack<Font>();
|
||||
Tags = new List<IMarkupTag>();
|
||||
}
|
||||
|
||||
public MarkupDrawingContext(int capacity)
|
||||
{
|
||||
Color = new Stack<Color>(capacity);
|
||||
Font = new Stack<Font>(capacity);
|
||||
Tags = new List<IMarkupTag>();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Color.Clear();
|
||||
Font.Clear();
|
||||
Tags.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Reflection;
|
||||
using Robust.Shared.Sandboxing;
|
||||
@@ -15,24 +16,29 @@ public sealed class MarkupTagManager
|
||||
/// <summary>
|
||||
/// Tags defined in engine need to be instantiated here because of sandboxing
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, IMarkupTag> _markupTagTypes = new()
|
||||
{
|
||||
{"color", new ColorTag()},
|
||||
{"cmdlink", new CommandLinkTag()},
|
||||
{"font", new FontTag()},
|
||||
{"bold", new BoldTag()},
|
||||
{"italic", new ItalicTag()}
|
||||
};
|
||||
private readonly Dictionary<string, IMarkupTag> _markupTagTypes = new IMarkupTag[] {
|
||||
new BoldItalicTag(),
|
||||
new BoldTag(),
|
||||
new BulletTag(),
|
||||
new ColorTag(),
|
||||
new CommandLinkTag(),
|
||||
new FontTag(),
|
||||
new HeadingTag(),
|
||||
new ItalicTag()
|
||||
}.ToDictionary(x => x.Name.ToLower(), x => x);
|
||||
|
||||
/// <summary>
|
||||
/// A list of <see cref="IMarkupTag"/> types that shouldn't be instantiated through reflection
|
||||
/// </summary>
|
||||
private readonly List<Type> _engineTypes = new()
|
||||
{
|
||||
typeof(BoldItalicTag),
|
||||
typeof(BoldTag),
|
||||
typeof(BulletTag),
|
||||
typeof(ColorTag),
|
||||
typeof(CommandLinkTag),
|
||||
typeof(FontTag),
|
||||
typeof(BoldTag),
|
||||
typeof(HeadingTag),
|
||||
typeof(ItalicTag)
|
||||
};
|
||||
|
||||
@@ -59,9 +65,11 @@ public sealed class MarkupTagManager
|
||||
return _markupTagTypes.GetValueOrDefault(name);
|
||||
}
|
||||
|
||||
public bool TryGetMarkupTag(string name, [NotNullWhen(true)] out IMarkupTag? tag)
|
||||
public bool TryGetMarkupTag(string name, Type[]? tagsAllowed, [NotNullWhen(true)] out IMarkupTag? tag)
|
||||
{
|
||||
if (_markupTagTypes.TryGetValue(name, out var markupTag))
|
||||
if (_markupTagTypes.TryGetValue(name, out var markupTag)
|
||||
// Using a whitelist prevents new tags from sneaking in.
|
||||
&& (tagsAllowed == null || Array.IndexOf(tagsAllowed, markupTag.GetType()) != -1))
|
||||
{
|
||||
tag = markupTag;
|
||||
return true;
|
||||
|
||||
@@ -16,9 +16,9 @@ namespace Robust.Client.UserInterface
|
||||
/// </summary>
|
||||
internal struct RichTextEntry
|
||||
{
|
||||
private static readonly Color DefaultColor = new(200, 200, 200);
|
||||
|
||||
private readonly Color _defaultColor;
|
||||
private readonly MarkupTagManager _tagManager;
|
||||
private readonly Type[]? _tagsAllowed;
|
||||
|
||||
public readonly FormattedMessage Message;
|
||||
|
||||
@@ -39,13 +39,15 @@ namespace Robust.Client.UserInterface
|
||||
|
||||
private readonly Dictionary<int, Control> _tagControls = new();
|
||||
|
||||
public RichTextEntry(FormattedMessage message, Control parent, MarkupTagManager tagManager)
|
||||
public RichTextEntry(FormattedMessage message, Control parent, MarkupTagManager tagManager, Type[]? tagsAllowed = null, Color? defaultColor = null)
|
||||
{
|
||||
Message = message;
|
||||
Height = 0;
|
||||
Width = 0;
|
||||
LineBreaks = default;
|
||||
_defaultColor = defaultColor ?? new(200, 200, 200);
|
||||
_tagManager = tagManager;
|
||||
_tagsAllowed = tagsAllowed;
|
||||
|
||||
var nodeIndex = -1;
|
||||
foreach (var node in Message.Nodes)
|
||||
@@ -55,7 +57,7 @@ namespace Robust.Client.UserInterface
|
||||
if (node.Name == null)
|
||||
continue;
|
||||
|
||||
if (!_tagManager.TryGetMarkupTag(node.Name, out var tag) || !tag.TryGetControl(node, out var control))
|
||||
if (!_tagManager.TryGetMarkupTag(node.Name, _tagsAllowed, out var tag) || !tag.TryGetControl(node, out var control))
|
||||
continue;
|
||||
|
||||
parent.Children.Add(control);
|
||||
@@ -82,7 +84,7 @@ namespace Robust.Client.UserInterface
|
||||
var wordWrap = new WordWrap(maxSizeX);
|
||||
var context = new MarkupDrawingContext();
|
||||
context.Font.Push(defaultFont);
|
||||
context.Color.Push(DefaultColor);
|
||||
context.Color.Push(_defaultColor);
|
||||
|
||||
// Go over every node.
|
||||
// Nodes can change the markup drawing context and return additional text.
|
||||
@@ -171,7 +173,7 @@ namespace Robust.Client.UserInterface
|
||||
float uiScale)
|
||||
{
|
||||
context.Clear();
|
||||
context.Color.Push(DefaultColor);
|
||||
context.Color.Push(_defaultColor);
|
||||
context.Font.Push(defaultFont);
|
||||
|
||||
var globalBreakCounter = 0;
|
||||
@@ -186,7 +188,7 @@ namespace Robust.Client.UserInterface
|
||||
var text = ProcessNode(node, context);
|
||||
if (!context.Color.TryPeek(out var color) || !context.Font.TryPeek(out var font))
|
||||
{
|
||||
color = DefaultColor;
|
||||
color = _defaultColor;
|
||||
font = defaultFont;
|
||||
}
|
||||
|
||||
@@ -226,15 +228,17 @@ namespace Robust.Client.UserInterface
|
||||
return node.Value.StringValue ?? "";
|
||||
|
||||
//Skip the node if there is no markup tag for it.
|
||||
if (!_tagManager.TryGetMarkupTag(node.Name, out var tag))
|
||||
if (!_tagManager.TryGetMarkupTag(node.Name, _tagsAllowed, out var tag))
|
||||
return "";
|
||||
|
||||
if (!node.Closing)
|
||||
{
|
||||
context.Tags.Add(tag);
|
||||
tag.PushDrawContext(node, context);
|
||||
return tag.TextBefore(node);
|
||||
}
|
||||
|
||||
context.Tags.Remove(tag);
|
||||
tag.PopDrawContext(node, context);
|
||||
return tag.TextAfter(node);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ internal partial class UserInterfaceManager
|
||||
public void SetActiveTheme(string themeName)
|
||||
{
|
||||
if (!_themes.TryGetValue(themeName, out var theme) || (theme == CurrentTheme)) return;
|
||||
CurrentTheme = theme;
|
||||
UpdateTheme(theme);
|
||||
}
|
||||
|
||||
public void SetDefaultTheme(string themeId)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Robust.Server.GameObjects;
|
||||
|
||||
/// <summary>
|
||||
/// Lets any entities with this component ignore user interface range checks that would normally
|
||||
/// close the UI automatically.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed class IgnoreUIRangeComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -17,6 +17,8 @@ namespace Robust.Server.GameObjects
|
||||
[Dependency] private readonly IPlayerManager _playerMan = default!;
|
||||
[Dependency] private readonly TransformSystem _xformSys = default!;
|
||||
|
||||
private EntityQuery<IgnoreUIRangeComponent> _ignoreUIRangeQuery;
|
||||
|
||||
private readonly List<IPlayerSession> _sessionCache = new();
|
||||
|
||||
private readonly Dictionary<IPlayerSession, List<BoundUserInterface>> _openInterfaces = new();
|
||||
@@ -30,6 +32,8 @@ namespace Robust.Server.GameObjects
|
||||
SubscribeLocalEvent<ServerUserInterfaceComponent, ComponentInit>(OnUserInterfaceInit);
|
||||
SubscribeLocalEvent<ServerUserInterfaceComponent, ComponentShutdown>(OnUserInterfaceShutdown);
|
||||
_playerMan.PlayerStatusChanged += OnPlayerStatusChanged;
|
||||
|
||||
_ignoreUIRangeQuery = GetEntityQuery<IgnoreUIRangeComponent>();
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
@@ -174,6 +178,9 @@ namespace Robust.Server.GameObjects
|
||||
if (!query.TryGetComponent(session.AttachedEntity, out var xform))
|
||||
continue;
|
||||
|
||||
if (_ignoreUIRangeQuery.HasComponent(session.AttachedEntity))
|
||||
continue;
|
||||
|
||||
if (uiMap != xform.MapID)
|
||||
{
|
||||
CloseUi(ui, session, activeUis);
|
||||
|
||||
@@ -191,7 +191,7 @@ namespace Robust.Server.GameStates
|
||||
|
||||
using (_usageHistogram.WithLabels("Clean Dirty").NewTimer())
|
||||
{
|
||||
_pvs.CleanupDirty(_playerManager.ServerSessions);
|
||||
_pvs.CleanupDirty(players);
|
||||
}
|
||||
|
||||
// keep the deletion history buffers clean
|
||||
|
||||
@@ -13,15 +13,18 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0" PrivateAssets="All" />
|
||||
<PackageReference Include="SpaceWizards.HttpListener" Version="0.1.0" />
|
||||
<!-- -->
|
||||
<PackageReference Include="SpaceWizards.HttpListener" Version="0.1.0" PrivateAssets="compile" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="6.0.9" />
|
||||
<PackageReference Include="SQLitePCLRaw.provider.sqlite3" Version="2.1.4" Condition="'$(UseSystemSqlite)' == 'True'" />
|
||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.4" Condition="'$(UseSystemSqlite)' != 'True'" />
|
||||
<PackageReference Include="SQLitePCLRaw.provider.sqlite3" Version="2.1.4" Condition="'$(UseSystemSqlite)' == 'True'" PrivateAssets="compile" />
|
||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.4" Condition="'$(UseSystemSqlite)' != 'True'" PrivateAssets="compile" />
|
||||
<PackageReference Include="prometheus-net" Version="4.1.1" />
|
||||
<PackageReference Include="Serilog.Sinks.Loki" Version="4.0.0-beta3" />
|
||||
<PackageReference Include="Serilog.Sinks.Loki" Version="4.0.0-beta3" PrivateAssets="compile" />
|
||||
<PackageReference Include="Microsoft.Extensions.Primitives" Version="6.0.0" />
|
||||
<PackageReference Include="prometheus-net.DotNetRuntime" Version="4.2.2" />
|
||||
<PackageReference Include="TerraFX.Interop.Windows" Version="10.0.20348-rc2" PrivateAssets="compile" />
|
||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="6.0.2" PrivateAssets="compile" />
|
||||
<PackageReference Include="SpaceWizards.Sodium" Version="0.2.1" PrivateAssets="compile" />
|
||||
<PackageReference Include="SharpZstd.Interop" Version="1.5.2-beta2" PrivateAssets="compile" />
|
||||
<PackageReference Condition="'$(FullRelease)' != 'True'" Include="JetBrains.Profiler.Api" Version="1.2.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0" PrivateAssets="All" />
|
||||
<PackageReference Condition="'$(TargetFramework)' == 'net472'" Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\MSBuild\Robust.Properties.targets" />
|
||||
|
||||
@@ -1409,6 +1409,13 @@ namespace Robust.Shared.GameObjects
|
||||
return _traitDict.TryGetValue(uid, out var comp) && !comp.Deleted;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[Pure]
|
||||
public bool HasComponent(EntityUid? uid)
|
||||
{
|
||||
return uid != null && HasComponent(uid.Value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[Pure]
|
||||
public bool Resolve(EntityUid uid, [NotNullWhen(true)] ref TComp1? component, bool logMissing = true)
|
||||
|
||||
@@ -661,6 +661,15 @@ namespace Robust.Shared.GameObjects
|
||||
return uid.HasValue && EntityExists(uid.Value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsPaused(EntityUid? uid, MetaDataComponent? metadata = null)
|
||||
{
|
||||
if (uid == null)
|
||||
return false;
|
||||
|
||||
return _metaQuery.Resolve(uid.Value, ref metadata) && metadata.EntityPaused;
|
||||
}
|
||||
|
||||
public bool Deleted(EntityUid uid)
|
||||
{
|
||||
return !_entTraitArray[CompIdx.ArrayIndex<MetaDataComponent>()].TryGetValue(uid, out var comp) || ((MetaDataComponent) comp).EntityDeleted;
|
||||
|
||||
@@ -182,6 +182,12 @@ public partial class EntitySystem
|
||||
|
||||
#region Entity Metadata
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
protected bool IsPaused(EntityUid? uid, MetaDataComponent? metadata = null)
|
||||
{
|
||||
return EntityManager.IsPaused(uid, metadata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks an entity as dirty.
|
||||
/// </summary>
|
||||
|
||||
@@ -134,6 +134,11 @@ namespace Robust.Shared.GameObjects
|
||||
/// </summary>
|
||||
bool EntityExists([NotNullWhen(true)] EntityUid? uid);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if entity is valid and paused.
|
||||
/// </summary>
|
||||
bool IsPaused([NotNullWhen(true)] EntityUid? uid, MetaDataComponent? metadata = null);
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether an entity with the specified ID has been deleted or is nonexistent.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Shared.Network
|
||||
{
|
||||
@@ -28,10 +29,13 @@ namespace Robust.Shared.Network
|
||||
/// On the server, this is the session ID for this client.
|
||||
/// On the client, this is the session ID for the client.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
NetUserId UserId { get; }
|
||||
|
||||
[ViewVariables]
|
||||
string UserName { get; }
|
||||
|
||||
[ViewVariables]
|
||||
LoginType AuthType { get; }
|
||||
|
||||
/// <summary>
|
||||
@@ -47,11 +51,13 @@ namespace Robust.Shared.Network
|
||||
/// <summary>
|
||||
/// Average round trip time in milliseconds between the remote peer and us.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
short Ping { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the channel is currently connected to a remote peer.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
bool IsConnected { get; }
|
||||
|
||||
NetUserData UserData { get; }
|
||||
|
||||
@@ -8,19 +8,19 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.ILVerification" Version="6.0.0" />
|
||||
<PackageReference Include="Nett" Version="0.15.0" />
|
||||
<PackageReference Include="Microsoft.ILVerification" Version="6.0.0" PrivateAssets="compile" />
|
||||
<PackageReference Include="Nett" Version="0.15.0" PrivateAssets="compile" />
|
||||
<PackageReference Include="Pidgin" Version="2.5.0" />
|
||||
<PackageReference Include="prometheus-net" Version="4.1.1" />
|
||||
<PackageReference Include="Robust.Shared.AuthLib" Version="0.1.2" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="YamlDotNet" Version="12.0.0" />
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" PrivateAssets="compile" />
|
||||
<PackageReference Include="Linguini.Bundle" Version="0.1.3" />
|
||||
<PackageReference Include="SharpZstd.Interop" Version="1.5.2-beta2" />
|
||||
<PackageReference Include="SpaceWizards.Sodium" Version="0.2.1" />
|
||||
<PackageReference Include="SharpZstd.Interop" Version="1.5.2-beta2" PrivateAssets="compile" />
|
||||
<PackageReference Include="SpaceWizards.Sodium" Version="0.2.1" PrivateAssets="compile" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
|
||||
<PackageReference Include="TerraFX.Interop.Windows" Version="10.0.20348-rc2" />
|
||||
<PackageReference Include="TerraFX.Interop.Windows" Version="10.0.20348-rc2" PrivateAssets="compile" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Lidgren.Network\Lidgren.Network.csproj" />
|
||||
|
||||
@@ -44,14 +44,20 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
continue;
|
||||
|
||||
case ComponentAvailability.Unknown:
|
||||
Logger.ErrorS(SerializationManager.LogCategory, $"Unknown component '{compType}' in prototype!");
|
||||
dependencies
|
||||
.Resolve<ILogManager>()
|
||||
.GetSawmill(SerializationManager.LogCategory)
|
||||
.Error($"Unknown component '{compType}' in prototype!");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Has this type already been added?
|
||||
if (components.ContainsKey(compType))
|
||||
{
|
||||
Logger.ErrorS(SerializationManager.LogCategory, $"Component of type '{compType}' defined twice in prototype!");
|
||||
dependencies
|
||||
.Resolve<ILogManager>()
|
||||
.GetSawmill(SerializationManager.LogCategory)
|
||||
.Error(SerializationManager.LogCategory, $"Component of type '{compType}' defined twice in prototype!");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,18 +37,22 @@ public abstract class SharedPrototypeLoadManager : IGamePrototypeLoadManager
|
||||
protected virtual void LoadPrototypeData(GamePrototypeLoadMessage message)
|
||||
{
|
||||
var data = message.PrototypeData;
|
||||
LoadedPrototypes.Add(data);
|
||||
_replay.RecordReplayMessage(new ReplayPrototypeUploadMsg { PrototypeData = data });
|
||||
|
||||
// TODO validate yaml before loading?
|
||||
|
||||
var changed = new Dictionary<Type, HashSet<string>>();
|
||||
_prototypeManager.LoadString(data, true, changed);
|
||||
_prototypeManager.ResolveResults();
|
||||
_prototypeManager.ReloadPrototypes(changed);
|
||||
_localizationManager.ReloadLocalizations();
|
||||
|
||||
// Add to replay recording after we have loaded the file, in case it contains bad yaml that throws exceptions.
|
||||
LoadedPrototypes.Add(data);
|
||||
_replay.RecordReplayMessage(new ReplayPrototypeUploadMsg { PrototypeData = data });
|
||||
_sawmill.Info("Loaded adminbus prototype data.");
|
||||
}
|
||||
|
||||
private void OnStartReplayRecording(MappingDataNode metadat, List<object> events)
|
||||
private void OnStartReplayRecording(MappingDataNode metadata, List<object> events)
|
||||
{
|
||||
foreach (var prototype in LoadedPrototypes)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ using Pidgin;
|
||||
using Robust.Shared.Maths;
|
||||
using static Pidgin.Parser;
|
||||
using static Pidgin.Parser<char>;
|
||||
|
||||
namespace Robust.Shared.Utility;
|
||||
|
||||
public sealed partial class FormattedMessage
|
||||
@@ -65,7 +66,7 @@ public sealed partial class FormattedMessage
|
||||
|
||||
//This checks for a backslash and one reserved character
|
||||
private static readonly Parser<char, char> EscapeSequence =
|
||||
Escape.Then(OneOf(Escape, Begin, End, Slash));
|
||||
Try(Escape.Then(OneOf(Escape, Begin, End, Slash)));
|
||||
|
||||
//Parses text by repeatedly parsing escape sequences or any character except [ and \
|
||||
//The result is put into a new markup node representing text (it has no name)
|
||||
|
||||
@@ -10,7 +10,6 @@ using Robust.Shared.Physics.Dynamics;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.UnitTesting.Server.Maps
|
||||
{
|
||||
@@ -59,18 +58,19 @@ entities:
|
||||
[OneTimeSetUp]
|
||||
public void Setup()
|
||||
{
|
||||
// For some reason RobustUnitTest doesn't discover PVSSystem but this does here so ?
|
||||
var syssy = IoCManager.Resolve<IEntitySystemManager>();
|
||||
syssy.Shutdown();
|
||||
syssy.Initialize();
|
||||
|
||||
var compFactory = IoCManager.Resolve<IComponentFactory>();
|
||||
compFactory.RegisterClass<MapDeserializeTestComponent>();
|
||||
compFactory.RegisterClass<VisibilityComponent>();
|
||||
compFactory.RegisterClass<ActorComponent>();
|
||||
compFactory.RegisterClass<IgnoreUIRangeComponent>();
|
||||
compFactory.GenerateNetIds();
|
||||
IoCManager.Resolve<ISerializationManager>().Initialize();
|
||||
|
||||
// For some reason RobustUnitTest doesn't discover PVSSystem but this does here so ?
|
||||
var syssy = IoCManager.Resolve<IEntitySystemManager>();
|
||||
syssy.Shutdown();
|
||||
syssy.Initialize();
|
||||
|
||||
var resourceManager = IoCManager.Resolve<IResourceManagerInternal>();
|
||||
resourceManager.Initialize(null);
|
||||
resourceManager.MountString("/TestMap.yml", MapData);
|
||||
|
||||
@@ -12,7 +12,6 @@ using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Physics.Dynamics;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
using Robust.UnitTesting.Server;
|
||||
using SharpFont.PostScript;
|
||||
|
||||
namespace Robust.UnitTesting.Shared.Physics;
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using NUnit.Framework;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using TerraFX.Interop.Windows;
|
||||
|
||||
namespace Robust.UnitTesting.Shared.Serialization;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user