почти важно (#135)
* Add data field for id card microwave behaviour (#28087) * Move replacement chance from ReplacementAccentComponent to ReplacementAccentPrototype (#28049) Move replacement chance to ReplacementAccentPrototype * Resolves Bible summon message being sent to all users (#28104) * Changed PopupEntity overload used to ensure message is only sent to user * Updated uid for PopupEntity call * Updating _popupSystem.PopupEntity call in AttemptSummon * Random book story generator refactor (#28082) * Randomized book overhaul * Fix prototype names * Improved setting paper content * Praise Ratvar * Fix activatable UI popup message spam (#28123) Fixed activatable UI popup message spam * Modify battery assert to avoid floating point errors (#28007) * Update component query benchmarks (#27967) * Add more component query benchmarks. * Rename benchmark * Use non-generic `TryComp()` for metadata & transform (#28133) * sleeper agent appear later into the round and only once (#28160) --------- Co-authored-by: DrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com> Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com> Co-authored-by: double_b <40827162+benjamin-burges@users.noreply.github.com> Co-authored-by: Tayrtahn <tayrtahn@gmail.com> Co-authored-by: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Co-authored-by: Killerqu00 <47712032+Killerqu00@users.noreply.github.com>
This commit is contained in:
273
Content.Benchmarks/ComponentQueryBenchmark.cs
Normal file
273
Content.Benchmarks/ComponentQueryBenchmark.cs
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BenchmarkDotNet.Attributes;
|
||||||
|
using BenchmarkDotNet.Configs;
|
||||||
|
using Content.IntegrationTests;
|
||||||
|
using Content.IntegrationTests.Pair;
|
||||||
|
using Content.Shared.Clothing.Components;
|
||||||
|
using Content.Shared.Doors.Components;
|
||||||
|
using Content.Shared.Item;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Shared;
|
||||||
|
using Robust.Shared.Analyzers;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Map.Components;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
|
namespace Content.Benchmarks;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Benchmarks for comparing the speed of various component fetching/lookup related methods, including directed event
|
||||||
|
/// subscriptions
|
||||||
|
/// </summary>
|
||||||
|
[Virtual]
|
||||||
|
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
|
||||||
|
[CategoriesColumn]
|
||||||
|
public class ComponentQueryBenchmark
|
||||||
|
{
|
||||||
|
public const string Map = "Maps/atlas.yml";
|
||||||
|
|
||||||
|
private TestPair _pair = default!;
|
||||||
|
private IEntityManager _entMan = default!;
|
||||||
|
private MapId _mapId = new(10);
|
||||||
|
private EntityQuery<ItemComponent> _itemQuery;
|
||||||
|
private EntityQuery<ClothingComponent> _clothingQuery;
|
||||||
|
private EntityQuery<MapComponent> _mapQuery;
|
||||||
|
private EntityUid[] _items = default!;
|
||||||
|
|
||||||
|
[GlobalSetup]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
ProgramShared.PathOffset = "../../../../";
|
||||||
|
PoolManager.Startup(typeof(QueryBenchSystem).Assembly);
|
||||||
|
|
||||||
|
_pair = PoolManager.GetServerClient().GetAwaiter().GetResult();
|
||||||
|
_entMan = _pair.Server.ResolveDependency<IEntityManager>();
|
||||||
|
|
||||||
|
_itemQuery = _entMan.GetEntityQuery<ItemComponent>();
|
||||||
|
_clothingQuery = _entMan.GetEntityQuery<ClothingComponent>();
|
||||||
|
_mapQuery = _entMan.GetEntityQuery<MapComponent>();
|
||||||
|
|
||||||
|
_pair.Server.ResolveDependency<IRobustRandom>().SetSeed(42);
|
||||||
|
_pair.Server.WaitPost(() =>
|
||||||
|
{
|
||||||
|
var success = _entMan.System<MapLoaderSystem>().TryLoad(_mapId, Map, out _);
|
||||||
|
if (!success)
|
||||||
|
throw new Exception("Map load failed");
|
||||||
|
_pair.Server.MapMan.DoMapInitialize(_mapId);
|
||||||
|
}).GetAwaiter().GetResult();
|
||||||
|
|
||||||
|
_items = new EntityUid[_entMan.Count<ItemComponent>()];
|
||||||
|
var i = 0;
|
||||||
|
var enumerator = _entMan.AllEntityQueryEnumerator<ItemComponent>();
|
||||||
|
while (enumerator.MoveNext(out var uid, out _))
|
||||||
|
{
|
||||||
|
_items[i++] = uid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[GlobalCleanup]
|
||||||
|
public async Task Cleanup()
|
||||||
|
{
|
||||||
|
await _pair.DisposeAsync();
|
||||||
|
PoolManager.Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region TryComp
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Baseline TryComp benchmark. When the benchmark was created, around 40% of the items were clothing.
|
||||||
|
/// </summary>
|
||||||
|
[Benchmark(Baseline = true)]
|
||||||
|
[BenchmarkCategory("TryComp")]
|
||||||
|
public int TryComp()
|
||||||
|
{
|
||||||
|
var hashCode = 0;
|
||||||
|
foreach (var uid in _items)
|
||||||
|
{
|
||||||
|
if (_clothingQuery.TryGetComponent(uid, out var clothing))
|
||||||
|
hashCode = HashCode.Combine(hashCode, clothing.GetHashCode());
|
||||||
|
}
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Variant of <see cref="TryComp"/> that is meant to always fail to get a component.
|
||||||
|
/// </summary>
|
||||||
|
[Benchmark]
|
||||||
|
[BenchmarkCategory("TryComp")]
|
||||||
|
public int TryCompFail()
|
||||||
|
{
|
||||||
|
var hashCode = 0;
|
||||||
|
foreach (var uid in _items)
|
||||||
|
{
|
||||||
|
if (_mapQuery.TryGetComponent(uid, out var map))
|
||||||
|
hashCode = HashCode.Combine(hashCode, map.GetHashCode());
|
||||||
|
}
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Variant of <see cref="TryComp"/> that is meant to always succeed getting a component.
|
||||||
|
/// </summary>
|
||||||
|
[Benchmark]
|
||||||
|
[BenchmarkCategory("TryComp")]
|
||||||
|
public int TryCompSucceed()
|
||||||
|
{
|
||||||
|
var hashCode = 0;
|
||||||
|
foreach (var uid in _items)
|
||||||
|
{
|
||||||
|
if (_itemQuery.TryGetComponent(uid, out var item))
|
||||||
|
hashCode = HashCode.Combine(hashCode, item.GetHashCode());
|
||||||
|
}
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Variant of <see cref="TryComp"/> that uses `Resolve()` to try get the component.
|
||||||
|
/// </summary>
|
||||||
|
[Benchmark]
|
||||||
|
[BenchmarkCategory("TryComp")]
|
||||||
|
public int Resolve()
|
||||||
|
{
|
||||||
|
var hashCode = 0;
|
||||||
|
foreach (var uid in _items)
|
||||||
|
{
|
||||||
|
DoResolve(uid, ref hashCode);
|
||||||
|
}
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void DoResolve(EntityUid uid, ref int hash, ClothingComponent? clothing = null)
|
||||||
|
{
|
||||||
|
if (_clothingQuery.Resolve(uid, ref clothing, false))
|
||||||
|
hash = HashCode.Combine(hash, clothing.GetHashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Enumeration
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
[BenchmarkCategory("Item Enumerator")]
|
||||||
|
public int SingleItemEnumerator()
|
||||||
|
{
|
||||||
|
var hashCode = 0;
|
||||||
|
var enumerator = _entMan.AllEntityQueryEnumerator<ItemComponent>();
|
||||||
|
while (enumerator.MoveNext(out var item))
|
||||||
|
{
|
||||||
|
hashCode = HashCode.Combine(hashCode, item.GetHashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
[BenchmarkCategory("Item Enumerator")]
|
||||||
|
public int DoubleItemEnumerator()
|
||||||
|
{
|
||||||
|
var hashCode = 0;
|
||||||
|
var enumerator = _entMan.AllEntityQueryEnumerator<ClothingComponent, ItemComponent>();
|
||||||
|
while (enumerator.MoveNext(out _, out var item))
|
||||||
|
{
|
||||||
|
hashCode = HashCode.Combine(hashCode, item.GetHashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
[BenchmarkCategory("Item Enumerator")]
|
||||||
|
public int TripleItemEnumerator()
|
||||||
|
{
|
||||||
|
var hashCode = 0;
|
||||||
|
var enumerator = _entMan.AllEntityQueryEnumerator<ClothingComponent, ItemComponent, TransformComponent>();
|
||||||
|
while (enumerator.MoveNext(out _, out _, out var xform))
|
||||||
|
{
|
||||||
|
hashCode = HashCode.Combine(hashCode, xform.GetHashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
[BenchmarkCategory("Airlock Enumerator")]
|
||||||
|
public int SingleAirlockEnumerator()
|
||||||
|
{
|
||||||
|
var hashCode = 0;
|
||||||
|
var enumerator = _entMan.AllEntityQueryEnumerator<AirlockComponent>();
|
||||||
|
while (enumerator.MoveNext(out var airlock))
|
||||||
|
{
|
||||||
|
hashCode = HashCode.Combine(hashCode, airlock.GetHashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
[BenchmarkCategory("Airlock Enumerator")]
|
||||||
|
public int DoubleAirlockEnumerator()
|
||||||
|
{
|
||||||
|
var hashCode = 0;
|
||||||
|
var enumerator = _entMan.AllEntityQueryEnumerator<AirlockComponent, DoorComponent>();
|
||||||
|
while (enumerator.MoveNext(out _, out var door))
|
||||||
|
{
|
||||||
|
hashCode = HashCode.Combine(hashCode, door.GetHashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
[BenchmarkCategory("Airlock Enumerator")]
|
||||||
|
public int TripleAirlockEnumerator()
|
||||||
|
{
|
||||||
|
var hashCode = 0;
|
||||||
|
var enumerator = _entMan.AllEntityQueryEnumerator<AirlockComponent, DoorComponent, TransformComponent>();
|
||||||
|
while (enumerator.MoveNext(out _, out _, out var xform))
|
||||||
|
{
|
||||||
|
hashCode = HashCode.Combine(hashCode, xform.GetHashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
[Benchmark(Baseline = true)]
|
||||||
|
[BenchmarkCategory("Events")]
|
||||||
|
public int StructEvents()
|
||||||
|
{
|
||||||
|
var ev = new QueryBenchEvent();
|
||||||
|
foreach (var uid in _items)
|
||||||
|
{
|
||||||
|
_entMan.EventBus.RaiseLocalEvent(uid, ref ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ev.HashCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ByRefEvent]
|
||||||
|
public struct QueryBenchEvent
|
||||||
|
{
|
||||||
|
public int HashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class QueryBenchSystem : EntitySystem
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<ClothingComponent, QueryBenchEvent>(OnEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEvent(EntityUid uid, ClothingComponent component, ref QueryBenchEvent args)
|
||||||
|
{
|
||||||
|
args.HashCode = HashCode.Combine(args.HashCode, component.GetHashCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
#nullable enable
|
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using BenchmarkDotNet.Attributes;
|
|
||||||
using Content.IntegrationTests;
|
|
||||||
using Content.IntegrationTests.Pair;
|
|
||||||
using Content.Shared.Clothing.Components;
|
|
||||||
using Content.Shared.Item;
|
|
||||||
using Robust.Server.GameObjects;
|
|
||||||
using Robust.Shared;
|
|
||||||
using Robust.Shared.Analyzers;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Random;
|
|
||||||
|
|
||||||
namespace Content.Benchmarks;
|
|
||||||
|
|
||||||
[Virtual]
|
|
||||||
public class EntityQueryBenchmark
|
|
||||||
{
|
|
||||||
public const string Map = "Maps/atlas.yml";
|
|
||||||
|
|
||||||
private TestPair _pair = default!;
|
|
||||||
private IEntityManager _entMan = default!;
|
|
||||||
private MapId _mapId = new MapId(10);
|
|
||||||
private EntityQuery<ClothingComponent> _clothingQuery;
|
|
||||||
|
|
||||||
[GlobalSetup]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
ProgramShared.PathOffset = "../../../../";
|
|
||||||
PoolManager.Startup(null);
|
|
||||||
|
|
||||||
_pair = PoolManager.GetServerClient().GetAwaiter().GetResult();
|
|
||||||
_entMan = _pair.Server.ResolveDependency<IEntityManager>();
|
|
||||||
|
|
||||||
_pair.Server.ResolveDependency<IRobustRandom>().SetSeed(42);
|
|
||||||
_pair.Server.WaitPost(() =>
|
|
||||||
{
|
|
||||||
var success = _entMan.System<MapLoaderSystem>().TryLoad(_mapId, Map, out _);
|
|
||||||
if (!success)
|
|
||||||
throw new Exception("Map load failed");
|
|
||||||
_pair.Server.MapMan.DoMapInitialize(_mapId);
|
|
||||||
}).GetAwaiter().GetResult();
|
|
||||||
|
|
||||||
_clothingQuery = _entMan.GetEntityQuery<ClothingComponent>();
|
|
||||||
|
|
||||||
// Apparently ~40% of entities are items, and 1 in 6 of those are clothing.
|
|
||||||
/*
|
|
||||||
var entCount = _entMan.EntityCount;
|
|
||||||
var itemCount = _entMan.Count<ItemComponent>();
|
|
||||||
var clothingCount = _entMan.Count<ClothingComponent>();
|
|
||||||
var itemRatio = (float) itemCount / entCount;
|
|
||||||
var clothingRatio = (float) clothingCount / entCount;
|
|
||||||
Console.WriteLine($"Entities: {entCount}. Items: {itemRatio:P2}. Clothing: {clothingRatio:P2}.");
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
[GlobalCleanup]
|
|
||||||
public async Task Cleanup()
|
|
||||||
{
|
|
||||||
await _pair.DisposeAsync();
|
|
||||||
PoolManager.Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Benchmark]
|
|
||||||
public int HasComponent()
|
|
||||||
{
|
|
||||||
var hashCode = 0;
|
|
||||||
var enumerator = _entMan.AllEntityQueryEnumerator<ItemComponent>();
|
|
||||||
while (enumerator.MoveNext(out var uid, out var _))
|
|
||||||
{
|
|
||||||
if (_entMan.HasComponent<ClothingComponent>(uid))
|
|
||||||
hashCode = HashCode.Combine(hashCode, uid.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hashCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Benchmark]
|
|
||||||
public int HasComponentQuery()
|
|
||||||
{
|
|
||||||
var hashCode = 0;
|
|
||||||
var enumerator = _entMan.AllEntityQueryEnumerator<ItemComponent>();
|
|
||||||
while (enumerator.MoveNext(out var uid, out var _))
|
|
||||||
{
|
|
||||||
if (_clothingQuery.HasComponent(uid))
|
|
||||||
hashCode = HashCode.Combine(hashCode, uid.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hashCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Benchmark]
|
|
||||||
public int TryGetComponent()
|
|
||||||
{
|
|
||||||
var hashCode = 0;
|
|
||||||
var enumerator = _entMan.AllEntityQueryEnumerator<ItemComponent>();
|
|
||||||
while (enumerator.MoveNext(out var uid, out var _))
|
|
||||||
{
|
|
||||||
if (_entMan.TryGetComponent(uid, out ClothingComponent? clothing))
|
|
||||||
hashCode = HashCode.Combine(hashCode, clothing.GetHashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
return hashCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Benchmark]
|
|
||||||
public int TryGetComponentQuery()
|
|
||||||
{
|
|
||||||
var hashCode = 0;
|
|
||||||
var enumerator = _entMan.AllEntityQueryEnumerator<ItemComponent>();
|
|
||||||
while (enumerator.MoveNext(out var uid, out var _))
|
|
||||||
{
|
|
||||||
if (_clothingQuery.TryGetComponent(uid, out var clothing))
|
|
||||||
hashCode = HashCode.Combine(hashCode, clothing.GetHashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
return hashCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Enumerate all entities with both an item and clothing component.
|
|
||||||
/// </summary>
|
|
||||||
[Benchmark]
|
|
||||||
public int Enumerator()
|
|
||||||
{
|
|
||||||
var hashCode = 0;
|
|
||||||
var enumerator = _entMan.AllEntityQueryEnumerator<ItemComponent, ClothingComponent>();
|
|
||||||
while (enumerator.MoveNext(out var _, out var clothing))
|
|
||||||
{
|
|
||||||
hashCode = HashCode.Combine(hashCode, clothing.GetHashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
return hashCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -26,7 +26,7 @@ public class MapLoadBenchmark
|
|||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
ProgramShared.PathOffset = "../../../../";
|
ProgramShared.PathOffset = "../../../../";
|
||||||
PoolManager.Startup(null);
|
PoolManager.Startup();
|
||||||
|
|
||||||
_pair = PoolManager.GetServerClient().GetAwaiter().GetResult();
|
_pair = PoolManager.GetServerClient().GetAwaiter().GetResult();
|
||||||
var server = _pair.Server;
|
var server = _pair.Server;
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class PvsBenchmark
|
|||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
ProgramShared.PathOffset = "../../../../";
|
ProgramShared.PathOffset = "../../../../";
|
||||||
#endif
|
#endif
|
||||||
PoolManager.Startup(null);
|
PoolManager.Startup();
|
||||||
|
|
||||||
_pair = PoolManager.GetServerClient().GetAwaiter().GetResult();
|
_pair = PoolManager.GetServerClient().GetAwaiter().GetResult();
|
||||||
_entMan = _pair.Server.ResolveDependency<IEntityManager>();
|
_entMan = _pair.Server.ResolveDependency<IEntityManager>();
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class SpawnEquipDeleteBenchmark
|
|||||||
public async Task SetupAsync()
|
public async Task SetupAsync()
|
||||||
{
|
{
|
||||||
ProgramShared.PathOffset = "../../../../";
|
ProgramShared.PathOffset = "../../../../";
|
||||||
PoolManager.Startup(null);
|
PoolManager.Startup();
|
||||||
_pair = await PoolManager.GetServerClient();
|
_pair = await PoolManager.GetServerClient();
|
||||||
var server = _pair.Server;
|
var server = _pair.Server;
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public sealed partial class GravitySystem
|
|||||||
{
|
{
|
||||||
var localPlayer = _playerManager.LocalEntity;
|
var localPlayer = _playerManager.LocalEntity;
|
||||||
|
|
||||||
if (!TryComp<TransformComponent>(localPlayer, out var xform) ||
|
if (!TryComp(localPlayer, out TransformComponent? xform) ||
|
||||||
xform.GridUid != uid && xform.MapUid != uid)
|
xform.GridUid != uid && xform.MapUid != uid)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -46,7 +46,7 @@ public sealed partial class GravitySystem
|
|||||||
|
|
||||||
var localPlayer = _playerManager.LocalEntity;
|
var localPlayer = _playerManager.LocalEntity;
|
||||||
|
|
||||||
if (!TryComp<TransformComponent>(localPlayer, out var xform))
|
if (!TryComp(localPlayer, out TransformComponent? xform))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (xform.GridUid != uid ||
|
if (xform.GridUid != uid ||
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem
|
|||||||
{
|
{
|
||||||
if (_dragging == null) return;
|
if (_dragging == null) return;
|
||||||
|
|
||||||
if (_lastMousePosition != null && TryComp<TransformComponent>(_dragging.Value, out var xform) &&
|
if (_lastMousePosition != null && TryComp(_dragging.Value, out TransformComponent? xform) &&
|
||||||
TryComp<PhysicsComponent>(_dragging.Value, out var body) &&
|
TryComp<PhysicsComponent>(_dragging.Value, out var body) &&
|
||||||
xform.MapID == _lastMousePosition.Value.MapId)
|
xform.MapID == _lastMousePosition.Value.MapId)
|
||||||
{
|
{
|
||||||
@@ -104,7 +104,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem
|
|||||||
StartDragging(gridUid, Transform(gridUid).InvWorldMatrix.Transform(mousePos.Position));
|
StartDragging(gridUid, Transform(gridUid).InvWorldMatrix.Transform(mousePos.Position));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TryComp<TransformComponent>(_dragging, out var xform))
|
if (!TryComp(_dragging, out TransformComponent? xform))
|
||||||
{
|
{
|
||||||
StopDragging();
|
StopDragging();
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public sealed class SalvageSystem : SharedSalvageSystem
|
|||||||
|
|
||||||
var player = _playerManager.LocalEntity;
|
var player = _playerManager.LocalEntity;
|
||||||
|
|
||||||
if (!TryComp<TransformComponent>(player, out var xform) ||
|
if (!TryComp(player, out TransformComponent? xform) ||
|
||||||
!TryComp<SalvageExpeditionComponent>(xform.MapUid, out var expedition) ||
|
!TryComp<SalvageExpeditionComponent>(xform.MapUid, out var expedition) ||
|
||||||
expedition.Stage < ExpeditionStage.MusicCountdown)
|
expedition.Stage < ExpeditionStage.MusicCountdown)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public sealed class SpriteFadeSystem : EntitySystem
|
|||||||
var spriteQuery = GetEntityQuery<SpriteComponent>();
|
var spriteQuery = GetEntityQuery<SpriteComponent>();
|
||||||
var change = ChangeRate * frameTime;
|
var change = ChangeRate * frameTime;
|
||||||
|
|
||||||
if (TryComp<TransformComponent>(player, out var playerXform) &&
|
if (TryComp(player, out TransformComponent? playerXform) &&
|
||||||
_stateManager.CurrentState is GameplayState state &&
|
_stateManager.CurrentState is GameplayState state &&
|
||||||
spriteQuery.TryGetComponent(player, out var playerSprite))
|
spriteQuery.TryGetComponent(player, out var playerSprite))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ public sealed class TetherGunSystem : SharedTetherGunSystem
|
|||||||
|
|
||||||
const float BufferDistance = 0.1f;
|
const float BufferDistance = 0.1f;
|
||||||
|
|
||||||
if (TryComp<TransformComponent>(gun.TetherEntity, out var tetherXform) &&
|
if (TryComp(gun.TetherEntity, out TransformComponent? tetherXform) &&
|
||||||
tetherXform.Coordinates.TryDistance(EntityManager, TransformSystem, coords, out var distance) &&
|
tetherXform.Coordinates.TryDistance(EntityManager, TransformSystem, coords, out var distance) &&
|
||||||
distance < BufferDistance)
|
distance < BufferDistance)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,11 +15,8 @@ public static partial class PoolManager
|
|||||||
| BindingFlags.Public
|
| BindingFlags.Public
|
||||||
| BindingFlags.DeclaredOnly;
|
| BindingFlags.DeclaredOnly;
|
||||||
|
|
||||||
private static void DiscoverTestPrototypes(Assembly? assembly = null)
|
private static void DiscoverTestPrototypes(Assembly assembly)
|
||||||
{
|
{
|
||||||
assembly ??= typeof(PoolManager).Assembly;
|
|
||||||
_testPrototypes.Clear();
|
|
||||||
|
|
||||||
foreach (var type in assembly.GetTypes())
|
foreach (var type in assembly.GetTypes())
|
||||||
{
|
{
|
||||||
foreach (var field in type.GetFields(Flags))
|
foreach (var field in type.GetFields(Flags))
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ public static partial class PoolManager
|
|||||||
private static bool _dead;
|
private static bool _dead;
|
||||||
private static Exception? _poolFailureReason;
|
private static Exception? _poolFailureReason;
|
||||||
|
|
||||||
|
private static HashSet<Assembly> _contentAssemblies = default!;
|
||||||
|
|
||||||
public static async Task<(RobustIntegrationTest.ServerIntegrationInstance, PoolTestLogHandler)> GenerateServer(
|
public static async Task<(RobustIntegrationTest.ServerIntegrationInstance, PoolTestLogHandler)> GenerateServer(
|
||||||
PoolSettings poolSettings,
|
PoolSettings poolSettings,
|
||||||
TextWriter testOut)
|
TextWriter testOut)
|
||||||
@@ -54,12 +56,7 @@ public static partial class PoolManager
|
|||||||
LoadConfigAndUserData = false,
|
LoadConfigAndUserData = false,
|
||||||
LoadContentResources = !poolSettings.NoLoadContent,
|
LoadContentResources = !poolSettings.NoLoadContent,
|
||||||
},
|
},
|
||||||
ContentAssemblies = new[]
|
ContentAssemblies = _contentAssemblies.ToArray()
|
||||||
{
|
|
||||||
typeof(Shared.Entry.EntryPoint).Assembly,
|
|
||||||
typeof(Server.Entry.EntryPoint).Assembly,
|
|
||||||
typeof(PoolManager).Assembly
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var logHandler = new PoolTestLogHandler("SERVER");
|
var logHandler = new PoolTestLogHandler("SERVER");
|
||||||
@@ -140,7 +137,7 @@ public static partial class PoolManager
|
|||||||
{
|
{
|
||||||
typeof(Shared.Entry.EntryPoint).Assembly,
|
typeof(Shared.Entry.EntryPoint).Assembly,
|
||||||
typeof(Client.Entry.EntryPoint).Assembly,
|
typeof(Client.Entry.EntryPoint).Assembly,
|
||||||
typeof(PoolManager).Assembly
|
typeof(PoolManager).Assembly,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -422,13 +419,26 @@ we are just going to end this here to save a lot of time. This is the exception
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialize the pool manager.
|
/// Initialize the pool manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="assembly">Assembly to search for to discover extra test prototypes.</param>
|
/// <param name="extraAssemblies">Assemblies to search for to discover extra prototypes and systems.</param>
|
||||||
public static void Startup(Assembly? assembly)
|
public static void Startup(params Assembly[] extraAssemblies)
|
||||||
{
|
{
|
||||||
if (_initialized)
|
if (_initialized)
|
||||||
throw new InvalidOperationException("Already initialized");
|
throw new InvalidOperationException("Already initialized");
|
||||||
|
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
DiscoverTestPrototypes(assembly);
|
_contentAssemblies =
|
||||||
|
[
|
||||||
|
typeof(Shared.Entry.EntryPoint).Assembly,
|
||||||
|
typeof(Server.Entry.EntryPoint).Assembly,
|
||||||
|
typeof(PoolManager).Assembly
|
||||||
|
];
|
||||||
|
_contentAssemblies.UnionWith(extraAssemblies);
|
||||||
|
|
||||||
|
_testPrototypes.Clear();
|
||||||
|
DiscoverTestPrototypes(typeof(PoolManager).Assembly);
|
||||||
|
foreach (var assembly in extraAssemblies)
|
||||||
|
{
|
||||||
|
DiscoverTestPrototypes(assembly);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public sealed class PoolManagerTestEventHandler
|
|||||||
[OneTimeSetUp]
|
[OneTimeSetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
PoolManager.Startup(typeof(PoolManagerTestEventHandler).Assembly);
|
PoolManager.Startup();
|
||||||
// If the tests seem to be stuck, we try to end it semi-nicely
|
// If the tests seem to be stuck, we try to end it semi-nicely
|
||||||
_ = Task.Delay(MaximumTotalTestingTimeLimit).ContinueWith(_ =>
|
_ = Task.Delay(MaximumTotalTestingTimeLimit).ContinueWith(_ =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace Content.MapRenderer
|
|||||||
if (!CommandLineArguments.TryParse(args, out var arguments))
|
if (!CommandLineArguments.TryParse(args, out var arguments))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PoolManager.Startup(null);
|
PoolManager.Startup();
|
||||||
if (arguments.Maps.Count == 0)
|
if (arguments.Maps.Count == 0)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Didn't specify any maps to paint! Loading the map list...");
|
Console.WriteLine("Didn't specify any maps to paint! Loading the map list...");
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ public sealed class IdCardSystem : SharedIdCardSystem
|
|||||||
|
|
||||||
private void OnMicrowaved(EntityUid uid, IdCardComponent component, BeingMicrowavedEvent args)
|
private void OnMicrowaved(EntityUid uid, IdCardComponent component, BeingMicrowavedEvent args)
|
||||||
{
|
{
|
||||||
|
if (!component.CanMicrowave)
|
||||||
|
return;
|
||||||
|
|
||||||
if (TryComp<AccessComponent>(uid, out var access))
|
if (TryComp<AccessComponent>(uid, out var access))
|
||||||
{
|
{
|
||||||
float randomPick = _random.NextFloat();
|
float randomPick = _random.NextFloat();
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ public sealed partial class AtmosphereSystem
|
|||||||
foreach (var grid in _mapManager.GetAllGrids(playerMap.Value).OrderBy(o => o.Owner))
|
foreach (var grid in _mapManager.GetAllGrids(playerMap.Value).OrderBy(o => o.Owner))
|
||||||
{
|
{
|
||||||
var uid = grid.Owner;
|
var uid = grid.Owner;
|
||||||
if (!TryComp<TransformComponent>(uid, out var gridXform))
|
if (!TryComp(uid, out TransformComponent? gridXform))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
options.Add(new CompletionOption(uid.ToString(), $"{MetaData(uid).EntityName} - Map {gridXform.MapID}"));
|
options.Add(new CompletionOption(uid.ToString(), $"{MetaData(uid).EntityName} - Map {gridXform.MapID}"));
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ namespace Content.Server.Bible
|
|||||||
{
|
{
|
||||||
Act = () =>
|
Act = () =>
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(args.User, out var userXform))
|
if (!TryComp(args.User, out TransformComponent? userXform))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
AttemptSummon((uid, component), args.User, userXform);
|
AttemptSummon((uid, component), args.User, userXform);
|
||||||
@@ -267,7 +267,7 @@ namespace Content.Server.Bible
|
|||||||
// If this is going to use a ghost role mob spawner, attach it to the bible.
|
// If this is going to use a ghost role mob spawner, attach it to the bible.
|
||||||
if (HasComp<GhostRoleMobSpawnerComponent>(familiar))
|
if (HasComp<GhostRoleMobSpawnerComponent>(familiar))
|
||||||
{
|
{
|
||||||
_popupSystem.PopupEntity(Loc.GetString("bible-summon-requested"), user, PopupType.Medium);
|
_popupSystem.PopupEntity(Loc.GetString("bible-summon-requested"), user, user, PopupType.Medium);
|
||||||
_transform.SetParent(familiar, uid);
|
_transform.SetParent(familiar, uid);
|
||||||
}
|
}
|
||||||
component.AlreadySummoned = true;
|
component.AlreadySummoned = true;
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace Content.Server.Engineering.EntitySystems
|
|||||||
if (component.Deleted || Deleted(uid))
|
if (component.Deleted || Deleted(uid))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TryComp<TransformComponent>(uid, out var transformComp))
|
if (!TryComp(uid, out TransformComponent? transformComp))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var entity = EntityManager.SpawnEntity(component.Prototype, transformComp.Coordinates);
|
var entity = EntityManager.SpawnEntity(component.Prototype, transformComp.Coordinates);
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ namespace Content.Server.Explosion.EntitySystems
|
|||||||
|
|
||||||
private void HandleGibTrigger(EntityUid uid, GibOnTriggerComponent component, TriggerEvent args)
|
private void HandleGibTrigger(EntityUid uid, GibOnTriggerComponent component, TriggerEvent args)
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(uid, out var xform))
|
if (!TryComp(uid, out TransformComponent? xform))
|
||||||
return;
|
return;
|
||||||
if (component.DeleteItems)
|
if (component.DeleteItems)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ public sealed class FaxSystem : EntitySystem
|
|||||||
if (sendEntity == null)
|
if (sendEntity == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TryComp<MetaDataComponent>(sendEntity, out var metadata) ||
|
if (!TryComp(sendEntity, out MetaDataComponent? metadata) ||
|
||||||
!TryComp<PaperComponent>(sendEntity, out var paper))
|
!TryComp<PaperComponent>(sendEntity, out var paper))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -506,7 +506,7 @@ public sealed class FaxSystem : EntitySystem
|
|||||||
if (!component.KnownFaxes.TryGetValue(component.DestinationFaxAddress, out var faxName))
|
if (!component.KnownFaxes.TryGetValue(component.DestinationFaxAddress, out var faxName))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TryComp<MetaDataComponent>(sendEntity, out var metadata) ||
|
if (!TryComp(sendEntity, out MetaDataComponent? metadata) ||
|
||||||
!TryComp<PaperComponent>(sendEntity, out var paper))
|
!TryComp<PaperComponent>(sendEntity, out var paper))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace Content.Server.Gravity
|
|||||||
private void OnComponentShutdown(EntityUid uid, GravityGeneratorComponent component, ComponentShutdown args)
|
private void OnComponentShutdown(EntityUid uid, GravityGeneratorComponent component, ComponentShutdown args)
|
||||||
{
|
{
|
||||||
if (component.GravityActive &&
|
if (component.GravityActive &&
|
||||||
TryComp<TransformComponent>(uid, out var xform) &&
|
TryComp(uid, out TransformComponent? xform) &&
|
||||||
TryComp(xform.ParentUid, out GravityComponent? gravity))
|
TryComp(xform.ParentUid, out GravityComponent? gravity))
|
||||||
{
|
{
|
||||||
component.GravityActive = false;
|
component.GravityActive = false;
|
||||||
@@ -118,7 +118,7 @@ namespace Content.Server.Gravity
|
|||||||
UpdateUI(ent, chargeRate);
|
UpdateUI(ent, chargeRate);
|
||||||
|
|
||||||
if (active != gravGen.GravityActive &&
|
if (active != gravGen.GravityActive &&
|
||||||
TryComp<TransformComponent>(uid, out var xform) &&
|
TryComp(uid, out TransformComponent? xform) &&
|
||||||
TryComp<GravityComponent>(xform.ParentUid, out var gravity))
|
TryComp<GravityComponent>(xform.ParentUid, out var gravity))
|
||||||
{
|
{
|
||||||
// Force it on in the faster path.
|
// Force it on in the faster path.
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ namespace Content.Server.Medical
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var name = "Unknown";
|
var name = "Unknown";
|
||||||
if (TryComp<MetaDataComponent>(args.Using.Value, out var metadata))
|
if (TryComp(args.Using.Value, out MetaDataComponent? metadata))
|
||||||
name = metadata.EntityName;
|
name = metadata.EntityName;
|
||||||
|
|
||||||
InteractionVerb verb = new()
|
InteractionVerb verb = new()
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ public sealed partial class PathfindingSystem
|
|||||||
|
|
||||||
if (end.GraphUid != start.GraphUid)
|
if (end.GraphUid != start.GraphUid)
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(start.GraphUid, out var startXform) ||
|
if (!TryComp(start.GraphUid, out TransformComponent? startXform) ||
|
||||||
!TryComp<TransformComponent>(end.GraphUid, out var endXform))
|
!TryComp(end.GraphUid, out TransformComponent? endXform))
|
||||||
{
|
{
|
||||||
return Vector2.Zero;
|
return Vector2.Zero;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ public sealed partial class PathfindingSystem
|
|||||||
|
|
||||||
private void OnBodyTypeChange(ref PhysicsBodyTypeChangedEvent ev)
|
private void OnBodyTypeChange(ref PhysicsBodyTypeChangedEvent ev)
|
||||||
{
|
{
|
||||||
if (TryComp<TransformComponent>(ev.Entity, out var xform) &&
|
if (TryComp(ev.Entity, out TransformComponent? xform) &&
|
||||||
xform.GridUid != null)
|
xform.GridUid != null)
|
||||||
{
|
{
|
||||||
var aabb = _lookup.GetAABBNoContainer(ev.Entity, xform.Coordinates.Position, xform.LocalRotation);
|
var aabb = _lookup.GetAABBNoContainer(ev.Entity, xform.Coordinates.Position, xform.LocalRotation);
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ namespace Content.Server.NPC.Pathfinding
|
|||||||
int limit = 40,
|
int limit = 40,
|
||||||
PathFlags flags = PathFlags.None)
|
PathFlags flags = PathFlags.None)
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(entity, out var start))
|
if (!TryComp(entity, out TransformComponent? start))
|
||||||
return new PathResultEvent(PathResult.NoPath, new List<PathPoly>());
|
return new PathResultEvent(PathResult.NoPath, new List<PathPoly>());
|
||||||
|
|
||||||
var layer = 0;
|
var layer = 0;
|
||||||
@@ -294,7 +294,7 @@ namespace Content.Server.NPC.Pathfinding
|
|||||||
CancellationToken cancelToken,
|
CancellationToken cancelToken,
|
||||||
PathFlags flags = PathFlags.None)
|
PathFlags flags = PathFlags.None)
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(entity, out var start))
|
if (!TryComp(entity, out TransformComponent? start))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var request = GetRequest(entity, start.Coordinates, end, range, cancelToken, flags);
|
var request = GetRequest(entity, start.Coordinates, end, range, cancelToken, flags);
|
||||||
@@ -325,8 +325,8 @@ namespace Content.Server.NPC.Pathfinding
|
|||||||
CancellationToken cancelToken,
|
CancellationToken cancelToken,
|
||||||
PathFlags flags = PathFlags.None)
|
PathFlags flags = PathFlags.None)
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(entity, out var xform) ||
|
if (!TryComp(entity, out TransformComponent? xform) ||
|
||||||
!TryComp<TransformComponent>(target, out var targetXform))
|
!TryComp(target, out TransformComponent? targetXform))
|
||||||
return new PathResultEvent(PathResult.NoPath, new List<PathPoly>());
|
return new PathResultEvent(PathResult.NoPath, new List<PathPoly>());
|
||||||
|
|
||||||
var request = GetRequest(entity, xform.Coordinates, targetXform.Coordinates, range, cancelToken, flags);
|
var request = GetRequest(entity, xform.Coordinates, targetXform.Coordinates, range, cancelToken, flags);
|
||||||
@@ -400,7 +400,7 @@ namespace Content.Server.NPC.Pathfinding
|
|||||||
var gridUid = coordinates.GetGridUid(EntityManager);
|
var gridUid = coordinates.GetGridUid(EntityManager);
|
||||||
|
|
||||||
if (!TryComp<GridPathfindingComponent>(gridUid, out var comp) ||
|
if (!TryComp<GridPathfindingComponent>(gridUid, out var comp) ||
|
||||||
!TryComp<TransformComponent>(gridUid, out var xform))
|
!TryComp(gridUid, out TransformComponent? xform))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -260,8 +260,8 @@ public sealed class NPCUtilitySystem : EntitySystem
|
|||||||
{
|
{
|
||||||
var radius = blackboard.GetValueOrDefault<float>(NPCBlackboard.VisionRadius, EntityManager);
|
var radius = blackboard.GetValueOrDefault<float>(NPCBlackboard.VisionRadius, EntityManager);
|
||||||
|
|
||||||
if (!TryComp<TransformComponent>(targetUid, out var targetXform) ||
|
if (!TryComp(targetUid, out TransformComponent? targetXform) ||
|
||||||
!TryComp<TransformComponent>(owner, out var xform))
|
!TryComp(owner, out TransformComponent? xform))
|
||||||
{
|
{
|
||||||
return 0f;
|
return 0f;
|
||||||
}
|
}
|
||||||
@@ -308,8 +308,8 @@ public sealed class NPCUtilitySystem : EntitySystem
|
|||||||
|
|
||||||
if (blackboard.TryGetValue<EntityUid>("Target", out var currentTarget, EntityManager) &&
|
if (blackboard.TryGetValue<EntityUid>("Target", out var currentTarget, EntityManager) &&
|
||||||
currentTarget == targetUid &&
|
currentTarget == targetUid &&
|
||||||
TryComp<TransformComponent>(owner, out var xform) &&
|
TryComp(owner, out TransformComponent? xform) &&
|
||||||
TryComp<TransformComponent>(targetUid, out var targetXform) &&
|
TryComp(targetUid, out TransformComponent? targetXform) &&
|
||||||
xform.Coordinates.TryDistance(EntityManager, _transform, targetXform.Coordinates, out var distance) &&
|
xform.Coordinates.TryDistance(EntityManager, _transform, targetXform.Coordinates, out var distance) &&
|
||||||
distance <= radius + bufferRange)
|
distance <= radius + bufferRange)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public sealed class PAISystem : SharedPAISystem
|
|||||||
if (TryComp<InstrumentComponent>(uid, out var instrument))
|
if (TryComp<InstrumentComponent>(uid, out var instrument))
|
||||||
_instrumentSystem.Clean(uid, instrument);
|
_instrumentSystem.Clean(uid, instrument);
|
||||||
|
|
||||||
if (TryComp<MetaDataComponent>(uid, out var metadata))
|
if (TryComp(uid, out MetaDataComponent? metadata))
|
||||||
{
|
{
|
||||||
var proto = metadata.EntityPrototype;
|
var proto = metadata.EntityPrototype;
|
||||||
if (proto != null)
|
if (proto != null)
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
|
using Content.Shared.StoryGen;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Server.Paper;
|
namespace Content.Server.Paper;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds randomly generated stories to Paper component
|
/// Adds a randomly generated story to the content of a <see cref="PaperComponent"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent, Access(typeof(PaperRandomStorySystem))]
|
[RegisterComponent, Access(typeof(PaperRandomStorySystem))]
|
||||||
public sealed partial class PaperRandomStoryComponent : Component
|
public sealed partial class PaperRandomStoryComponent : Component
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="StoryTemplatePrototype"/> ID to use for story generation.
|
||||||
|
/// </summary>
|
||||||
[DataField]
|
[DataField]
|
||||||
public List<string>? StorySegments;
|
public ProtoId<StoryTemplatePrototype> Template;
|
||||||
|
|
||||||
[DataField]
|
|
||||||
public string StorySeparator = " ";
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
using Content.Server.RandomMetadata;
|
using Content.Shared.StoryGen;
|
||||||
|
|
||||||
namespace Content.Server.Paper;
|
namespace Content.Server.Paper;
|
||||||
|
|
||||||
public sealed class PaperRandomStorySystem : EntitySystem
|
public sealed class PaperRandomStorySystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly StoryGeneratorSystem _storyGen = default!;
|
||||||
[Dependency] private readonly RandomMetadataSystem _randomMeta = default!;
|
[Dependency] private readonly PaperSystem _paper = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -19,11 +19,9 @@ public sealed class PaperRandomStorySystem : EntitySystem
|
|||||||
if (!TryComp<PaperComponent>(paperStory, out var paper))
|
if (!TryComp<PaperComponent>(paperStory, out var paper))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (paperStory.Comp.StorySegments == null)
|
if (!_storyGen.TryGenerateStoryFromTemplate(paperStory.Comp.Template, out var story))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var story = _randomMeta.GetRandomFromSegments(paperStory.Comp.StorySegments, paperStory.Comp.StorySeparator);
|
_paper.SetContent(paperStory.Owner, story, paper);
|
||||||
|
|
||||||
paper.Content += $"\n{story}";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ namespace Content.Server.Paper
|
|||||||
if (TryComp<AppearanceComponent>(uid, out var appearance))
|
if (TryComp<AppearanceComponent>(uid, out var appearance))
|
||||||
_appearance.SetData(uid, PaperVisuals.Status, PaperStatus.Written, appearance);
|
_appearance.SetData(uid, PaperVisuals.Status, PaperStatus.Written, appearance);
|
||||||
|
|
||||||
if (TryComp<MetaDataComponent>(uid, out var meta))
|
if (TryComp(uid, out MetaDataComponent? meta))
|
||||||
_metaSystem.SetEntityDescription(uid, "", meta);
|
_metaSystem.SetEntityDescription(uid, "", meta);
|
||||||
|
|
||||||
_adminLogger.Add(LogType.Chat, LogImpact.Low,
|
_adminLogger.Add(LogType.Chat, LogImpact.Low,
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ namespace Content.Server.Physics.Controllers
|
|||||||
consoleEnt = cargoConsole.Entity;
|
consoleEnt = cargoConsole.Entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TryComp<TransformComponent>(consoleEnt, out var xform)) continue;
|
if (!TryComp(consoleEnt, out TransformComponent? xform)) continue;
|
||||||
|
|
||||||
var gridId = xform.GridUid;
|
var gridId = xform.GridUid;
|
||||||
// This tries to see if the grid is a shuttle and if the console should work.
|
// This tries to see if the grid is a shuttle and if the console should work.
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ public sealed partial class PolymorphSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configuration.TransferName && TryComp<MetaDataComponent>(uid, out var targetMeta))
|
if (configuration.TransferName && TryComp(uid, out MetaDataComponent? targetMeta))
|
||||||
_metaData.SetEntityName(child, targetMeta.EntityName);
|
_metaData.SetEntityName(child, targetMeta.EntityName);
|
||||||
|
|
||||||
if (configuration.TransferHumanoidAppearance)
|
if (configuration.TransferHumanoidAppearance)
|
||||||
|
|||||||
@@ -240,7 +240,8 @@ namespace Content.Server.Power.Pow3r
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unmet <= 0 || totalBatterySupply <= 0)
|
// Return if normal supplies met all demand or there are no supplying batteries
|
||||||
|
if (unmet <= 0 || totalMaxBatterySupply <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Target output capacity for batteries
|
// Target output capacity for batteries
|
||||||
@@ -275,8 +276,8 @@ namespace Content.Server.Power.Pow3r
|
|||||||
|
|
||||||
battery.SupplyRampTarget = battery.MaxEffectiveSupply * relativeTargetBatteryOutput - battery.CurrentReceiving * battery.Efficiency;
|
battery.SupplyRampTarget = battery.MaxEffectiveSupply * relativeTargetBatteryOutput - battery.CurrentReceiving * battery.Efficiency;
|
||||||
|
|
||||||
DebugTools.Assert(battery.SupplyRampTarget + battery.CurrentReceiving * battery.Efficiency <= battery.LoadingNetworkDemand
|
DebugTools.Assert(battery.MaxEffectiveSupply * relativeTargetBatteryOutput <= battery.LoadingNetworkDemand
|
||||||
|| MathHelper.CloseToPercent(battery.SupplyRampTarget + battery.CurrentReceiving * battery.Efficiency, battery.LoadingNetworkDemand, 0.001));
|
|| MathHelper.CloseToPercent(battery.MaxEffectiveSupply * relativeTargetBatteryOutput, battery.LoadingNetworkDemand, 0.001));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ public sealed class ProjectileSystem : SharedProjectileSystem
|
|||||||
if (component.DeleteOnCollide)
|
if (component.DeleteOnCollide)
|
||||||
QueueDel(uid);
|
QueueDel(uid);
|
||||||
|
|
||||||
if (component.ImpactEffect != null && TryComp<TransformComponent>(uid, out var xform))
|
if (component.ImpactEffect != null && TryComp(uid, out TransformComponent? xform))
|
||||||
{
|
{
|
||||||
RaiseNetworkEvent(new ImpactEffectEvent(component.ImpactEffect, GetNetCoordinates(xform.Coordinates)), Filter.Pvs(xform.Coordinates, entityMan: EntityManager));
|
RaiseNetworkEvent(new ImpactEffectEvent(component.ImpactEffect, GetNetCoordinates(xform.Coordinates)), Filter.Pvs(xform.Coordinates, entityMan: EntityManager));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public sealed class FultonSystem : SharedFultonSystem
|
|||||||
private void Fulton(EntityUid uid, FultonedComponent component)
|
private void Fulton(EntityUid uid, FultonedComponent component)
|
||||||
{
|
{
|
||||||
if (!Deleted(component.Beacon) &&
|
if (!Deleted(component.Beacon) &&
|
||||||
TryComp<TransformComponent>(component.Beacon, out var beaconXform) &&
|
TryComp(component.Beacon, out TransformComponent? beaconXform) &&
|
||||||
!Container.IsEntityOrParentInContainer(component.Beacon.Value, xform: beaconXform) &&
|
!Container.IsEntityOrParentInContainer(component.Beacon.Value, xform: beaconXform) &&
|
||||||
CanFulton(uid))
|
CanFulton(uid))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public sealed partial class SalvageSystem
|
|||||||
|
|
||||||
private void OnConsoleFTLAttempt(ref ConsoleFTLAttemptEvent ev)
|
private void OnConsoleFTLAttempt(ref ConsoleFTLAttemptEvent ev)
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(ev.Uid, out var xform) ||
|
if (!TryComp(ev.Uid, out TransformComponent? xform) ||
|
||||||
!TryComp<SalvageExpeditionComponent>(xform.MapUid, out var salvage))
|
!TryComp<SalvageExpeditionComponent>(xform.MapUid, out var salvage))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ public sealed class ArrivalsSystem : EntitySystem
|
|||||||
|
|
||||||
TryGetArrivals(out var arrivals);
|
TryGetArrivals(out var arrivals);
|
||||||
|
|
||||||
if (TryComp<TransformComponent>(arrivals, out var arrivalsXform))
|
if (TryComp(arrivals, out TransformComponent? arrivalsXform))
|
||||||
{
|
{
|
||||||
var mapId = arrivalsXform.MapID;
|
var mapId = arrivalsXform.MapID;
|
||||||
|
|
||||||
@@ -413,7 +413,7 @@ public sealed class ArrivalsSystem : EntitySystem
|
|||||||
var curTime = _timing.CurTime;
|
var curTime = _timing.CurTime;
|
||||||
TryGetArrivals(out var arrivals);
|
TryGetArrivals(out var arrivals);
|
||||||
|
|
||||||
if (TryComp<TransformComponent>(arrivals, out var arrivalsXform))
|
if (TryComp(arrivals, out TransformComponent? arrivalsXform))
|
||||||
{
|
{
|
||||||
while (query.MoveNext(out var uid, out var comp, out var shuttle, out var xform))
|
while (query.MoveNext(out var uid, out var comp, out var shuttle, out var xform))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
|||||||
if (!Resolve(stationUid, ref stationShuttle))
|
if (!Resolve(stationUid, ref stationShuttle))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TryComp<TransformComponent>(stationShuttle.EmergencyShuttle, out var xform) ||
|
if (!TryComp(stationShuttle.EmergencyShuttle, out TransformComponent? xform) ||
|
||||||
!TryComp<ShuttleComponent>(stationShuttle.EmergencyShuttle, out var shuttle))
|
!TryComp<ShuttleComponent>(stationShuttle.EmergencyShuttle, out var shuttle))
|
||||||
{
|
{
|
||||||
Log.Error($"Attempted to call an emergency shuttle for an uninitialized station? Station: {ToPrettyString(stationUid)}. Shuttle: {ToPrettyString(stationShuttle.EmergencyShuttle)}");
|
Log.Error($"Attempted to call an emergency shuttle for an uninitialized station? Station: {ToPrettyString(stationUid)}. Shuttle: {ToPrettyString(stationShuttle.EmergencyShuttle)}");
|
||||||
@@ -294,7 +294,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
|||||||
|
|
||||||
if (_shuttle.TryFTLDock(stationShuttle.EmergencyShuttle.Value, shuttle, targetGrid.Value, DockTag))
|
if (_shuttle.TryFTLDock(stationShuttle.EmergencyShuttle.Value, shuttle, targetGrid.Value, DockTag))
|
||||||
{
|
{
|
||||||
if (TryComp<TransformComponent>(targetGrid.Value, out var targetXform))
|
if (TryComp(targetGrid.Value, out TransformComponent? targetXform))
|
||||||
{
|
{
|
||||||
var angle = _dock.GetAngle(stationShuttle.EmergencyShuttle.Value, xform, targetGrid.Value, targetXform,
|
var angle = _dock.GetAngle(stationShuttle.EmergencyShuttle.Value, xform, targetGrid.Value, targetXform,
|
||||||
xformQuery);
|
xformQuery);
|
||||||
@@ -350,7 +350,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Post mapinit? fancy
|
// Post mapinit? fancy
|
||||||
if (TryComp<TransformComponent>(component.Entity, out var xform))
|
if (TryComp(component.Entity, out TransformComponent? xform))
|
||||||
{
|
{
|
||||||
component.MapEntity = xform.MapUid;
|
component.MapEntity = xform.MapUid;
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
|
|||||||
RaiseLocalEvent(entity.Value, ref getShuttleEv);
|
RaiseLocalEvent(entity.Value, ref getShuttleEv);
|
||||||
entity = getShuttleEv.Console;
|
entity = getShuttleEv.Console;
|
||||||
|
|
||||||
TryComp<TransformComponent>(entity, out var consoleXform);
|
TryComp(entity, out TransformComponent? consoleXform);
|
||||||
var shuttleGridUid = consoleXform?.GridUid;
|
var shuttleGridUid = consoleXform?.GridUid;
|
||||||
|
|
||||||
NavInterfaceState navState;
|
NavInterfaceState navState;
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ public sealed partial class ShuttleSystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TryComp<DockingComponent>(uid, out var dock) ||
|
if (!TryComp<DockingComponent>(uid, out var dock) ||
|
||||||
!TryComp<TransformComponent>(uid, out var xform) ||
|
!TryComp(uid, out TransformComponent? xform) ||
|
||||||
xform.GridUid == null)
|
xform.GridUid == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -196,7 +196,7 @@ public sealed partial class ShuttleSystem
|
|||||||
|
|
||||||
if (_loader.TryLoad(mapId, component.Path.ToString(), out var ent) &&
|
if (_loader.TryLoad(mapId, component.Path.ToString(), out var ent) &&
|
||||||
ent.Count == 1 &&
|
ent.Count == 1 &&
|
||||||
TryComp<TransformComponent>(ent[0], out var shuttleXform))
|
TryComp(ent[0], out TransformComponent? shuttleXform))
|
||||||
{
|
{
|
||||||
var escape = GetSingleDock(ent[0]);
|
var escape = GetSingleDock(ent[0]);
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public sealed partial class ShuttleSystem
|
|||||||
|
|
||||||
private void OnIFFShow(EntityUid uid, IFFConsoleComponent component, IFFShowIFFMessage args)
|
private void OnIFFShow(EntityUid uid, IFFConsoleComponent component, IFFShowIFFMessage args)
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(uid, out var xform) || xform.GridUid == null ||
|
if (!TryComp(uid, out TransformComponent? xform) || xform.GridUid == null ||
|
||||||
(component.AllowedFlags & IFFFlags.HideLabel) == 0x0)
|
(component.AllowedFlags & IFFFlags.HideLabel) == 0x0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -34,7 +34,7 @@ public sealed partial class ShuttleSystem
|
|||||||
|
|
||||||
private void OnIFFShowVessel(EntityUid uid, IFFConsoleComponent component, IFFShowVesselMessage args)
|
private void OnIFFShowVessel(EntityUid uid, IFFConsoleComponent component, IFFShowVesselMessage args)
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(uid, out var xform) || xform.GridUid == null ||
|
if (!TryComp(uid, out TransformComponent? xform) || xform.GridUid == null ||
|
||||||
(component.AllowedFlags & IFFFlags.Hide) == 0x0)
|
(component.AllowedFlags & IFFFlags.Hide) == 0x0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -54,7 +54,7 @@ public sealed partial class ShuttleSystem
|
|||||||
{
|
{
|
||||||
// If we anchor / re-anchor then make sure flags up to date.
|
// If we anchor / re-anchor then make sure flags up to date.
|
||||||
if (!args.Anchored ||
|
if (!args.Anchored ||
|
||||||
!TryComp<TransformComponent>(uid, out var xform) ||
|
!TryComp(uid, out TransformComponent? xform) ||
|
||||||
!TryComp<IFFComponent>(xform.GridUid, out var iff))
|
!TryComp<IFFComponent>(xform.GridUid, out var iff))
|
||||||
{
|
{
|
||||||
_uiSystem.SetUiState(uid, IFFConsoleUiKey.Key, new IFFConsoleBoundUserInterfaceState()
|
_uiSystem.SetUiState(uid, IFFConsoleUiKey.Key, new IFFConsoleBoundUserInterfaceState()
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public sealed class SpawnOnDespawnSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnDespawn(EntityUid uid, SpawnOnDespawnComponent comp, ref TimedDespawnEvent args)
|
private void OnDespawn(EntityUid uid, SpawnOnDespawnComponent comp, ref TimedDespawnEvent args)
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(uid, out var xform))
|
if (!TryComp(uid, out TransformComponent? xform))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Spawn(comp.Prototype, xform.Coordinates);
|
Spawn(comp.Prototype, xform.Coordinates);
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ namespace Content.Server.Speech.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("wordReplacements")]
|
[DataField("wordReplacements")]
|
||||||
public Dictionary<string, string>? WordReplacements;
|
public Dictionary<string, string>? WordReplacements;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Allows you to substitute words, not always, but with some chance
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public float ReplacementChance = 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -33,10 +39,5 @@ namespace Content.Server.Speech.Components
|
|||||||
[DataField("accent", customTypeSerializer: typeof(PrototypeIdSerializer<ReplacementAccentPrototype>), required: true)]
|
[DataField("accent", customTypeSerializer: typeof(PrototypeIdSerializer<ReplacementAccentPrototype>), required: true)]
|
||||||
public string Accent = default!;
|
public string Accent = default!;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Allows you to substitute words, not always, but with some chance
|
|
||||||
/// </summary>
|
|
||||||
[DataField]
|
|
||||||
public float ReplacementChance = 1f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,6 @@ namespace Content.Server.Speech.EntitySystems
|
|||||||
|
|
||||||
private void OnAccent(EntityUid uid, ReplacementAccentComponent component, AccentGetEvent args)
|
private void OnAccent(EntityUid uid, ReplacementAccentComponent component, AccentGetEvent args)
|
||||||
{
|
{
|
||||||
if (!_random.Prob(component.ReplacementChance))
|
|
||||||
return;
|
|
||||||
|
|
||||||
args.Message = ApplyReplacements(args.Message, component.Accent);
|
args.Message = ApplyReplacements(args.Message, component.Accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +36,9 @@ namespace Content.Server.Speech.EntitySystems
|
|||||||
if (!_proto.TryIndex<ReplacementAccentPrototype>(accent, out var prototype))
|
if (!_proto.TryIndex<ReplacementAccentPrototype>(accent, out var prototype))
|
||||||
return message;
|
return message;
|
||||||
|
|
||||||
|
if (!_random.Prob(prototype.ReplacementChance))
|
||||||
|
return message;
|
||||||
|
|
||||||
// Prioritize fully replacing if that exists--
|
// Prioritize fully replacing if that exists--
|
||||||
// ideally both aren't used at the same time (but we don't have a way to enforce that in serialization yet)
|
// ideally both aren't used at the same time (but we don't have a way to enforce that in serialization yet)
|
||||||
if (prototype.FullReplacements != null)
|
if (prototype.FullReplacements != null)
|
||||||
|
|||||||
@@ -46,4 +46,7 @@ public sealed partial class IdCardComponent : Component
|
|||||||
|
|
||||||
[DataField]
|
[DataField]
|
||||||
public LocId FullNameLocId = "access-id-card-component-owner-full-name-job-title-text";
|
public LocId FullNameLocId = "access-id-card-component-owner-full-name-job-title-text";
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public bool CanMicrowave = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -577,7 +577,7 @@ namespace Content.Shared.Interaction
|
|||||||
Ignored? predicate = null,
|
Ignored? predicate = null,
|
||||||
bool popup = false)
|
bool popup = false)
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(other, out var otherXform))
|
if (!TryComp(other, out TransformComponent? otherXform))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return InRangeUnobstructed(origin, other, otherXform.Coordinates, otherXform.LocalRotation, range, collisionMask, predicate,
|
return InRangeUnobstructed(origin, other, otherXform.Coordinates, otherXform.LocalRotation, range, collisionMask, predicate,
|
||||||
@@ -640,7 +640,7 @@ namespace Content.Shared.Interaction
|
|||||||
fixtureA.FixtureCount > 0 &&
|
fixtureA.FixtureCount > 0 &&
|
||||||
TryComp<FixturesComponent>(other, out var fixtureB) &&
|
TryComp<FixturesComponent>(other, out var fixtureB) &&
|
||||||
fixtureB.FixtureCount > 0 &&
|
fixtureB.FixtureCount > 0 &&
|
||||||
TryComp<TransformComponent>(origin, out var xformA))
|
TryComp(origin, out TransformComponent? xformA))
|
||||||
{
|
{
|
||||||
var (worldPosA, worldRotA) = xformA.GetWorldPositionRotation();
|
var (worldPosA, worldRotA) = xformA.GetWorldPositionRotation();
|
||||||
var xfA = new Transform(worldPosA, worldRotA);
|
var xfA = new Transform(worldPosA, worldRotA);
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public abstract class SharedJetpackSystem : EntitySystem
|
|||||||
if (args.Handled)
|
if (args.Handled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (TryComp<TransformComponent>(uid, out var xform) && !CanEnableOnGrid(xform.GridUid))
|
if (TryComp(uid, out TransformComponent? xform) && !CanEnableOnGrid(xform.GridUid))
|
||||||
{
|
{
|
||||||
_popup.PopupClient(Loc.GetString("jetpack-no-station"), uid, args.Performer);
|
_popup.PopupClient(Loc.GetString("jetpack-no-station"), uid, args.Performer);
|
||||||
|
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ namespace Content.Shared.Movement.Systems
|
|||||||
// For stuff like "Moving out of locker" or the likes
|
// For stuff like "Moving out of locker" or the likes
|
||||||
// We'll relay a movement input to the parent.
|
// We'll relay a movement input to the parent.
|
||||||
if (_container.IsEntityInContainer(entity) &&
|
if (_container.IsEntityInContainer(entity) &&
|
||||||
TryComp<TransformComponent>(entity, out var xform) &&
|
TryComp(entity, out TransformComponent? xform) &&
|
||||||
xform.ParentUid.IsValid() &&
|
xform.ParentUid.IsValid() &&
|
||||||
_mobState.IsAlive(entity))
|
_mobState.IsAlive(entity))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ public sealed partial class PressurizedSolutionSystem : EntitySystem
|
|||||||
var solution = _solutionContainer.SplitSolution(soln.Value, interactions.Volume);
|
var solution = _solutionContainer.SplitSolution(soln.Value, interactions.Volume);
|
||||||
|
|
||||||
// Spray the solution onto the ground and anyone nearby
|
// Spray the solution onto the ground and anyone nearby
|
||||||
if (TryComp<TransformComponent>(entity, out var transform))
|
if (TryComp(entity, out TransformComponent? transform))
|
||||||
_puddle.TrySplashSpillAt(entity, transform.Coordinates, solution, out _, sound: false);
|
_puddle.TrySplashSpillAt(entity, transform.Coordinates, solution, out _, sound: false);
|
||||||
|
|
||||||
var drinkName = Identity.Entity(entity, EntityManager);
|
var drinkName = Identity.Entity(entity, EntityManager);
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public abstract partial class SharedDrinkSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
string remainingString = "drink-component-on-examine-is-half-full";
|
string remainingString = "drink-component-on-examine-is-half-full";
|
||||||
|
|
||||||
if (TryComp<MetaDataComponent>(args.Examiner, out var examiner) && examiner.EntityName.Length > 0
|
if (TryComp(args.Examiner, out MetaDataComponent? examiner) && examiner.EntityName.Length > 0
|
||||||
&& string.Compare(examiner.EntityName.Substring(0, 1), "m", StringComparison.InvariantCultureIgnoreCase) > 0)
|
&& string.Compare(examiner.EntityName.Substring(0, 1), "m", StringComparison.InvariantCultureIgnoreCase) > 0)
|
||||||
remainingString = "drink-component-on-examine-is-half-empty";
|
remainingString = "drink-component-on-examine-is-half-empty";
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public sealed class RulesSystem : EntitySystem
|
|||||||
break;
|
break;
|
||||||
case GridInRangeRule griddy:
|
case GridInRangeRule griddy:
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(uid, out var xform))
|
if (!TryComp(uid, out TransformComponent? xform))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ public sealed class RulesSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
case InSpaceRule:
|
case InSpaceRule:
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(uid, out var xform) ||
|
if (!TryComp(uid, out TransformComponent? xform) ||
|
||||||
xform.GridUid != null)
|
xform.GridUid != null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -146,7 +146,7 @@ public sealed class RulesSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
case NearbyEntitiesRule entity:
|
case NearbyEntitiesRule entity:
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(uid, out var xform) ||
|
if (!TryComp(uid, out TransformComponent? xform) ||
|
||||||
xform.MapUid == null)
|
xform.MapUid == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -177,7 +177,7 @@ public sealed class RulesSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
case NearbyTilesPercentRule tiles:
|
case NearbyTilesPercentRule tiles:
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(uid, out var xform) ||
|
if (!TryComp(uid, out TransformComponent? xform) ||
|
||||||
!TryComp<MapGridComponent>(xform.GridUid, out var grid))
|
!TryComp<MapGridComponent>(xform.GridUid, out var grid))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -227,7 +227,7 @@ public sealed class RulesSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
case OnMapGridRule:
|
case OnMapGridRule:
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(uid, out var xform) ||
|
if (!TryComp(uid, out TransformComponent? xform) ||
|
||||||
xform.GridUid != xform.MapUid ||
|
xform.GridUid != xform.MapUid ||
|
||||||
xform.MapUid == null)
|
xform.MapUid == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public abstract class SharedEmitSoundSystem : EntitySystem
|
|||||||
private void OnEmitSoundOnLand(EntityUid uid, BaseEmitSoundComponent component, ref LandEvent args)
|
private void OnEmitSoundOnLand(EntityUid uid, BaseEmitSoundComponent component, ref LandEvent args)
|
||||||
{
|
{
|
||||||
if (!args.PlaySound ||
|
if (!args.PlaySound ||
|
||||||
!TryComp<TransformComponent>(uid, out var xform) ||
|
!TryComp(uid, out TransformComponent? xform) ||
|
||||||
!TryComp<MapGridComponent>(xform.GridUid, out var grid))
|
!TryComp<MapGridComponent>(xform.GridUid, out var grid))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_xformQuery.TryGetComponent(uid, out var transformOwner) && TryComp<TransformComponent>(target, out var transformEnt))
|
if (TryComp(uid, out TransformComponent? transformOwner) && TryComp(target, out TransformComponent? transformEnt))
|
||||||
{
|
{
|
||||||
var parent = transformOwner.ParentUid;
|
var parent = transformOwner.ParentUid;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Robust.Shared.Collections;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
|
namespace Content.Shared.StoryGen;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides functionality to generate a story from a <see cref="StoryTemplatePrototype"/>.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class StoryGeneratorSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to generate a random story using the given template, picking a random word from the referenced
|
||||||
|
/// datasets for each variable and passing them into the localization system with template.
|
||||||
|
/// If <paramref name="seed"/> is specified, the randomizer will be seeded with it for consistent story generation;
|
||||||
|
/// otherwise the variables will be randomized.
|
||||||
|
/// Fails if the template prototype cannot be loaded.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>true if the template was loaded, otherwise false.</returns>
|
||||||
|
public bool TryGenerateStoryFromTemplate(ProtoId<StoryTemplatePrototype> template, [NotNullWhen(true)] out string? story, int? seed = null)
|
||||||
|
{
|
||||||
|
// Get the story template prototype from the ID
|
||||||
|
if (!_protoMan.TryIndex(template, out var templateProto))
|
||||||
|
{
|
||||||
|
story = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If given a seed, use it
|
||||||
|
if (seed != null)
|
||||||
|
_random.SetSeed(seed.Value);
|
||||||
|
|
||||||
|
// Pick values for all of the variables in the template
|
||||||
|
var variables = new ValueList<(string, object)>(templateProto.Variables.Count);
|
||||||
|
foreach (var (name, list) in templateProto.Variables)
|
||||||
|
{
|
||||||
|
// Get the prototype for the world list dataset
|
||||||
|
if (!_protoMan.TryIndex(list, out var listProto))
|
||||||
|
continue; // Missed one, but keep going with the rest of the story
|
||||||
|
|
||||||
|
// Pick a random word from the dataset and localize it
|
||||||
|
var chosenWord = Loc.GetString(_random.Pick(listProto.Values));
|
||||||
|
variables.Add((name, chosenWord));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass the variables to the localization system and build the story
|
||||||
|
story = Loc.GetString(templateProto.LocId, variables.ToArray());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
33
Content.Shared/StoryGen/Prototypes/StoryTemplatePrototype.cs
Normal file
33
Content.Shared/StoryGen/Prototypes/StoryTemplatePrototype.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using Content.Shared.Dataset;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared.StoryGen;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Prototype for a story template that can be filled in with words chosen from <see cref="DatasetPrototype"/>s.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, Prototype("storyTemplate")]
|
||||||
|
public sealed partial class StoryTemplatePrototype : IPrototype
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Identifier for this prototype instance.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
[IdDataField]
|
||||||
|
public string ID { get; private set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Localization ID of the Fluent string that forms the structure of this story.
|
||||||
|
/// </summary>
|
||||||
|
[DataField(required: true)]
|
||||||
|
public LocId LocId { get; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dictionary containing the name of each variable to pass to the template and the ID of the
|
||||||
|
/// <see cref="DatasetPrototype"/> from which a random entry will be selected as its value.
|
||||||
|
/// For example, <c>name: book_character</c> will pick a random entry from the book_character
|
||||||
|
/// dataset which can then be used in the template by <c>{$name}</c>.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public Dictionary<string, ProtoId<DatasetPrototype>> Variables { get; } = default!;
|
||||||
|
}
|
||||||
@@ -215,7 +215,7 @@ public sealed partial class ActivatableUISystem : EntitySystem
|
|||||||
if (aui.SingleUser && aui.CurrentSingleUser != null && user != aui.CurrentSingleUser)
|
if (aui.SingleUser && aui.CurrentSingleUser != null && user != aui.CurrentSingleUser)
|
||||||
{
|
{
|
||||||
var message = Loc.GetString("machine-already-in-use", ("machine", uiEntity));
|
var message = Loc.GetString("machine-already-in-use", ("machine", uiEntity));
|
||||||
_popupSystem.PopupEntity(message, uiEntity, user);
|
_popupSystem.PopupClient(message, uiEntity, user);
|
||||||
|
|
||||||
if (_uiSystem.IsUiOpen(uiEntity, aui.Key))
|
if (_uiSystem.IsUiOpen(uiEntity, aui.Key))
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -348,7 +348,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
|||||||
|
|
||||||
public bool AttemptLightAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityUid target)
|
public bool AttemptLightAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityUid target)
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(target, out var targetXform))
|
if (!TryComp(target, out TransformComponent? targetXform))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return AttemptAttack(user, weaponUid, weapon, new LightAttackEvent(GetNetEntity(target), GetNetEntity(weaponUid), GetNetCoordinates(targetXform.Coordinates)), null);
|
return AttemptAttack(user, weaponUid, weapon, new LightAttackEvent(GetNetEntity(target), GetNetEntity(weaponUid), GetNetCoordinates(targetXform.Coordinates)), null);
|
||||||
@@ -356,7 +356,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
|||||||
|
|
||||||
public bool AttemptDisarmAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityUid target)
|
public bool AttemptDisarmAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityUid target)
|
||||||
{
|
{
|
||||||
if (!TryComp<TransformComponent>(target, out var targetXform))
|
if (!TryComp(target, out TransformComponent? targetXform))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return AttemptAttack(user, weaponUid, weapon, new DisarmAttackEvent(GetNetEntity(target), GetNetCoordinates(targetXform.Coordinates)), null);
|
return AttemptAttack(user, weaponUid, weapon, new DisarmAttackEvent(GetNetEntity(target), GetNetCoordinates(targetXform.Coordinates)), null);
|
||||||
@@ -552,7 +552,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
|||||||
// For consistency with wide attacks stuff needs damageable.
|
// For consistency with wide attacks stuff needs damageable.
|
||||||
if (Deleted(target) ||
|
if (Deleted(target) ||
|
||||||
!HasComp<DamageableComponent>(target) ||
|
!HasComp<DamageableComponent>(target) ||
|
||||||
!TryComp<TransformComponent>(target, out var targetXform) ||
|
!TryComp(target, out TransformComponent? targetXform) ||
|
||||||
// Not in LOS.
|
// Not in LOS.
|
||||||
!InRange(user, target.Value, component.Range, session))
|
!InRange(user, target.Value, component.Range, session))
|
||||||
{
|
{
|
||||||
@@ -641,7 +641,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
|||||||
private bool DoHeavyAttack(EntityUid user, HeavyAttackEvent ev, EntityUid meleeUid, MeleeWeaponComponent component, ICommonSession? session)
|
private bool DoHeavyAttack(EntityUid user, HeavyAttackEvent ev, EntityUid meleeUid, MeleeWeaponComponent component, ICommonSession? session)
|
||||||
{
|
{
|
||||||
// TODO: This is copy-paste as fuck with DoPreciseAttack
|
// TODO: This is copy-paste as fuck with DoPreciseAttack
|
||||||
if (!TryComp<TransformComponent>(user, out var userXform))
|
if (!TryComp(user, out TransformComponent? userXform))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var targetMap = GetCoordinates(ev.Coordinates).ToMap(EntityManager, TransformSystem);
|
var targetMap = GetCoordinates(ev.Coordinates).ToMap(EntityManager, TransformSystem);
|
||||||
@@ -860,7 +860,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
|||||||
private void DoLungeAnimation(EntityUid user, EntityUid weapon, Angle angle, MapCoordinates coordinates, float length, string? animation)
|
private void DoLungeAnimation(EntityUid user, EntityUid weapon, Angle angle, MapCoordinates coordinates, float length, string? animation)
|
||||||
{
|
{
|
||||||
// TODO: Assert that offset eyes are still okay.
|
// TODO: Assert that offset eyes are still okay.
|
||||||
if (!TryComp<TransformComponent>(user, out var userXform))
|
if (!TryComp(user, out TransformComponent? userXform))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var invMatrix = TransformSystem.GetInvWorldMatrix(userXform);
|
var invMatrix = TransformSystem.GetInvWorldMatrix(userXform);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace Content.YAMLLinter
|
|||||||
{
|
{
|
||||||
private static async Task<int> Main(string[] _)
|
private static async Task<int> Main(string[] _)
|
||||||
{
|
{
|
||||||
PoolManager.Startup(null);
|
PoolManager.Startup();
|
||||||
var stopwatch = new Stopwatch();
|
var stopwatch = new Stopwatch();
|
||||||
stopwatch.Start();
|
stopwatch.Start();
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ story-gen-book-character29 = space dragon
|
|||||||
story-gen-book-character30 = revolutionary
|
story-gen-book-character30 = revolutionary
|
||||||
story-gen-book-character31 = nuclear operative
|
story-gen-book-character31 = nuclear operative
|
||||||
story-gen-book-character32 = narsie cultist
|
story-gen-book-character32 = narsie cultist
|
||||||
story-gen-book-character33 = ratwar cultist
|
story-gen-book-character33 = ratvar cultist
|
||||||
story-gen-book-character34 = greytider
|
story-gen-book-character34 = greytider
|
||||||
story-gen-book-character35 = arachnid
|
story-gen-book-character35 = arachnid
|
||||||
story-gen-book-character36 = vox
|
story-gen-book-character36 = vox
|
||||||
@@ -98,7 +98,7 @@ story-gen-book-character40 = slime
|
|||||||
story-gen-book-character-trait1 = stupid
|
story-gen-book-character-trait1 = stupid
|
||||||
story-gen-book-character-trait2 = smart
|
story-gen-book-character-trait2 = smart
|
||||||
story-gen-book-character-trait3 = funny
|
story-gen-book-character-trait3 = funny
|
||||||
story-gen-book-character-trait4 = attractive
|
story-gen-book-character-trait4 = attractive
|
||||||
story-gen-book-character-trait5 = charming
|
story-gen-book-character-trait5 = charming
|
||||||
story-gen-book-character-trait6 = nasty
|
story-gen-book-character-trait6 = nasty
|
||||||
story-gen-book-character-trait7 = dying
|
story-gen-book-character-trait7 = dying
|
||||||
@@ -113,7 +113,7 @@ story-gen-book-character-trait15 = сharismatic
|
|||||||
story-gen-book-character-trait16 = stoic
|
story-gen-book-character-trait16 = stoic
|
||||||
story-gen-book-character-trait17 = cute
|
story-gen-book-character-trait17 = cute
|
||||||
story-gen-book-character-trait18 = dwarven
|
story-gen-book-character-trait18 = dwarven
|
||||||
story-gen-book-character-trait19 = beer-smelling
|
story-gen-book-character-trait19 = beer-smelling
|
||||||
story-gen-book-character-trait20 = joyful
|
story-gen-book-character-trait20 = joyful
|
||||||
story-gen-book-character-trait21 = painfully beautiful
|
story-gen-book-character-trait21 = painfully beautiful
|
||||||
story-gen-book-character-trait22 = robotic
|
story-gen-book-character-trait22 = robotic
|
||||||
@@ -121,20 +121,20 @@ story-gen-book-character-trait23 = holographic
|
|||||||
story-gen-book-character-trait24 = hysterically laughing
|
story-gen-book-character-trait24 = hysterically laughing
|
||||||
|
|
||||||
story-gen-book-event1 = a zombie outbreak
|
story-gen-book-event1 = a zombie outbreak
|
||||||
story-gen-book-event2 = a nuclear explosion
|
story-gen-book-event2 = a nuclear explosion
|
||||||
story-gen-book-event3 = a mass murder
|
story-gen-book-event3 = a mass murder
|
||||||
story-gen-book-event4 = a sudden depressurization
|
story-gen-book-event4 = a sudden depressurization
|
||||||
story-gen-book-event5 = a blackout
|
story-gen-book-event5 = a blackout
|
||||||
story-gen-book-event6 = the starvation of the protagonists
|
story-gen-book-event6 = the protagonists nearly starving
|
||||||
story-gen-book-event7 = a wasting illness
|
story-gen-book-event7 = a wasting illness
|
||||||
story-gen-book-event8 = love at first sight
|
story-gen-book-event8 = love at first sight
|
||||||
story-gen-book-event9 = a rush of inspiration
|
story-gen-book-event9 = a rush of inspiration
|
||||||
story-gen-book-event10 = the occurrence of some mystical phenomena
|
story-gen-book-event10 = some mystical phenomena
|
||||||
story-gen-book-event11 = divine intervention
|
story-gen-book-event11 = divine intervention
|
||||||
story-gen-book-event12 = the characters' own selfish motives
|
story-gen-book-event12 = the characters' own selfish motives
|
||||||
story-gen-book-event13 = an unforeseen deception
|
story-gen-book-event13 = an unforeseen deception
|
||||||
story-gen-book-event14 = the resurrection of one of these characters from the dead
|
story-gen-book-event14 = the resurrection of one of the characters from the dead
|
||||||
story-gen-book-event15 = the terrible torture of the protagonist
|
story-gen-book-event15 = the brutal torture of the protagonists
|
||||||
story-gen-book-event16 = the inadvertent loosing of a gravitational singularity
|
story-gen-book-event16 = the inadvertent loosing of a gravitational singularity
|
||||||
story-gen-book-event17 = a psychic prediction of future events
|
story-gen-book-event17 = a psychic prediction of future events
|
||||||
story-gen-book-event18 = an antimatter explosion
|
story-gen-book-event18 = an antimatter explosion
|
||||||
@@ -145,31 +145,31 @@ story-gen-book-event22 = having a quarrel with a close friend
|
|||||||
story-gen-book-event23 = the sudden loss of their home in a fiery blaze
|
story-gen-book-event23 = the sudden loss of their home in a fiery blaze
|
||||||
story-gen-book-event24 = the loss of a PDA
|
story-gen-book-event24 = the loss of a PDA
|
||||||
|
|
||||||
story-gen-book-action1 = share in a kiss with a
|
story-gen-book-action1 = share in a kiss with
|
||||||
story-gen-book-action2 = strangle to death a
|
story-gen-book-action2 = strangle
|
||||||
story-gen-book-action3 = manage to blow apart a
|
story-gen-book-action3 = blow apart
|
||||||
story-gen-book-action4 = manage to win a game of chess against a
|
story-gen-book-action4 = win a game of chess against
|
||||||
story-gen-book-action5 = narrowly lose a game of chess against a
|
story-gen-book-action5 = lose a game of chess against
|
||||||
story-gen-book-action6 = reveal the hidden secrets of a
|
story-gen-book-action6 = reveal the hidden secrets of
|
||||||
story-gen-book-action7 = manipulate a
|
story-gen-book-action7 = manipulate
|
||||||
story-gen-book-action8 = sacrifice upon an altar a
|
story-gen-book-action8 = sacrifice a hamster to
|
||||||
story-gen-book-action9 = attend the wedding of a
|
story-gen-book-action9 = infiltrate the wedding of
|
||||||
story-gen-book-action10 = join forces to defeat their common enemy, a
|
story-gen-book-action10 = join forces to defeat their common enemy,
|
||||||
story-gen-book-action11 = are forced to work together to escape a
|
story-gen-book-action11 = are forced to work together to escape
|
||||||
story-gen-book-action12 = give a valuable gift to
|
story-gen-book-action12 = give a valuable gift to
|
||||||
|
|
||||||
story-gen-book-action-trait1 = terribly
|
story-gen-book-action-trait1 = clumsily
|
||||||
story-gen-book-action-trait2 = disgustingly
|
story-gen-book-action-trait2 = disgustingly
|
||||||
story-gen-book-action-trait3 = marvelously
|
story-gen-book-action-trait3 = marvelously
|
||||||
story-gen-book-action-trait4 = nicely
|
story-gen-book-action-trait4 = nicely
|
||||||
story-gen-book-action-trait5 = weirdly
|
story-gen-book-action-trait5 = weirdly
|
||||||
story-gen-book-action-trait6 = amusingly
|
story-gen-book-action-trait6 = amusingly
|
||||||
story-gen-book-action-trait7 = fancifully
|
story-gen-book-action-trait7 = fancifully
|
||||||
story-gen-book-action-trait8 = impressively
|
story-gen-book-action-trait8 = impressively
|
||||||
story-gen-book-action-trait9 = irresponsibly
|
story-gen-book-action-trait9 = irresponsibly
|
||||||
story-gen-book-action-trait10 = severely
|
story-gen-book-action-trait10 = severely
|
||||||
story-gen-book-action-trait11 = ruthlessly
|
story-gen-book-action-trait11 = ruthlessly
|
||||||
story-gen-book-action-trait12 = playfully
|
story-gen-book-action-trait12 = playfully
|
||||||
story-gen-book-action-trait13 = thoughtfully
|
story-gen-book-action-trait13 = thoughtfully
|
||||||
|
|
||||||
story-gen-book-location1 = in an underground complex
|
story-gen-book-location1 = in an underground complex
|
||||||
@@ -178,7 +178,7 @@ story-gen-book-location3 = while trapped in outer space
|
|||||||
story-gen-book-location4 = while in a news office
|
story-gen-book-location4 = while in a news office
|
||||||
story-gen-book-location5 = in a hidden garden
|
story-gen-book-location5 = in a hidden garden
|
||||||
story-gen-book-location6 = in the kitchen of a local restaurant
|
story-gen-book-location6 = in the kitchen of a local restaurant
|
||||||
story-gen-book-location7 = under the counter of the local sports bar
|
story-gen-book-location7 = under the counter of the local sports bar
|
||||||
story-gen-book-location8 = in an ancient library
|
story-gen-book-location8 = in an ancient library
|
||||||
story-gen-book-location9 = while deep in bowels of the space station's maintenance corridors
|
story-gen-book-location9 = while deep in bowels of the space station's maintenance corridors
|
||||||
story-gen-book-location10 = on the bridge of a starship
|
story-gen-book-location10 = on the bridge of a starship
|
||||||
@@ -192,7 +192,7 @@ story-gen-book-location17 = standing too close to an anomaly
|
|||||||
story-gen-book-location18 = while huddling on the evacuation shuttle
|
story-gen-book-location18 = while huddling on the evacuation shuttle
|
||||||
story-gen-book-location19 = standing in freshly fallen snow
|
story-gen-book-location19 = standing in freshly fallen snow
|
||||||
story-gen-book-location20 = lost in the woods
|
story-gen-book-location20 = lost in the woods
|
||||||
story-gen-book-location21 = iin the harsh desert
|
story-gen-book-location21 = in the harsh desert
|
||||||
story-gen-book-location22 = worrying about their social media networks
|
story-gen-book-location22 = worrying about their social media networks
|
||||||
story-gen-book-location23 = atop of a mountain
|
story-gen-book-location23 = atop of a mountain
|
||||||
story-gen-book-location24 = while driving a car
|
story-gen-book-location24 = while driving a car
|
||||||
@@ -207,15 +207,15 @@ story-gen-book-location32 = while trapped in a shadow dimension
|
|||||||
story-gen-book-location33 = while trying to escape a destroyed space station
|
story-gen-book-location33 = while trying to escape a destroyed space station
|
||||||
story-gen-book-location34 = while sandwiched between a Tesla ball and a gravitational singularity
|
story-gen-book-location34 = while sandwiched between a Tesla ball and a gravitational singularity
|
||||||
|
|
||||||
story-gen-book-element1 = The plot
|
story-gen-book-element1 = plot
|
||||||
story-gen-book-element2 = The twist
|
story-gen-book-element2 = twist
|
||||||
story-gen-book-element3 = The climax
|
story-gen-book-element3 = climax
|
||||||
story-gen-book-element4 = The final act
|
story-gen-book-element4 = final act
|
||||||
story-gen-book-element5 = The ending
|
story-gen-book-element5 = ending
|
||||||
story-gen-book-element6 = The moral of the story
|
story-gen-book-element6 = moral of the story
|
||||||
story-gen-book-element7 = The theme of this work
|
story-gen-book-element7 = theme of this work
|
||||||
story-gen-book-element8 = The literary style
|
story-gen-book-element8 = literary style
|
||||||
story-gen-book-element9 = The illustrations
|
story-gen-book-element9 = artwork
|
||||||
|
|
||||||
story-gen-book-element-trait1 = terrifying
|
story-gen-book-element-trait1 = terrifying
|
||||||
story-gen-book-element-trait2 = disgusting
|
story-gen-book-element-trait2 = disgusting
|
||||||
|
|||||||
4
Resources/Locale/en-US/storygen/story-template.ftl
Normal file
4
Resources/Locale/en-US/storygen/story-template.ftl
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
story-template-generic =
|
||||||
|
This is { INDEFINITE($bookGenre) } {$bookGenre} about { INDEFINITE($char1Adj) } {$char1Adj} {$char1Type} and { INDEFINITE($char2Adj) } {$char2Adj} {$char2Type}. Due to {$event}, they {$actionTrait} {$action} { INDEFINITE($char3Type) } {$char3Type} {$location}.
|
||||||
|
|
||||||
|
The {$element} is {$elementTrait}.
|
||||||
@@ -431,6 +431,7 @@
|
|||||||
|
|
||||||
- type: accent
|
- type: accent
|
||||||
id: liar
|
id: liar
|
||||||
|
replacementChance: 0.15
|
||||||
wordReplacements:
|
wordReplacements:
|
||||||
liar-word-1: liar-word-replacement-1
|
liar-word-1: liar-word-replacement-1
|
||||||
liar-word-2: liar-word-replacement-2
|
liar-word-2: liar-word-replacement-2
|
||||||
@@ -474,4 +475,4 @@
|
|||||||
liar-word-39: liar-word-replacement-39
|
liar-word-39: liar-word-replacement-39
|
||||||
liar-word-40: liar-word-replacement-40
|
liar-word-40: liar-word-replacement-40
|
||||||
liar-word-41: liar-word-replacement-41
|
liar-word-41: liar-word-replacement-41
|
||||||
liar-word-42: liar-word-replacement-42
|
liar-word-42: liar-word-replacement-42
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
- type: dataset
|
- type: dataset
|
||||||
id: book_type
|
id: BookTypes
|
||||||
values:
|
values:
|
||||||
- story-gen-book-type1
|
- story-gen-book-type1
|
||||||
- story-gen-book-type2
|
- story-gen-book-type2
|
||||||
- story-gen-book-type3
|
- story-gen-book-type3
|
||||||
- story-gen-book-type4
|
- story-gen-book-type4
|
||||||
- story-gen-book-type5
|
- story-gen-book-type5
|
||||||
- story-gen-book-type6
|
- story-gen-book-type6
|
||||||
- story-gen-book-type7
|
- story-gen-book-type7
|
||||||
- story-gen-book-type8
|
- story-gen-book-type8
|
||||||
- story-gen-book-type9
|
- story-gen-book-type9
|
||||||
- story-gen-book-type10
|
- story-gen-book-type10
|
||||||
- story-gen-book-type11
|
- story-gen-book-type11
|
||||||
- story-gen-book-type12
|
- story-gen-book-type12
|
||||||
|
|
||||||
- type: dataset
|
- type: dataset
|
||||||
id: book_genre
|
id: BookGenres
|
||||||
values:
|
values:
|
||||||
- story-gen-book-genre1
|
- story-gen-book-genre1
|
||||||
- story-gen-book-genre2
|
- story-gen-book-genre2
|
||||||
- story-gen-book-genre3
|
- story-gen-book-genre3
|
||||||
- story-gen-book-genre4
|
- story-gen-book-genre4
|
||||||
- story-gen-book-genre5
|
- story-gen-book-genre5
|
||||||
- story-gen-book-genre6
|
- story-gen-book-genre6
|
||||||
- story-gen-book-genre7
|
- story-gen-book-genre7
|
||||||
- story-gen-book-genre8
|
- story-gen-book-genre8
|
||||||
- story-gen-book-genre9
|
- story-gen-book-genre9
|
||||||
- story-gen-book-genre10
|
- story-gen-book-genre10
|
||||||
- story-gen-book-genre11
|
- story-gen-book-genre11
|
||||||
- story-gen-book-genre12
|
- story-gen-book-genre12
|
||||||
@@ -33,17 +33,17 @@
|
|||||||
- story-gen-book-genre14
|
- story-gen-book-genre14
|
||||||
|
|
||||||
- type: dataset
|
- type: dataset
|
||||||
id: book_hint_appearance
|
id: BookHintAppearances
|
||||||
values:
|
values:
|
||||||
- story-gen-book-appearance1
|
- story-gen-book-appearance1
|
||||||
- story-gen-book-appearance2
|
- story-gen-book-appearance2
|
||||||
- story-gen-book-appearance3
|
- story-gen-book-appearance3
|
||||||
- story-gen-book-appearance4
|
- story-gen-book-appearance4
|
||||||
- story-gen-book-appearance5
|
- story-gen-book-appearance5
|
||||||
- story-gen-book-appearance6
|
- story-gen-book-appearance6
|
||||||
- story-gen-book-appearance7
|
- story-gen-book-appearance7
|
||||||
- story-gen-book-appearance8
|
- story-gen-book-appearance8
|
||||||
- story-gen-book-appearance9
|
- story-gen-book-appearance9
|
||||||
- story-gen-book-appearance10
|
- story-gen-book-appearance10
|
||||||
- story-gen-book-appearance11
|
- story-gen-book-appearance11
|
||||||
- story-gen-book-appearance12
|
- story-gen-book-appearance12
|
||||||
@@ -64,17 +64,17 @@
|
|||||||
- story-gen-book-appearance27
|
- story-gen-book-appearance27
|
||||||
|
|
||||||
- type: dataset
|
- type: dataset
|
||||||
id: book_character
|
id: BookCharacters
|
||||||
values:
|
values:
|
||||||
- story-gen-book-character1
|
- story-gen-book-character1
|
||||||
- story-gen-book-character2
|
- story-gen-book-character2
|
||||||
- story-gen-book-character3
|
- story-gen-book-character3
|
||||||
- story-gen-book-character4
|
- story-gen-book-character4
|
||||||
- story-gen-book-character5
|
- story-gen-book-character5
|
||||||
- story-gen-book-character6
|
- story-gen-book-character6
|
||||||
- story-gen-book-character7
|
- story-gen-book-character7
|
||||||
- story-gen-book-character8
|
- story-gen-book-character8
|
||||||
- story-gen-book-character9
|
- story-gen-book-character9
|
||||||
- story-gen-book-character10
|
- story-gen-book-character10
|
||||||
- story-gen-book-character11
|
- story-gen-book-character11
|
||||||
- story-gen-book-character12
|
- story-gen-book-character12
|
||||||
@@ -108,17 +108,17 @@
|
|||||||
- story-gen-book-character40
|
- story-gen-book-character40
|
||||||
|
|
||||||
- type: dataset
|
- type: dataset
|
||||||
id: book_character_trait
|
id: BookCharacterTraits
|
||||||
values:
|
values:
|
||||||
- story-gen-book-character-trait1
|
- story-gen-book-character-trait1
|
||||||
- story-gen-book-character-trait2
|
- story-gen-book-character-trait2
|
||||||
- story-gen-book-character-trait3
|
- story-gen-book-character-trait3
|
||||||
- story-gen-book-character-trait4
|
- story-gen-book-character-trait4
|
||||||
- story-gen-book-character-trait5
|
- story-gen-book-character-trait5
|
||||||
- story-gen-book-character-trait6
|
- story-gen-book-character-trait6
|
||||||
- story-gen-book-character-trait7
|
- story-gen-book-character-trait7
|
||||||
- story-gen-book-character-trait8
|
- story-gen-book-character-trait8
|
||||||
- story-gen-book-character-trait9
|
- story-gen-book-character-trait9
|
||||||
- story-gen-book-character-trait10
|
- story-gen-book-character-trait10
|
||||||
- story-gen-book-character-trait11
|
- story-gen-book-character-trait11
|
||||||
- story-gen-book-character-trait12
|
- story-gen-book-character-trait12
|
||||||
@@ -137,17 +137,17 @@
|
|||||||
|
|
||||||
|
|
||||||
- type: dataset
|
- type: dataset
|
||||||
id: book_event
|
id: BookEvents
|
||||||
values:
|
values:
|
||||||
- story-gen-book-event1
|
- story-gen-book-event1
|
||||||
- story-gen-book-event2
|
- story-gen-book-event2
|
||||||
- story-gen-book-event3
|
- story-gen-book-event3
|
||||||
- story-gen-book-event4
|
- story-gen-book-event4
|
||||||
- story-gen-book-event5
|
- story-gen-book-event5
|
||||||
- story-gen-book-event6
|
- story-gen-book-event6
|
||||||
- story-gen-book-event7
|
- story-gen-book-event7
|
||||||
- story-gen-book-event8
|
- story-gen-book-event8
|
||||||
- story-gen-book-event9
|
- story-gen-book-event9
|
||||||
- story-gen-book-event10
|
- story-gen-book-event10
|
||||||
- story-gen-book-event11
|
- story-gen-book-event11
|
||||||
- story-gen-book-event12
|
- story-gen-book-event12
|
||||||
@@ -165,50 +165,50 @@
|
|||||||
- story-gen-book-event24
|
- story-gen-book-event24
|
||||||
|
|
||||||
- type: dataset
|
- type: dataset
|
||||||
id: book_action
|
id: BookActions
|
||||||
values:
|
values:
|
||||||
- story-gen-book-action1
|
- story-gen-book-action1
|
||||||
- story-gen-book-action2
|
- story-gen-book-action2
|
||||||
- story-gen-book-action3
|
- story-gen-book-action3
|
||||||
- story-gen-book-action4
|
- story-gen-book-action4
|
||||||
- story-gen-book-action5
|
- story-gen-book-action5
|
||||||
- story-gen-book-action6
|
- story-gen-book-action6
|
||||||
- story-gen-book-action7
|
- story-gen-book-action7
|
||||||
- story-gen-book-action8
|
- story-gen-book-action8
|
||||||
- story-gen-book-action9
|
- story-gen-book-action9
|
||||||
- story-gen-book-action10
|
- story-gen-book-action10
|
||||||
- story-gen-book-action11
|
- story-gen-book-action11
|
||||||
- story-gen-book-action12
|
- story-gen-book-action12
|
||||||
|
|
||||||
- type: dataset
|
- type: dataset
|
||||||
id: book_action_trait
|
id: BookActionTraits
|
||||||
values:
|
values:
|
||||||
- story-gen-book-action-trait1
|
- story-gen-book-action-trait1
|
||||||
- story-gen-book-action-trait2
|
- story-gen-book-action-trait2
|
||||||
- story-gen-book-action-trait3
|
- story-gen-book-action-trait3
|
||||||
- story-gen-book-action-trait4
|
- story-gen-book-action-trait4
|
||||||
- story-gen-book-action-trait5
|
- story-gen-book-action-trait5
|
||||||
- story-gen-book-action-trait6
|
- story-gen-book-action-trait6
|
||||||
- story-gen-book-action-trait7
|
- story-gen-book-action-trait7
|
||||||
- story-gen-book-action-trait8
|
- story-gen-book-action-trait8
|
||||||
- story-gen-book-action-trait9
|
- story-gen-book-action-trait9
|
||||||
- story-gen-book-action-trait10
|
- story-gen-book-action-trait10
|
||||||
- story-gen-book-action-trait11
|
- story-gen-book-action-trait11
|
||||||
- story-gen-book-action-trait12
|
- story-gen-book-action-trait12
|
||||||
- story-gen-book-action-trait13
|
- story-gen-book-action-trait13
|
||||||
|
|
||||||
- type: dataset
|
- type: dataset
|
||||||
id: book_location
|
id: BookLocations
|
||||||
values:
|
values:
|
||||||
- story-gen-book-location1
|
- story-gen-book-location1
|
||||||
- story-gen-book-location2
|
- story-gen-book-location2
|
||||||
- story-gen-book-location3
|
- story-gen-book-location3
|
||||||
- story-gen-book-location4
|
- story-gen-book-location4
|
||||||
- story-gen-book-location5
|
- story-gen-book-location5
|
||||||
- story-gen-book-location6
|
- story-gen-book-location6
|
||||||
- story-gen-book-location7
|
- story-gen-book-location7
|
||||||
- story-gen-book-location8
|
- story-gen-book-location8
|
||||||
- story-gen-book-location9
|
- story-gen-book-location9
|
||||||
- story-gen-book-location10
|
- story-gen-book-location10
|
||||||
- story-gen-book-location11
|
- story-gen-book-location11
|
||||||
- story-gen-book-location12
|
- story-gen-book-location12
|
||||||
@@ -236,7 +236,7 @@
|
|||||||
- story-gen-book-location34
|
- story-gen-book-location34
|
||||||
|
|
||||||
- type: dataset
|
- type: dataset
|
||||||
id: book_story_element
|
id: BookStoryElements
|
||||||
values:
|
values:
|
||||||
- story-gen-book-element1
|
- story-gen-book-element1
|
||||||
- story-gen-book-element2
|
- story-gen-book-element2
|
||||||
@@ -249,18 +249,18 @@
|
|||||||
- story-gen-book-element9
|
- story-gen-book-element9
|
||||||
|
|
||||||
- type: dataset
|
- type: dataset
|
||||||
id: book_story_element_trait
|
id: BookStoryElementTraits
|
||||||
values:
|
values:
|
||||||
- story-gen-book-element-trait1
|
- story-gen-book-element-trait1
|
||||||
- story-gen-book-element-trait2
|
- story-gen-book-element-trait2
|
||||||
- story-gen-book-element-trait3
|
- story-gen-book-element-trait3
|
||||||
- story-gen-book-element-trait4
|
- story-gen-book-element-trait4
|
||||||
- story-gen-book-element-trait5
|
- story-gen-book-element-trait5
|
||||||
- story-gen-book-element-trait6
|
- story-gen-book-element-trait6
|
||||||
- story-gen-book-element-trait7
|
- story-gen-book-element-trait7
|
||||||
- story-gen-book-element-trait8
|
- story-gen-book-element-trait8
|
||||||
- story-gen-book-element-trait9
|
- story-gen-book-element-trait9
|
||||||
- story-gen-book-element-trait10
|
- story-gen-book-element-trait10
|
||||||
- story-gen-book-element-trait11
|
- story-gen-book-element-trait11
|
||||||
- story-gen-book-element-trait12
|
- story-gen-book-element-trait12
|
||||||
- story-gen-book-element-trait13
|
- story-gen-book-element-trait13
|
||||||
|
|||||||
@@ -361,8 +361,8 @@
|
|||||||
components:
|
components:
|
||||||
- type: RandomMetadata
|
- type: RandomMetadata
|
||||||
nameSegments:
|
nameSegments:
|
||||||
- book_hint_appearance
|
- BookHintAppearances
|
||||||
- book_type
|
- BookTypes
|
||||||
- type: RandomSprite
|
- type: RandomSprite
|
||||||
available:
|
available:
|
||||||
- cover:
|
- cover:
|
||||||
@@ -423,33 +423,7 @@
|
|||||||
suffix: random visual, random story
|
suffix: random visual, random story
|
||||||
components:
|
components:
|
||||||
- type: PaperRandomStory
|
- type: PaperRandomStory
|
||||||
storySegments:
|
template: GenericStory
|
||||||
- "This is a "
|
|
||||||
- book_genre
|
|
||||||
- " about a "
|
|
||||||
- book_character_trait
|
|
||||||
- " "
|
|
||||||
- book_character
|
|
||||||
- " and "
|
|
||||||
- book_character_trait
|
|
||||||
- " "
|
|
||||||
- book_character
|
|
||||||
- ". Due to "
|
|
||||||
- book_event
|
|
||||||
- ", they "
|
|
||||||
- book_action_trait
|
|
||||||
- " "
|
|
||||||
- book_action
|
|
||||||
- " "
|
|
||||||
- book_character
|
|
||||||
- " "
|
|
||||||
- book_location
|
|
||||||
- ". \n\n"
|
|
||||||
- book_story_element
|
|
||||||
- " is "
|
|
||||||
- book_story_element_trait
|
|
||||||
- "."
|
|
||||||
storySeparator: ""
|
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: BookBase
|
parent: BookBase
|
||||||
|
|||||||
@@ -452,10 +452,10 @@
|
|||||||
noSpawn: true
|
noSpawn: true
|
||||||
components:
|
components:
|
||||||
- type: StationEvent
|
- type: StationEvent
|
||||||
earliestStart: 25
|
earliestStart: 30
|
||||||
weight: 8
|
weight: 8
|
||||||
minimumPlayers: 15
|
minimumPlayers: 15
|
||||||
reoccurrenceDelay: 30
|
maxOccurrences: 1 # can only happen once per round
|
||||||
startAnnouncement: station-event-communication-interception
|
startAnnouncement: station-event-communication-interception
|
||||||
startAudio:
|
startAudio:
|
||||||
path: /Audio/Announcements/intercept.ogg
|
path: /Audio/Announcements/intercept.ogg
|
||||||
|
|||||||
16
Resources/Prototypes/StoryGen/story-templates.yml
Normal file
16
Resources/Prototypes/StoryGen/story-templates.yml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
- type: storyTemplate
|
||||||
|
id: GenericStory
|
||||||
|
locId: story-template-generic
|
||||||
|
variables:
|
||||||
|
bookGenre: BookGenres
|
||||||
|
char1Type: BookCharacters
|
||||||
|
char1Adj: BookCharacterTraits
|
||||||
|
char2Type: BookCharacters
|
||||||
|
char2Adj: BookCharacterTraits
|
||||||
|
event: BookEvents
|
||||||
|
action: BookActions
|
||||||
|
actionTrait: BookActionTraits
|
||||||
|
char3Type: BookCharacters
|
||||||
|
location: BookLocations
|
||||||
|
element: BookStoryElements
|
||||||
|
elementTrait: BookStoryElementTraits
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
- type: trait
|
- type: trait
|
||||||
id: PirateAccent
|
id: PirateAccent
|
||||||
name: trait-pirate-accent-name
|
name: trait-pirate-accent-name
|
||||||
description: trait-pirate-accent-desc
|
description: trait-pirate-accent-desc
|
||||||
|
|||||||
Reference in New Issue
Block a user