From b8e919daa24521b0d2acef701a32f9ab35d7a0b5 Mon Sep 17 00:00:00 2001 From: TobleroneSwordfish <20713227+TobleroneSwordfish@users.noreply.github.com> Date: Thu, 23 Jan 2025 19:22:04 +0000 Subject: [PATCH] Fix atom name/desc not copying on appearance set (#2145) Co-authored-by: wixoaGit --- .../DMProject/Tests/atom_appearance.dm | 10 +++ .../DMProject/Tests/string_interpolation.dm | 13 ++++ Content.IntegrationTests/DMProject/code.dm | 2 + .../DMProject/environment.dme | 2 + .../Tests/Preprocessor/macro_newline_var.dm | 14 +++-- .../Tests/Preprocessor/macro_numeric_path.dm | 12 ++-- .../Tests/Text/StringInterpolation2.dm | 6 +- .../Tests/Text/StringInterpolation3.dm | 31 ++++++---- .../Tests/Text/StringInterpolation4.dm | 32 ++++------ .../Tests/Text/StringInterpolation5.dm | 35 ++++++++--- .../Tests/Text/StringInterpolation6.dm | 26 ++++---- .../Tests/Text/StringInterpolation7.dm | 61 +++++++++++-------- .../Tests/Text/StringInterpolation8.dm | 11 ---- .../Tests/Text/StringInterpolation9.dm | 39 ------------ OpenDream.sln.DotSettings | 1 + .../DebugWindows/IconDebugWindow.xaml.cs | 1 + OpenDreamClient/Rendering/DMISpriteSystem.cs | 4 +- OpenDreamRuntime/AtomManager.cs | 32 ++++++---- OpenDreamRuntime/Objects/DreamObject.cs | 11 +++- .../Objects/Types/DreamObjectAtom.cs | 28 +++------ .../Objects/Types/DreamObjectMovable.cs | 2 +- OpenDreamShared/Dream/ImmutableAppearance.cs | 19 +++++- OpenDreamShared/Dream/MutableAppearance.cs | 5 ++ .../Network/Messages/MsgAllAppearances.cs | 6 +- 24 files changed, 216 insertions(+), 187 deletions(-) create mode 100644 Content.IntegrationTests/DMProject/Tests/atom_appearance.dm create mode 100644 Content.IntegrationTests/DMProject/Tests/string_interpolation.dm delete mode 100644 Content.Tests/DMProject/Tests/Text/StringInterpolation8.dm delete mode 100644 Content.Tests/DMProject/Tests/Text/StringInterpolation9.dm diff --git a/Content.IntegrationTests/DMProject/Tests/atom_appearance.dm b/Content.IntegrationTests/DMProject/Tests/atom_appearance.dm new file mode 100644 index 0000000000..4b07dda7e3 --- /dev/null +++ b/Content.IntegrationTests/DMProject/Tests/atom_appearance.dm @@ -0,0 +1,10 @@ +/obj/thingtocopy + name = "hello" + desc = "this is a thing" + +/proc/test_appearance() + var/obj/thingtocopy/T = new() + var/obj/otherthing = new() + otherthing.appearance = T.appearance + ASSERT(otherthing.name == T.name) + ASSERT(otherthing.desc == T.desc) \ No newline at end of file diff --git a/Content.IntegrationTests/DMProject/Tests/string_interpolation.dm b/Content.IntegrationTests/DMProject/Tests/string_interpolation.dm new file mode 100644 index 0000000000..f64128b0c1 --- /dev/null +++ b/Content.IntegrationTests/DMProject/Tests/string_interpolation.dm @@ -0,0 +1,13 @@ +/obj/blombo + name = "Blombo" + gender = FEMALE + +/obj/blorpo + name = "Blorpo" + gender = MALE + +/proc/test_string_interpolation() + var/obj/blombo/b = new + var/obj/blorpo/b2 = new + var/result_text = "[b]? Nobody likes \him. \He is awful! Unlike [b2]. \He is pretty cool!" + ASSERT(result_text == "Blombo? Nobody likes her. She is awful! Unlike Blorpo. He is pretty cool!") \ No newline at end of file diff --git a/Content.IntegrationTests/DMProject/code.dm b/Content.IntegrationTests/DMProject/code.dm index 894fc35758..6e6827200f 100644 --- a/Content.IntegrationTests/DMProject/code.dm +++ b/Content.IntegrationTests/DMProject/code.dm @@ -30,7 +30,9 @@ test_color_matrix() test_range() test_verb_duplicate() + test_appearance() test_nonlocal_var() test_images() test_filter_init() + test_string_interpolation() world.log << "IntegrationTests successful, /world/New() exiting..." \ No newline at end of file diff --git a/Content.IntegrationTests/DMProject/environment.dme b/Content.IntegrationTests/DMProject/environment.dme index aa33082512..80f5c14baf 100644 --- a/Content.IntegrationTests/DMProject/environment.dme +++ b/Content.IntegrationTests/DMProject/environment.dme @@ -1,4 +1,5 @@ #include "code.dm" +#include "Tests/atom_appearance.dm" #include "Tests/block.dm" #include "Tests/color_matrix.dm" #include "Tests/range.dm" @@ -6,5 +7,6 @@ #include "Tests/nonlocal_var.dm" #include "Tests/image.dm" #include "Tests/filter_initial.dm" +#include "Tests/string_interpolation.dm" #include "map.dmm" #include "interface.dmf" \ No newline at end of file diff --git a/Content.Tests/DMProject/Tests/Preprocessor/macro_newline_var.dm b/Content.Tests/DMProject/Tests/Preprocessor/macro_newline_var.dm index 2d2d609cc8..4aa1d76373 100644 --- a/Content.Tests/DMProject/Tests/Preprocessor/macro_newline_var.dm +++ b/Content.Tests/DMProject/Tests/Preprocessor/macro_newline_var.dm @@ -1,8 +1,10 @@ +/datum/var/name + #define DEFINE_FLOORS(_PATH, _VARS) \ - /obj/simulated/floor/_PATH{_VARS};\ - /obj/unsimulated/floor/_PATH{_VARS};\ - /obj/simulated/floor/airless/_PATH{_VARS};\ - /obj/unsimulated/floor/airless/_PATH{_VARS}; + /datum/simulated/floor/_PATH{_VARS};\ + /datum/unsimulated/floor/_PATH{_VARS};\ + /datum/simulated/floor/airless/_PATH{_VARS};\ + /datum/unsimulated/floor/airless/_PATH{_VARS}; var/list/gvars_datum_init_order = list() @@ -42,8 +44,8 @@ proc/RunTest() ASSERT(test.len == 4) InitGlobaltest2() ASSERT(test2.len == 2) - var/obj/simulated/floor/carpet/regalcarpet/C1 = new() - var/obj/simulated/floor/carpet/regalcarpet/border/C2 = new() + var/datum/simulated/floor/carpet/regalcarpet/C1 = new() + var/datum/simulated/floor/carpet/regalcarpet/border/C2 = new() ASSERT(C1.name == "regal carpet") ASSERT(C2.name == "regal carpet border") diff --git a/Content.Tests/DMProject/Tests/Preprocessor/macro_numeric_path.dm b/Content.Tests/DMProject/Tests/Preprocessor/macro_numeric_path.dm index a3d4448a56..2adb74318d 100644 --- a/Content.Tests/DMProject/Tests/Preprocessor/macro_numeric_path.dm +++ b/Content.Tests/DMProject/Tests/Preprocessor/macro_numeric_path.dm @@ -1,15 +1,17 @@ -/obj/thing_1/dodaa +/datum/var/name + +/datum/thing_1/dodaa name = "underscore 1 test" -#define NUMPATH_OBJDEF(num) /obj/thing_##num/name = #num +#define NUMPATH_OBJDEF(num) /datum/thing_##num/name = #num NUMPATH_OBJDEF(4) NUMPATH_OBJDEF(stuff) /proc/RunTest() - var/obj/thing_1/dodaa/D = new + var/datum/thing_1/dodaa/D = new ASSERT(D.name == "underscore 1 test") - var/obj/thing_4/T = new + var/datum/thing_4/T = new ASSERT(T.name == "4") - var/obj/thing_stuff/Y = new + var/datum/thing_stuff/Y = new ASSERT(Y.name == "stuff") \ No newline at end of file diff --git a/Content.Tests/DMProject/Tests/Text/StringInterpolation2.dm b/Content.Tests/DMProject/Tests/Text/StringInterpolation2.dm index 385d9c0c88..1322bff03a 100644 --- a/Content.Tests/DMProject/Tests/Text/StringInterpolation2.dm +++ b/Content.Tests/DMProject/Tests/Text/StringInterpolation2.dm @@ -1,8 +1,8 @@ -/obj/blombo - name = "Blombo" +/datum/blombo + var/name = "Blombo" /proc/RunTest() - var/obj/blombo/b = new + var/datum/blombo/b = new var/result_text = "Nobody likes [b]!" ASSERT(result_text == "Nobody likes Blombo!") diff --git a/Content.Tests/DMProject/Tests/Text/StringInterpolation3.dm b/Content.Tests/DMProject/Tests/Text/StringInterpolation3.dm index 54cb329034..20bea3f509 100644 --- a/Content.Tests/DMProject/Tests/Text/StringInterpolation3.dm +++ b/Content.Tests/DMProject/Tests/Text/StringInterpolation3.dm @@ -1,14 +1,23 @@ +/datum/test/var/name -/obj/blombo - name = "Blombo" - gender = FEMALE - -/obj/blorpo - name = "Blorpo" - gender = MALE +/datum/test/test1 + name = "" +/datum/test/test2 + name = " " // 3 spaces +/datum/test/test3 + name = "\t" /proc/RunTest() - var/obj/blombo/b = new - var/obj/blorpo/b2 = new - var/result_text = "[b]? Nobody likes \him. \He is awful! Unlike [b2]. \He is pretty cool!" - ASSERT(result_text == "Blombo? Nobody likes her. She is awful! Unlike Blorpo. He is pretty cool!") + var/list/correct = list( + "/datum/test/test1: ", + "/datum/test/test2: ", + "/datum/test/test3: \t" + ) + var/i = 1 + for (var/T in typesof(/datum/test)) + if(T == /datum/test) + continue + var/datum/test/D = new T() + var/true_text = correct[i] + ASSERT(true_text == "[T]: \the [D]") + ++i diff --git a/Content.Tests/DMProject/Tests/Text/StringInterpolation4.dm b/Content.Tests/DMProject/Tests/Text/StringInterpolation4.dm index 5688dd1030..e960741bb0 100644 --- a/Content.Tests/DMProject/Tests/Text/StringInterpolation4.dm +++ b/Content.Tests/DMProject/Tests/Text/StringInterpolation4.dm @@ -1,21 +1,15 @@ -/obj/test1 - name = "" -/obj/test2 - name = " " // 3 spaces -/obj/test3 - name = "\t" + /proc/RunTest() - var/list/correct = list( - "/obj/test1: ", - "/obj/test2: ", - "/obj/test3: \t" - ) - var/i = 1 - for (var/T in typesof(/obj)) - if(T == /obj) - continue - var/obj/O = new T() - var/true_text = correct[i] - ASSERT(true_text == "[T]: \the [O]") - ++i + var/text = "["1"]\s" + ASSERT(text == "1s") + text = "[0]\s" + ASSERT(text == "0s") + text = "[null]\s" + ASSERT(text == "s") + text = "[1]\s" + ASSERT(text == "1") + text = "[1.00000001]\s" + ASSERT(text == "1") + text = "[1.0001]\s" + ASSERT(text == "1.0001s") diff --git a/Content.Tests/DMProject/Tests/Text/StringInterpolation5.dm b/Content.Tests/DMProject/Tests/Text/StringInterpolation5.dm index fc768b0371..d2b0eeb0cd 100644 --- a/Content.Tests/DMProject/Tests/Text/StringInterpolation5.dm +++ b/Content.Tests/DMProject/Tests/Text/StringInterpolation5.dm @@ -1,11 +1,30 @@ /proc/RunTest() - var/atom/O = new() - O.name = "foo" - O.gender = FEMALE - var/atom/O2 = new - O2.name = "foob" - O2.gender = MALE - var/text = "[O2], \ref[O], \his" - ASSERT(findtextEx(text,", his") != 0) + var/text = "[0]\th" + ASSERT(text == "0th") + text = "[1]\th" + ASSERT(text == "1st") + text = "[2]\th" + ASSERT(text == "2nd") + text = "[3]\th" + ASSERT(text == "3rd") + text = "[4]\th" + ASSERT(text == "4th") + text = "[-1]\th" + ASSERT(text == "-1th") + text = "[4.52]\th" + ASSERT(text == "4th") + text = "the fitness [1.7]\th is a" + ASSERT(text == "the fitness 1st is a") + text = "the fitness [99999999]\th is a" + ASSERT(text == "the fitness 100000000th is a") + text = "[null]\th" + ASSERT(text == "0th") + var/datum/D = new + text = "[D]\th" + ASSERT(text == "0th") + var/foo = "bar" + text = "[foo]\th" + ASSERT(text == "0th") + diff --git a/Content.Tests/DMProject/Tests/Text/StringInterpolation6.dm b/Content.Tests/DMProject/Tests/Text/StringInterpolation6.dm index e960741bb0..4d9b638105 100644 --- a/Content.Tests/DMProject/Tests/Text/StringInterpolation6.dm +++ b/Content.Tests/DMProject/Tests/Text/StringInterpolation6.dm @@ -1,15 +1,11 @@ - - -/proc/RunTest() - var/text = "["1"]\s" - ASSERT(text == "1s") - text = "[0]\s" - ASSERT(text == "0s") - text = "[null]\s" - ASSERT(text == "s") - text = "[1]\s" - ASSERT(text == "1") - text = "[1.00000001]\s" - ASSERT(text == "1") - text = "[1.0001]\s" - ASSERT(text == "1.0001s") +/proc/RunTest() + ASSERT("\roman[1.5]" == "i") + ASSERT("\roman [1.5]" == " i") + ASSERT("\Roman[1.5]" == "I") + ASSERT("\Roman [1.5]" == " I") + ASSERT("\roman shitposts [1]" == " shitposts i") + ASSERT("\roman shitposts [1] \the [2] [3]\s" == " shitposts i 3s") + ASSERT("\roman[1.#INF]" == "∞") + ASSERT("\roman[-1.#INF]" == "-∞") + ASSERT("\roman [-1.#INF]" == " -∞") + ASSERT("\roman[1.#IND]" == "�") \ No newline at end of file diff --git a/Content.Tests/DMProject/Tests/Text/StringInterpolation7.dm b/Content.Tests/DMProject/Tests/Text/StringInterpolation7.dm index d2b0eeb0cd..9ff619a52a 100644 --- a/Content.Tests/DMProject/Tests/Text/StringInterpolation7.dm +++ b/Content.Tests/DMProject/Tests/Text/StringInterpolation7.dm @@ -1,30 +1,39 @@ +/datum/thing + var/name = "thing" +/datum/Thing + var/name = "Thing" + +/datum/proper_thing + var/name = "\proper thing" + +/datum/plural_things + var/name = "things" + var/gender = PLURAL /proc/RunTest() - var/text = "[0]\th" - ASSERT(text == "0th") - text = "[1]\th" - ASSERT(text == "1st") - text = "[2]\th" - ASSERT(text == "2nd") - text = "[3]\th" - ASSERT(text == "3rd") - text = "[4]\th" - ASSERT(text == "4th") - text = "[-1]\th" - ASSERT(text == "-1th") - text = "[4.52]\th" - ASSERT(text == "4th") - text = "the fitness [1.7]\th is a" - ASSERT(text == "the fitness 1st is a") - text = "the fitness [99999999]\th is a" - ASSERT(text == "the fitness 100000000th is a") - text = "[null]\th" - ASSERT(text == "0th") - var/datum/D = new - text = "[D]\th" - ASSERT(text == "0th") - var/foo = "bar" - text = "[foo]\th" - ASSERT(text == "0th") + // Lowercase \a on datums + ASSERT("\a [new /datum/thing]" == "a thing") + ASSERT("\a [new /datum/Thing]" == "Thing") + ASSERT("\a [new /datum/proper_thing]" == "thing") + ASSERT("\a [new /datum/plural_things]" == "some things") + + // Uppercase \A on datums + ASSERT("\A [new /datum/thing]" == "A thing") + ASSERT("\A [new /datum/Thing]" == "Thing") + ASSERT("\A [new /datum/proper_thing]" == "thing") + ASSERT("\A [new /datum/plural_things]" == "Some things") + + // Lowercase \a on strings + ASSERT("\a ["thing"]" == "a thing") + ASSERT("\a ["Thing"]" == "Thing") + ASSERT("\a ["\proper thing"]" == "thing") + + // Uppercase \A on strings + ASSERT("\A ["thing"]" == "A thing") + ASSERT("\A ["Thing"]" == "Thing") + ASSERT("\A ["\proper thing"]" == "thing") + // Invalid \a + ASSERT("\a [123]" == "") + ASSERT("\A [123]" == "") \ No newline at end of file diff --git a/Content.Tests/DMProject/Tests/Text/StringInterpolation8.dm b/Content.Tests/DMProject/Tests/Text/StringInterpolation8.dm deleted file mode 100644 index 4d9b638105..0000000000 --- a/Content.Tests/DMProject/Tests/Text/StringInterpolation8.dm +++ /dev/null @@ -1,11 +0,0 @@ -/proc/RunTest() - ASSERT("\roman[1.5]" == "i") - ASSERT("\roman [1.5]" == " i") - ASSERT("\Roman[1.5]" == "I") - ASSERT("\Roman [1.5]" == " I") - ASSERT("\roman shitposts [1]" == " shitposts i") - ASSERT("\roman shitposts [1] \the [2] [3]\s" == " shitposts i 3s") - ASSERT("\roman[1.#INF]" == "∞") - ASSERT("\roman[-1.#INF]" == "-∞") - ASSERT("\roman [-1.#INF]" == " -∞") - ASSERT("\roman[1.#IND]" == "�") \ No newline at end of file diff --git a/Content.Tests/DMProject/Tests/Text/StringInterpolation9.dm b/Content.Tests/DMProject/Tests/Text/StringInterpolation9.dm deleted file mode 100644 index 9ff619a52a..0000000000 --- a/Content.Tests/DMProject/Tests/Text/StringInterpolation9.dm +++ /dev/null @@ -1,39 +0,0 @@ -/datum/thing - var/name = "thing" - -/datum/Thing - var/name = "Thing" - -/datum/proper_thing - var/name = "\proper thing" - -/datum/plural_things - var/name = "things" - var/gender = PLURAL - -/proc/RunTest() - // Lowercase \a on datums - ASSERT("\a [new /datum/thing]" == "a thing") - ASSERT("\a [new /datum/Thing]" == "Thing") - ASSERT("\a [new /datum/proper_thing]" == "thing") - ASSERT("\a [new /datum/plural_things]" == "some things") - - // Uppercase \A on datums - ASSERT("\A [new /datum/thing]" == "A thing") - ASSERT("\A [new /datum/Thing]" == "Thing") - ASSERT("\A [new /datum/proper_thing]" == "thing") - ASSERT("\A [new /datum/plural_things]" == "Some things") - - // Lowercase \a on strings - ASSERT("\a ["thing"]" == "a thing") - ASSERT("\a ["Thing"]" == "Thing") - ASSERT("\a ["\proper thing"]" == "thing") - - // Uppercase \A on strings - ASSERT("\A ["thing"]" == "A thing") - ASSERT("\A ["Thing"]" == "Thing") - ASSERT("\A ["\proper thing"]" == "thing") - - // Invalid \a - ASSERT("\a [123]" == "") - ASSERT("\A [123]" == "") \ No newline at end of file diff --git a/OpenDream.sln.DotSettings b/OpenDream.sln.DotSettings index 3c4c83094e..9303eadec4 100644 --- a/OpenDream.sln.DotSettings +++ b/OpenDream.sln.DotSettings @@ -10,6 +10,7 @@ 1 1 AABB + RT DM DMF DMI diff --git a/OpenDreamClient/Interface/DebugWindows/IconDebugWindow.xaml.cs b/OpenDreamClient/Interface/DebugWindows/IconDebugWindow.xaml.cs index bbdec962a0..338956b9f4 100644 --- a/OpenDreamClient/Interface/DebugWindows/IconDebugWindow.xaml.cs +++ b/OpenDreamClient/Interface/DebugWindows/IconDebugWindow.xaml.cs @@ -45,6 +45,7 @@ private void Update() { // Would be nice if we could use ViewVariables instead, but I couldn't find a nice way to do that // Would be especially nice if we could use VV to make these editable AddPropertyIfNotDefault("Name", appearance.Name, MutableAppearance.Default.Name); + AddPropertyIfNotDefault("Desc", appearance.Desc, MutableAppearance.Default.Desc); AddPropertyIfNotDefault("Icon State", appearance.IconState, MutableAppearance.Default.IconState); AddPropertyIfNotDefault("Direction", appearance.Direction, MutableAppearance.Default.Direction); AddPropertyIfNotDefault("Inherits Direction", appearance.InheritsDirection, MutableAppearance.Default.InheritsDirection); diff --git a/OpenDreamClient/Rendering/DMISpriteSystem.cs b/OpenDreamClient/Rendering/DMISpriteSystem.cs index 46f9e10069..562f27a7be 100644 --- a/OpenDreamClient/Rendering/DMISpriteSystem.cs +++ b/OpenDreamClient/Rendering/DMISpriteSystem.cs @@ -39,7 +39,9 @@ public override void Shutdown() { } private void OnIconSizeChanged(EntityUid uid) { - _entityManager.TryGetComponent(uid, out var transform); + if (!_entityManager.TryGetComponent(uid, out var transform)) + return; + _lookupSystem.FindAndAddToEntityTree(uid, xform: transform); } diff --git a/OpenDreamRuntime/AtomManager.cs b/OpenDreamRuntime/AtomManager.cs index eef1f98338..0a376bce57 100644 --- a/OpenDreamRuntime/AtomManager.cs +++ b/OpenDreamRuntime/AtomManager.cs @@ -233,6 +233,7 @@ public void DeleteMovableEntity(DreamObjectMovable movable) { public bool IsValidAppearanceVar(string name) { switch (name) { case "name": + case "desc": case "icon": case "icon_state": case "dir": @@ -277,6 +278,10 @@ public void SetAppearanceVar(MutableAppearance appearance, string varName, Dream value.TryGetValueAsString(out var name); appearance.Name = name ?? string.Empty; break; + case "desc": + value.TryGetValueAsString(out var desc); + appearance.Desc = desc; + break; case "icon": if (_resourceManager.TryLoadIcon(value, out var icon)) { appearance.Icon = icon.Id; @@ -439,6 +444,10 @@ public DreamValue GetAppearanceVar(ImmutableAppearance appearance, string varNam switch (varName) { case "name": return new(appearance.Name); + case "desc": + if (appearance.Desc == null) + return DreamValue.Null; + return new(appearance.Desc); case "icon": if (appearance.Icon == null) return DreamValue.Null; @@ -551,9 +560,9 @@ public DreamValue GetAppearanceVar(ImmutableAppearance appearance, string varNam /// The atom to find the appearance of. public ImmutableAppearance MustGetAppearance(DreamObject atom) { return atom switch { + DreamObjectArea area => area.Appearance, DreamObjectTurf turf => turf.Appearance, DreamObjectMovable movable => movable.SpriteComponent.Appearance!, - DreamObjectArea area => area.Appearance, DreamObjectImage image => image.IsMutableAppearance ? AppearanceSystem!.AddAppearance(image.MutableAppearance!, registerAppearance: false) : image.SpriteComponent!.Appearance!, _ => throw new Exception($"Cannot get appearance of {atom}") }; @@ -563,16 +572,15 @@ public ImmutableAppearance MustGetAppearance(DreamObject atom) { /// Optionally looks up for an appearance. Does not try to create a new one when one is not found for this atom. /// public bool TryGetAppearance(DreamObject atom, [NotNullWhen(true)] out ImmutableAppearance? appearance) { - if (atom is DreamObjectTurf turf) - appearance = turf.Appearance; - else if (atom is DreamObjectMovable { SpriteComponent.Appearance: not null } movable) - appearance = movable.SpriteComponent.Appearance; - else if (atom is DreamObjectImage image) - appearance = image.IsMutableAppearance ? AppearanceSystem!.AddAppearance(image.MutableAppearance!, registerAppearance: false) : image.SpriteComponent?.Appearance; - else if (atom is DreamObjectArea area) - appearance = area.Appearance; - else - appearance = null; + appearance = atom switch { + DreamObjectArea area => area.Appearance, + DreamObjectTurf turf => turf.Appearance, + DreamObjectMovable { SpriteComponent.Appearance: { } movableAppearance } => movableAppearance, + DreamObjectImage image => image.IsMutableAppearance + ? AppearanceSystem!.AddAppearance(image.MutableAppearance!, registerAppearance: false) + : image.SpriteComponent?.Appearance, + _ => null + }; return appearance is not null; } @@ -692,6 +700,7 @@ public MutableAppearance GetAppearanceFromDefinition(DreamObjectDefinition def) return appearance; def.TryGetVariable("name", out var nameVar); + def.TryGetVariable("desc", out var descVar); def.TryGetVariable("icon", out var iconVar); def.TryGetVariable("icon_state", out var stateVar); def.TryGetVariable("color", out var colorVar); @@ -712,6 +721,7 @@ public MutableAppearance GetAppearanceFromDefinition(DreamObjectDefinition def) appearance = MutableAppearance.Get(); SetAppearanceVar(appearance, "name", nameVar); + SetAppearanceVar(appearance, "desc", descVar); SetAppearanceVar(appearance, "icon", iconVar); SetAppearanceVar(appearance, "icon_state", stateVar); SetAppearanceVar(appearance, "color", colorVar); diff --git a/OpenDreamRuntime/Objects/DreamObject.cs b/OpenDreamRuntime/Objects/DreamObject.cs index 19794ab9b0..e3e4389248 100644 --- a/OpenDreamRuntime/Objects/DreamObject.cs +++ b/OpenDreamRuntime/Objects/DreamObject.cs @@ -376,10 +376,15 @@ public string GetNameUnformatted() { /// /// Returns the name of this object with no formatting evaluated /// - /// public string GetRawName() { - if (!TryGetVariable("name", out DreamValue nameVar) || !nameVar.TryGetValueAsString(out string? name)) - return ObjectDefinition.Type.ToString(); + string name = ObjectDefinition.Type; + + if (this is DreamObjectAtom) { + if (AtomManager.TryGetAppearance(this, out var appearance)) + name = appearance.Name; + } else if (TryGetVariable("name", out DreamValue nameVar) && nameVar.TryGetValueAsString(out var nameVarStr)) { + name = nameVarStr; + } return name; } diff --git a/OpenDreamRuntime/Objects/Types/DreamObjectAtom.cs b/OpenDreamRuntime/Objects/Types/DreamObjectAtom.cs index 63f7a47e29..20cba60f33 100644 --- a/OpenDreamRuntime/Objects/Types/DreamObjectAtom.cs +++ b/OpenDreamRuntime/Objects/Types/DreamObjectAtom.cs @@ -4,8 +4,6 @@ namespace OpenDreamRuntime.Objects.Types; [Virtual] public class DreamObjectAtom : DreamObject { - public string? Name; - public string? Desc; public readonly DreamOverlaysList Overlays; public readonly DreamOverlaysList Underlays; public readonly DreamVisContentsList VisContents; @@ -21,11 +19,6 @@ public DreamObjectAtom(DreamObjectDefinition objectDefinition) : base(objectDefi AtomManager.AddAtom(this); } - public override void Initialize(DreamProcArguments args) { - ObjectDefinition.Variables["name"].TryGetValueAsString(out Name); - ObjectDefinition.Variables["desc"].TryGetValueAsString(out Desc); - } - protected override void HandleDeletion(bool possiblyThreaded) { // SAFETY: RemoveAtom is not threadsafe. if (possiblyThreaded) { @@ -38,6 +31,13 @@ protected override void HandleDeletion(bool possiblyThreaded) { base.HandleDeletion(possiblyThreaded); } + public string GetRTEntityDesc() { + if (AtomManager.TryGetAppearance(this, out var appearance) && appearance.Desc != null) + return appearance.Desc; + + return ObjectDefinition.Type; + } + protected override bool TryGetVar(string varName, out DreamValue value) { switch (varName) { // x/y/z/loc should be overriden by subtypes @@ -49,13 +49,6 @@ protected override bool TryGetVar(string varName, out DreamValue value) { case "loc": value = DreamValue.Null; return true; - - case "name": - value = (Name != null) ? new(Name) : DreamValue.Null; - return true; - case "desc": - value = (Desc != null) ? new(Desc) : DreamValue.Null; - return true; case "appearance": var appearanceCopy = AtomManager.MustGetAppearance(this).ToMutable(); @@ -101,13 +94,6 @@ protected override void SetVar(string varName, DreamValue value) { case "z": case "loc": break; - - case "name": - value.TryGetValueAsString(out Name); - break; - case "desc": - value.TryGetValueAsString(out Desc); - break; case "appearance": if (!AtomManager.TryCreateAppearanceFrom(value, out var newAppearance)) return; // Ignore attempts to set an invalid appearance diff --git a/OpenDreamRuntime/Objects/Types/DreamObjectMovable.cs b/OpenDreamRuntime/Objects/Types/DreamObjectMovable.cs index ae565f51ae..685aeced7f 100644 --- a/OpenDreamRuntime/Objects/Types/DreamObjectMovable.cs +++ b/OpenDreamRuntime/Objects/Types/DreamObjectMovable.cs @@ -43,7 +43,7 @@ public override void Initialize(DreamProcArguments args) { if (EntityManager.TryGetComponent(Entity, out MetaDataComponent? metaData)) { MetaDataSystem?.SetEntityName(Entity, GetDisplayName(), metaData); - MetaDataSystem?.SetEntityDescription(Entity, Desc ?? string.Empty, metaData); + MetaDataSystem?.SetEntityDescription(Entity, GetRTEntityDesc(), metaData); } args.GetArgument(0).TryGetValueAsDreamObject(out var loc); diff --git a/OpenDreamShared/Dream/ImmutableAppearance.cs b/OpenDreamShared/Dream/ImmutableAppearance.cs index 8dc97ecc2a..5688237d6d 100644 --- a/OpenDreamShared/Dream/ImmutableAppearance.cs +++ b/OpenDreamShared/Dream/ImmutableAppearance.cs @@ -29,7 +29,9 @@ public sealed class ImmutableAppearance : IEquatable { private bool _needsFinalizer; private int? _storedHashCode; private readonly SharedAppearanceSystem? _appearanceSystem; + [ViewVariables] public readonly string Name = MutableAppearance.Default.Name; + [ViewVariables] public readonly string? Desc = MutableAppearance.Default.Desc; [ViewVariables] public readonly int? Icon = MutableAppearance.Default.Icon; [ViewVariables] public readonly string? IconState = MutableAppearance.Default.IconState; [ViewVariables] public readonly AtomDirection Direction = MutableAppearance.Default.Direction; @@ -76,6 +78,7 @@ public ImmutableAppearance(MutableAppearance appearance, SharedAppearanceSystem? _appearanceSystem = serverAppearanceSystem; Name = appearance.Name; + Desc = appearance.Desc; Icon = appearance.Icon; IconState = appearance.IconState; Direction = appearance.Direction; @@ -142,6 +145,7 @@ public bool Equals(ImmutableAppearance? immutableAppearance) { if (immutableAppearance == null) return false; if (immutableAppearance.Name != Name) return false; + if (immutableAppearance.Desc != Desc) return false; if (immutableAppearance.Icon != Icon) return false; if (immutableAppearance.IconState != IconState) return false; if (immutableAppearance.Direction != Direction) return false; @@ -150,9 +154,9 @@ public bool Equals(ImmutableAppearance? immutableAppearance) { if (immutableAppearance.PixelOffset2 != PixelOffset2) return false; if (immutableAppearance.Color != Color) return false; if (immutableAppearance.Alpha != Alpha) return false; - if (immutableAppearance.GlideSize != GlideSize) return false; + if (!immutableAppearance.GlideSize.Equals(GlideSize)) return false; if (!immutableAppearance.ColorMatrix.Equals(ColorMatrix)) return false; - if (immutableAppearance.Layer != Layer) return false; + if (!immutableAppearance.Layer.Equals(Layer)) return false; if (immutableAppearance.Plane != Plane) return false; if (immutableAppearance.RenderSource != RenderSource) return false; if (immutableAppearance.RenderTarget != RenderTarget) return false; @@ -171,7 +175,6 @@ public bool Equals(ImmutableAppearance? immutableAppearance) { if (immutableAppearance.MaptextSize != MaptextSize) return false; if (immutableAppearance.MaptextOffset != MaptextOffset) return false; - for (int i = 0; i < Filters.Length; i++) { if (immutableAppearance.Filters[i] != Filters[i]) return false; } @@ -218,6 +221,7 @@ public override int GetHashCode() { HashCode hashCode = new HashCode(); hashCode.Add(Name); + hashCode.Add(Desc); hashCode.Add(Icon); hashCode.Add(IconState); hashCode.Add(Direction); @@ -283,6 +287,9 @@ public ImmutableAppearance(NetIncomingMessage buffer, IRobustSerializer serializ case IconAppearanceProperty.Name: Name = buffer.ReadString(); break; + case IconAppearanceProperty.Desc: + Desc = buffer.ReadString(); + break; case IconAppearanceProperty.Id: _registeredId = buffer.ReadVariableUInt32(); break; @@ -448,6 +455,7 @@ public MutableAppearance ToMutable() { MutableAppearance result = MutableAppearance.Get(); result.Name = Name; + result.Desc = Desc; result.Icon = Icon; result.IconState = IconState; result.Direction = Direction; @@ -496,6 +504,11 @@ public void WriteToBuffer(NetOutgoingMessage buffer, IRobustSerializer serialize buffer.Write(Name); } + if (Desc != MutableAppearance.Default.Desc) { + buffer.Write((byte)IconAppearanceProperty.Desc); + buffer.Write(Desc); + } + if (Icon != null) { buffer.Write((byte)IconAppearanceProperty.Icon); buffer.WriteVariableInt32(Icon.Value); diff --git a/OpenDreamShared/Dream/MutableAppearance.cs b/OpenDreamShared/Dream/MutableAppearance.cs index 6750f2381b..76c853cb03 100644 --- a/OpenDreamShared/Dream/MutableAppearance.cs +++ b/OpenDreamShared/Dream/MutableAppearance.cs @@ -26,6 +26,7 @@ public sealed class MutableAppearance : IEquatable, IDisposab private static Stack _mutableAppearancePool = new(); [ViewVariables] public string Name = string.Empty; + [ViewVariables] public string? Desc = string.Empty; [ViewVariables] public int? Icon; [ViewVariables] public string? IconState; [ViewVariables] public AtomDirection Direction = AtomDirection.South; @@ -106,6 +107,7 @@ public static MutableAppearance GetCopy(MutableAppearance appearance) { public void CopyFrom(MutableAppearance appearance) { Name = appearance.Name; + Desc = appearance.Desc; Icon = appearance.Icon; IconState = appearance.IconState; Direction = appearance.Direction; @@ -149,6 +151,7 @@ public bool Equals(MutableAppearance? appearance) { if (appearance == null) return false; if (appearance.Name != Name) return false; + if (appearance.Desc != Desc) return false; if (appearance.Icon != Icon) return false; if (appearance.IconState != IconState) return false; if (appearance.Direction != Direction) return false; @@ -242,6 +245,7 @@ public override int GetHashCode() { HashCode hashCode = new HashCode(); hashCode.Add(Name); + hashCode.Add(Desc); hashCode.Add(Icon); hashCode.Add(IconState); hashCode.Add(Direction); @@ -376,6 +380,7 @@ public enum AnimationFlags { //used for encoding for netmessages public enum IconAppearanceProperty : byte { Name, + Desc, Icon, IconState, Direction, diff --git a/OpenDreamShared/Network/Messages/MsgAllAppearances.cs b/OpenDreamShared/Network/Messages/MsgAllAppearances.cs index 6f7a2bc0f4..2d4b1afd91 100644 --- a/OpenDreamShared/Network/Messages/MsgAllAppearances.cs +++ b/OpenDreamShared/Network/Messages/MsgAllAppearances.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; +using System.Collections.Generic; using Lidgren.Network; using OpenDreamShared.Dream; using Robust.Shared.Network; @@ -12,6 +9,7 @@ namespace OpenDreamShared.Network.Messages; public sealed class MsgAllAppearances(Dictionary allAppearances) : NetMessage { public override MsgGroups MsgGroup => MsgGroups.EntityEvent; public Dictionary AllAppearances = allAppearances; + public MsgAllAppearances() : this(new()) { } public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer) {