почти важно (#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:
@@ -46,4 +46,7 @@ public sealed partial class IdCardComponent : Component
|
||||
|
||||
[DataField]
|
||||
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,
|
||||
bool popup = false)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(other, out var otherXform))
|
||||
if (!TryComp(other, out TransformComponent? otherXform))
|
||||
return false;
|
||||
|
||||
return InRangeUnobstructed(origin, other, otherXform.Coordinates, otherXform.LocalRotation, range, collisionMask, predicate,
|
||||
@@ -640,7 +640,7 @@ namespace Content.Shared.Interaction
|
||||
fixtureA.FixtureCount > 0 &&
|
||||
TryComp<FixturesComponent>(other, out var fixtureB) &&
|
||||
fixtureB.FixtureCount > 0 &&
|
||||
TryComp<TransformComponent>(origin, out var xformA))
|
||||
TryComp(origin, out TransformComponent? xformA))
|
||||
{
|
||||
var (worldPosA, worldRotA) = xformA.GetWorldPositionRotation();
|
||||
var xfA = new Transform(worldPosA, worldRotA);
|
||||
|
||||
@@ -113,7 +113,7 @@ public abstract class SharedJetpackSystem : EntitySystem
|
||||
if (args.Handled)
|
||||
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);
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@ namespace Content.Shared.Movement.Systems
|
||||
// For stuff like "Moving out of locker" or the likes
|
||||
// We'll relay a movement input to the parent.
|
||||
if (_container.IsEntityInContainer(entity) &&
|
||||
TryComp<TransformComponent>(entity, out var xform) &&
|
||||
TryComp(entity, out TransformComponent? xform) &&
|
||||
xform.ParentUid.IsValid() &&
|
||||
_mobState.IsAlive(entity))
|
||||
{
|
||||
|
||||
@@ -179,7 +179,7 @@ public sealed partial class PressurizedSolutionSystem : EntitySystem
|
||||
var solution = _solutionContainer.SplitSolution(soln.Value, interactions.Volume);
|
||||
|
||||
// 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);
|
||||
|
||||
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";
|
||||
|
||||
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)
|
||||
remainingString = "drink-component-on-examine-is-half-empty";
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ public sealed class RulesSystem : EntitySystem
|
||||
break;
|
||||
case GridInRangeRule griddy:
|
||||
{
|
||||
if (!TryComp<TransformComponent>(uid, out var xform))
|
||||
if (!TryComp(uid, out TransformComponent? xform))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -50,7 +50,7 @@ public sealed class RulesSystem : EntitySystem
|
||||
}
|
||||
case InSpaceRule:
|
||||
{
|
||||
if (!TryComp<TransformComponent>(uid, out var xform) ||
|
||||
if (!TryComp(uid, out TransformComponent? xform) ||
|
||||
xform.GridUid != null)
|
||||
{
|
||||
return false;
|
||||
@@ -146,7 +146,7 @@ public sealed class RulesSystem : EntitySystem
|
||||
}
|
||||
case NearbyEntitiesRule entity:
|
||||
{
|
||||
if (!TryComp<TransformComponent>(uid, out var xform) ||
|
||||
if (!TryComp(uid, out TransformComponent? xform) ||
|
||||
xform.MapUid == null)
|
||||
{
|
||||
return false;
|
||||
@@ -177,7 +177,7 @@ public sealed class RulesSystem : EntitySystem
|
||||
}
|
||||
case NearbyTilesPercentRule tiles:
|
||||
{
|
||||
if (!TryComp<TransformComponent>(uid, out var xform) ||
|
||||
if (!TryComp(uid, out TransformComponent? xform) ||
|
||||
!TryComp<MapGridComponent>(xform.GridUid, out var grid))
|
||||
{
|
||||
return false;
|
||||
@@ -227,7 +227,7 @@ public sealed class RulesSystem : EntitySystem
|
||||
}
|
||||
case OnMapGridRule:
|
||||
{
|
||||
if (!TryComp<TransformComponent>(uid, out var xform) ||
|
||||
if (!TryComp(uid, out TransformComponent? xform) ||
|
||||
xform.GridUid != xform.MapUid ||
|
||||
xform.MapUid == null)
|
||||
{
|
||||
|
||||
@@ -73,7 +73,7 @@ public abstract class SharedEmitSoundSystem : EntitySystem
|
||||
private void OnEmitSoundOnLand(EntityUid uid, BaseEmitSoundComponent component, ref LandEvent args)
|
||||
{
|
||||
if (!args.PlaySound ||
|
||||
!TryComp<TransformComponent>(uid, out var xform) ||
|
||||
!TryComp(uid, out TransformComponent? xform) ||
|
||||
!TryComp<MapGridComponent>(xform.GridUid, out var grid))
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -471,7 +471,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
||||
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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
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))
|
||||
return true;
|
||||
|
||||
@@ -348,7 +348,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
|
||||
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 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)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(target, out var targetXform))
|
||||
if (!TryComp(target, out TransformComponent? targetXform))
|
||||
return false;
|
||||
|
||||
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.
|
||||
if (Deleted(target) ||
|
||||
!HasComp<DamageableComponent>(target) ||
|
||||
!TryComp<TransformComponent>(target, out var targetXform) ||
|
||||
!TryComp(target, out TransformComponent? targetXform) ||
|
||||
// Not in LOS.
|
||||
!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)
|
||||
{
|
||||
// TODO: This is copy-paste as fuck with DoPreciseAttack
|
||||
if (!TryComp<TransformComponent>(user, out var userXform))
|
||||
if (!TryComp(user, out TransformComponent? userXform))
|
||||
return false;
|
||||
|
||||
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)
|
||||
{
|
||||
// TODO: Assert that offset eyes are still okay.
|
||||
if (!TryComp<TransformComponent>(user, out var userXform))
|
||||
if (!TryComp(user, out TransformComponent? userXform))
|
||||
return;
|
||||
|
||||
var invMatrix = TransformSystem.GetInvWorldMatrix(userXform);
|
||||
|
||||
Reference in New Issue
Block a user