diff --git a/Content.Tests/DMProject/Tests/List/ListSplice.dm b/Content.Tests/DMProject/Tests/List/ListSplice.dm new file mode 100644 index 0000000000..9839d62ad9 --- /dev/null +++ b/Content.Tests/DMProject/Tests/List/ListSplice.dm @@ -0,0 +1,10 @@ + +/proc/RunTest() + var/list/L = list("foo", "bar", "test", "value") + L.Splice(2, 4, "lorem", "ipsum", "word", "another word") + ASSERT(L ~= list("foo","lorem","ipsum","word","another word","value")) + + // Again with list() as the arg + var/list/L2 = list("foo", "bar", "test", "value") + L2.Splice(2, 4, list("lorem", "ipsum", "word", "another word")) + ASSERT(L2 ~= list("foo","lorem","ipsum","word","another word","value")) diff --git a/DMCompiler/DMStandard/Types/List.dm b/DMCompiler/DMStandard/Types/List.dm index 013c1e56c3..e8d25d096d 100644 --- a/DMCompiler/DMStandard/Types/List.dm +++ b/DMCompiler/DMStandard/Types/List.dm @@ -13,6 +13,4 @@ proc/Remove(Item1) proc/RemoveAll(Item1) proc/Swap(Index1, Index2) - - proc/Splice(Start=1,End=0, ...) - set opendream_unimplemented = TRUE + proc/Splice(Start = 1 as num, End = 0 as num, Item1, ...) as null diff --git a/OpenDreamRuntime/Procs/Native/DreamProcNative.cs b/OpenDreamRuntime/Procs/Native/DreamProcNative.cs index d2020f15f3..7c28ec7f0e 100644 --- a/OpenDreamRuntime/Procs/Native/DreamProcNative.cs +++ b/OpenDreamRuntime/Procs/Native/DreamProcNative.cs @@ -128,6 +128,7 @@ public static void SetupNativeProcs(DreamObjectTree objectTree) { objectTree.SetNativeProc(objectTree.List, DreamProcNativeList.NativeProc_Join); objectTree.SetNativeProc(objectTree.List, DreamProcNativeList.NativeProc_Remove); objectTree.SetNativeProc(objectTree.List, DreamProcNativeList.NativeProc_RemoveAll); + objectTree.SetNativeProc(objectTree.List, DreamProcNativeList.NativeProc_Splice); objectTree.SetNativeProc(objectTree.List, DreamProcNativeList.NativeProc_Swap); objectTree.SetNativeProc(objectTree.Matrix, DreamProcNativeMatrix.NativeProc_Add); diff --git a/OpenDreamRuntime/Procs/Native/DreamProcNativeList.cs b/OpenDreamRuntime/Procs/Native/DreamProcNativeList.cs index bb6c98276a..48152e7dd2 100644 --- a/OpenDreamRuntime/Procs/Native/DreamProcNativeList.cs +++ b/OpenDreamRuntime/Procs/Native/DreamProcNativeList.cs @@ -163,6 +163,36 @@ private static int ListRemove(DreamList list, ReadOnlySpan args) { return itemRemoved; } + [DreamProc("Splice")] + [DreamProcParameter("Start", Type = DreamValueTypeFlag.Float, DefaultValue = 1)] + [DreamProcParameter("End", Type = DreamValueTypeFlag.Float, DefaultValue = 0)] + [DreamProcParameter("Item1")] + public static DreamValue NativeProc_Splice(NativeProc.Bundle bundle, DreamObject? src, DreamObject? usr) { + int startIndex = bundle.GetArgument(0, "Start").MustGetValueAsInteger(); //1-indexed + int end = bundle.GetArgument(1, "End").MustGetValueAsInteger(); //1-indexed + DreamList list = (DreamList)src!; + + list.Cut(startIndex, end); + + if (startIndex <= 0) startIndex = list.GetLength() + 1; + if (bundle.Arguments.Length < 3) return DreamValue.Null; + + // i = 2 is Item1 + for (var i = 2; i < bundle.Arguments.Length; i++) { + var item = bundle.Arguments[i]; + + if (item.TryGetValueAsDreamList(out var valueList)) { + foreach (DreamValue value in valueList.GetValues()) { + list.Insert(startIndex++, value); + } + } else { + list.Insert(startIndex++, item); + } + } + + return DreamValue.Null; + } + [DreamProc("Swap")] [DreamProcParameter("Index1", Type = DreamValueTypeFlag.Float)] [DreamProcParameter("Index2", Type = DreamValueTypeFlag.Float)]