Files
RobustToolbox/Robust.Server/GameObjects/Components/Renderable/SpriteComponent.cs
T
2021-11-30 15:07:08 +01:00

437 lines
13 KiB
C#

using System;
using System.Collections.Generic;
using Robust.Shared.GameObjects;
using DrawDepthTag = Robust.Shared.GameObjects.DrawDepth;
using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Players;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
namespace Robust.Server.GameObjects
{
[ComponentReference(typeof(SharedSpriteComponent))]
[ComponentReference(typeof(ISpriteRenderableComponent))]
public class SpriteComponent : SharedSpriteComponent, ISpriteRenderableComponent, ISerializationHooks
{
const string LayerSerializationCache = "spritelayersrv";
[ViewVariables]
[DataField("layers", priority: 2, readOnly: true)]
private List<PrototypeLayerData> Layers = new();
[DataField("visible")]
private bool _visible = true;
[DataField("drawdepth", customTypeSerializer: typeof(ConstantSerializer<DrawDepthTag>))]
private int _drawDepth = DrawDepthTag.Default;
[DataField("scale")]
private Vector2 _scale = Vector2.One;
[DataField("offset")]
private Vector2 _offset = Vector2.Zero;
[DataField("color")]
private Color _color = Color.White;
[DataField("sprite")]
private string? _baseRSIPath;
[DataField("rotation")]
private Angle _rotation = Angle.Zero;
[DataField("state")] private string? state;
[DataField("texture")] private string? texture;
[ViewVariables(VVAccess.ReadWrite)]
public int DrawDepth
{
get => _drawDepth;
set
{
if (_drawDepth == value) return;
_drawDepth = value;
Dirty();
}
}
[ViewVariables(VVAccess.ReadWrite)]
public override bool Visible
{
get => _visible;
set
{
if (_visible == value) return;
_visible = value;
Dirty();
}
}
[ViewVariables(VVAccess.ReadWrite)]
public Vector2 Scale
{
get => _scale;
set
{
_scale = value;
Dirty();
}
}
[ViewVariables(VVAccess.ReadWrite)]
public Angle Rotation
{
get => _rotation;
set
{
_rotation = value;
Dirty();
}
}
[ViewVariables(VVAccess.ReadWrite)]
public Vector2 Offset
{
get => _offset;
set
{
_offset = value;
Dirty();
}
}
[ViewVariables(VVAccess.ReadWrite)]
public Color Color
{
get => _color;
set
{
_color = value;
Dirty();
}
}
[ViewVariables(VVAccess.ReadWrite)]
public string? BaseRSIPath
{
get => _baseRSIPath;
set
{
_baseRSIPath = value;
Dirty();
}
}
private uint _renderOrder;
[ViewVariables(VVAccess.ReadWrite)]
public uint RenderOrder
{
get => _renderOrder;
set
{
_renderOrder = value;
Dirty();
}
}
[ViewVariables]
public int LayerCount => Layers.Count;
void ISerializationHooks.AfterDeserialization()
{
if (Layers.Count == 0)
{
if (state != null || texture != null)
{
var layerZeroData = SharedSpriteComponent.PrototypeLayerData.New();
if (!string.IsNullOrWhiteSpace(state))
{
layerZeroData.State = state;
}
if (!string.IsNullOrWhiteSpace(texture))
{
layerZeroData.TexturePath = texture;
}
Layers.Insert(0, layerZeroData);
state = null;
texture = null;
}
}
}
public int AddLayerWithSprite(SpriteSpecifier specifier)
{
var layer = PrototypeLayerData.New();
switch (specifier)
{
case SpriteSpecifier.Texture tex:
layer.TexturePath = tex.TexturePath.ToString();
break;
case SpriteSpecifier.Rsi rsi:
layer.RsiPath = rsi.RsiPath.ToString();
layer.State = rsi.RsiState;
break;
default:
throw new NotImplementedException();
}
Layers.Add(layer);
Dirty();
return Layers.Count - 1;
}
public int AddLayerWithTexture(string texture)
{
var layer = PrototypeLayerData.New();
layer.TexturePath = texture;
Layers.Add(layer);
Dirty();
return Layers.Count - 1;
}
public int AddLayerWithTexture(ResourcePath texture)
{
return AddLayerWithTexture(texture.ToString());
}
public int AddLayerWithState(string stateId)
{
var layer = PrototypeLayerData.New();
layer.State = stateId;
Layers.Add(layer);
Dirty();
return Layers.Count - 1;
}
public int AddLayerWithState(string stateId, string rsiPath)
{
var layer = PrototypeLayerData.New();
layer.State = stateId;
layer.RsiPath = rsiPath;
Layers.Add(layer);
Dirty();
return Layers.Count - 1;
}
public int AddLayerWithState(string stateId, ResourcePath rsiPath)
{
return AddLayerWithState(stateId, rsiPath.ToString());
}
public void RemoveLayer(int layer)
{
if (Layers.Count <= layer)
{
Logger.ErrorS("go.comp.sprite", "Layer with index '{0}' does not exist, cannot remove! Trace:\n{1}",
layer, Environment.StackTrace);
return;
}
Layers.RemoveAt(layer);
Dirty();
}
public void LayerSetShader(int layer, string shaderName)
{
if (Layers.Count <= layer)
{
Logger.ErrorS("go.comp.sprite", "Layer with index '{0}' does not exist, cannot set shader! Trace:\n{1}",
layer, Environment.StackTrace);
return;
}
var thelayer = Layers[layer];
thelayer.Shader = shaderName;
Layers[layer] = thelayer;
Dirty();
}
public void LayerSetSprite(int layer, SpriteSpecifier specifier)
{
if (Layers.Count <= layer)
{
Logger.ErrorS("go.comp.sprite", "Layer with index '{0}' does not exist, cannot set sprite! Trace:\n{1}",
layer, Environment.StackTrace);
return;
}
var thelayer = Layers[layer];
switch (specifier)
{
case SpriteSpecifier.Texture tex:
thelayer.TexturePath = tex.TexturePath.ToString();
thelayer.RsiPath = null;
thelayer.State = null;
break;
case SpriteSpecifier.Rsi rsi:
thelayer.TexturePath = null;
thelayer.RsiPath = rsi.RsiPath.ToString();
thelayer.State = rsi.RsiState;
break;
default:
throw new NotImplementedException();
}
Layers[layer] = thelayer;
Dirty();
}
public void LayerSetTexture(int layer, string texturePath)
{
if (Layers.Count <= layer)
{
Logger.ErrorS("go.comp.sprite",
"Layer with index '{0}' does not exist, cannot set texture! Trace:\n{1}", layer,
Environment.StackTrace);
return;
}
var thelayer = Layers[layer];
thelayer.State = null;
thelayer.TexturePath = texturePath;
Layers[layer] = thelayer;
Dirty();
}
public void LayerSetTexture(int layer, ResourcePath texturePath)
{
LayerSetTexture(layer, texturePath.ToString());
}
public void LayerSetState(int layer, string stateId)
{
if (Layers.Count <= layer)
{
Logger.ErrorS("go.comp.sprite", "Layer with index '{0}' does not exist, cannot set state! Trace:\n{1}",
layer, Environment.StackTrace);
return;
}
var thelayer = Layers[layer];
thelayer.State = stateId;
thelayer.TexturePath = null;
Layers[layer] = thelayer;
Dirty();
}
public void LayerSetState(int layer, string stateId, string rsiPath)
{
if (Layers.Count <= layer)
{
Logger.ErrorS("go.comp.sprite",
"Layer with index '{0}' does not exist, cannot set state & RSI! Trace:\n{1}", layer,
Environment.StackTrace);
return;
}
var thelayer = Layers[layer];
thelayer.RsiPath = rsiPath;
thelayer.State = stateId;
thelayer.TexturePath = null;
Layers[layer] = thelayer;
Dirty();
}
public void LayerSetState(int layer, string stateId, ResourcePath rsiPath)
{
LayerSetState(layer, stateId, rsiPath.ToString());
}
public void LayerSetRSI(int layer, string rsiPath)
{
if (Layers.Count <= layer)
{
Logger.ErrorS("go.comp.sprite", "Layer with index '{0}' does not exist, cannot set RSI! Trace:\n{1}",
layer, Environment.StackTrace);
return;
}
var thelayer = Layers[layer];
thelayer.RsiPath = rsiPath;
Layers[layer] = thelayer;
Dirty();
}
public void LayerSetRSI(int layer, ResourcePath rsiPath)
{
LayerSetRSI(layer, rsiPath.ToString());
}
public void LayerSetScale(int layer, Vector2 scale)
{
if (Layers.Count <= layer)
{
Logger.ErrorS("go.comp.sprite", "Layer with index '{0}' does not exist, cannot set scale! Trace:\n{1}",
layer, Environment.StackTrace);
return;
}
var thelayer = Layers[layer];
thelayer.Scale = scale;
Layers[layer] = thelayer;
Dirty();
}
public void LayerSetRotation(int layer, Angle rotation)
{
if (Layers.Count <= layer)
{
Logger.ErrorS("go.comp.sprite",
"Layer with index '{0}' does not exist, cannot set rotation! Trace:\n{1}", layer,
Environment.StackTrace);
return;
}
var thelayer = Layers[layer];
thelayer.Rotation = rotation;
Layers[layer] = thelayer;
Dirty();
}
public void LayerSetVisible(int layer, bool visible)
{
if (Layers.Count <= layer)
{
Logger.ErrorS("go.comp.sprite",
"Layer with index '{0}' does not exist, cannot set visibility! Trace:\n{1}", layer,
Environment.StackTrace);
return;
}
var thelayer = Layers[layer];
thelayer.Visible = visible;
Layers[layer] = thelayer;
Dirty();
}
public void LayerSetColor(int layer, Color color)
{
if (Layers.Count <= layer)
{
Logger.ErrorS("go.comp.sprite", "Layer with index '{0}' does not exist, cannot set color! Trace:\n{1}",
layer, Environment.StackTrace);
return;
}
var thelayer = Layers[layer];
thelayer.Color = color;
Layers[layer] = thelayer;
Dirty();
}
public override ComponentState GetComponentState()
{
return new SpriteComponentState(Visible, DrawDepth, Scale, Rotation, Offset, Color,
BaseRSIPath, Layers, RenderOrder);
}
}
}