mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Remove lights component reference (#4316)
This commit is contained in:
@@ -2,11 +2,13 @@ using Robust.Client.GameObjects;
|
||||
using Robust.Shared.ComponentTrees;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Client.ComponentTrees;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class LightTreeComponent: Component, IComponentTreeComponent<PointLightComponent>
|
||||
{
|
||||
[ViewVariables]
|
||||
public DynamicTree<ComponentTreeEntry<PointLightComponent>> Tree { get; set; } = default!;
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.ComponentTrees;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedPointLightComponent))]
|
||||
public sealed partial class PointLightComponent : SharedPointLightComponent, IComponentTreeEntry<PointLightComponent>
|
||||
{
|
||||
public EntityUid? TreeUid { get; set; }
|
||||
|
||||
public DynamicTree<ComponentTreeEntry<PointLightComponent>>? Tree { get; set; }
|
||||
|
||||
public bool AddToTree => Enabled && !ContainerOccluded;
|
||||
public bool TreeUpdateQueued { get; set; }
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[Animatable]
|
||||
public override Color Color
|
||||
{
|
||||
get => _color;
|
||||
set => base.Color = value;
|
||||
}
|
||||
|
||||
[Access(typeof(PointLightSystem))]
|
||||
public bool ContainerOccluded;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the light mask should automatically rotate with the entity. (like a flashlight)
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool MaskAutoRotate
|
||||
{
|
||||
get => _maskAutoRotate;
|
||||
set => _maskAutoRotate = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Local rotation of the light mask around the center origin
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[Animatable]
|
||||
public Angle Rotation
|
||||
{
|
||||
get => _rotation;
|
||||
set => _rotation = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The resource path to the mask texture the light will use.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public string? MaskPath
|
||||
{
|
||||
get => _maskPath;
|
||||
set
|
||||
{
|
||||
if (_maskPath?.Equals(value) != false) return;
|
||||
_maskPath = value;
|
||||
EntitySystem.Get<PointLightSystem>().UpdateMask(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a mask texture that will be applied to the light while rendering.
|
||||
/// The mask's red channel will be linearly multiplied.p
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public Texture? Mask { get; set; }
|
||||
|
||||
[DataField("autoRot")]
|
||||
private bool _maskAutoRotate;
|
||||
private Angle _rotation;
|
||||
|
||||
[DataField("mask")]
|
||||
internal string? _maskPath;
|
||||
}
|
||||
}
|
||||
38
Robust.Client/GameObjects/Components/PointLightComponent.cs
Normal file
38
Robust.Client/GameObjects/Components/PointLightComponent.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.ComponentTrees;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Client.GameObjects;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class PointLightComponent : SharedPointLightComponent, IComponentTreeEntry<PointLightComponent>
|
||||
{
|
||||
#region Component Tree
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public EntityUid? TreeUid { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public DynamicTree<ComponentTreeEntry<PointLightComponent>>? Tree { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public bool AddToTree => Enabled && !ContainerOccluded;
|
||||
|
||||
/// <inheritdoc />
|
||||
[ViewVariables]
|
||||
public bool TreeUpdateQueued { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Set a mask texture that will be applied to the light while rendering.
|
||||
/// The mask's red channel will be linearly multiplied.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
internal Texture? Mask;
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
@@ -24,7 +26,7 @@ namespace Robust.Client.GameObjects
|
||||
int AnimationFrame { get; }
|
||||
bool AutoAnimated { get; set; }
|
||||
|
||||
RSI.State.Direction EffectiveDirection(Angle worldRotation);
|
||||
RsiDirection EffectiveDirection(Angle worldRotation);
|
||||
|
||||
/// <summary>
|
||||
/// Layer size in pixels.
|
||||
|
||||
@@ -12,6 +12,8 @@ using Robust.Shared;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.ComponentTrees;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
@@ -26,8 +28,8 @@ using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using static Robust.Client.ComponentTrees.SpriteTreeSystem;
|
||||
using DrawDepthTag = Robust.Shared.GameObjects.DrawDepth;
|
||||
using RSIDirection = Robust.Client.Graphics.RSI.State.Direction;
|
||||
using static Robust.Shared.Serialization.TypeSerializers.Implementations.SpriteSpecifierSerializer;
|
||||
using Direction = Robust.Shared.Maths.Direction;
|
||||
|
||||
namespace Robust.Client.GameObjects
|
||||
{
|
||||
@@ -1347,11 +1349,11 @@ namespace Robust.Client.GameObjects
|
||||
state = GetFallbackState(resourceCache);
|
||||
}
|
||||
|
||||
return state.Directions switch
|
||||
return state.RsiDirections switch
|
||||
{
|
||||
RSI.State.DirectionType.Dir1 => 1,
|
||||
RSI.State.DirectionType.Dir4 => 4,
|
||||
RSI.State.DirectionType.Dir8 => 8,
|
||||
RsiDirectionType.Dir1 => 1,
|
||||
RsiDirectionType.Dir4 => 4,
|
||||
RsiDirectionType.Dir8 => 8,
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
}
|
||||
@@ -1389,7 +1391,7 @@ namespace Robust.Client.GameObjects
|
||||
builder.AppendFormat(
|
||||
"vis/depth/scl/rot/ofs/col/norot/override/dir: {0}/{1}/{2}/{3}/{4}/{5}/{6}/{8}/{7}\n",
|
||||
Visible, DrawDepth, Scale, Rotation, Offset,
|
||||
Color, NoRotation, entities.GetComponent<TransformComponent>(Owner).WorldRotation.ToRsiDirection(RSI.State.DirectionType.Dir8),
|
||||
Color, NoRotation, entities.GetComponent<TransformComponent>(Owner).WorldRotation.ToRsiDirection(RsiDirectionType.Dir8),
|
||||
DirectionOverride
|
||||
);
|
||||
|
||||
@@ -1689,7 +1691,7 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
int ISpriteLayer.AnimationFrame => AnimationFrame;
|
||||
|
||||
public RSIDirection EffectiveDirection(Angle worldRotation)
|
||||
public RsiDirection EffectiveDirection(Angle worldRotation)
|
||||
{
|
||||
if (State == default)
|
||||
{
|
||||
@@ -1710,23 +1712,23 @@ namespace Robust.Client.GameObjects
|
||||
return default;
|
||||
}
|
||||
|
||||
public RSIDirection EffectiveDirection(RSI.State state, Angle worldRotation,
|
||||
public RsiDirection EffectiveDirection(RSI.State state, Angle worldRotation,
|
||||
Direction? overrideDirection)
|
||||
{
|
||||
if (state.Directions == RSI.State.DirectionType.Dir1)
|
||||
if (state.RsiDirections == RsiDirectionType.Dir1)
|
||||
{
|
||||
return RSIDirection.South;
|
||||
return RsiDirection.South;
|
||||
}
|
||||
else
|
||||
{
|
||||
RSIDirection dir;
|
||||
RsiDirection dir;
|
||||
if (overrideDirection != null)
|
||||
{
|
||||
dir = overrideDirection.Value.Convert(state.Directions);
|
||||
dir = overrideDirection.Value.Convert(state.RsiDirections);
|
||||
}
|
||||
else
|
||||
{
|
||||
dir = worldRotation.ToRsiDirection(state.Directions);
|
||||
dir = worldRotation.ToRsiDirection(state.RsiDirections);
|
||||
}
|
||||
|
||||
return dir.OffsetRsiDir(DirOffset);
|
||||
@@ -1882,20 +1884,20 @@ namespace Robust.Client.GameObjects
|
||||
else if (_parent.SnapCardinals && (!_parent.GranularLayersRendering || RenderingStrategy == LayerRenderingStrategy.UseSpriteStrategy)
|
||||
|| _parent.GranularLayersRendering && RenderingStrategy == LayerRenderingStrategy.SnapToCardinals)
|
||||
{
|
||||
DebugTools.Assert(_actualState == null || _actualState.Directions == RSI.State.DirectionType.Dir1);
|
||||
DebugTools.Assert(_actualState == null || _actualState.RsiDirections == RsiDirectionType.Dir1);
|
||||
size = new Vector2(longestSide, longestSide);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Build the bounding box based on how many directions the sprite has
|
||||
size = (_actualState?.Directions) switch
|
||||
size = (_actualState?.RsiDirections) switch
|
||||
{
|
||||
// If we have four cardinal directions, take the longest side of our texture and square it, then turn that into our bounding box.
|
||||
// This accounts for all possible rotations.
|
||||
RSI.State.DirectionType.Dir4 => new Vector2(longestSide, longestSide),
|
||||
RsiDirectionType.Dir4 => new Vector2(longestSide, longestSide),
|
||||
|
||||
// If we have eight directions, find the maximum length of the texture (accounting for rotation), then square it to make
|
||||
RSI.State.DirectionType.Dir8 => new Vector2(longestRotatedSide, longestRotatedSide),
|
||||
RsiDirectionType.Dir8 => new Vector2(longestRotatedSide, longestRotatedSide),
|
||||
|
||||
// If we have only one direction or an invalid RSI state, create a simple bounding box with the size of the texture.
|
||||
_ => textureSize
|
||||
@@ -1929,9 +1931,9 @@ namespace Robust.Client.GameObjects
|
||||
/// Given the apparent rotation of an entity on screen (world + eye rotation), get layer's matrix for drawing &
|
||||
/// relevant RSI direction.
|
||||
/// </summary>
|
||||
public void GetLayerDrawMatrix(RSIDirection dir, out Matrix3 layerDrawMatrix)
|
||||
public void GetLayerDrawMatrix(RsiDirection dir, out Matrix3 layerDrawMatrix)
|
||||
{
|
||||
if (_parent.NoRotation || dir == RSIDirection.South)
|
||||
if (_parent.NoRotation || dir == RsiDirection.South)
|
||||
layerDrawMatrix = LocalMatrix;
|
||||
else
|
||||
{
|
||||
@@ -1956,11 +1958,11 @@ namespace Robust.Client.GameObjects
|
||||
/// Converts an angle (between 0 and 2pi) to an RSI direction. This will slightly bias the angle to avoid flickering for
|
||||
/// 4-directional sprites.
|
||||
/// </summary>
|
||||
public static RSIDirection GetDirection(RSI.State.DirectionType dirType, Angle angle)
|
||||
public static RsiDirection GetDirection(RsiDirectionType dirType, Angle angle)
|
||||
{
|
||||
if (dirType == RSI.State.DirectionType.Dir1)
|
||||
return RSIDirection.South;
|
||||
else if (dirType == RSI.State.DirectionType.Dir8)
|
||||
if (dirType == RsiDirectionType.Dir1)
|
||||
return RsiDirection.South;
|
||||
else if (dirType == RsiDirectionType.Dir8)
|
||||
return angle.GetDir().Convert(dirType);
|
||||
|
||||
// For 4-directional sprites, as entities are often moving & facing diagonally, we will slightly bias the
|
||||
@@ -1973,10 +1975,10 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
return ((int)Math.Round(modTheta / MathHelper.PiOver2) % 4) switch
|
||||
{
|
||||
0 => RSIDirection.South,
|
||||
1 => RSIDirection.East,
|
||||
2 => RSIDirection.North,
|
||||
_ => RSIDirection.West,
|
||||
0 => RsiDirection.South,
|
||||
1 => RsiDirection.East,
|
||||
2 => RsiDirection.North,
|
||||
_ => RsiDirection.West,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1988,7 +1990,7 @@ namespace Robust.Client.GameObjects
|
||||
if (!Visible || Blank)
|
||||
return;
|
||||
|
||||
var dir = _actualState == null ? RSIDirection.South : GetDirection(_actualState.Directions, angle);
|
||||
var dir = _actualState == null ? RsiDirection.South : GetDirection(_actualState.RsiDirections, angle);
|
||||
|
||||
// Set the drawing transform for this layer
|
||||
GetLayerDrawMatrix(dir, out var layerMatrix);
|
||||
@@ -1998,7 +2000,7 @@ namespace Robust.Client.GameObjects
|
||||
// The direction used to draw the sprite can differ from the one that the angle would naively suggest,
|
||||
// due to direction overrides or offsets.
|
||||
if (overrideDirection != null && _actualState != null)
|
||||
dir = overrideDirection.Value.Convert(_actualState.Directions);
|
||||
dir = overrideDirection.Value.Convert(_actualState.RsiDirections);
|
||||
dir = dir.OffsetRsiDir(DirOffset);
|
||||
|
||||
// Get the correct directional texture from the state, and draw it!
|
||||
@@ -2021,7 +2023,7 @@ namespace Robust.Client.GameObjects
|
||||
drawingHandle.UseShader(null);
|
||||
}
|
||||
|
||||
private Texture GetRenderTexture(RSI.State? state, RSIDirection dir)
|
||||
private Texture GetRenderTexture(RSI.State? state, RsiDirection dir)
|
||||
{
|
||||
if (state == null)
|
||||
return Texture ?? _parent.resourceCache.GetFallback<TextureResource>().Texture;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Robust.Client.ComponentTrees;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
@@ -15,59 +17,108 @@ namespace Robust.Client.GameObjects
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<PointLightComponent, ComponentInit>(HandleInit);
|
||||
SubscribeLocalEvent<PointLightComponent, ComponentHandleState>(OnLightHandleState);
|
||||
}
|
||||
|
||||
private void OnLightHandleState(EntityUid uid, PointLightComponent component, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not PointLightComponentState state)
|
||||
return;
|
||||
|
||||
component.Enabled = state.Enabled;
|
||||
component.Offset = state.Offset;
|
||||
component.Softness = state.Softness;
|
||||
component.CastShadows = state.CastShadows;
|
||||
component.Energy = state.Energy;
|
||||
component.Radius = state.Radius;
|
||||
component.Color = state.Color;
|
||||
}
|
||||
|
||||
public override SharedPointLightComponent EnsureLight(EntityUid uid)
|
||||
{
|
||||
return EnsureComp<PointLightComponent>(uid);
|
||||
}
|
||||
|
||||
public override bool ResolveLight(EntityUid uid, [NotNullWhen(true)] ref SharedPointLightComponent? component)
|
||||
{
|
||||
if (TryComp<PointLightComponent>(uid, out var comp))
|
||||
{
|
||||
component = comp;
|
||||
return true;
|
||||
}
|
||||
|
||||
component = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool TryGetLight(EntityUid uid, [NotNullWhen(true)] out SharedPointLightComponent? component)
|
||||
{
|
||||
if (TryComp<PointLightComponent>(uid, out var comp))
|
||||
{
|
||||
component = comp;
|
||||
return true;
|
||||
}
|
||||
|
||||
component = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool RemoveLightDeferred(EntityUid uid)
|
||||
{
|
||||
return RemCompDeferred<PointLightComponent>(uid);
|
||||
}
|
||||
|
||||
private void HandleInit(EntityUid uid, PointLightComponent component, ComponentInit args)
|
||||
{
|
||||
UpdateMask(component);
|
||||
SetMask(component.MaskPath, component);
|
||||
}
|
||||
|
||||
internal void UpdateMask(PointLightComponent component)
|
||||
public void SetMask(string? maskPath, PointLightComponent component)
|
||||
{
|
||||
if (component._maskPath is not null)
|
||||
component.Mask = _resourceCache.GetResource<TextureResource>(component._maskPath);
|
||||
if (maskPath is not null)
|
||||
component.Mask = _resourceCache.GetResource<TextureResource>(maskPath);
|
||||
else
|
||||
component.Mask = null;
|
||||
}
|
||||
|
||||
#region Setters
|
||||
public void SetContainerOccluded(EntityUid uid, bool occluded, PointLightComponent? comp = null)
|
||||
|
||||
public void SetContainerOccluded(EntityUid uid, bool occluded, SharedPointLightComponent? comp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref comp) || occluded == comp.ContainerOccluded)
|
||||
if (!ResolveLight(uid, ref comp) || occluded == comp.ContainerOccluded || comp is not PointLightComponent clientComp)
|
||||
return;
|
||||
|
||||
comp.ContainerOccluded = occluded;
|
||||
Dirty(uid, comp);
|
||||
|
||||
if (comp.Enabled)
|
||||
_lightTree.QueueTreeUpdate(uid, comp);
|
||||
_lightTree.QueueTreeUpdate(uid, clientComp);
|
||||
}
|
||||
|
||||
public override void SetEnabled(EntityUid uid, bool enabled, SharedPointLightComponent? comp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref comp) || enabled == comp.Enabled)
|
||||
if (!ResolveLight(uid, ref comp) || enabled == comp.Enabled || comp is not PointLightComponent clientComp)
|
||||
return;
|
||||
|
||||
comp._enabled = enabled;
|
||||
comp.Enabled = enabled;
|
||||
RaiseLocalEvent(uid, new PointLightToggleEvent(comp.Enabled));
|
||||
Dirty(uid, comp);
|
||||
|
||||
var cast = (PointLightComponent)comp;
|
||||
if (!cast.ContainerOccluded)
|
||||
_lightTree.QueueTreeUpdate(uid, cast);
|
||||
if (!comp.ContainerOccluded)
|
||||
_lightTree.QueueTreeUpdate(uid, clientComp);
|
||||
}
|
||||
|
||||
public override void SetRadius(EntityUid uid, float radius, SharedPointLightComponent? comp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref comp) || MathHelper.CloseToPercent(radius, comp.Radius))
|
||||
if (!ResolveLight(uid, ref comp) || MathHelper.CloseToPercent(radius, comp.Radius) ||
|
||||
comp is not PointLightComponent clientComp)
|
||||
return;
|
||||
|
||||
comp._radius = radius;
|
||||
comp.Radius = radius;
|
||||
Dirty(uid, comp);
|
||||
|
||||
var cast = (PointLightComponent)comp;
|
||||
if (cast.TreeUid != null)
|
||||
_lightTree.QueueTreeUpdate(uid, cast);
|
||||
if (clientComp.TreeUid != null)
|
||||
_lightTree.QueueTreeUpdate(uid, clientComp);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using JetBrains.Annotations;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenToolkit.Graphics.OpenGL4;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using ES20 = OpenToolkit.Graphics.ES20;
|
||||
|
||||
@@ -19,6 +19,7 @@ using Robust.Client.ComponentTrees;
|
||||
using Robust.Shared.Graphics;
|
||||
using static Robust.Shared.GameObjects.OccluderComponent;
|
||||
using Robust.Shared.Utility;
|
||||
using TextureWrapMode = Robust.Shared.Graphics.TextureWrapMode;
|
||||
using Vector4 = Robust.Shared.Maths.Vector4;
|
||||
|
||||
namespace Robust.Client.Graphics.Clyde
|
||||
|
||||
@@ -5,6 +5,7 @@ using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Maths;
|
||||
using OpenToolkit.Graphics.OpenGL4;
|
||||
using Robust.Shared.Graphics;
|
||||
|
||||
namespace Robust.Client.Graphics.Clyde
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using OpenToolkit.Graphics.OpenGL4;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Numerics;
|
||||
using System.Text;
|
||||
using OpenToolkit.Graphics.OpenGL4;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
@@ -8,6 +8,8 @@ using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using OpenToolkit.Graphics.OpenGL4;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using SixLabors.ImageSharp;
|
||||
@@ -17,6 +19,7 @@ using OGLTextureWrapMode = OpenToolkit.Graphics.OpenGL.TextureWrapMode;
|
||||
using PIF = OpenToolkit.Graphics.OpenGL4.PixelInternalFormat;
|
||||
using PF = OpenToolkit.Graphics.OpenGL4.PixelFormat;
|
||||
using PT = OpenToolkit.Graphics.OpenGL4.PixelType;
|
||||
using TextureWrapMode = Robust.Shared.Graphics.TextureWrapMode;
|
||||
|
||||
namespace Robust.Client.Graphics.Clyde
|
||||
{
|
||||
|
||||
@@ -12,6 +12,7 @@ using Robust.Client.UserInterface;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Log;
|
||||
@@ -21,6 +22,7 @@ using Robust.Shared.Timing;
|
||||
using SixLabors.ImageSharp;
|
||||
using Color = Robust.Shared.Maths.Color;
|
||||
using DependencyAttribute = Robust.Shared.IoC.DependencyAttribute;
|
||||
using TextureWrapMode = Robust.Shared.Graphics.TextureWrapMode;
|
||||
|
||||
namespace Robust.Client.Graphics.Clyde
|
||||
{
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
internal enum ClydeStockTexture : byte
|
||||
{
|
||||
White,
|
||||
Black,
|
||||
Transparent
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Numerics;
|
||||
using System.Text;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
@@ -154,7 +155,7 @@ namespace Robust.Client.Graphics
|
||||
Vector2 scale,
|
||||
Angle? worldRot,
|
||||
Angle eyeRotation = default,
|
||||
Direction? overrideDirection = null,
|
||||
Shared.Maths.Direction? overrideDirection = null,
|
||||
SpriteComponent? sprite = null,
|
||||
TransformComponent? xform = null,
|
||||
SharedTransformSystem? xformSystem = null);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Numerics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.IO;
|
||||
using System.Text;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using SharpFont;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Numerics;
|
||||
using System.Threading.Tasks;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Robust.Shared.Graphics;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Robust.Client.Graphics
|
||||
Vector2 scale,
|
||||
Angle? worldRot,
|
||||
Angle eyeRotation = default,
|
||||
Direction? overrideDirection = null,
|
||||
Shared.Maths.Direction? overrideDirection = null,
|
||||
SpriteComponent? sprite = null,
|
||||
TransformComponent? xform = null,
|
||||
SharedTransformSystem? xformSystem = null);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using Robust.Shared.Graphics;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
namespace Robust.Client.Graphics
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
public interface IRsiStateLike : IDirectionalTextureProvider
|
||||
{
|
||||
RSI.State.DirectionType Directions { get; }
|
||||
RsiDirectionType RsiDirections { get; }
|
||||
bool IsAnimated { get; }
|
||||
int AnimationFrameCount { get; }
|
||||
|
||||
float GetDelay(int frame);
|
||||
Texture GetFrame(RSI.State.Direction dir, int frame);
|
||||
Texture GetFrame(RsiDirection dir, int frame);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using JetBrains.Annotations;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Enums;
|
||||
using System;
|
||||
using Robust.Shared.Graphics;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -25,7 +27,7 @@ namespace Robust.Client.Graphics
|
||||
// 2D array for the texture to use for each animation frame at each direction.
|
||||
public readonly Texture[][] Icons;
|
||||
|
||||
internal State(Vector2i size, RSI rsi, StateId stateId, DirectionType direction, float[] delays, Texture[][] icons)
|
||||
internal State(Vector2i size, RSI rsi, StateId stateId, RsiDirectionType rsiDirection, float[] delays, Texture[][] icons)
|
||||
{
|
||||
DebugTools.Assert(size.X > 0);
|
||||
DebugTools.Assert(size.Y > 0);
|
||||
@@ -34,7 +36,7 @@ namespace Robust.Client.Graphics
|
||||
Size = size;
|
||||
RSI = rsi;
|
||||
StateId = stateId;
|
||||
Directions = direction;
|
||||
RsiDirections = rsiDirection;
|
||||
Delays = delays;
|
||||
TotalDelay = delays.Sum();
|
||||
Icons = icons;
|
||||
@@ -63,7 +65,7 @@ namespace Robust.Client.Graphics
|
||||
/// <summary>
|
||||
/// How many directions this state has.
|
||||
/// </summary>
|
||||
public DirectionType Directions { get; }
|
||||
public RsiDirectionType RsiDirections { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The first frame of the "south" direction.
|
||||
@@ -90,14 +92,14 @@ namespace Robust.Client.Graphics
|
||||
|
||||
int IRsiStateLike.AnimationFrameCount => DelayCount;
|
||||
|
||||
public Texture GetFrame(Direction direction, int frame)
|
||||
public Texture GetFrame(RsiDirection rsiDirection, int frame)
|
||||
{
|
||||
return Icons[(int) direction][frame];
|
||||
return Icons[(int) rsiDirection][frame];
|
||||
}
|
||||
|
||||
public Texture[] GetFrames(Direction direction)
|
||||
public Texture[] GetFrames(RsiDirection rsiDirection)
|
||||
{
|
||||
return Icons[(int) direction];
|
||||
return Icons[(int) rsiDirection];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -124,52 +126,12 @@ namespace Robust.Client.Graphics
|
||||
|
||||
Texture IDirectionalTextureProvider.TextureFor(Shared.Maths.Direction dir)
|
||||
{
|
||||
if (Directions == DirectionType.Dir1)
|
||||
if (RsiDirections == RsiDirectionType.Dir1)
|
||||
{
|
||||
return Frame0;
|
||||
}
|
||||
|
||||
return GetFrame(dir.Convert(Directions), 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies which types of directions an RSI state has.
|
||||
/// </summary>
|
||||
public enum DirectionType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// A single direction, namely South.
|
||||
/// </summary>
|
||||
Dir1,
|
||||
|
||||
/// <summary>
|
||||
/// 4 cardinal directions.
|
||||
/// </summary>
|
||||
Dir4,
|
||||
|
||||
/// <summary>
|
||||
/// 4 cardinal + 4 diagonal directions.
|
||||
/// </summary>
|
||||
Dir8,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies a direction in an RSI state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Value of the enum here matches the index used to store it in the icons array. If this ever changes, then
|
||||
/// <see cref="GameObjects.SpriteComponent.Layer._rsiDirectionMatrices"/> also needs to be updated.
|
||||
/// </remarks>
|
||||
public enum Direction : byte
|
||||
{
|
||||
South = 0,
|
||||
North = 1,
|
||||
East = 2,
|
||||
West = 3,
|
||||
SouthEast = 4,
|
||||
SouthWest = 5,
|
||||
NorthEast = 6,
|
||||
NorthWest = 7,
|
||||
return GetFrame(dir.Convert(RsiDirections), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
@@ -1,233 +1,112 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
using Color = Robust.Shared.Maths.Color;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
namespace Robust.Client.Graphics;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a texture used for drawing things.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public abstract class Texture : IRsiStateLike
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a texture used for drawing things.
|
||||
/// The width of the texture, in pixels.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public abstract class Texture : IRsiStateLike
|
||||
public int Width => Size.X;
|
||||
|
||||
/// <summary>
|
||||
/// The height of the texture, in pixels.
|
||||
/// </summary>
|
||||
public int Height => Size.Y;
|
||||
|
||||
/// <summary>
|
||||
/// The size of the texture, in pixels.
|
||||
/// </summary>
|
||||
public Vector2i Size { get; /*protected set;*/ }
|
||||
|
||||
public Color this[int x, int y] => this.GetPixel(x, y);
|
||||
|
||||
protected Texture(Vector2i size)
|
||||
{
|
||||
/// <summary>
|
||||
/// The width of the texture, in pixels.
|
||||
/// </summary>
|
||||
public int Width => Size.X;
|
||||
Size = size;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The height of the texture, in pixels.
|
||||
/// </summary>
|
||||
public int Height => Size.Y;
|
||||
Texture IDirectionalTextureProvider.Default => this;
|
||||
|
||||
/// <summary>
|
||||
/// The size of the texture, in pixels.
|
||||
/// </summary>
|
||||
public Vector2i Size { get; /*protected set;*/ }
|
||||
Texture IDirectionalTextureProvider.TextureFor(Direction dir)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public Color this[int x, int y] => this.GetPixel(x, y);
|
||||
RsiDirectionType IRsiStateLike.RsiDirections => RsiDirectionType.Dir1;
|
||||
bool IRsiStateLike.IsAnimated => false;
|
||||
int IRsiStateLike.AnimationFrameCount => 0;
|
||||
|
||||
protected Texture(Vector2i size)
|
||||
{
|
||||
Size = size;
|
||||
}
|
||||
float IRsiStateLike.GetDelay(int frame)
|
||||
{
|
||||
if (frame != 0)
|
||||
throw new IndexOutOfRangeException();
|
||||
|
||||
public static Texture Transparent =>
|
||||
IoCManager.Resolve<IClydeInternal>().GetStockTexture(ClydeStockTexture.Transparent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static Texture White =>
|
||||
IoCManager.Resolve<IClydeInternal>().GetStockTexture(ClydeStockTexture.White);
|
||||
Texture IRsiStateLike.GetFrame(RsiDirection dir, int frame)
|
||||
{
|
||||
if (frame != 0)
|
||||
throw new IndexOutOfRangeException();
|
||||
|
||||
public static Texture Black =>
|
||||
IoCManager.Resolve<IClydeInternal>().GetStockTexture(ClydeStockTexture.Black);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads a new texture an existing image.
|
||||
/// </summary>
|
||||
/// <param name="image">The image to load.</param>
|
||||
/// <param name="name">The "name" of this texture. This can be referred to later to aid debugging.</param>
|
||||
/// <param name="loadParameters">
|
||||
/// Parameters that influence the loading of textures.
|
||||
/// Defaults to <see cref="TextureLoadParameters.Default"/> if <c>null</c>.
|
||||
/// </param>
|
||||
/// <typeparam name="T">The type of pixels of the image. At the moment, images must be <see cref="Rgba32"/>.</typeparam>
|
||||
public static Texture LoadFromImage<T>(Image<T> image, string? name = null,
|
||||
TextureLoadParameters? loadParameters = null) where T : unmanaged, IPixel<T>
|
||||
{
|
||||
var manager = IoCManager.Resolve<IClyde>();
|
||||
return manager.LoadTextureFromImage(image, name, loadParameters);
|
||||
}
|
||||
public abstract Color GetPixel(int x, int y);
|
||||
|
||||
/// <summary>
|
||||
/// Loads an image from a stream containing PNG data.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to load the image from.</param>
|
||||
/// <param name="name">The "name" of this texture. This can be referred to later to aid debugging.</param>
|
||||
/// <param name="loadParameters">
|
||||
/// Parameters that influence the loading of textures.
|
||||
/// Defaults to <see cref="TextureLoadParameters.Default"/> if <c>null</c>.
|
||||
/// </param>
|
||||
public static Texture LoadFromPNGStream(Stream stream, string? name = null,
|
||||
TextureLoadParameters? loadParameters = null)
|
||||
{
|
||||
var manager = IoCManager.Resolve<IClyde>();
|
||||
return manager.LoadTextureFromPNGStream(stream, name, loadParameters);
|
||||
}
|
||||
public static Texture Transparent =>
|
||||
IoCManager.Resolve<IClydeInternal>().GetStockTexture(ClydeStockTexture.Transparent);
|
||||
|
||||
Texture IDirectionalTextureProvider.Default => this;
|
||||
public static Texture White =>
|
||||
IoCManager.Resolve<IClydeInternal>().GetStockTexture(ClydeStockTexture.White);
|
||||
|
||||
Texture IDirectionalTextureProvider.TextureFor(Direction dir)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
public static Texture Black =>
|
||||
IoCManager.Resolve<IClydeInternal>().GetStockTexture(ClydeStockTexture.Black);
|
||||
|
||||
RSI.State.DirectionType IRsiStateLike.Directions => RSI.State.DirectionType.Dir1;
|
||||
bool IRsiStateLike.IsAnimated => false;
|
||||
int IRsiStateLike.AnimationFrameCount => 0;
|
||||
|
||||
float IRsiStateLike.GetDelay(int frame)
|
||||
{
|
||||
if (frame != 0)
|
||||
throw new IndexOutOfRangeException();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Texture IRsiStateLike.GetFrame(RSI.State.Direction dir, int frame)
|
||||
{
|
||||
if (frame != 0)
|
||||
throw new IndexOutOfRangeException();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public abstract Color GetPixel(int x, int y);
|
||||
/// <summary>
|
||||
/// Loads a new texture an existing image.
|
||||
/// </summary>
|
||||
/// <param name="image">The image to load.</param>
|
||||
/// <param name="name">The "name" of this texture. This can be referred to later to aid debugging.</param>
|
||||
/// <param name="loadParameters">
|
||||
/// Parameters that influence the loading of textures.
|
||||
/// Defaults to <see cref="Robust.Client.Graphics.TextureLoadParameters.Default"/> if <c>null</c>.
|
||||
/// </param>
|
||||
/// <typeparam name="T">The type of pixels of the image. At the moment, images must be <see cref="Rgba32"/>.</typeparam>
|
||||
public static Texture LoadFromImage<T>(Image<T> image, string? name = null,
|
||||
TextureLoadParameters? loadParameters = null) where T : unmanaged, IPixel<T>
|
||||
{
|
||||
var manager = IoCManager.Resolve<IClyde>();
|
||||
return manager.LoadTextureFromImage(image, name, loadParameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flags for loading of textures.
|
||||
/// Loads an image from a stream containing PNG data.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public struct TextureLoadParameters
|
||||
/// <param name="stream">The stream to load the image from.</param>
|
||||
/// <param name="name">The "name" of this texture. This can be referred to later to aid debugging.</param>
|
||||
/// <param name="loadParameters">
|
||||
/// Parameters that influence the loading of textures.
|
||||
/// Defaults to <see cref="Robust.Client.Graphics.TextureLoadParameters.Default"/> if <c>null</c>.
|
||||
/// </param>
|
||||
public static Texture LoadFromPNGStream(Stream stream, string? name = null,
|
||||
TextureLoadParameters? loadParameters = null)
|
||||
{
|
||||
/// <summary>
|
||||
/// The default sampling parameters for the texture.
|
||||
/// </summary>
|
||||
public TextureSampleParameters SampleParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, the image data will be treated as sRGB.
|
||||
/// </summary>
|
||||
public bool Srgb { get; set; }
|
||||
|
||||
public static TextureLoadParameters FromYaml(YamlMappingNode yaml)
|
||||
{
|
||||
var loadParams = Default;
|
||||
if (yaml.TryGetNode("sample", out YamlMappingNode? sampleNode))
|
||||
{
|
||||
loadParams.SampleParameters = TextureSampleParameters.FromYaml(sampleNode);
|
||||
}
|
||||
|
||||
if (yaml.TryGetNode("srgb", out var srgb))
|
||||
{
|
||||
loadParams.Srgb = srgb.AsBool();
|
||||
}
|
||||
|
||||
return loadParams;
|
||||
}
|
||||
|
||||
public static readonly TextureLoadParameters Default = new()
|
||||
{
|
||||
SampleParameters = TextureSampleParameters.Default,
|
||||
Srgb = true
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sample flags for textures.
|
||||
/// These are separate from <see cref="TextureLoadParameters"/>,
|
||||
/// because it is possible to create "proxies" to existing textures
|
||||
/// with different sampling parameters than the base texture.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public struct TextureSampleParameters
|
||||
{
|
||||
// NOTE: If somebody is gonna add support for 3D/1D textures, change this doc comment.
|
||||
// See the note on this page for why: https://www.khronos.org/opengl/wiki/Sampler_Object#Filtering
|
||||
/// <summary>
|
||||
/// If true, use bi-linear texture filtering if the texture cannot be rendered 1:1
|
||||
/// </summary>
|
||||
public bool Filter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controls how to wrap the texture if texture coordinates outside 0-1 are accessed.
|
||||
/// </summary>
|
||||
public TextureWrapMode WrapMode { get; set; }
|
||||
|
||||
public static TextureSampleParameters FromYaml(YamlMappingNode node)
|
||||
{
|
||||
var wrap = TextureWrapMode.None;
|
||||
var filter = false;
|
||||
|
||||
if (node.TryGetNode("filter", out var filterNode))
|
||||
{
|
||||
filter = filterNode.AsBool();
|
||||
}
|
||||
|
||||
if (node.TryGetNode("wrap", out var wrapNode))
|
||||
{
|
||||
switch (wrapNode.AsString())
|
||||
{
|
||||
case "none":
|
||||
wrap = TextureWrapMode.None;
|
||||
break;
|
||||
case "repeat":
|
||||
wrap = TextureWrapMode.Repeat;
|
||||
break;
|
||||
case "mirrored_repeat":
|
||||
wrap = TextureWrapMode.MirroredRepeat;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Not a valid wrap mode.");
|
||||
}
|
||||
}
|
||||
|
||||
return new TextureSampleParameters {Filter = filter, WrapMode = wrap};
|
||||
}
|
||||
|
||||
public static readonly TextureSampleParameters Default = new()
|
||||
{
|
||||
Filter = false,
|
||||
WrapMode = TextureWrapMode.None
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Controls behavior when reading texture coordinates outside 0-1, which usually wraps the texture somehow.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public enum TextureWrapMode : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Do not wrap, instead clamp to edge.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Repeat the texture.
|
||||
/// </summary>
|
||||
Repeat,
|
||||
|
||||
/// <summary>
|
||||
/// Repeat the texture mirrored.
|
||||
/// </summary>
|
||||
MirroredRepeat,
|
||||
var manager = IoCManager.Resolve<IClyde>();
|
||||
return manager.LoadTextureFromPNGStream(stream, name, loadParameters);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using Robust.Shared.Enums;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Direction = Robust.Shared.Maths.Direction;
|
||||
|
||||
namespace Robust.Client.Map;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ using Robust.Client.Player;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Input.Binding;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -20,6 +21,7 @@ using Robust.Shared.Reflection;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.Log;
|
||||
using Direction = Robust.Shared.Maths.Direction;
|
||||
|
||||
namespace Robust.Client.Placement
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
@@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Resources;
|
||||
@@ -116,9 +118,9 @@ namespace Robust.Client.ResourceManagement
|
||||
|
||||
var dirType = stateObject.DirCount switch
|
||||
{
|
||||
1 => RSI.State.DirectionType.Dir1,
|
||||
4 => RSI.State.DirectionType.Dir4,
|
||||
8 => RSI.State.DirectionType.Dir8,
|
||||
1 => RsiDirectionType.Dir1,
|
||||
4 => RsiDirectionType.Dir4,
|
||||
8 => RsiDirectionType.Dir8,
|
||||
_ => throw new InvalidOperationException()
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
@@ -55,9 +55,6 @@
|
||||
<RobustLinkAssemblies Include="TerraFX.Interop.Windows" />
|
||||
<RobustLinkAssemblies Include="OpenToolkit.Graphics" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="GameObjects\Components\Eye\" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\MSBuild\Robust.Properties.targets" />
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -21,7 +23,7 @@ namespace Robust.Client.UserInterface.Controls
|
||||
/// </summary>
|
||||
public TextureRect DisplayRect { get; }
|
||||
|
||||
public RSI.State.Direction RsiDirection { get; } = RSI.State.Direction.South;
|
||||
public RsiDirection RsiDirection { get; } = RsiDirection.South;
|
||||
|
||||
public AnimatedTextureRect()
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Maths;
|
||||
using Timer = Robust.Shared.Timing.Timer;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Client.UserInterface.Controls
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using Direction = Robust.Shared.Maths.Direction;
|
||||
|
||||
namespace Robust.Client.UserInterface.Controls
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Numerics;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Numerics;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.Maths;
|
||||
using static Robust.Client.UserInterface.StylesheetHelpers;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
@@ -1,39 +1,40 @@
|
||||
using System;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.Maths;
|
||||
using static Robust.Client.GameObjects.SpriteComponent;
|
||||
using RSIDirection = Robust.Client.Graphics.RSI.State.Direction;
|
||||
using Direction = Robust.Shared.Maths.Direction;
|
||||
|
||||
namespace Robust.Client.Utility
|
||||
{
|
||||
public static class DirExt
|
||||
{
|
||||
public static Direction Convert(this RSIDirection dir)
|
||||
public static Direction Convert(this RsiDirection dir)
|
||||
{
|
||||
switch (dir)
|
||||
{
|
||||
case RSIDirection.South:
|
||||
case RsiDirection.South:
|
||||
return Direction.South;
|
||||
|
||||
case RSIDirection.North:
|
||||
case RsiDirection.North:
|
||||
return Direction.North;
|
||||
|
||||
case RSIDirection.East:
|
||||
case RsiDirection.East:
|
||||
return Direction.East;
|
||||
|
||||
case RSIDirection.West:
|
||||
case RsiDirection.West:
|
||||
return Direction.West;
|
||||
|
||||
case RSIDirection.SouthEast:
|
||||
case RsiDirection.SouthEast:
|
||||
return Direction.SouthEast;
|
||||
|
||||
case RSIDirection.SouthWest:
|
||||
case RsiDirection.SouthWest:
|
||||
return Direction.SouthWest;
|
||||
|
||||
case RSIDirection.NorthEast:
|
||||
case RsiDirection.NorthEast:
|
||||
return Direction.NorthEast;
|
||||
|
||||
case RSIDirection.NorthWest:
|
||||
case RsiDirection.NorthWest:
|
||||
return Direction.NorthWest;
|
||||
}
|
||||
|
||||
@@ -46,54 +47,54 @@ namespace Robust.Client.Utility
|
||||
/// <param name="dir">The direction to round</param>
|
||||
/// <returns><paramref name="dir"/> if it's a cardinal direction, otherwise either north or
|
||||
/// south.</returns>
|
||||
public static RSIDirection RoundToCardinal(this RSIDirection dir)
|
||||
public static RsiDirection RoundToCardinal(this RsiDirection dir)
|
||||
{
|
||||
switch (dir)
|
||||
{
|
||||
case RSIDirection.NorthEast:
|
||||
case RSIDirection.NorthWest:
|
||||
return RSIDirection.North;
|
||||
case RsiDirection.NorthEast:
|
||||
case RsiDirection.NorthWest:
|
||||
return RsiDirection.North;
|
||||
|
||||
case RSIDirection.SouthEast:
|
||||
case RSIDirection.SouthWest:
|
||||
return RSIDirection.South;
|
||||
case RsiDirection.SouthEast:
|
||||
case RsiDirection.SouthWest:
|
||||
return RsiDirection.South;
|
||||
|
||||
default:
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
|
||||
public static RSIDirection Convert(this Direction dir, RSI.State.DirectionType type)
|
||||
public static RsiDirection Convert(this Direction dir, RsiDirectionType type)
|
||||
{
|
||||
if (type == RSI.State.DirectionType.Dir1)
|
||||
return RSIDirection.South;
|
||||
if (type == RsiDirectionType.Dir1)
|
||||
return RsiDirection.South;
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case Direction.North:
|
||||
return RSIDirection.North;
|
||||
return RsiDirection.North;
|
||||
|
||||
case Direction.South:
|
||||
return RSIDirection.South;
|
||||
return RsiDirection.South;
|
||||
|
||||
case Direction.East:
|
||||
return RSIDirection.East;
|
||||
return RsiDirection.East;
|
||||
|
||||
case Direction.West:
|
||||
return RSIDirection.West;
|
||||
return RsiDirection.West;
|
||||
}
|
||||
|
||||
var rsiDir = dir switch
|
||||
{
|
||||
Direction.SouthEast => RSIDirection.SouthEast,
|
||||
Direction.SouthWest => RSIDirection.SouthWest,
|
||||
Direction.NorthEast => RSIDirection.NorthEast,
|
||||
Direction.NorthWest => RSIDirection.NorthWest,
|
||||
Direction.SouthEast => RsiDirection.SouthEast,
|
||||
Direction.SouthWest => RsiDirection.SouthWest,
|
||||
Direction.NorthEast => RsiDirection.NorthEast,
|
||||
Direction.NorthWest => RsiDirection.NorthWest,
|
||||
_ => throw new ArgumentException($"Unknown dir: {dir}.", nameof(dir))
|
||||
};
|
||||
|
||||
// Round down to a four-way direction if appropriate.
|
||||
if (type == RSI.State.DirectionType.Dir4)
|
||||
if (type == RsiDirectionType.Dir4)
|
||||
{
|
||||
return RoundToCardinal(rsiDir);
|
||||
}
|
||||
@@ -111,18 +112,18 @@ namespace Robust.Client.Utility
|
||||
return (Direction)(((int)dir + 1) % 8);
|
||||
}
|
||||
|
||||
public static RSIDirection ToRsiDirection(this Angle angle, RSI.State.DirectionType type)
|
||||
public static RsiDirection ToRsiDirection(this Angle angle, RsiDirectionType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
RSI.State.DirectionType.Dir1 => RSIDirection.South,
|
||||
RSI.State.DirectionType.Dir4 => angle.GetCardinalDir().Convert(type),
|
||||
RSI.State.DirectionType.Dir8 => angle.GetDir().Convert(type),
|
||||
RsiDirectionType.Dir1 => RsiDirection.South,
|
||||
RsiDirectionType.Dir4 => angle.GetCardinalDir().Convert(type),
|
||||
RsiDirectionType.Dir8 => angle.GetDir().Convert(type),
|
||||
_ => throw new ArgumentOutOfRangeException($"Unknown rsi direction type: {type}.", nameof(type))
|
||||
};
|
||||
}
|
||||
|
||||
public static RSIDirection OffsetRsiDir(this RSIDirection dir, DirectionOffset offset)
|
||||
public static RsiDirection OffsetRsiDir(this RsiDirection dir, DirectionOffset offset)
|
||||
{
|
||||
// There is probably a better way to do this.
|
||||
// Eh.
|
||||
@@ -136,32 +137,32 @@ namespace Robust.Client.Utility
|
||||
case DirectionOffset.Clockwise:
|
||||
return dir switch
|
||||
{
|
||||
RSIDirection.North => RSIDirection.East,
|
||||
RSIDirection.East => RSIDirection.South,
|
||||
RSIDirection.South => RSIDirection.West,
|
||||
RSIDirection.West => RSIDirection.North,
|
||||
RsiDirection.North => RsiDirection.East,
|
||||
RsiDirection.East => RsiDirection.South,
|
||||
RsiDirection.South => RsiDirection.West,
|
||||
RsiDirection.West => RsiDirection.North,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
case DirectionOffset.CounterClockwise:
|
||||
return dir switch
|
||||
{
|
||||
RSIDirection.North => RSIDirection.West,
|
||||
RSIDirection.East => RSIDirection.North,
|
||||
RSIDirection.South => RSIDirection.East,
|
||||
RSIDirection.West => RSIDirection.South,
|
||||
RsiDirection.North => RsiDirection.West,
|
||||
RsiDirection.East => RsiDirection.North,
|
||||
RsiDirection.South => RsiDirection.East,
|
||||
RsiDirection.West => RsiDirection.South,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
case DirectionOffset.Flip:
|
||||
switch (dir)
|
||||
{
|
||||
case RSIDirection.North:
|
||||
return RSIDirection.South;
|
||||
case RSIDirection.East:
|
||||
return RSIDirection.West;
|
||||
case RSIDirection.South:
|
||||
return RSIDirection.North;
|
||||
case RSIDirection.West:
|
||||
return RSIDirection.East;
|
||||
case RsiDirection.North:
|
||||
return RsiDirection.South;
|
||||
case RsiDirection.East:
|
||||
return RsiDirection.West;
|
||||
case RsiDirection.South:
|
||||
return RsiDirection.North;
|
||||
case RsiDirection.West:
|
||||
return RsiDirection.East;
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Robust.Server.GameObjects
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedPointLightComponent))]
|
||||
public sealed partial class PointLightComponent : SharedPointLightComponent {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Robust.Server.GameObjects;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class PointLightComponent : SharedPointLightComponent
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,9 +1,62 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Robust.Server.GameObjects
|
||||
namespace Robust.Server.GameObjects;
|
||||
|
||||
public sealed class PointLightSystem : SharedPointLightSystem
|
||||
{
|
||||
public sealed class PointLightSystem : SharedPointLightSystem
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<PointLightComponent, ComponentGetState>(OnLightGetState);
|
||||
}
|
||||
|
||||
private void OnLightGetState(EntityUid uid, PointLightComponent component, ref ComponentGetState args)
|
||||
{
|
||||
args.State = new PointLightComponentState()
|
||||
{
|
||||
Color = component.Color,
|
||||
Enabled = component.Enabled,
|
||||
Energy = component.Energy,
|
||||
Offset = component.Offset,
|
||||
Radius = component.Radius,
|
||||
Softness = component.Softness,
|
||||
CastShadows = component.CastShadows,
|
||||
};
|
||||
}
|
||||
|
||||
public override SharedPointLightComponent EnsureLight(EntityUid uid)
|
||||
{
|
||||
return EnsureComp<PointLightComponent>(uid);
|
||||
}
|
||||
|
||||
public override bool ResolveLight(EntityUid uid, [NotNullWhen(true)] ref SharedPointLightComponent? component)
|
||||
{
|
||||
if (TryComp<PointLightComponent>(uid, out var comp))
|
||||
{
|
||||
component = comp;
|
||||
return true;
|
||||
}
|
||||
|
||||
component = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool TryGetLight(EntityUid uid, [NotNullWhen(true)] out SharedPointLightComponent? component)
|
||||
{
|
||||
if (TryComp<PointLightComponent>(uid, out var comp))
|
||||
{
|
||||
component = comp;
|
||||
return true;
|
||||
}
|
||||
|
||||
component = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool RemoveLightDeferred(EntityUid uid)
|
||||
{
|
||||
return RemCompDeferred<PointLightComponent>(uid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,24 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
namespace Robust.Shared.GameObjects;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class PointLightComponentState : ComponentState
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class PointLightComponentState : ComponentState
|
||||
{
|
||||
public readonly Color Color;
|
||||
public Color Color;
|
||||
|
||||
public readonly float Energy;
|
||||
public float Energy;
|
||||
|
||||
public readonly float Softness;
|
||||
public readonly bool Enabled;
|
||||
public readonly bool CastShadows;
|
||||
public float Softness;
|
||||
|
||||
public readonly float Radius;
|
||||
public readonly Vector2 Offset;
|
||||
public bool CastShadows;
|
||||
|
||||
public PointLightComponentState(bool enabled, Color color, float radius, Vector2 offset, float energy, float softness, bool castShadows)
|
||||
{
|
||||
Enabled = enabled;
|
||||
Color = color;
|
||||
Radius = radius;
|
||||
Offset = offset;
|
||||
Energy = energy;
|
||||
Softness = softness;
|
||||
CastShadows = castShadows;
|
||||
}
|
||||
}
|
||||
public bool Enabled;
|
||||
|
||||
public float Radius;
|
||||
|
||||
public Vector2 Offset;
|
||||
}
|
||||
|
||||
@@ -1,121 +1,77 @@
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
{
|
||||
[NetworkedComponent]
|
||||
[NetworkedComponent, Access(typeof(SharedPointLightSystem))]
|
||||
public abstract partial class SharedPointLightComponent : Component
|
||||
{
|
||||
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
|
||||
|
||||
[DataField("color")]
|
||||
protected Color _color = Color.White;
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("color"), AutoNetworkedField]
|
||||
[Animatable]
|
||||
public Color Color { get; set; } = Color.White;
|
||||
|
||||
/// <summary>
|
||||
/// Offset from the center of the entity.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("offset")]
|
||||
protected Vector2 _offset = Vector2.Zero;
|
||||
[Access(Other = AccessPermissions.ReadWriteExecute)]
|
||||
public Vector2 Offset = Vector2.Zero;
|
||||
|
||||
[DataField("energy")]
|
||||
private float _energy = 1f;
|
||||
[DataField("softness")]
|
||||
private float _softness = 1f;
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("energy"), AutoNetworkedField]
|
||||
[Animatable]
|
||||
public float Energy { get; set; } = 1f;
|
||||
|
||||
[DataField("softness"), AutoNetworkedField, Animatable]
|
||||
public float Softness { get; set; } = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this pointlight should cast shadows
|
||||
/// </summary>
|
||||
[DataField("castShadows")]
|
||||
[DataField("castShadows"), AutoNetworkedField]
|
||||
public bool CastShadows = true;
|
||||
|
||||
[Access(typeof(SharedPointLightSystem))]
|
||||
[DataField("enabled")]
|
||||
public bool _enabled = true;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[Animatable] // please somebody ECS animations
|
||||
public bool Enabled
|
||||
{
|
||||
get => _enabled;
|
||||
[Obsolete("Use the system's setter")]
|
||||
set => _sysMan.GetEntitySystem<SharedPointLightSystem>().SetEnabled(Owner, value, this);
|
||||
}
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public virtual Color Color
|
||||
{
|
||||
get => _color;
|
||||
set
|
||||
{
|
||||
if (_color.Equals(value)) return;
|
||||
_color = value;
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
[Animatable]
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// How far the light projects.
|
||||
/// </summary>
|
||||
[DataField("radius")]
|
||||
[Access(typeof(SharedPointLightSystem))]
|
||||
public float _radius = 5f;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[Animatable] // please somebody ECS animations
|
||||
public float Radius
|
||||
{
|
||||
get => _radius;
|
||||
[Obsolete("Use the system's setter")]
|
||||
set => _sysMan.GetEntitySystem<SharedPointLightSystem>().SetRadius(Owner, value, this);
|
||||
}
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public Vector2 Offset
|
||||
{
|
||||
get => _offset;
|
||||
set
|
||||
{
|
||||
if (_offset.EqualsApprox(value)) return;
|
||||
_offset = value;
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[Animatable]
|
||||
public float Energy
|
||||
{
|
||||
get => _energy;
|
||||
set
|
||||
{
|
||||
if (_energy.Equals(value)) return;
|
||||
_energy = value;
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
public float Radius { get; set; } = 5f;
|
||||
|
||||
[ViewVariables]
|
||||
public bool ContainerOccluded;
|
||||
|
||||
/// <summary>
|
||||
/// Soft shadow strength multiplier.
|
||||
/// Has no effect if soft shadows are not enabled.
|
||||
/// Determines if the light mask should automatically rotate with the entity. (like a flashlight)
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)] [DataField("autoRot")]
|
||||
public bool MaskAutoRotate;
|
||||
|
||||
/// <summary>
|
||||
/// Local rotation of the light mask around the center origin
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[Animatable]
|
||||
public float Softness
|
||||
{
|
||||
get => _softness;
|
||||
set
|
||||
{
|
||||
if (_softness.Equals(value)) return;
|
||||
_softness = value;
|
||||
Dirty();
|
||||
}
|
||||
}
|
||||
public Angle Rotation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The resource path to the mask texture the light will use.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("mask")]
|
||||
public string? MaskPath;
|
||||
}
|
||||
|
||||
public sealed class PointLightToggleEvent : EntityEventArgs
|
||||
|
||||
@@ -1,52 +1,70 @@
|
||||
using Robust.Shared.GameStates;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
namespace Robust.Shared.GameObjects;
|
||||
|
||||
public abstract class SharedPointLightSystem : EntitySystem
|
||||
{
|
||||
public abstract class SharedPointLightSystem : EntitySystem
|
||||
public abstract SharedPointLightComponent EnsureLight(EntityUid uid);
|
||||
|
||||
public abstract bool ResolveLight(EntityUid uid, [NotNullWhen(true)] ref SharedPointLightComponent? component);
|
||||
|
||||
public abstract bool TryGetLight(EntityUid uid, [NotNullWhen(true)] out SharedPointLightComponent? component);
|
||||
|
||||
public abstract bool RemoveLightDeferred(EntityUid uid);
|
||||
|
||||
public void SetCastShadows(EntityUid uid, bool value, SharedPointLightComponent? comp = null)
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<SharedPointLightComponent, ComponentGetState>(GetCompState);
|
||||
SubscribeLocalEvent<SharedPointLightComponent, ComponentHandleState>(HandleCompState);
|
||||
}
|
||||
if (!ResolveLight(uid, ref comp) || value == comp.CastShadows)
|
||||
return;
|
||||
|
||||
private void GetCompState(EntityUid uid, SharedPointLightComponent component, ref ComponentGetState args)
|
||||
{
|
||||
args.State = new PointLightComponentState(component.Enabled, component.Color, component.Radius, component.Offset, component.Energy, component.Softness, component.CastShadows);
|
||||
}
|
||||
comp.CastShadows = value;
|
||||
Dirty(uid, comp);
|
||||
}
|
||||
|
||||
private void HandleCompState(EntityUid uid, SharedPointLightComponent component, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not PointLightComponentState newState) return;
|
||||
public void SetColor(EntityUid uid, Color value, SharedPointLightComponent? comp = null)
|
||||
{
|
||||
if (!ResolveLight(uid, ref comp) || value == comp.Color)
|
||||
return;
|
||||
|
||||
SetEnabled(uid, newState.Enabled, component);
|
||||
SetRadius(uid, newState.Radius, component);
|
||||
component.Offset = newState.Offset;
|
||||
component.Color = newState.Color;
|
||||
component.Energy = newState.Energy;
|
||||
component.Softness = newState.Softness;
|
||||
component.CastShadows = newState.CastShadows;
|
||||
}
|
||||
comp.Color = value;
|
||||
Dirty(uid, comp);
|
||||
}
|
||||
|
||||
public virtual void SetEnabled(EntityUid uid, bool enabled, SharedPointLightComponent? comp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref comp) || enabled == comp.Enabled)
|
||||
return;
|
||||
public virtual void SetEnabled(EntityUid uid, bool enabled, SharedPointLightComponent? comp = null)
|
||||
{
|
||||
if (!ResolveLight(uid, ref comp) || enabled == comp.Enabled)
|
||||
return;
|
||||
|
||||
comp._enabled = enabled;
|
||||
RaiseLocalEvent(uid, new PointLightToggleEvent(comp.Enabled));
|
||||
Dirty(uid, comp);
|
||||
}
|
||||
comp.Enabled = enabled;
|
||||
RaiseLocalEvent(uid, new PointLightToggleEvent(comp.Enabled));
|
||||
Dirty(uid, comp);
|
||||
}
|
||||
|
||||
public virtual void SetRadius(EntityUid uid, float radius, SharedPointLightComponent? comp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref comp) || MathHelper.CloseToPercent(comp.Radius, radius))
|
||||
return;
|
||||
public void SetEnergy(EntityUid uid, float value, SharedPointLightComponent? comp = null)
|
||||
{
|
||||
if (!ResolveLight(uid, ref comp) || MathHelper.CloseToPercent(comp.Energy, value))
|
||||
return;
|
||||
|
||||
comp._radius = radius;
|
||||
Dirty(uid, comp);
|
||||
}
|
||||
comp.Energy = value;
|
||||
Dirty(uid, comp);
|
||||
}
|
||||
|
||||
public virtual void SetRadius(EntityUid uid, float radius, SharedPointLightComponent? comp = null)
|
||||
{
|
||||
if (!ResolveLight(uid, ref comp) || MathHelper.CloseToPercent(comp.Radius, radius))
|
||||
return;
|
||||
|
||||
comp.Radius = radius;
|
||||
Dirty(uid, comp);
|
||||
}
|
||||
|
||||
public void SetSoftness(EntityUid uid, float value, SharedPointLightComponent? comp = null)
|
||||
{
|
||||
if (!ResolveLight(uid, ref comp) || MathHelper.CloseToPercent(comp.Softness, value))
|
||||
return;
|
||||
|
||||
comp.Softness = value;
|
||||
Dirty(uid, comp);
|
||||
}
|
||||
}
|
||||
|
||||
9
Robust.Shared/Graphics/ClydeStockTexture.cs
Normal file
9
Robust.Shared/Graphics/ClydeStockTexture.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Robust.Shared.Graphics
|
||||
{
|
||||
public enum ClydeStockTexture : byte
|
||||
{
|
||||
White,
|
||||
Black,
|
||||
Transparent
|
||||
}
|
||||
}
|
||||
20
Robust.Shared/Graphics/RSI/RsiDirection.cs
Normal file
20
Robust.Shared/Graphics/RSI/RsiDirection.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace Robust.Shared.Graphics.RSI;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies a direction in an RSI state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Value of the enum here matches the index used to store it in the icons array. If this ever changes, then
|
||||
/// <see cref="Robust.Client.GameObjects.SpriteComponent.Layer._rsiDirectionMatrices"/> also needs to be updated.
|
||||
/// </remarks>
|
||||
public enum RsiDirection : byte
|
||||
{
|
||||
South = 0,
|
||||
North = 1,
|
||||
East = 2,
|
||||
West = 3,
|
||||
SouthEast = 4,
|
||||
SouthWest = 5,
|
||||
NorthEast = 6,
|
||||
NorthWest = 7,
|
||||
}
|
||||
22
Robust.Shared/Graphics/RSI/RsiDirectionType.cs
Normal file
22
Robust.Shared/Graphics/RSI/RsiDirectionType.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace Robust.Shared.Graphics.RSI;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies which types of directions an RSI state has.
|
||||
/// </summary>
|
||||
public enum RsiDirectionType : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// A single direction, namely South.
|
||||
/// </summary>
|
||||
Dir1,
|
||||
|
||||
/// <summary>
|
||||
/// 4 cardinal directions.
|
||||
/// </summary>
|
||||
Dir4,
|
||||
|
||||
/// <summary>
|
||||
/// 4 cardinal + 4 diagonal directions.
|
||||
/// </summary>
|
||||
Dir8,
|
||||
}
|
||||
44
Robust.Shared/Graphics/TextureLoadParameters.cs
Normal file
44
Robust.Shared/Graphics/TextureLoadParameters.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.Shared.Graphics;
|
||||
|
||||
/// <summary>
|
||||
/// Flags for loading of textures.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public struct TextureLoadParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// The default sampling parameters for the texture.
|
||||
/// </summary>
|
||||
public TextureSampleParameters SampleParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, the image data will be treated as sRGB.
|
||||
/// </summary>
|
||||
public bool Srgb { get; set; }
|
||||
|
||||
public static TextureLoadParameters FromYaml(YamlMappingNode yaml)
|
||||
{
|
||||
var loadParams = Default;
|
||||
if (yaml.TryGetNode("sample", out YamlMappingNode? sampleNode))
|
||||
{
|
||||
loadParams.SampleParameters = TextureSampleParameters.FromYaml(sampleNode);
|
||||
}
|
||||
|
||||
if (yaml.TryGetNode("srgb", out var srgb))
|
||||
{
|
||||
loadParams.Srgb = srgb.AsBool();
|
||||
}
|
||||
|
||||
return loadParams;
|
||||
}
|
||||
|
||||
public static readonly TextureLoadParameters Default = new()
|
||||
{
|
||||
SampleParameters = TextureSampleParameters.Default,
|
||||
Srgb = true
|
||||
};
|
||||
}
|
||||
65
Robust.Shared/Graphics/TextureSampleParameters.cs
Normal file
65
Robust.Shared/Graphics/TextureSampleParameters.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.Shared.Graphics;
|
||||
|
||||
/// <summary>
|
||||
/// Sample flags for textures.
|
||||
/// These are separate from <see cref="TextureLoadParameters"/>,
|
||||
/// because it is possible to create "proxies" to existing textures
|
||||
/// with different sampling parameters than the base texture.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public struct TextureSampleParameters
|
||||
{
|
||||
// NOTE: If somebody is gonna add support for 3D/1D textures, change this doc comment.
|
||||
// See the note on this page for why: https://www.khronos.org/opengl/wiki/Sampler_Object#Filtering
|
||||
/// <summary>
|
||||
/// If true, use bi-linear texture filtering if the texture cannot be rendered 1:1
|
||||
/// </summary>
|
||||
public bool Filter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controls how to wrap the texture if texture coordinates outside 0-1 are accessed.
|
||||
/// </summary>
|
||||
public TextureWrapMode WrapMode { get; set; }
|
||||
|
||||
public static TextureSampleParameters FromYaml(YamlMappingNode node)
|
||||
{
|
||||
var wrap = TextureWrapMode.None;
|
||||
var filter = false;
|
||||
|
||||
if (node.TryGetNode("filter", out var filterNode))
|
||||
{
|
||||
filter = filterNode.AsBool();
|
||||
}
|
||||
|
||||
if (node.TryGetNode("wrap", out var wrapNode))
|
||||
{
|
||||
switch (wrapNode.AsString())
|
||||
{
|
||||
case "none":
|
||||
wrap = TextureWrapMode.None;
|
||||
break;
|
||||
case "repeat":
|
||||
wrap = TextureWrapMode.Repeat;
|
||||
break;
|
||||
case "mirrored_repeat":
|
||||
wrap = TextureWrapMode.MirroredRepeat;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Not a valid wrap mode.");
|
||||
}
|
||||
}
|
||||
|
||||
return new TextureSampleParameters {Filter = filter, WrapMode = wrap};
|
||||
}
|
||||
|
||||
public static readonly TextureSampleParameters Default = new()
|
||||
{
|
||||
Filter = false,
|
||||
WrapMode = TextureWrapMode.None
|
||||
};
|
||||
}
|
||||
26
Robust.Shared/Graphics/TextureWrapMode.cs
Normal file
26
Robust.Shared/Graphics/TextureWrapMode.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Robust.Shared.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
/// Controls behavior when reading texture coordinates outside 0-1, which usually wraps the texture somehow.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public enum TextureWrapMode : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Do not wrap, instead clamp to edge.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Repeat the texture.
|
||||
/// </summary>
|
||||
Repeat,
|
||||
|
||||
/// <summary>
|
||||
/// Repeat the texture mirrored.
|
||||
/// </summary>
|
||||
MirroredRepeat,
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Shared.Graphics;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.UnitTesting.Client.Graphics
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Robust.UnitTesting.Shared.Prototypes
|
||||
Assert.That(prototype.Components, Contains.Key("PointLight"));
|
||||
});
|
||||
|
||||
var componentData = prototype.Components["PointLight"].Component as PointLightComponent;
|
||||
var componentData = prototype.Components["PointLight"].Component as SharedPointLightComponent;
|
||||
|
||||
Assert.That(componentData!.NetSyncEnabled, Is.EqualTo(false));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user