mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
Add EntManager + ProtoManager helpers for random picks (#4869)
* Add EntManager + ProtoManager helpers for random picks Lets us cleanup content a bit from these being re-implemented. * weh
This commit is contained in:
@@ -39,8 +39,7 @@ END TEMPLATE-->
|
||||
|
||||
### New features
|
||||
|
||||
* You can now specify CVar overrides via environment variable with the `ROBUST_CVAR_*` prefix. For example `ROBUST_CVAR_game__hostname=foobar` would set the appropriate CVar. Double underscores in the environment variable name are replaced with ".".
|
||||
* Added non-generic variant of `GetCVar` to `IConfigurationManager`.
|
||||
* Add TryGetRandom to EntityManager to get a random entity with the specified component and TryGetRandom to IPrototypeManager to return a random prototype of the specified type.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
namespace Robust.Shared.GameObjects
|
||||
using Robust.Shared.Collections;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
{
|
||||
public static class EntityManagerExt
|
||||
{
|
||||
@@ -19,5 +22,79 @@
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Picks an entity at random with the supplied component.
|
||||
/// </summary>
|
||||
public static bool TryGetRandom<TComp1>(this IEntityManager entManager, IRobustRandom random, out EntityUid entity, bool includePaused = false) where TComp1 : IComponent
|
||||
{
|
||||
var entities = new ValueList<EntityUid>();
|
||||
|
||||
if (includePaused)
|
||||
{
|
||||
var query = entManager.AllEntityQueryEnumerator<TComp1>();
|
||||
|
||||
while (query.MoveNext(out var uid, out _))
|
||||
{
|
||||
entities.Add(uid);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var query = entManager.EntityQueryEnumerator<TComp1>();
|
||||
|
||||
while (query.MoveNext(out var uid, out _))
|
||||
{
|
||||
entities.Add(uid);
|
||||
}
|
||||
}
|
||||
|
||||
if (entities.Count == 0)
|
||||
{
|
||||
entity = EntityUid.Invalid;
|
||||
return false;
|
||||
}
|
||||
|
||||
entity = random.Pick(entities);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Picks an entity at random with the supplied components.
|
||||
/// </summary>
|
||||
public static bool TryGetRandom<TComp1, TComp2>(this IEntityManager entManager, IRobustRandom random, out EntityUid entity, bool includePaused = false)
|
||||
where TComp1 : IComponent
|
||||
where TComp2 : IComponent
|
||||
{
|
||||
var entities = new ValueList<EntityUid>();
|
||||
|
||||
if (includePaused)
|
||||
{
|
||||
var query = entManager.AllEntityQueryEnumerator<TComp1, TComp2>();
|
||||
|
||||
while (query.MoveNext(out var uid, out _, out _))
|
||||
{
|
||||
entities.Add(uid);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var query = entManager.EntityQueryEnumerator<TComp1, TComp2>();
|
||||
|
||||
while (query.MoveNext(out var uid, out _, out _))
|
||||
{
|
||||
entities.Add(uid);
|
||||
}
|
||||
}
|
||||
|
||||
if (entities.Count == 0)
|
||||
{
|
||||
entity = EntityUid.Invalid;
|
||||
return false;
|
||||
}
|
||||
|
||||
entity = random.Pick(entities);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
@@ -386,6 +387,11 @@ public interface IPrototypeManager
|
||||
/// For example: /Prototypes/Guidebook
|
||||
/// </param>
|
||||
void AbstractDirectory(ResPath path);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get a random prototype.
|
||||
/// </summary>
|
||||
bool TryGetRandom<T>(IRobustRandom random, [NotNullWhen(true)] out IPrototype? prototype) where T : class, IPrototype;
|
||||
}
|
||||
|
||||
internal interface IPrototypeManagerInternal : IPrototypeManager
|
||||
|
||||
@@ -1082,6 +1082,34 @@ namespace Robust.Shared.Prototypes
|
||||
_prototypeDataCache[prototype.ID] = data;
|
||||
return data;
|
||||
}
|
||||
|
||||
public bool TryGetRandom<T>(IRobustRandom random, [NotNullWhen(true)] out IPrototype? prototype) where T : class, IPrototype
|
||||
{
|
||||
var count = Count<T>();
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
prototype = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
var index = 0;
|
||||
|
||||
var picked = random.Next(count);
|
||||
|
||||
foreach (var proto in EnumeratePrototypes<T>())
|
||||
{
|
||||
if (index == picked)
|
||||
{
|
||||
prototype = proto;
|
||||
return true;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException($"Unable to pick valid prototype for {typeof(T)}?");
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class InvalidPrototypeNameException : Exception
|
||||
|
||||
Reference in New Issue
Block a user