From 2d3d3a202b708a8f8a867604b19f21b594aab79a Mon Sep 17 00:00:00 2001 From: wixoaGit Date: Sun, 26 May 2024 00:23:44 -0400 Subject: [PATCH] Add support for `/image.filters` --- OpenDreamRuntime/Objects/Types/DreamList.cs | 34 +++++++++---------- .../Objects/Types/DreamObjectImage.cs | 22 ++++++++++++ 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/OpenDreamRuntime/Objects/Types/DreamList.cs b/OpenDreamRuntime/Objects/Types/DreamList.cs index f5527a253e..67c1c4d553 100644 --- a/OpenDreamRuntime/Objects/Types/DreamList.cs +++ b/OpenDreamRuntime/Objects/Types/DreamList.cs @@ -647,24 +647,24 @@ private List GetVerbs() { } // atom.overlays or atom.underlays list -// Operates on an atom's appearance +// Operates on an object's appearance public sealed class DreamOverlaysList : DreamList { [Dependency] private readonly AtomManager _atomManager = default!; private readonly ServerAppearanceSystem? _appearanceSystem; - private readonly DreamObject _atom; + private readonly DreamObject _owner; private readonly bool _isUnderlays; - public DreamOverlaysList(DreamObjectDefinition listDef, DreamObject atom, ServerAppearanceSystem? appearanceSystem, bool isUnderlays) : base(listDef, 0) { + public DreamOverlaysList(DreamObjectDefinition listDef, DreamObject owner, ServerAppearanceSystem? appearanceSystem, bool isUnderlays) : base(listDef, 0) { IoCManager.InjectDependencies(this); - _atom = atom; + _owner = owner; _appearanceSystem = appearanceSystem; _isUnderlays = isUnderlays; } public override List GetValues() { - var appearance = _atomManager.MustGetAppearance(_atom); + var appearance = _atomManager.MustGetAppearance(_owner); if (appearance == null || _appearanceSystem == null) return new List(); @@ -681,7 +681,7 @@ public override List GetValues() { } public override void Cut(int start = 1, int end = 0) { - _atomManager.UpdateAppearance(_atom, appearance => { + _atomManager.UpdateAppearance(_owner, appearance => { List overlaysList = GetOverlaysList(appearance); int count = overlaysList.Count + 1; if (end == 0 || end > count) end = count; @@ -715,7 +715,7 @@ public override void AddValue(DreamValue value) { if (_appearanceSystem == null) return; - _atomManager.UpdateAppearance(_atom, appearance => { + _atomManager.UpdateAppearance(_owner, appearance => { IconAppearance? overlayAppearance = CreateOverlayAppearance(_atomManager, value, appearance.Icon); overlayAppearance ??= new IconAppearance(); @@ -727,7 +727,7 @@ public override void RemoveValue(DreamValue value) { if (_appearanceSystem == null) return; - _atomManager.UpdateAppearance(_atom, appearance => { + _atomManager.UpdateAppearance(_owner, appearance => { IconAppearance? overlayAppearance = CreateOverlayAppearance(_atomManager, value, appearance.Icon); if (overlayAppearance == null || !_appearanceSystem.TryGetAppearanceId(overlayAppearance, out var id)) return; @@ -745,7 +745,7 @@ private List GetOverlaysList(IconAppearance appearance) => _isUnderlays ? appearance.Underlays : appearance.Overlays; private IconAppearance GetAppearance() { - IconAppearance? appearance = _atomManager.MustGetAppearance(_atom); + IconAppearance? appearance = _atomManager.MustGetAppearance(_owner); if (appearance == null) throw new Exception("Atom has no appearance"); @@ -858,20 +858,20 @@ public override int GetLength() { } // atom.filters list -// Operates on an atom's appearance +// Operates on an object's appearance public sealed class DreamFilterList : DreamList { [Dependency] private readonly AtomManager _atomManager = default!; [Dependency] private readonly ISerializationManager _serializationManager = default!; - private readonly DreamObjectAtom _atom; + private readonly DreamObject _owner; - public DreamFilterList(DreamObjectDefinition listDef, DreamObjectAtom atom) : base(listDef, 0) { + public DreamFilterList(DreamObjectDefinition listDef, DreamObject owner) : base(listDef, 0) { IoCManager.InjectDependencies(this); - _atom = atom; + _owner = owner; } public override void Cut(int start = 1, int end = 0) { - _atomManager.UpdateAppearance(_atom, appearance => { + _atomManager.UpdateAppearance(_owner, appearance => { int filterCount = appearance.Filters.Count + 1; if (end == 0 || end > filterCount) end = filterCount; @@ -886,7 +886,7 @@ public int GetIndexOfFilter(DreamFilter filter) { } public void SetFilter(int index, DreamFilter filter) { - _atomManager.UpdateAppearance(_atom, appearance => { + _atomManager.UpdateAppearance(_owner, appearance => { if (index < 1 || index > appearance.Filters.Count) throw new Exception($"Cannot index {index} on filter list"); @@ -931,7 +931,7 @@ public override void AddValue(DreamValue value) { DreamFilter copy = _serializationManager.CreateCopy(filter, notNullableOverride: true); // Adding a filter creates a copy DreamObjectFilter.FilterAttachedTo[copy] = this; - _atomManager.UpdateAppearance(_atom, appearance => { + _atomManager.UpdateAppearance(_owner, appearance => { appearance.Filters.Add(copy); }); } @@ -941,7 +941,7 @@ public override int GetLength() { } private IconAppearance GetAppearance() { - IconAppearance? appearance = _atomManager.MustGetAppearance(_atom); + IconAppearance? appearance = _atomManager.MustGetAppearance(_owner); if (appearance == null) throw new Exception("Atom has no appearance"); diff --git a/OpenDreamRuntime/Objects/Types/DreamObjectImage.cs b/OpenDreamRuntime/Objects/Types/DreamObjectImage.cs index 0a6b182576..430f72037e 100644 --- a/OpenDreamRuntime/Objects/Types/DreamObjectImage.cs +++ b/OpenDreamRuntime/Objects/Types/DreamObjectImage.cs @@ -11,6 +11,7 @@ public sealed class DreamObjectImage : DreamObject { private DreamObject? _loc; private DreamList _overlays; private DreamList _underlays; + private DreamList _filters; private EntityUid _entity = EntityUid.Invalid; /// @@ -29,9 +30,11 @@ public DreamObjectImage(DreamObjectDefinition objectDefinition) : base(objectDef // /mutable_appearance.overlays and /mutable_appearance.underlays are normal lists _overlays = ObjectTree.CreateList(); _underlays = ObjectTree.CreateList(); + _filters = ObjectTree.CreateList(); } else { _overlays = new DreamOverlaysList(ObjectTree.List.ObjectDefinition, this, AppearanceSystem, false); _underlays = new DreamOverlaysList(ObjectTree.List.ObjectDefinition, this, AppearanceSystem, true); + _filters = new DreamFilterList(ObjectTree.List.ObjectDefinition, this); } } @@ -81,6 +84,9 @@ protected override bool TryGetVar(string varName, out DreamValue value) { case "underlays": value = new(_underlays); return true; + case "filters": + value = new(_filters); + return true; default: { if (AtomManager.IsValidAppearanceVar(varName)) { value = AtomManager.GetAppearanceVar(Appearance!, varName); @@ -178,6 +184,22 @@ protected override void SetVar(string varName, DreamValue value) { break; } + case "filters": { + value.TryGetValueAsDreamList(out var valueList); + + _filters.Cut(); + + if (valueList != null) { + // TODO: This should postpone UpdateAppearance until after everything is added + foreach (DreamValue underlayValue in valueList.GetValues()) { + _filters.AddValue(underlayValue); + } + } else if (!value.IsNull) { + _filters.AddValue(value); + } + + break; + } case "override": { Appearance!.Override = value.IsTruthy(); break;