From 52446993ffbc97d73e2a0c2fe147509f5acbe8d7 Mon Sep 17 00:00:00 2001 From: wixoa Date: Sun, 10 Sep 2023 22:58:50 -0400 Subject: [PATCH 1/8] Fix `\a` on strings (#1454) * Fix `\a` on strings * Add a test --- .../Tests/Text/StringInterpolation9.dm | 39 ++++++++++ OpenDreamRuntime/Objects/DreamObject.cs | 19 +++-- OpenDreamRuntime/Procs/DMOpcodeHandlers.cs | 71 +++++++++++-------- 3 files changed, 91 insertions(+), 38 deletions(-) create mode 100644 Content.Tests/DMProject/Tests/Text/StringInterpolation9.dm diff --git a/Content.Tests/DMProject/Tests/Text/StringInterpolation9.dm b/Content.Tests/DMProject/Tests/Text/StringInterpolation9.dm new file mode 100644 index 0000000000..9ff619a52a --- /dev/null +++ b/Content.Tests/DMProject/Tests/Text/StringInterpolation9.dm @@ -0,0 +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() + // 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/OpenDreamRuntime/Objects/DreamObject.cs b/OpenDreamRuntime/Objects/DreamObject.cs index 305ec32b0e..3d054eb781 100644 --- a/OpenDreamRuntime/Objects/DreamObject.cs +++ b/OpenDreamRuntime/Objects/DreamObject.cs @@ -276,8 +276,6 @@ public static bool StringIsProper(string str) { return true; case StringFormatEncoder.FormatSuffix.Improper: return false; - default: - break; } } @@ -312,9 +310,7 @@ public string GetDisplayName(StringFormatEncoder.FormatSuffix? suffix = null) { if (this is DreamObjectClient client) return client.Connection.Session!.Name; - if (!TryGetVariable("name", out DreamValue nameVar) || !nameVar.TryGetValueAsString(out string? name)) - return ObjectDefinition.Type.ToString(); - + var name = GetRawName(); bool isProper = StringIsProper(name); name = StringFormatEncoder.RemoveFormatting(name); // TODO: Care about other formatting macros for obj names beyond \proper & \improper if(!isProper) { @@ -335,9 +331,18 @@ public string GetDisplayName(StringFormatEncoder.FormatSuffix? suffix = null) { /// Similar to except it just returns the name as plaintext, with formatting removed. No article or anything. /// public string GetNameUnformatted() { + return StringFormatEncoder.RemoveFormatting(GetRawName()); + } + + /// + /// 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.Empty; - return StringFormatEncoder.RemoveFormatting(name); + return ObjectDefinition.Type.ToString(); + + return name; } #endregion Name Helpers diff --git a/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs b/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs index f9b8cab3ca..0043d5c807 100644 --- a/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs +++ b/OpenDreamRuntime/Procs/DMOpcodeHandlers.cs @@ -372,26 +372,28 @@ public static ProcStatus FormatString(DMProcState state) { nextInterpIndex++; continue; } - case StringFormatEncoder.FormatSuffix.StringifyNoArticle: - { - if (interps[nextInterpIndex].TryGetValueAsDreamObject(out var dreamObject) && dreamObject != null) { + case StringFormatEncoder.FormatSuffix.StringifyNoArticle: { + if (interps[nextInterpIndex].TryGetValueAsDreamObject(out var dreamObject)) { formattedString.Append(dreamObject.GetNameUnformatted()); + } else if (interps[nextInterpIndex].TryGetValueAsString(out var interpStr)) { + formattedString.Append(StringFormatEncoder.RemoveFormatting(interpStr)); } // NOTE probably should put this above the TryGetAsDreamObject function and continue if formatting has occured if(postPrefix != null) { // Cursed Hack - switch(postPrefix) { + switch (postPrefix) { case StringFormatEncoder.FormatSuffix.LowerRoman: ToRoman(ref formattedString, interps, nextInterpIndex, false); break; case StringFormatEncoder.FormatSuffix.UpperRoman: ToRoman(ref formattedString, interps, nextInterpIndex, true); break; - default: break; } + postPrefix = null; } - //Things that aren't objects just print nothing in this case + + //Things that aren't objects or strings just print nothing in this case prevInterpIndex = nextInterpIndex; nextInterpIndex++; continue; @@ -414,33 +416,40 @@ public static ProcStatus FormatString(DMProcState state) { continue; } case StringFormatEncoder.FormatSuffix.UpperIndefiniteArticle: - case StringFormatEncoder.FormatSuffix.LowerIndefiniteArticle: - { - bool wasCapital = formatType == StringFormatEncoder.FormatSuffix.UpperIndefiniteArticle; // saves some wordiness with the ternaries below - if (interps[nextInterpIndex].TryGetValueAsDreamObject(out var dreamObject) && dreamObject != null) - { - bool hasName = dreamObject.TryGetVariable("name", out var objectName); - string nameStr = objectName.Stringify(); - if (!hasName) continue; // datums that lack a name var don't use articles - if (DreamObject.StringIsProper(nameStr)) continue; // Proper nouns don't need articles, I guess. - - if (dreamObject.TryGetVariable("gender", out var gender)) // Aayy babe whats ya pronouns - { - if (gender.TryGetValueAsString(out var str) && str == "plural") // NOTE: In Byond, this part does not work if var/gender is not a native property of this object. - { - formattedString.Append(wasCapital ? "Some" : "some"); - continue; - } - } - if (DreamObject.StringStartsWithVowel(nameStr)) - { - formattedString.Append(wasCapital ? "An " : "an "); - continue; + case StringFormatEncoder.FormatSuffix.LowerIndefiniteArticle: { + var interpValue = interps[nextInterpIndex]; + string displayName; + bool isPlural = false; + + if (interpValue.TryGetValueAsDreamObject(out var dreamObject)) { + displayName = dreamObject.GetRawName(); + + // Aayy babe whats ya pronouns + if (dreamObject.TryGetVariable("gender", out var gender) && + gender.TryGetValueAsString(out var genderStr)) { + // NOTE: In Byond, this part does not work if var/gender is not a native property of this object. + isPlural = (genderStr == "plural"); } - formattedString.Append(wasCapital ? "A " : "a "); - continue; + } else if (interpValue.TryGetValueAsString(out var interpStr)) { + displayName = interpStr; + } else { + break; } - continue; + + if (DreamObject.StringIsProper(displayName)) + break; // Proper nouns don't need articles, I guess. + + // saves some wordiness with the ternaries below + bool wasCapital = formatType == StringFormatEncoder.FormatSuffix.UpperIndefiniteArticle; + + if (isPlural) + formattedString.Append(wasCapital ? "Some " : "some "); + else if (DreamObject.StringStartsWithVowel(displayName)) + formattedString.Append(wasCapital ? "An " : "an "); + else + formattedString.Append(wasCapital ? "A " : "a "); + + break; } //Suffix macros case StringFormatEncoder.FormatSuffix.UpperSubjectPronoun: From 4c0f24a1dabb08712746e32b250245a2f5f29e63 Mon Sep 17 00:00:00 2001 From: Amy <3855802+amylizzle@users.noreply.github.com> Date: Mon, 11 Sep 2023 14:36:56 +0100 Subject: [PATCH 2/8] make menu elements addressable (#1447) Co-authored-by: amy --- OpenDreamClient/Interface/DreamInterfaceManager.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenDreamClient/Interface/DreamInterfaceManager.cs b/OpenDreamClient/Interface/DreamInterfaceManager.cs index a6260f2105..ec1cfe9ec8 100644 --- a/OpenDreamClient/Interface/DreamInterfaceManager.cs +++ b/OpenDreamClient/Interface/DreamInterfaceManager.cs @@ -375,6 +375,9 @@ public void FrameUpdate(FrameEventArgs frameEventArgs) { window = Windows[windowId]; } else if (_popupWindows.TryGetValue(windowId, out var popup)) { window = popup.WindowElement; + } else if (Menus.TryGetValue(windowId, out var menu)) { + if(menu.MenuElements.TryGetValue(elementId, out var menuElement)) + return menuElement; } if (window != null) { From 72633ba57bad48a8d2865b8f9736e600184587ba Mon Sep 17 00:00:00 2001 From: wixoa Date: Wed, 13 Sep 2023 10:33:14 -0400 Subject: [PATCH 3/8] Support sleep calls without parentheses (#1461) --- DMCompiler/Compiler/DM/DMParser.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/DMCompiler/Compiler/DM/DMParser.cs b/DMCompiler/Compiler/DM/DMParser.cs index 2a630fdb62..e1b9d8d8de 100644 --- a/DMCompiler/Compiler/DM/DMParser.cs +++ b/DMCompiler/Compiler/DM/DMParser.cs @@ -636,7 +636,20 @@ public DMASTFile File() { if (expression != null) { switch (expression) { case DMASTIdentifier identifier: - Check(TokenType.DM_Colon); + // This could be a sleep without parentheses + if (!Check(TokenType.DM_Colon) && !leadingColon && identifier.Identifier == "sleep") { + var procIdentifier = new DMASTCallableProcIdentifier(expression.Location, "sleep"); + var sleepTime = Expression(); + if (sleepTime == null) // The argument is optional + sleepTime = new DMASTConstantNull(Location.Internal); + + // TODO: Make sleep an opcode + expression = new DMASTProcCall(expression.Location, procIdentifier, + new[] { new DMASTCallParameter(sleepTime.Location, sleepTime) }); + break; + } + + // But it was a label return Label(identifier); case DMASTRightShift rightShift: // A right shift on its own becomes a special "input" statement From 6f9755f98e023d757a3e95fb480697e1add864d3 Mon Sep 17 00:00:00 2001 From: wixoa Date: Fri, 15 Sep 2023 12:04:40 -0400 Subject: [PATCH 4/8] Use a for loop in `DreamList.ContainsValue()` (#1470) --- OpenDreamRuntime/Objects/Types/DreamList.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OpenDreamRuntime/Objects/Types/DreamList.cs b/OpenDreamRuntime/Objects/Types/DreamList.cs index 750091cd67..55862fb108 100644 --- a/OpenDreamRuntime/Objects/Types/DreamList.cs +++ b/OpenDreamRuntime/Objects/Types/DreamList.cs @@ -142,7 +142,12 @@ public virtual void AddValue(DreamValue value) { //Does not include associations public virtual bool ContainsValue(DreamValue value) { - return _values.Contains(value); + for (int i = 0; i < _values.Count; i++) { + if (_values[i].Equals(value)) + return true; + } + + return false; } public virtual bool ContainsKey(DreamValue value) { From f46e718f355e5533b0508f06cacaa23d84882bb5 Mon Sep 17 00:00:00 2001 From: wixoa Date: Fri, 15 Sep 2023 12:15:41 -0400 Subject: [PATCH 5/8] Set `/mob.density` to true by default (#1466) --- DMCompiler/DMStandard/Types/Atoms/Mob.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/DMCompiler/DMStandard/Types/Atoms/Mob.dm b/DMCompiler/DMStandard/Types/Atoms/Mob.dm index 14b1d0659a..ebcfcbea70 100644 --- a/DMCompiler/DMStandard/Types/Atoms/Mob.dm +++ b/DMCompiler/DMStandard/Types/Atoms/Mob.dm @@ -12,6 +12,7 @@ var/sight = 0 var/see_in_dark = 2 as opendream_unimplemented + density = TRUE layer = MOB_LAYER proc/Login() From 5143df248b7fedddf0c859acde75acaaec0001b1 Mon Sep 17 00:00:00 2001 From: wixoa Date: Fri, 15 Sep 2023 12:16:19 -0400 Subject: [PATCH 6/8] Set `usr` when calling client's movement procs (#1469) --- OpenDreamRuntime/DreamConnection.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/OpenDreamRuntime/DreamConnection.cs b/OpenDreamRuntime/DreamConnection.cs index d52c8e27db..a7c97e71bd 100644 --- a/OpenDreamRuntime/DreamConnection.cs +++ b/OpenDreamRuntime/DreamConnection.cs @@ -328,15 +328,15 @@ public void HandleCommand(string fullCommand) { switch (command) { //TODO: Maybe move these verbs to DM code? - case ".north": Client?.SpawnProc("North"); break; - case ".east": Client?.SpawnProc("East"); break; - case ".south": Client?.SpawnProc("South"); break; - case ".west": Client?.SpawnProc("West"); break; - case ".northeast": Client?.SpawnProc("Northeast"); break; - case ".southeast": Client?.SpawnProc("Southeast"); break; - case ".southwest": Client?.SpawnProc("Southwest"); break; - case ".northwest": Client?.SpawnProc("Northwest"); break; - case ".center": Client?.SpawnProc("Center"); break; + case ".north": Client?.SpawnProc("North", Mob); break; + case ".east": Client?.SpawnProc("East", Mob); break; + case ".south": Client?.SpawnProc("South", Mob); break; + case ".west": Client?.SpawnProc("West", Mob); break; + case ".northeast": Client?.SpawnProc("Northeast", Mob); break; + case ".southeast": Client?.SpawnProc("Southeast", Mob); break; + case ".southwest": Client?.SpawnProc("Southwest", Mob); break; + case ".northwest": Client?.SpawnProc("Northwest", Mob); break; + case ".center": Client?.SpawnProc("Center", Mob); break; default: { if (_availableVerbs.TryGetValue(command, out var value)) { From 0fb43f6f57898944fa0a96ad9557ac00f2b7f8a9 Mon Sep 17 00:00:00 2001 From: Amy <3855802+amylizzle@users.noreply.github.com> Date: Sun, 17 Sep 2023 15:51:33 +0100 Subject: [PATCH 7/8] Fixes `findtextlast()` and adds test (#1451) * jesus christ * remove debug statements from test * fix defaults for findlasttextex --------- Co-authored-by: amy --- .../DMProject/Tests/Text/findlasttext.dm | 20 ++++++ .../Procs/Native/DreamProcNativeRoot.cs | 66 +++++++++++-------- 2 files changed, 60 insertions(+), 26 deletions(-) create mode 100644 Content.Tests/DMProject/Tests/Text/findlasttext.dm diff --git a/Content.Tests/DMProject/Tests/Text/findlasttext.dm b/Content.Tests/DMProject/Tests/Text/findlasttext.dm new file mode 100644 index 0000000000..c8d6eb403b --- /dev/null +++ b/Content.Tests/DMProject/Tests/Text/findlasttext.dm @@ -0,0 +1,20 @@ +/proc/RunTest() + ASSERT(findlasttext("abcdefg", "f", 0, -1) == 0) + ASSERT(findlasttext("abcdefg", "f", 0, -2) == 6) + ASSERT(findlasttext("abcdefg", "f", 6) == 6) + ASSERT(findlasttext("abcdefg", "f", 5) == 0) + ASSERT(findlasttext("abcdefg", "bc", 2) == 2) + ASSERT(findlasttext("abcdefg", "ab", 10) == 1) + ASSERT(findlasttext("abcdefg", "f", 5) == 0) + ASSERT(findlasttext("Banana", "na", -3) == 3) + ASSERT(findlasttext("Banana", "na", -5) == 0) + ASSERT(findlasttext("Banana", "na", 0) == 5) + ASSERT(findlasttext("Banana", "na", 3) == 3) + ASSERT(findlasttext("Banana", "na", 2) == 0) + ASSERT(findlasttext("Banana", "na", 5) == 5) + ASSERT(findlasttext("Banana", "na", 50) == 5) + ASSERT(findlasttext("Banana", "na", -50) == 0) + ASSERT(findlasttext("abcdefg", "f", 6, -50) == 6) + ASSERT(findlasttext("abcdefg", "f", 6, 50) == 0) + + \ No newline at end of file diff --git a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs index acf31b8c0f..22de0d1361 100644 --- a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs +++ b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs @@ -691,8 +691,8 @@ public static DreamValue NativeProc_findtextEx(NativeProc.Bundle bundle, DreamOb [DreamProc("findlasttext")] [DreamProcParameter("Haystack", Type = DreamValueTypeFlag.String)] [DreamProcParameter("Needle", Type = DreamValueTypeFlag.String)] - [DreamProcParameter("Start", Type = DreamValueTypeFlag.Float, DefaultValue = 1)] - [DreamProcParameter("End", Type = DreamValueTypeFlag.Float, DefaultValue = 0)] + [DreamProcParameter("Start", Type = DreamValueTypeFlag.Float, DefaultValue = 0)] + [DreamProcParameter("End", Type = DreamValueTypeFlag.Float, DefaultValue = 1)] public static DreamValue NativeProc_findlasttext(NativeProc.Bundle bundle, DreamObject? src, DreamObject? usr) { // TODO This is for handling nulls, check if it works right for other bad types int failCount = 0; @@ -706,26 +706,33 @@ public static DreamValue NativeProc_findlasttext(NativeProc.Bundle bundle, Dream return new DreamValue(failCount == 2 ? 1 : 0); } - int start = bundle.GetArgument(2, "Start").MustGetValueAsInteger(); //1-indexed - int end = bundle.GetArgument(3, "End").MustGetValueAsInteger(); //1-indexed + int start = bundle.GetArgument(2, "Start").MustGetValueAsInteger(); //chars from the end + int end = bundle.GetArgument(3, "End").MustGetValueAsInteger(); //1-indexed from the beginning + int actualstart; + int actualcount; - if (end == 0) { - end = text.Length + 1; - } + if(start > 0) + actualstart = start-1; + else + actualstart = (text.Length-1) + start; + actualstart += needle.Length-1; + actualstart = Math.Max(Math.Min(text.Length, actualstart),0); - int needleIndex = text.LastIndexOf(needle, end - 1, end - start, StringComparison.OrdinalIgnoreCase); - if (needleIndex != -1) { - return new DreamValue(needleIndex + 1); //1-indexed - } else { - return new DreamValue(0); - } + if(end > 0) + actualcount = actualstart - (end-1); + else + actualcount = actualstart - ((text.Length-1) + (end)); + actualcount += needle.Length-1; + actualcount = Math.Max(Math.Min(actualstart+1, actualcount),0); + int needleIndex = text.LastIndexOf(needle, actualstart, actualcount, StringComparison.OrdinalIgnoreCase); + return new DreamValue(needleIndex + 1); //1-indexed, or 0 if not found (LastIndexOf returns -1 if not found) } [DreamProc("findlasttextEx")] [DreamProcParameter("Haystack", Type = DreamValueTypeFlag.String)] [DreamProcParameter("Needle", Type = DreamValueTypeFlag.String)] - [DreamProcParameter("Start", Type = DreamValueTypeFlag.Float, DefaultValue = 1)] - [DreamProcParameter("End", Type = DreamValueTypeFlag.Float, DefaultValue = 0)] + [DreamProcParameter("Start", Type = DreamValueTypeFlag.Float, DefaultValue = 0)] + [DreamProcParameter("End", Type = DreamValueTypeFlag.Float, DefaultValue = 1)] public static DreamValue NativeProc_findlasttextEx(NativeProc.Bundle bundle, DreamObject? src, DreamObject? usr) { // TODO This is for handling nulls, check if it works right for other bad types int failCount = 0; @@ -741,17 +748,24 @@ public static DreamValue NativeProc_findlasttextEx(NativeProc.Bundle bundle, Dre int start = bundle.GetArgument(2, "Start").GetValueAsInteger(); //1-indexed int end = bundle.GetArgument(3, "End").GetValueAsInteger(); //1-indexed - - if (end == 0) { - end = text.Length + 1; - } - - int needleIndex = text.LastIndexOf(needle, end - 1, end - start, StringComparison.InvariantCulture); - if (needleIndex != -1) { - return new DreamValue(needleIndex + 1); //1-indexed - } else { - return new DreamValue(0); - } + int actualstart; + int actualcount; + + if(start > 0) + actualstart = start-1; + else + actualstart = (text.Length-1) + start; + actualstart += needle.Length-1; + actualstart = Math.Max(Math.Min(text.Length, actualstart),0); + + if(end > 0) + actualcount = actualstart - (end-1); + else + actualcount = actualstart - ((text.Length-1) + (end)); + actualcount += needle.Length-1; + actualcount = Math.Max(Math.Min(actualstart+1, actualcount),0); + int needleIndex = text.LastIndexOf(needle, actualstart, actualcount, StringComparison.InvariantCulture); + return new DreamValue(needleIndex + 1); //1-indexed, or 0 if not found (LastIndexOf returns -1 if not found) } [DreamProc("flick")] From 90fce273639e4f79f3751a76aad6589d162eef52 Mon Sep 17 00:00:00 2001 From: ZeWaka Date: Thu, 21 Sep 2023 13:44:14 -0700 Subject: [PATCH 8/8] Upgrade RobustToolbox to v158 (#1471) * Upgrade to v154.2.0 * Upgrade to v156.0.0 * Update to RobustToolbox v157.1.0 * Upgrade to RobustToolbox v158.0.0 --- OpenDreamClient/Input/MouseInputSystem.cs | 4 +++- .../Interface/Controls/ScalingViewport.cs | 1 + .../Rendering/ClientAppearanceSystem.cs | 3 ++- OpenDreamClient/Rendering/ClientImagesSystem.cs | 14 ++++++++------ .../Rendering/ClientScreenOverlaySystem.cs | 6 ++++-- OpenDreamClient/Rendering/DreamViewOverlay.cs | 5 +++-- OpenDreamRuntime/AtomManager.cs | 4 +++- OpenDreamRuntime/Input/MouseInputSystem.cs | 4 +++- OpenDreamRuntime/Objects/Types/DreamList.cs | 5 +++-- .../Rendering/ServerAppearanceSystem.cs | 2 +- .../Rendering/ServerClientImagesSystem.cs | 6 ++++-- .../Rendering/ServerScreenOverlaySystem.cs | 7 +++++-- OpenDreamShared/Dream/IconAppearance.cs | 4 ++-- OpenDreamShared/Input/SharedMouseInputSystem.cs | 6 +++--- .../Rendering/SharedAppearanceSystem.cs | 4 ++-- .../Rendering/SharedClientImagesSystem.cs | 8 ++++---- .../Rendering/SharedScreenOverlaySystem.cs | 8 ++++---- RobustToolbox | 2 +- 18 files changed, 56 insertions(+), 37 deletions(-) diff --git a/OpenDreamClient/Input/MouseInputSystem.cs b/OpenDreamClient/Input/MouseInputSystem.cs index 883805040e..c0757b8c50 100644 --- a/OpenDreamClient/Input/MouseInputSystem.cs +++ b/OpenDreamClient/Input/MouseInputSystem.cs @@ -18,6 +18,7 @@ internal sealed class MouseInputSystem : SharedMouseInputSystem { [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IOverlayManager _overlayManager = default!; [Dependency] private readonly EntityLookupSystem _lookupSystem = default!; + [Dependency] private IEntityManager _entityManager = default!; private DreamViewOverlay? _dreamViewOverlay; private ContextMenuPopup _contextMenu = default!; @@ -87,7 +88,8 @@ public bool HandleViewportClick(ScalingViewport viewport, GUIBoundKeyEventArgs a // TODO: Take icon transformations into account Vector2i iconPosition = (Vector2i) ((mapCoords.Position - entity.Position) * EyeManager.PixelsPerMeter); - RaiseNetworkEvent(new EntityClickedEvent(entity.ClickUid, screenLoc, middle, shift, ctrl, alt, iconPosition)); + NetEntity ent = _entityManager.GetNetEntity(entity.ClickUid); + RaiseNetworkEvent(new EntityClickedEvent(ent, screenLoc, middle, shift, ctrl, alt, iconPosition)); return true; } diff --git a/OpenDreamClient/Interface/Controls/ScalingViewport.cs b/OpenDreamClient/Interface/Controls/ScalingViewport.cs index 972f002af0..bb0de7f9c9 100644 --- a/OpenDreamClient/Interface/Controls/ScalingViewport.cs +++ b/OpenDreamClient/Interface/Controls/ScalingViewport.cs @@ -2,6 +2,7 @@ using Robust.Client.Input; using Robust.Client.UserInterface; using Robust.Client.UserInterface.CustomControls; +using Robust.Shared.Graphics; using Robust.Shared.Map; using Robust.Shared.Utility; using SixLabors.ImageSharp.PixelFormats; diff --git a/OpenDreamClient/Rendering/ClientAppearanceSystem.cs b/OpenDreamClient/Rendering/ClientAppearanceSystem.cs index e12000d26d..2407ea2036 100644 --- a/OpenDreamClient/Rendering/ClientAppearanceSystem.cs +++ b/OpenDreamClient/Rendering/ClientAppearanceSystem.cs @@ -72,7 +72,8 @@ private void OnNewAppearance(NewAppearanceEvent e) { } private void OnAnimation(AnimationEvent e) { - if (!_entityManager.TryGetComponent(e.Entity, out var sprite)) + EntityUid ent = _entityManager.GetEntity(e.Entity); + if (!_entityManager.TryGetComponent(ent, out var sprite)) return; LoadAppearance(e.TargetAppearanceId, targetAppearance => { diff --git a/OpenDreamClient/Rendering/ClientImagesSystem.cs b/OpenDreamClient/Rendering/ClientImagesSystem.cs index 9078616d6e..24d8579d6f 100644 --- a/OpenDreamClient/Rendering/ClientImagesSystem.cs +++ b/OpenDreamClient/Rendering/ClientImagesSystem.cs @@ -41,7 +41,8 @@ public bool TryGetClientImages(EntityUid entity, Vector3? tileCoords, [NotNullWh } private void OnAddClientImage(AddClientImageEvent e) { - if(e.AttachedEntity == EntityUid.Invalid) { + EntityUid ent = _entityManager.GetEntity(e.AttachedEntity); + if(ent == EntityUid.Invalid) { if(!TurfClientImages.TryGetValue(e.TurfCoords, out var iconList)) iconList = new List(); if(!_idToIcon.ContainsKey(e.ImageAppearance)){ @@ -51,30 +52,31 @@ private void OnAddClientImage(AddClientImageEvent e) { iconList.Add(e.ImageAppearance); TurfClientImages[e.TurfCoords] = iconList; } else { - if(!AMClientImages.TryGetValue(e.AttachedEntity, out var iconList)) + if(!AMClientImages.TryGetValue(ent, out var iconList)) iconList = new List(); if(!_idToIcon.ContainsKey(e.ImageAppearance)){ DreamIcon icon = new DreamIcon(e.ImageAppearance); _idToIcon[e.ImageAppearance] = icon; } iconList.Add(e.ImageAppearance); - AMClientImages[e.AttachedEntity] = iconList; + AMClientImages[ent] = iconList; } } private void OnRemoveClientImage(RemoveClientImageEvent e) { - if(e.AttachedEntity == EntityUid.Invalid) { + EntityUid ent = _entityManager.GetEntity(e.AttachedEntity); + if(ent == EntityUid.Invalid) { if(!TurfClientImages.TryGetValue(e.TurfCoords, out var iconList)) return; iconList.Remove(e.ImageAppearance); TurfClientImages[e.TurfCoords] = iconList; _idToIcon.Remove(e.ImageAppearance); } else { - if(!AMClientImages.TryGetValue(e.AttachedEntity, out var iconList)) + if(!AMClientImages.TryGetValue(ent, out var iconList)) return; iconList.Remove(e.ImageAppearance); - AMClientImages[e.AttachedEntity] = iconList; + AMClientImages[ent] = iconList; _idToIcon.Remove(e.ImageAppearance); } } diff --git a/OpenDreamClient/Rendering/ClientScreenOverlaySystem.cs b/OpenDreamClient/Rendering/ClientScreenOverlaySystem.cs index 86afc05443..5a2bd05319 100644 --- a/OpenDreamClient/Rendering/ClientScreenOverlaySystem.cs +++ b/OpenDreamClient/Rendering/ClientScreenOverlaySystem.cs @@ -16,11 +16,13 @@ public override void Shutdown() { } private void OnAddScreenObject(AddScreenObjectEvent e) { - ScreenObjects.Add(e.ScreenObject); + EntityUid ent = _entityManager.GetEntity(e.ScreenObject); + ScreenObjects.Add(ent); } private void OnRemoveScreenObject(RemoveScreenObjectEvent e) { - ScreenObjects.Remove(e.ScreenObject); + EntityUid ent = _entityManager.GetEntity(e.ScreenObject); + ScreenObjects.Remove(ent); } } } diff --git a/OpenDreamClient/Rendering/DreamViewOverlay.cs b/OpenDreamClient/Rendering/DreamViewOverlay.cs index 8e0adf4bdb..7e4029b864 100644 --- a/OpenDreamClient/Rendering/DreamViewOverlay.cs +++ b/OpenDreamClient/Rendering/DreamViewOverlay.cs @@ -304,10 +304,11 @@ private void ProcessIconComponents(DreamIcon icon, Vector2 position, EntityUid u } foreach (var visContent in icon.Appearance.VisContents) { - if (!_spriteQuery.TryGetComponent(visContent, out var sprite)) + EntityUid visContentEntity = _entityManager.GetEntity(visContent); + if (!_spriteQuery.TryGetComponent(visContentEntity, out var sprite)) continue; - ProcessIconComponents(sprite.Icon, position, visContent, false, ref tieBreaker, result, current, keepTogether); + ProcessIconComponents(sprite.Icon, position, visContentEntity, false, ref tieBreaker, result, current, keepTogether); // TODO: click uid should be set to current.uid again // TODO: vis_flags diff --git a/OpenDreamRuntime/AtomManager.cs b/OpenDreamRuntime/AtomManager.cs index adcc0bb55b..47d99387dd 100644 --- a/OpenDreamRuntime/AtomManager.cs +++ b/OpenDreamRuntime/AtomManager.cs @@ -344,7 +344,9 @@ public void AnimateAppearance(DreamObjectAtom atom, TimeSpan duration, Action _visContents = new(); @@ -755,7 +756,7 @@ public override void AddValue(DreamValue value) { _atomManager.UpdateAppearance(_atom, appearance => { // Add even an invalid UID to keep this and _visContents in sync - appearance.VisContents.Add(entity); + appearance.VisContents.Add(_entityManager.GetNetEntity(entity)); }); } @@ -765,7 +766,7 @@ public override void RemoveValue(DreamValue value) { _visContents.Remove(movable); _atomManager.UpdateAppearance(_atom, appearance => { - appearance.VisContents.Remove(movable.Entity); + appearance.VisContents.Remove(_entityManager.GetNetEntity(movable.Entity)); }); } diff --git a/OpenDreamRuntime/Rendering/ServerAppearanceSystem.cs b/OpenDreamRuntime/Rendering/ServerAppearanceSystem.cs index a59405ce6c..71225731b5 100644 --- a/OpenDreamRuntime/Rendering/ServerAppearanceSystem.cs +++ b/OpenDreamRuntime/Rendering/ServerAppearanceSystem.cs @@ -51,7 +51,7 @@ public bool TryGetAppearanceId(IconAppearance appearance, out int appearanceId) return _appearanceToId.TryGetValue(appearance, out appearanceId); } - public void Animate(EntityUid entity, IconAppearance targetAppearance, TimeSpan duration) { + public void Animate(NetEntity entity, IconAppearance targetAppearance, TimeSpan duration) { int appearanceId = AddAppearance(targetAppearance); RaiseNetworkEvent(new AnimationEvent(entity, appearanceId, duration)); diff --git a/OpenDreamRuntime/Rendering/ServerClientImagesSystem.cs b/OpenDreamRuntime/Rendering/ServerClientImagesSystem.cs index 0d1126bbe4..95b312d875 100644 --- a/OpenDreamRuntime/Rendering/ServerClientImagesSystem.cs +++ b/OpenDreamRuntime/Rendering/ServerClientImagesSystem.cs @@ -27,7 +27,8 @@ public void AddImageObject(DreamConnection connection, DreamObjectImage imageObj else if(loc is DreamObjectTurf turf) turfCoords = new Vector3(turf.X, turf.Y, turf.Z); - RaiseNetworkEvent(new AddClientImageEvent(locEntity, turfCoords, imageAppearanceID), connection.Session.ConnectedClient); + NetEntity ent = GetNetEntity(locEntity); + RaiseNetworkEvent(new AddClientImageEvent(ent, turfCoords, imageAppearanceID), connection.Session.ConnectedClient); } public void RemoveImageObject(DreamConnection connection, DreamObjectImage imageObject) { @@ -46,6 +47,7 @@ public void RemoveImageObject(DreamConnection connection, DreamObjectImage image turfCoords = new Vector3(turf.X, turf.Y, turf.Z); - RaiseNetworkEvent(new RemoveClientImageEvent(locEntity, turfCoords, imageAppearanceID), connection.Session.ConnectedClient); + NetEntity ent = GetNetEntity(locEntity); + RaiseNetworkEvent(new RemoveClientImageEvent(ent, turfCoords, imageAppearanceID), connection.Session.ConnectedClient); } } diff --git a/OpenDreamRuntime/Rendering/ServerScreenOverlaySystem.cs b/OpenDreamRuntime/Rendering/ServerScreenOverlaySystem.cs index eb65a17cbc..f697e6823b 100644 --- a/OpenDreamRuntime/Rendering/ServerScreenOverlaySystem.cs +++ b/OpenDreamRuntime/Rendering/ServerScreenOverlaySystem.cs @@ -6,6 +6,7 @@ namespace OpenDreamRuntime.Rendering { public sealed class ServerScreenOverlaySystem : SharedScreenOverlaySystem { private readonly Dictionary> _sessionToScreenObjects = new(); + [Dependency] private IEntityManager _entityManager = default!; public override void Initialize() { SubscribeLocalEvent(HandleExpandPvsEvent); @@ -18,12 +19,14 @@ public void AddScreenObject(DreamConnection connection, DreamObjectMovable scree } objects.Add(screenObject.Entity); - RaiseNetworkEvent(new AddScreenObjectEvent(screenObject.Entity), connection.Session.ConnectedClient); + NetEntity ent = _entityManager.GetNetEntity(screenObject.Entity); + RaiseNetworkEvent(new AddScreenObjectEvent(ent), connection.Session.ConnectedClient); } public void RemoveScreenObject(DreamConnection connection, DreamObjectMovable screenObject) { _sessionToScreenObjects[connection.Session].Remove(screenObject.Entity); - RaiseNetworkEvent(new RemoveScreenObjectEvent(screenObject.Entity), connection.Session.ConnectedClient); + NetEntity ent = _entityManager.GetNetEntity(screenObject.Entity); + RaiseNetworkEvent(new RemoveScreenObjectEvent(ent), connection.Session.ConnectedClient); } private void HandleExpandPvsEvent(ref ExpandPvsEvent e) { diff --git a/OpenDreamShared/Dream/IconAppearance.cs b/OpenDreamShared/Dream/IconAppearance.cs index 5eb532d155..e82c044d24 100644 --- a/OpenDreamShared/Dream/IconAppearance.cs +++ b/OpenDreamShared/Dream/IconAppearance.cs @@ -42,7 +42,7 @@ public sealed class IconAppearance : IEquatable { [ViewVariables] public MouseOpacity MouseOpacity = MouseOpacity.PixelOpaque; [ViewVariables] public List Overlays = new(); [ViewVariables] public List Underlays = new(); - [ViewVariables] public List VisContents = new(); + [ViewVariables] public List VisContents = new(); [ViewVariables] public List Filters = new(); /// The Transform property of this appearance, in [a,d,b,e,c,f] order [ViewVariables] public float[] Transform = new float[6] { 1, 0, // a d @@ -72,7 +72,7 @@ public IconAppearance(IconAppearance appearance) { MouseOpacity = appearance.MouseOpacity; Overlays = new List(appearance.Overlays); Underlays = new List(appearance.Underlays); - VisContents = new List(appearance.VisContents); + VisContents = new List(appearance.VisContents); Filters = new List(appearance.Filters); Override = appearance.Override; diff --git a/OpenDreamShared/Input/SharedMouseInputSystem.cs b/OpenDreamShared/Input/SharedMouseInputSystem.cs index 2007e6c14a..2d61eeda9b 100644 --- a/OpenDreamShared/Input/SharedMouseInputSystem.cs +++ b/OpenDreamShared/Input/SharedMouseInputSystem.cs @@ -21,7 +21,7 @@ protected interface IAtomClickedEvent { [Serializable, NetSerializable] public sealed class EntityClickedEvent : EntityEventArgs, IAtomClickedEvent { - public EntityUid EntityUid { get; } + public NetEntity NetEntity { get; } public ScreenLocation ScreenLoc { get; } public bool Middle { get; } public bool Shift { get; } @@ -30,8 +30,8 @@ public sealed class EntityClickedEvent : EntityEventArgs, IAtomClickedEvent { public int IconX { get; } public int IconY { get; } - public EntityClickedEvent(EntityUid entityUid, ScreenLocation screenLoc, bool middle, bool shift, bool ctrl, bool alt, Vector2i iconPos) { - EntityUid = entityUid; + public EntityClickedEvent(NetEntity netEntity, ScreenLocation screenLoc, bool middle, bool shift, bool ctrl, bool alt, Vector2i iconPos) { + NetEntity = netEntity; ScreenLoc = screenLoc; Middle = middle; Shift = shift; diff --git a/OpenDreamShared/Rendering/SharedAppearanceSystem.cs b/OpenDreamShared/Rendering/SharedAppearanceSystem.cs index 1befa6326c..2182b484df 100644 --- a/OpenDreamShared/Rendering/SharedAppearanceSystem.cs +++ b/OpenDreamShared/Rendering/SharedAppearanceSystem.cs @@ -28,11 +28,11 @@ public NewAppearanceEvent(int appearanceID, IconAppearance appearance) { [Serializable, NetSerializable] public sealed class AnimationEvent : EntityEventArgs { - public EntityUid Entity; + public NetEntity Entity; public int TargetAppearanceId; public TimeSpan Duration; - public AnimationEvent(EntityUid entity, int targetAppearanceId, TimeSpan duration) { + public AnimationEvent(NetEntity entity, int targetAppearanceId, TimeSpan duration) { Entity = entity; TargetAppearanceId = targetAppearanceId; Duration = duration; diff --git a/OpenDreamShared/Rendering/SharedClientImagesSystem.cs b/OpenDreamShared/Rendering/SharedClientImagesSystem.cs index 71ce44641e..eb709f4f37 100644 --- a/OpenDreamShared/Rendering/SharedClientImagesSystem.cs +++ b/OpenDreamShared/Rendering/SharedClientImagesSystem.cs @@ -12,10 +12,10 @@ public class SharedClientImagesSystem : EntitySystem { [Serializable, NetSerializable] public sealed class AddClientImageEvent : EntityEventArgs { public Vector3 TurfCoords; - public EntityUid AttachedEntity; //if this is EntityUid.Invalid (ie, a turf) use the TurfCoords instead + public NetEntity AttachedEntity; //if this is NetEntity.Invalid (ie, a turf) use the TurfCoords instead public int ImageAppearance; - public AddClientImageEvent(EntityUid attachedEntity, Vector3 turfCoords, int imageAppearance) { + public AddClientImageEvent(NetEntity attachedEntity, Vector3 turfCoords, int imageAppearance) { TurfCoords = turfCoords; ImageAppearance = imageAppearance; AttachedEntity = attachedEntity; @@ -25,10 +25,10 @@ public AddClientImageEvent(EntityUid attachedEntity, Vector3 turfCoords, int ima [Serializable, NetSerializable] public sealed class RemoveClientImageEvent : EntityEventArgs { public Vector3 TurfCoords; - public EntityUid AttachedEntity; //if this is EntityUid.Invalid (ie, a turf) use the TurfCoords instead + public NetEntity AttachedEntity; //if this is NetEntity.Invalid (ie, a turf) use the TurfCoords instead public int ImageAppearance; - public RemoveClientImageEvent(EntityUid attachedEntity, Vector3 turfCoords, int imageAppearance) { + public RemoveClientImageEvent(NetEntity attachedEntity, Vector3 turfCoords, int imageAppearance) { TurfCoords = turfCoords; ImageAppearance = imageAppearance; AttachedEntity = attachedEntity; diff --git a/OpenDreamShared/Rendering/SharedScreenOverlaySystem.cs b/OpenDreamShared/Rendering/SharedScreenOverlaySystem.cs index fc4f74fd58..b7a44b189b 100644 --- a/OpenDreamShared/Rendering/SharedScreenOverlaySystem.cs +++ b/OpenDreamShared/Rendering/SharedScreenOverlaySystem.cs @@ -8,18 +8,18 @@ namespace OpenDreamShared.Rendering { public class SharedScreenOverlaySystem : EntitySystem { [Serializable, NetSerializable] public sealed class AddScreenObjectEvent : EntityEventArgs { - public EntityUid ScreenObject; + public NetEntity ScreenObject; - public AddScreenObjectEvent(EntityUid screenObject) { + public AddScreenObjectEvent(NetEntity screenObject) { ScreenObject = screenObject; } } [Serializable, NetSerializable] public sealed class RemoveScreenObjectEvent : EntityEventArgs { - public EntityUid ScreenObject; + public NetEntity ScreenObject; - public RemoveScreenObjectEvent(EntityUid screenObject) { + public RemoveScreenObjectEvent(NetEntity screenObject) { ScreenObject = screenObject; } } diff --git a/RobustToolbox b/RobustToolbox index 01546f32da..8ce3a03136 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 01546f32dafa76b4874732ba94435d7bd332a5e1 +Subproject commit 8ce3a03136e1f334772c3b60040923d0037bced8