* serv3 in shared pt 1 * beginning of deepclone api * progress in implementing ideepclone & serv3 in content * adds target * its cant hurt you it cant hurt you * more changes to content.server * adds dataclasses * almost there * renamed & edited entry * finishes refactoring content to use serv3 * gasmixture runtimes, next: reagentunit * fucin hell that was an annoying one * adds flags * fixes some yaml errors * removes comment * fixes generic components for now * removes todo actually clones values my god paul fixes bug involving resolving custom data classes from other proj renames dataclass fixes spritecomp adds WithFormat.Constants support * adds deepclone to ResistanceSet * adds a bunch of deepclone implementations adds a deepclone analyzer (TODO) adds a deep clone fallback for classes & structs * fixes a bunch of runtimes * adds deepclone to entityuid * adds generator to sln * gets rid of warnings * fixes * argh * componentdata refactors * more deepclone impl * heck me i reworked all of content deepclone * renames custom dataclasstarget * misc * reworks prototypes * deepclone nuke * renamed customdataclass attribute * fixes everything * misc fixed * the killcommit * getting there * changed yamlfieldattribute namespace * adds back iselfserialize * renames everything to data(field/definition) * ouch * Fix most errors on content * Fix more errors in content * Fix some components * work on tests * fixes some customdataclasses * fuggin shit * yes * yeas * Remove data classes * Data field naming fixes * arg * Git resetti RobustToolbox * Merge fixes * General fixes * Fix startup serialization errors * Fix DamageContainerPrototype when supported classes or types are null * Implement construction graph step type serializer * Fix up construction serialization * Fix up construction serialization part 2 * Fix null list in technology database component * Fix body serialization * Fix entity storage serialization * Fix actions serialization * Fix AI serialization * Fix reaction serialization * Fix body serialization * Fix grid atmosphere serialization * Rename IServ3Manager to ISerializationManager * Convert every non generic serializer to the new format, general fixes * Serialization and body system fix * pushinheritance fix * Update all prototypes to have a parent and have consistent id/parent properties * Merge fixes * smh my head * cuddling slaps * Content commit for engine PR * stuff * more fixes * argh * yes even you are fixed * changelog fixes * fixes seeds * argh * Test fixes * Add writing for alert order prototype * Fix alert order writing * FIX * its been alot ok * Fix the rest of the visualizers * Fix server alerts component tests * Fix alert prototype tests not using the read value * Fix alert prototype tests initializing serialization multiple times * THIS IS AN AMERICAN CODEBASE GOD BLESS THE USA * Add ImplicitDataDefinitionForInheritors to IMechanismBehavior Fixes the behaviors not being found * Fix NRE in strap component Good night to the 1 buckle optimization * Fix clothing component slot flags serialization tag * Fix body component in all components test * Merge fixes * ffs * Make construction graph prototype use serialization hooks * human yaml linted * a * Do the thing for construction * stuff * a * monke see yaml linter * LINT HARDER * Remove redundant todo * yes * Add skip hook argument to readers and copiers * we gamin * test/datafield fixes * adds more verbose validation * moves linter to action * Improve construction graph step type serializer error message * Fix ammo box component NRE * gamin * some updates to the linter * yes * removes that test * misc fixes * array fix priority fix misc fixes * adds proper info the validation * adds alwaysrelevant usa * Make yaml linter take half as long to run (~50% less) * Make yaml linter 5 times faster (~80% less execution time) * based vera being based * fixes mapsaving * warning cleanup & moves surpressor * removes old msbuild targets * Revert "Make yaml linter 5 times faster (~80% less execution time)" This reverts commit 3e6091359a26252c3e98828199553de668031c63. * Add -nowarn to yaml linter run configuration * Improve yaml linter message feedback * Make dependencies an argument instead of a property on the serialization manager * yamllinting slaps * Clean up type serializers * Move yaml linter code to its own method * Fix yaml errors * Change yaml linter action name and remove -nowarn * yaml linter please shut * Git resetti robust toolbox Co-authored-by: Paul <ritter.paul1+git@googlemail.com> Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
163 lines
5.8 KiB
C#
163 lines
5.8 KiB
C#
#nullable enable
|
|
|
|
using System.Collections.Generic;
|
|
using Content.Shared.GameObjects.Components;
|
|
using Content.Shared.Utility;
|
|
using JetBrains.Annotations;
|
|
using Robust.Client.GameObjects;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.Serialization.Manager.Attributes;
|
|
using Robust.Shared.Utility;
|
|
using YamlDotNet.RepresentationModel;
|
|
|
|
namespace Content.Client.GameObjects.Components
|
|
{
|
|
/// <summary>
|
|
/// Visualizer for items that come in stacks and have different appearance
|
|
/// depending on the size of the stack. Visualizer can work by switching between different
|
|
/// icons in <c>_spriteLayers</c> or if the sprite layers are supposed to be composed as transparent layers.
|
|
/// The former behavior is default and the latter behavior can be defined in prototypes.
|
|
///
|
|
/// <example>
|
|
/// <para>To define a Stack Visualizer prototype insert the following
|
|
/// snippet (you can skip Appearance if already defined)
|
|
/// </para>
|
|
/// <code>
|
|
/// - type: Appearance
|
|
/// visuals:
|
|
/// - type: StackVisualizer
|
|
/// stackLayers:
|
|
/// - goldbar_10
|
|
/// - goldbar_20
|
|
/// - goldbar_30
|
|
/// </code>
|
|
/// </example>
|
|
/// <example>
|
|
/// <para>Defining a stack visualizer with composable transparent layers</para>
|
|
/// <code>
|
|
/// - type: StackVisualizer
|
|
/// composite: true
|
|
/// stackLayers:
|
|
/// - cigarette_1
|
|
/// - cigarette_2
|
|
/// - cigarette_3
|
|
/// - cigarette_4
|
|
/// - cigarette_5
|
|
/// - cigarette_6
|
|
/// </code>
|
|
/// </example>
|
|
/// <seealso cref="_spriteLayers"/>
|
|
/// </summary>
|
|
[UsedImplicitly]
|
|
public class StackVisualizer : AppearanceVisualizer
|
|
{
|
|
/// <summary>
|
|
/// Default IconLayer stack.
|
|
/// </summary>
|
|
private const int IconLayer = 0;
|
|
|
|
/// <summary>
|
|
/// Sprite layers used in stack visualizer. Sprites first in layer correspond to lower stack states
|
|
/// e.g. <code>_spriteLayers[0]</code> is lower stack level than <code>_spriteLayers[1]</code>.
|
|
/// </summary>
|
|
[DataField("stackLayers")]
|
|
private readonly List<string> _spriteLayers = new();
|
|
|
|
/// <summary>
|
|
/// Determines if the visualizer uses composite or non-composite layers for icons. Defaults to false.
|
|
///
|
|
/// <list type="bullet">
|
|
/// <item>
|
|
/// <description>false: they are opaque and mutually exclusive (e.g. sprites in a wire coil). <b>Default value</b></description>
|
|
/// </item>
|
|
/// <item>
|
|
/// <description>true: they are transparent and thus layered one over another in ascending order first</description>
|
|
/// </item>
|
|
/// </list>
|
|
///
|
|
/// </summary>
|
|
[DataField("composite")]
|
|
private bool _isComposite;
|
|
[DataField("sprite")]
|
|
private ResourcePath? _spritePath;
|
|
|
|
public override void InitializeEntity(IEntity entity)
|
|
{
|
|
base.InitializeEntity(entity);
|
|
|
|
if (_isComposite
|
|
&& _spriteLayers.Count > 0
|
|
&& entity.TryGetComponent<ISpriteComponent>(out var spriteComponent))
|
|
{
|
|
var spritePath = _spritePath ?? spriteComponent.BaseRSI!.Path!;
|
|
|
|
foreach (var sprite in _spriteLayers)
|
|
{
|
|
spriteComponent.LayerMapReserveBlank(sprite);
|
|
spriteComponent.LayerSetSprite(sprite, new SpriteSpecifier.Rsi(spritePath, sprite));
|
|
spriteComponent.LayerSetVisible(sprite, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void OnChangeData(AppearanceComponent component)
|
|
{
|
|
base.OnChangeData(component);
|
|
|
|
if (component.Owner.TryGetComponent<ISpriteComponent>(out var spriteComponent))
|
|
{
|
|
if (_isComposite)
|
|
{
|
|
ProcessCompositeSprites(component, spriteComponent);
|
|
}
|
|
else
|
|
{
|
|
ProcessOpaqueSprites(component, spriteComponent);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ProcessOpaqueSprites(AppearanceComponent component, ISpriteComponent spriteComponent)
|
|
{
|
|
// Skip processing if no actual
|
|
if (!component.TryGetData<int>(StackVisuals.Actual, out var actual)) return;
|
|
if (!component.TryGetData<int>(StackVisuals.MaxCount, out var maxCount))
|
|
{
|
|
maxCount = _spriteLayers.Count;
|
|
}
|
|
|
|
var activeLayer = ContentHelpers.RoundToNearestLevels(actual, maxCount, _spriteLayers.Count - 1);
|
|
spriteComponent.LayerSetState(IconLayer, _spriteLayers[activeLayer]);
|
|
}
|
|
|
|
private void ProcessCompositeSprites(AppearanceComponent component, ISpriteComponent spriteComponent)
|
|
{
|
|
// If hidden, don't render any sprites
|
|
if (component.TryGetData<bool>(StackVisuals.Hide, out var hide)
|
|
&& hide)
|
|
{
|
|
foreach (var transparentSprite in _spriteLayers)
|
|
{
|
|
spriteComponent.LayerSetVisible(transparentSprite, false);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// Skip processing if no actual/maxCount
|
|
if (!component.TryGetData<int>(StackVisuals.Actual, out var actual)) return;
|
|
if (!component.TryGetData<int>(StackVisuals.MaxCount, out var maxCount))
|
|
{
|
|
maxCount = _spriteLayers.Count;
|
|
}
|
|
|
|
|
|
var activeTill = ContentHelpers.RoundToNearestLevels(actual, maxCount, _spriteLayers.Count);
|
|
for (var i = 0; i < _spriteLayers.Count; i++)
|
|
{
|
|
spriteComponent.LayerSetVisible(_spriteLayers[i], i < activeTill);
|
|
}
|
|
}
|
|
}
|
|
}
|