From 435a89a71dee03646b52b312731f2803be5b5b57 Mon Sep 17 00:00:00 2001 From: ike709 Date: Tue, 11 Feb 2025 01:53:43 -0600 Subject: [PATCH] Implement `values_dot()` --- .../DMProject/Tests/Builtins/values_dot.dm | 5 ++++ DMCompiler/DMStandard/_Standard.dm | 1 + .../Procs/Native/DreamProcNative.cs | 1 + .../Procs/Native/DreamProcNativeRoot.cs | 29 +++++++++++++++++++ 4 files changed, 36 insertions(+) create mode 100644 Content.Tests/DMProject/Tests/Builtins/values_dot.dm diff --git a/Content.Tests/DMProject/Tests/Builtins/values_dot.dm b/Content.Tests/DMProject/Tests/Builtins/values_dot.dm new file mode 100644 index 0000000000..8d78f0a188 --- /dev/null +++ b/Content.Tests/DMProject/Tests/Builtins/values_dot.dm @@ -0,0 +1,5 @@ + +/proc/RunTest() + ASSERT(values_dot(list(a=2.4,b=1,c=7),list(a=2,b=4,c=null)) == 8.8) + ASSERT(values_dot(list(),list(a=2,b=4)) == 0) + ASSERT(values_dot(list("a"),list(a=2,b=4)) == 0) \ No newline at end of file diff --git a/DMCompiler/DMStandard/_Standard.dm b/DMCompiler/DMStandard/_Standard.dm index 45effa8b85..2b4c887090 100644 --- a/DMCompiler/DMStandard/_Standard.dm +++ b/DMCompiler/DMStandard/_Standard.dm @@ -107,6 +107,7 @@ proc/typesof(Item1) as /list proc/uppertext(T as text) as text proc/url_decode(UrlText) as text proc/url_encode(PlainText, format = 0) as text +proc/values_dot(A, B) as num proc/values_product(Alist) as num proc/values_sum(Alist) as num proc/view(Dist = 5, Center = usr) as /list diff --git a/OpenDreamRuntime/Procs/Native/DreamProcNative.cs b/OpenDreamRuntime/Procs/Native/DreamProcNative.cs index 431d72d79e..a10346476e 100644 --- a/OpenDreamRuntime/Procs/Native/DreamProcNative.cs +++ b/OpenDreamRuntime/Procs/Native/DreamProcNative.cs @@ -108,6 +108,7 @@ public static void SetupNativeProcs(DreamObjectTree objectTree) { objectTree.SetGlobalNativeProc(DreamProcNativeRoot.NativeProc_uppertext); objectTree.SetGlobalNativeProc(DreamProcNativeRoot.NativeProc_url_decode); objectTree.SetGlobalNativeProc(DreamProcNativeRoot.NativeProc_url_encode); + objectTree.SetGlobalNativeProc(DreamProcNativeRoot.NativeProc_values_dot); objectTree.SetGlobalNativeProc(DreamProcNativeRoot.NativeProc_values_product); objectTree.SetGlobalNativeProc(DreamProcNativeRoot.NativeProc_values_sum); objectTree.SetGlobalNativeProc(DreamProcNativeRoot.NativeProc_view); diff --git a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs index b9a1ed7630..e2b4e0a586 100644 --- a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs +++ b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs @@ -3108,6 +3108,35 @@ public static DreamValue NativeProc_url_encode(NativeProc.Bundle bundle, DreamOb return new DreamValue(HttpUtility.UrlEncode(plainText)); } + [DreamProc("values_dot")] + [DreamProcParameter("A", Type = DreamValueTypeFlag.DreamObject)] + [DreamProcParameter("B", Type = DreamValueTypeFlag.DreamObject)] + public static DreamValue NativeProc_values_dot(NativeProc.Bundle bundle, DreamObject? src, DreamObject? usr) { + if (bundle.Arguments.Length != 2) throw new Exception("expected 2 arguments"); + + DreamValue argA = bundle.GetArgument(0, "A"); + DreamValue argB = bundle.GetArgument(1, "B"); + + float sum = 0; // Default return is 0 for invalid args + + if (argA.TryGetValueAsDreamList(out var listA) && listA.IsAssociative && argB.TryGetValueAsDreamList(out var listB) && listB.IsAssociative) { + var aValues = listA.GetAssociativeValues(); + var bValues = listB.GetAssociativeValues(); + + // sum += valueA * valueB + // for each assoc value whose key exists in both lists + // and when both assoc values are floats + foreach (var (key,value) in aValues) { + if (value.TryGetValueAsFloat(out var aFloat) && bValues.TryGetValue(key, out var bVal) && + bVal.TryGetValueAsFloat(out var bFloat)) { + sum += (aFloat * bFloat); + } + } + } + + return new DreamValue(sum); + } + [DreamProc("values_product")] [DreamProcParameter("Alist", Type = DreamValueTypeFlag.DreamObject)] public static DreamValue NativeProc_values_product(NativeProc.Bundle bundle, DreamObject? src, DreamObject? usr) {