2 using Microsoft.Xna.Framework;
4 using System.Collections.Generic;
5 using System.Collections.Immutable;
6 using System.Diagnostics;
13 public static class Rand
25 private static readonly Dictionary<RandSync, Random> syncedRandom =
new Dictionary<RandSync, Random> {
26 { RandSync.ServerAndClient,
new MTRandom() },
28 { RandSync.ClientOnly,
new MTRandom() }
32 public static Random GetRNG(RandSync randSync)
34 CheckRandThreadSafety(randSync);
35 return randSync == RandSync.Unsynced ? localRandom : syncedRandom[randSync];
38 public static void SetLocalRandom(
int seed)
40 localRandom =
new Random(seed);
43 public static void SetSyncedSeed(
int seed)
45 syncedRandom[RandSync.ServerAndClient] =
new MTRandom(seed);
47 syncedRandom[RandSync.ClientOnly] =
new MTRandom(seed);
51 public static int ThreadId = 0;
52 private static void CheckRandThreadSafety(RandSync sync)
54 if (ThreadId != 0 && sync == RandSync.Unsynced)
56 if (System.Threading.Thread.CurrentThread.ManagedThreadId != ThreadId)
58 Debug.WriteLine($
"Unsynced rand used in synced thread! {Environment.StackTrace}");
61 if (ThreadId != 0 && sync == RandSync.ServerAndClient)
63 if (System.Threading.Thread.CurrentThread.ManagedThreadId != ThreadId)
66 throw new Exception(
"Unauthorized multithreaded access to RandSync.ServerAndClient");
68 DebugConsole.ThrowError(
"Unauthorized multithreaded access to RandSync.ServerAndClient\n" + Environment.StackTrace.CleanupStackTrace());
74 public static float Range(
float minimum,
float maximum, RandSync sync=RandSync.Unsynced)
75 => GetRNG(sync).Range(minimum, maximum);
77 public static double Range(
double minimum,
double maximum, RandSync sync = RandSync.Unsynced)
78 => GetRNG(sync).Range(minimum, maximum);
83 public static int Range(
int minimum,
int maximum, RandSync sync = RandSync.Unsynced)
85 CheckRandThreadSafety(sync);
86 return (sync == RandSync.Unsynced ? localRandom : (syncedRandom[sync])).Next(maximum - minimum) + minimum;
89 public static int Int(
int max, RandSync sync = RandSync.Unsynced)
91 CheckRandThreadSafety(sync);
92 return (sync == RandSync.Unsynced ? localRandom : (syncedRandom[sync])).Next(max);
95 public static Vector2 Vector(
float length, RandSync sync = RandSync.Unsynced)
97 Vector2 randomVector =
new Vector2(Range(-1.0f, 1.0f, sync), Range(-1.0f, 1.0f, sync));
99 if (randomVector.LengthSquared() < 0.001f)
return new Vector2(0.0f, length);
101 return Vector2.Normalize(randomVector) * length;
107 public static float Value(RandSync sync = RandSync.Unsynced)
109 return Range(0f, 1f, sync);
112 public static Color Color(
bool randomAlpha =
false, RandSync sync = RandSync.Unsynced)
116 return new Color(Value(sync), Value(sync), Value(sync), Value(sync));
120 return new Color(Value(sync), Value(sync), Value(sync));
124 public static DoubleVector2 Vector(
double length, RandSync sync = RandSync.Unsynced)
126 double x = Range(-1.0, 1.0, sync);
127 double y = Range(-1.0, 1.0, sync);
129 double len = Math.Sqrt(x * x + y * y);
132 return new DoubleVector2(x / len * length, y / len * length);