From 82b6b866217878764ae0f7b1c881884fceb4d91c Mon Sep 17 00:00:00 2001 From: amy Date: Tue, 18 Feb 2025 23:09:46 +0000 Subject: [PATCH] generator --- DMCompiler/DMStandard/UnsortedAdditions.dm | 2 - OpenDreamRuntime/Objects/DreamObjectTree.cs | 8 +++ .../Objects/Types/DreamObjectGenerator.cs | 40 ++++++++++++ .../Procs/Native/DreamProcNativeRoot.cs | 62 +++++++++++++++++++ 4 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 OpenDreamRuntime/Objects/Types/DreamObjectGenerator.cs diff --git a/DMCompiler/DMStandard/UnsortedAdditions.dm b/DMCompiler/DMStandard/UnsortedAdditions.dm index c2542bd97c..5c83a94531 100644 --- a/DMCompiler/DMStandard/UnsortedAdditions.dm +++ b/DMCompiler/DMStandard/UnsortedAdditions.dm @@ -16,8 +16,6 @@ set opendream_unimplemented = TRUE /proc/findtextEx_char(Haystack,Needle,Start=1,End=0) set opendream_unimplemented = TRUE -/proc/generator(type, A, B, rand) - set opendream_unimplemented = TRUE /proc/load_resource(File) set opendream_unimplemented = TRUE proc/missile(Type, Start, End) diff --git a/OpenDreamRuntime/Objects/DreamObjectTree.cs b/OpenDreamRuntime/Objects/DreamObjectTree.cs index 668b00cab0..ee9e2394d3 100644 --- a/OpenDreamRuntime/Objects/DreamObjectTree.cs +++ b/OpenDreamRuntime/Objects/DreamObjectTree.cs @@ -48,6 +48,8 @@ public sealed class DreamObjectTree { public TreeEntry Movable { get; private set; } public TreeEntry Obj { get; private set; } public TreeEntry Mob { get; private set; } + public TreeEntry Generator { get; private set; } + public TreeEntry Particles { get; private set; } private FrozenDictionary _pathToType = FrozenDictionary.Empty; private FrozenDictionary _globalProcIds = FrozenDictionary.Empty; @@ -171,6 +173,10 @@ public DreamObject CreateObject(TreeEntry type) { return new DreamObjectArea(type.ObjectDefinition); if (type.ObjectDefinition.IsSubtypeOf(Atom)) return new DreamObjectAtom(type.ObjectDefinition); + if (type.ObjectDefinition.IsSubtypeOf(Generator)) + throw new Exception("Cannot create objects of type /generator with the generator() proc"); + if (type.ObjectDefinition.IsSubtypeOf(Particles)) + return new DreamObjectParticles(type.ObjectDefinition); if (type.ObjectDefinition.IsSubtypeOf(Client)) throw new Exception("Cannot create objects of type /client"); if (type.ObjectDefinition.IsSubtypeOf(Turf)) @@ -303,6 +309,8 @@ private void LoadTypesFromJson(DreamTypeJson[] types, ProcDefinitionJson[]? proc Movable = GetTreeEntry("/atom/movable"); Obj = GetTreeEntry("/obj"); Mob = GetTreeEntry("/mob"); + Particles = GetTreeEntry("/particles"); + Generator = GetTreeEntry("/generator"); // Load procs first so types can set their init proc's super proc LoadProcsFromJson(procs, globalProcs); diff --git a/OpenDreamRuntime/Objects/Types/DreamObjectGenerator.cs b/OpenDreamRuntime/Objects/Types/DreamObjectGenerator.cs new file mode 100644 index 0000000000..1583a9b569 --- /dev/null +++ b/OpenDreamRuntime/Objects/Types/DreamObjectGenerator.cs @@ -0,0 +1,40 @@ +using OpenDreamRuntime.Procs; + +namespace OpenDreamRuntime.Objects.Types; + +public sealed class DreamObjectGenerator : DreamObject { + + public DreamValue A { get; private set; } + public DreamValue B { get; private set; } + public GeneratorOutputType OutputType { get; private set; } + public GeneratorDistribution Distribution { get; private set; } + + + public DreamObjectGenerator(DreamObjectDefinition objectDefinition, DreamValue A, DreamValue B, GeneratorOutputType outputType, GeneratorDistribution dist) : base(objectDefinition) { + this.A = A; + this.B = B; + this.OutputType = outputType; + this.Distribution = dist; + } + public override void Initialize(DreamProcArguments args) { + base.Initialize(args); + } +} + +public enum GeneratorOutputType { + Num, + Vector, + Box, + Color, + Circle, + Sphere, + Square, + Cube +} + +public enum GeneratorDistribution { + Uniform, + Normal, + Linear, + Square +} diff --git a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs index e8c0511734..436a9c6d95 100644 --- a/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs +++ b/OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs @@ -23,6 +23,7 @@ using Robust.Server; using Robust.Shared.Asynchronous; using Vector4 = Robust.Shared.Maths.Vector4; +using System.ComponentModel; namespace OpenDreamRuntime.Procs.Native; /// @@ -1092,6 +1093,67 @@ public static DreamValue NativeProc_get_steps_to(NativeProc.Bundle bundle, Dream return new(result.GetLength() > 0 ? result : null); } + [DreamProc("generator")] + [DreamProcParameter("type", Type = DreamValueTypeFlag.String)] + [DreamProcParameter("A", Type = DreamValueTypeFlag.DreamObject)] + [DreamProcParameter("B", Type = DreamValueTypeFlag.DreamObject)] + [DreamProcParameter("rand", Type = DreamValueTypeFlag.Float)] + public static DreamValue NativeProc_generator(NativeProc.Bundle bundle, DreamObject? src, DreamObject? usr) { + string outputTypeString = bundle.GetArgument(0, "type").MustGetValueAsString(); + var A = bundle.GetArgument(1, "A"); + var B = bundle.GetArgument(2, "B"); + var distNum = bundle.GetArgument(3, "rand").MustGetValueAsInteger(); + + GeneratorOutputType outputType; + GeneratorDistribution distribution; + switch(outputTypeString){ + case "num": + outputType = GeneratorOutputType.Num; + break; + case "vector": + outputType = GeneratorOutputType.Vector; + break; + case "box": + outputType = GeneratorOutputType.Box; + break; + case "color": + outputType = GeneratorOutputType.Color; + break; + case "circle": + outputType = GeneratorOutputType.Circle; + break; + case "sphere": + outputType = GeneratorOutputType.Sphere; + break; + case "square": + outputType = GeneratorOutputType.Square; + break; + case "cube": + outputType = GeneratorOutputType.Cube; + break; + default: + throw new InvalidEnumArgumentException("Invalid output type specified in generator()"); + } + switch(distNum){ + case 0: + distribution = GeneratorDistribution.Uniform; + break; + case 1: + distribution = GeneratorDistribution.Normal; + break; + case 2: + distribution = GeneratorDistribution.Linear; + break; + case 3: + distribution = GeneratorDistribution.Square; + break; + default: + throw new InvalidEnumArgumentException("Invalid distribution type specified in generator()"); + } + return new(new DreamObjectGenerator(bundle.ObjectTree.Generator.ObjectDefinition, A, B, outputType, distribution)); + + } + [DreamProc("hascall")] [DreamProcParameter("Object", Type = DreamValueTypeFlag.DreamObject)] [DreamProcParameter("ProcName", Type = DreamValueTypeFlag.String)]