if (random.Prob(gen.Chance))
{
var coords = _maps.GridTileToLocal(_gridUid, _grid, tile);
- var protos = contentsTable.Table.GetSpawns(random, _entManager, _prototype);
+ var protos = _entTable.GetSpawns(contentsTable, random);
_entManager.SpawnEntitiesAttachedTo(coords, protos);
}
[DataField]
public bool Invert;
- public bool Evaluate(IEntityManager entMan, IPrototypeManager proto)
+ public bool Evaluate(EntityTableSelector root, IEntityManager entMan, IPrototypeManager proto, EntityTableContext ctx)
{
- var res = EvaluateImplementation(entMan, proto);
+ var res = EvaluateImplementation(root, entMan, proto, ctx);
// XOR eval to invert the result.
return res ^ Invert;
}
- public abstract bool EvaluateImplementation(IEntityManager entMan, IPrototypeManager proto);
+ protected abstract bool EvaluateImplementation(EntityTableSelector root, IEntityManager entMan, IPrototypeManager proto, EntityTableContext ctx);
}
+using Content.Shared.EntityTable.EntitySelectors;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
private static ISharedPlayerManager? _playerManager;
- public override bool EvaluateImplementation(IEntityManager entMan, IPrototypeManager proto)
+ protected override bool EvaluateImplementation(EntityTableSelector root, IEntityManager entMan, IPrototypeManager proto, EntityTableContext ctx)
{
// Don't resolve this repeatedly
_playerManager ??= IoCManager.Resolve<ISharedPlayerManager>();
protected override IEnumerable<EntProtoId> GetSpawnsImplementation(System.Random rand,
IEntityManager entMan,
- IPrototypeManager proto)
+ IPrototypeManager proto,
+ EntityTableContext ctx)
{
foreach (var child in Children)
{
- foreach (var spawn in child.GetSpawns(rand, entMan, proto))
+ foreach (var spawn in child.GetSpawns(rand, entMan, proto, ctx))
{
yield return spawn;
}
protected override IEnumerable<EntProtoId> GetSpawnsImplementation(System.Random rand,
IEntityManager entMan,
- IPrototypeManager proto)
+ IPrototypeManager proto,
+ EntityTableContext ctx)
{
var num = Amount.Get(rand);
for (var i = 0; i < num; i++)
public IEnumerable<EntProtoId> GetSpawns(System.Random rand,
IEntityManager entMan,
- IPrototypeManager proto)
+ IPrototypeManager proto,
+ EntityTableContext ctx)
{
- if (!CheckConditions(entMan, proto))
+ if (!CheckConditions(entMan, proto, ctx))
yield break;
var rolls = Rolls.Get(rand);
if (!rand.Prob(Prob))
continue;
- foreach (var spawn in GetSpawnsImplementation(rand, entMan, proto))
+ foreach (var spawn in GetSpawnsImplementation(rand, entMan, proto, ctx))
{
yield return spawn;
}
}
}
- public bool CheckConditions(IEntityManager entMan, IPrototypeManager proto)
+ public bool CheckConditions(IEntityManager entMan, IPrototypeManager proto, EntityTableContext ctx)
{
if (Conditions.Count == 0)
return true;
var success = false;
foreach (var condition in Conditions)
{
- var res = condition.Evaluate(entMan, proto);
+ var res = condition.Evaluate(this, entMan, proto, ctx);
if (RequireAll && !res)
return false; // intentional break out of loop and function
protected abstract IEnumerable<EntProtoId> GetSpawnsImplementation(System.Random rand,
IEntityManager entMan,
- IPrototypeManager proto);
+ IPrototypeManager proto,
+ EntityTableContext ctx);
}
protected override IEnumerable<EntProtoId> GetSpawnsImplementation(System.Random rand,
IEntityManager entMan,
- IPrototypeManager proto)
+ IPrototypeManager proto,
+ EntityTableContext ctx)
{
var children = new Dictionary<EntityTableSelector, float>(Children.Count);
foreach (var child in Children)
{
// Don't include invalid groups
- if (!child.CheckConditions(entMan, proto))
+ if (!child.CheckConditions(entMan, proto, ctx))
continue;
children.Add(child, child.Weight);
var pick = SharedRandomExtensions.Pick(children, rand);
- return pick.GetSpawns(rand, entMan, proto);
+ return pick.GetSpawns(rand, entMan, proto, ctx);
}
}
protected override IEnumerable<EntProtoId> GetSpawnsImplementation(System.Random rand,
IEntityManager entMan,
- IPrototypeManager proto)
+ IPrototypeManager proto,
+ EntityTableContext ctx)
{
- return proto.Index(TableId).Table.GetSpawns(rand, entMan, proto);
+ return proto.Index(TableId).Table.GetSpawns(rand, entMan, proto, ctx);
}
}
{
protected override IEnumerable<EntProtoId> GetSpawnsImplementation(System.Random rand,
IEntityManager entMan,
- IPrototypeManager proto)
+ IPrototypeManager proto,
+ EntityTableContext ctx)
{
yield break;
}
+using System.Diagnostics.CodeAnalysis;
using Content.Shared.EntityTable.EntitySelectors;
+using JetBrains.Annotations;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
- public IEnumerable<EntProtoId> GetSpawns(EntityTablePrototype entTableProto, System.Random? rand = null)
+ public IEnumerable<EntProtoId> GetSpawns(EntityTablePrototype entTableProto, System.Random? rand = null, EntityTableContext? ctx = null)
{
// convenient
- return GetSpawns(entTableProto.Table, rand);
+ return GetSpawns(entTableProto.Table, rand, ctx);
}
- public IEnumerable<EntProtoId> GetSpawns(EntityTableSelector? table, System.Random? rand = null)
+ public IEnumerable<EntProtoId> GetSpawns(EntityTableSelector? table, System.Random? rand = null, EntityTableContext? ctx = null)
{
if (table == null)
return new List<EntProtoId>();
rand ??= _random.GetRandom();
- return table.GetSpawns(rand, EntityManager, _prototypeManager);
+ ctx ??= new EntityTableContext();
+ return table.GetSpawns(rand, EntityManager, _prototypeManager, ctx);
+ }
+}
+
+/// <summary>
+/// Context used by selectors and conditions to evaluate in generic gamestate information.
+/// </summary>
+public sealed class EntityTableContext
+{
+ private readonly Dictionary<string, object> _data = new();
+
+ public EntityTableContext()
+ {
+
+ }
+
+ public EntityTableContext(Dictionary<string, object> data)
+ {
+ _data = data;
+ }
+
+ /// <summary>
+ /// Retrieves an arbitrary piece of data from the context based on a provided key.
+ /// </summary>
+ /// <param name="key">A string key that corresponds to the value we are searching for. </param>
+ /// <param name="value">The value we are trying to extract from the context object</param>
+ /// <typeparam name="T">The type of <see cref="value"/> that we are trying to retrieve</typeparam>
+ /// <returns>If <see cref="key"/> has a corresponding value of type <see cref="T"/></returns>
+ [PublicAPI]
+ public bool TryGetData<T>([ForbidLiteral] string key, [NotNullWhen(true)] out T? value)
+ {
+ value = default;
+ if (!_data.TryGetValue(key, out var valueData) || valueData is not T castValueData)
+ return false;
+
+ value = castValueData;
+ return true;
}
}