Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Content.Tests/DMProject/Tests/Stdlib/generator_rand.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/proc/RunTest()
var/generator/gen = generator("num", -1, 1)
var/result = gen.Rand()
ASSERT(isnum(result))
ASSERT((result >= -1 && result <= 1))
1 change: 0 additions & 1 deletion DMCompiler/DMStandard/Types/Generator.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
var/_binobj as opendream_unimplemented

/generator/proc/Rand()
set opendream_unimplemented = TRUE

/*
Generator Theory
Expand Down
18 changes: 18 additions & 0 deletions OpenDreamRuntime/Objects/Types/DreamObjectVector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,24 @@ public static DreamObjectVector CreateFromValue(DreamValue value, DreamObjectTre
return vector;
}

/// <summary>
/// Creates a <see cref="DreamObjectVector"/> from a <see cref="Vector3"/>
/// </summary>
public static DreamObjectVector CreateFromValue(Vector3 value, DreamObjectTree tree) {
var vector = tree.CreateObject<DreamObjectVector>(tree.Vector);
vector.Initialize(new(new(value.X), new(value.Y), new(value.Z)));
return vector;
}

/// <summary>
/// Creates a <see cref="DreamObjectVector"/> from a <see cref="Vector2"/>
/// </summary>
public static DreamObjectVector CreateFromValue(Vector2 value, DreamObjectTree tree) {
var vector = tree.CreateObject<DreamObjectVector>(tree.Vector);
vector.Initialize(new(new(value.X), new(value.Y)));
return vector;
}

// TODO: Operators, supports indexing and "most math"
// TODO: For loop support
}
2 changes: 2 additions & 0 deletions OpenDreamRuntime/Procs/Native/DreamProcNative.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ public static void SetupNativeProcs(DreamObjectTree objectTree) {
objectTree.SetNativeProc(objectTree.DatabaseQuery, DreamProcNativeDatabaseQuery.NativeProc_NextRow);
objectTree.SetNativeProc(objectTree.DatabaseQuery, DreamProcNativeDatabaseQuery.NativeProc_RowsAffected);

objectTree.SetNativeProc(objectTree.Generator, DreamProcNativeGenerator.NativeProc_Rand);

SetOverridableNativeProc(objectTree, objectTree.World, DreamProcNativeWorld.NativeProc_Error);
SetOverridableNativeProc(objectTree, objectTree.World, DreamProcNativeWorld.NativeProc_Reboot);
}
Expand Down
30 changes: 30 additions & 0 deletions OpenDreamRuntime/Procs/Native/DreamProcNativeGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using OpenDreamRuntime.Objects;
using OpenDreamRuntime.Objects.Types;
using OpenDreamShared.Dream;
using Robust.Shared.Random;

namespace OpenDreamRuntime.Procs.Native;

internal static class DreamProcNativeGenerator {
[DreamProc("Rand")]
public static DreamValue NativeProc_Rand(NativeProc.Bundle bundle, DreamObject? src, DreamObject? usr) {
var genObj = (DreamObjectGenerator)src!;

switch (genObj.Generator) {
case IGeneratorNum numGen: {
var result = numGen.Generate(IoCManager.Resolve<IRobustRandom>());
return new DreamValue(result);
}
case IGeneratorVector vecGen: {
var rand = IoCManager.Resolve<IRobustRandom>();
var resultObj = vecGen.PrefersVector3
? DreamObjectVector.CreateFromValue(vecGen.GenerateVector3(rand), bundle.ObjectTree)
: DreamObjectVector.CreateFromValue(vecGen.GenerateVector2(rand), bundle.ObjectTree);

return new DreamValue(resultObj);
}
default:
throw new Exception($"Invalid generator for Rand: {genObj}");
}
}
}
16 changes: 16 additions & 0 deletions OpenDreamShared/Dream/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ public interface IGeneratorNum : IGenerator {
}

public interface IGeneratorVector : IGenerator {
bool PrefersVector3 { get; set; }
public Vector2 GenerateVector2(IRobustRandom random);
public Vector3 GenerateVector3(IRobustRandom random);
}

[Serializable, NetSerializable]
public sealed class GeneratorNum(float low, float high, GeneratorDistribution distribution) : IGeneratorNum, IGeneratorVector {
public bool PrefersVector3 { get; set; } = false;
public GeneratorNum(float value) : this(value, value, GeneratorDistribution.Constant) { }

public float Generate(IRobustRandom random) {
Expand All @@ -58,6 +60,7 @@ public override string ToString() {

[Serializable, NetSerializable]
public sealed class GeneratorVector2(Vector2 low, Vector2 high, GeneratorDistribution distribution) : IGeneratorVector {
public bool PrefersVector3 { get; set; } = false;
public GeneratorVector2(Vector2 value) : this(value, value, GeneratorDistribution.Constant) { }

public Vector2 GenerateVector2(IRobustRandom random) {
Expand All @@ -77,6 +80,7 @@ public override string ToString() {

[Serializable, NetSerializable]
public sealed class GeneratorVector3(Vector3 low, Vector3 high, GeneratorDistribution distribution) : IGeneratorVector {
public bool PrefersVector3 { get; set; } = true;
public GeneratorVector3(Vector3 value) : this(value, value, GeneratorDistribution.Constant) { }

public Vector2 GenerateVector2(IRobustRandom random) {
Expand All @@ -96,6 +100,8 @@ public override string ToString() {

[Serializable, NetSerializable]
public sealed class GeneratorBox2(Vector2 low, Vector2 high, GeneratorDistribution distribution) : IGeneratorVector {
public bool PrefersVector3 { get; set; } = false;

public Vector2 GenerateVector2(IRobustRandom random) {
var x = IGenerator.GenerateNum(random, low.X, high.X, distribution);
var y = IGenerator.GenerateNum(random, low.Y, high.Y, distribution);
Expand All @@ -116,6 +122,8 @@ public override string ToString() {

[Serializable, NetSerializable]
public sealed class GeneratorBox3(Vector3 low, Vector3 high, GeneratorDistribution distribution) : IGeneratorVector {
public bool PrefersVector3 { get; set; } = true;

public Vector2 GenerateVector2(IRobustRandom random) {
var vector = GenerateVector3(random);

Expand All @@ -137,6 +145,8 @@ public override string ToString() {

[Serializable, NetSerializable]
public sealed class GeneratorCircle(float low, float high, GeneratorDistribution distribution) : IGeneratorVector {
public bool PrefersVector3 { get; set; } = false;

public Vector2 GenerateVector2(IRobustRandom random) {
var theta = random.NextFloat(0f, 360f);
var r = IGenerator.GenerateNum(random, low, high, distribution);
Expand All @@ -157,6 +167,8 @@ public override string ToString() {

[Serializable, NetSerializable]
public sealed class GeneratorSphere(float low, float high, GeneratorDistribution distribution) : IGeneratorVector {
public bool PrefersVector3 { get; set; } = true;

public Vector2 GenerateVector2(IRobustRandom random) {
var vector = GenerateVector3(random);

Expand All @@ -182,6 +194,8 @@ public override string ToString() {

[Serializable, NetSerializable]
public sealed class GeneratorSquare(Vector2 low, Vector2 high, GeneratorDistribution distribution) : IGeneratorVector {
public bool PrefersVector3 { get; set; } = false;

public Vector2 GenerateVector2(IRobustRandom random) {
var x = IGenerator.GenerateNum(random, -high.X, high.X, distribution);
var y = IGenerator.GenerateNum(random, -high.Y, high.Y, distribution);
Expand All @@ -207,6 +221,8 @@ public override string ToString() {

[Serializable, NetSerializable]
public sealed class GeneratorCube(Vector3 low, Vector3 high, GeneratorDistribution distribution) : IGeneratorVector {
public bool PrefersVector3 { get; set; } = true;

public Vector2 GenerateVector2(IRobustRandom random) {
var vector = GenerateVector3(random);

Expand Down
Loading