From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Fri, 10 Oct 2025 22:27:14 +0000 (+0200) Subject: Mindrole trigger condition (#40323) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=21460c86b08d0234aacf176d21b2147b85392755;p=space-station-14.git Mindrole trigger condition (#40323) * mind role trigger condition * fix * nits --------- Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com> --- diff --git a/Content.Shared/Roles/SharedRoleSystem.cs b/Content.Shared/Roles/SharedRoleSystem.cs index eeab329661..e85d4d86d8 100644 --- a/Content.Shared/Roles/SharedRoleSystem.cs +++ b/Content.Shared/Roles/SharedRoleSystem.cs @@ -23,7 +23,6 @@ public abstract class SharedRoleSystem : EntitySystem [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] protected readonly ISharedPlayerManager Player = default!; - [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; [Dependency] private readonly SharedMindSystem _minds = default!; [Dependency] private readonly IPrototypeManager _prototypes = default!; @@ -400,7 +399,7 @@ public abstract class SharedRoleSystem : EntitySystem foreach (var role in delete) { - _entityManager.DeleteEntity(role); + PredictedDel(role); } var update = MindRolesUpdate(mind); diff --git a/Content.Shared/Trigger/Components/Conditions/MindRoleTriggerConditionComponent.cs b/Content.Shared/Trigger/Components/Conditions/MindRoleTriggerConditionComponent.cs new file mode 100644 index 0000000000..32fb4d7d29 --- /dev/null +++ b/Content.Shared/Trigger/Components/Conditions/MindRoleTriggerConditionComponent.cs @@ -0,0 +1,27 @@ +using Content.Shared.Whitelist; +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Conditions; + +/// +/// Checks if a triggered entity or the user of a trigger has a certain mindrole. +/// Cancels the trigger otherwise. +/// +/// +/// Mind roles are only networked to their owner! So if you use this on any other entity than yourself it won't be predicted. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class MindRoleTriggerConditionComponent : BaseTriggerConditionComponent +{ + /// + /// Whitelist for what mind role components on the owning entity allow this trigger. + /// + [DataField, AutoNetworkedField] + public EntityWhitelist? EntityWhitelist; + + /// + /// Whitelist for what mind role components on the User allow this trigger. + /// + [DataField, AutoNetworkedField] + public EntityWhitelist? UserWhitelist; +} diff --git a/Content.Shared/Trigger/Components/Conditions/WhitelistTriggerConditionComponent.cs b/Content.Shared/Trigger/Components/Conditions/WhitelistTriggerConditionComponent.cs index a2779f79c6..7ec6188ee3 100644 --- a/Content.Shared/Trigger/Components/Conditions/WhitelistTriggerConditionComponent.cs +++ b/Content.Shared/Trigger/Components/Conditions/WhitelistTriggerConditionComponent.cs @@ -4,20 +4,20 @@ using Robust.Shared.GameStates; namespace Content.Shared.Trigger.Components.Conditions; /// -/// Checks if the user of a trigger satisfies a whitelist and blacklist condition for the triggered entity or the one triggering it. +/// Checks if the user of a trigger satisfies a whitelist and blacklist condition. /// Cancels the trigger otherwise. /// [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class WhitelistTriggerConditionComponent : BaseTriggerConditionComponent { /// - /// Whitelist for what entites can cause this trigger. + /// Whitelist for what entities can cause this trigger. /// [DataField, AutoNetworkedField] public EntityWhitelist? UserWhitelist; /// - /// Blacklist for what entites can cause this trigger. + /// Blacklist for what entities can cause this trigger. /// [DataField, AutoNetworkedField] public EntityWhitelist? UserBlacklist; diff --git a/Content.Shared/Trigger/Systems/TriggerSystem.Condition.cs b/Content.Shared/Trigger/Systems/TriggerSystem.Condition.cs index 2d0756556a..b039c8e9de 100644 --- a/Content.Shared/Trigger/Systems/TriggerSystem.Condition.cs +++ b/Content.Shared/Trigger/Systems/TriggerSystem.Condition.cs @@ -10,31 +10,36 @@ public sealed partial class TriggerSystem private void InitializeCondition() { SubscribeLocalEvent(OnWhitelistTriggerAttempt); - SubscribeLocalEvent(OnUseDelayTriggerAttempt); - SubscribeLocalEvent(OnToggleTriggerAttempt); - SubscribeLocalEvent>(OnToggleGetAltVerbs); - SubscribeLocalEvent(OnRandomChanceTriggerAttempt); + SubscribeLocalEvent(OnMindRoleTriggerAttempt); + + SubscribeLocalEvent>(OnToggleGetAltVerbs); } private void OnWhitelistTriggerAttempt(Entity ent, ref AttemptTriggerEvent args) { - if (args.Key == null || ent.Comp.Keys.Contains(args.Key)) - args.Cancelled |= !_whitelist.CheckBoth(args.User, ent.Comp.UserBlacklist, ent.Comp.UserWhitelist); + if (args.Key != null && !ent.Comp.Keys.Contains(args.Key)) + return; + + args.Cancelled |= !_whitelist.CheckBoth(args.User, ent.Comp.UserBlacklist, ent.Comp.UserWhitelist); } private void OnUseDelayTriggerAttempt(Entity ent, ref AttemptTriggerEvent args) { - if (args.Key == null || ent.Comp.Keys.Contains(args.Key)) - args.Cancelled |= _useDelay.IsDelayed(ent.Owner, ent.Comp.UseDelayId); + if (args.Key != null && !ent.Comp.Keys.Contains(args.Key)) + return; + + args.Cancelled |= _useDelay.IsDelayed(ent.Owner, ent.Comp.UseDelayId); } private void OnToggleTriggerAttempt(Entity ent, ref AttemptTriggerEvent args) { - if (args.Key == null || ent.Comp.Keys.Contains(args.Key)) - args.Cancelled |= !ent.Comp.Enabled; + if (args.Key != null && !ent.Comp.Keys.Contains(args.Key)) + return; + + args.Cancelled |= !ent.Comp.Enabled; } private void OnToggleGetAltVerbs(Entity ent, ref GetVerbsEvent args) @@ -62,19 +67,51 @@ public sealed partial class TriggerSystem private void OnRandomChanceTriggerAttempt(Entity ent, ref AttemptTriggerEvent args) { - if (args.Key == null || ent.Comp.Keys.Contains(args.Key)) + if (args.Key != null && !ent.Comp.Keys.Contains(args.Key)) + return; + + // TODO: Replace with RandomPredicted once the engine PR is merged + var hash = new List + { + (int)_timing.CurTick.Value, + GetNetEntity(ent).Id, + args.User == null ? 0 : GetNetEntity(args.User.Value).Id, + }; + var seed = SharedRandomExtensions.HashCodeCombine(hash); + var rand = new System.Random(seed); + + args.Cancelled |= !rand.Prob(ent.Comp.SuccessChance); // When not successful, Cancelled = true + } + private void OnMindRoleTriggerAttempt(Entity ent, ref AttemptTriggerEvent args) + { + if (args.Key != null && !ent.Comp.Keys.Contains(args.Key)) + return; + + if (ent.Comp.EntityWhitelist != null) { - // TODO: Replace with RandomPredicted once the engine PR is merged - var hash = new List + if (!_mind.TryGetMind(ent.Owner, out var entMindId, out var entMindComp)) + { + args.Cancelled = true; // the entity has no mind + return; + } + if (!_role.MindHasRole((entMindId, entMindComp), ent.Comp.EntityWhitelist)) + { + args.Cancelled = true; // the entity does not have the required role + return; + } + } + + if (ent.Comp.UserWhitelist != null) + { + if (args.User == null || !_mind.TryGetMind(args.User.Value, out var userMindId, out var userMindComp)) + { + args.Cancelled = true; // no user or the user has no mind + return; + } + if (!_role.MindHasRole((userMindId, userMindComp), ent.Comp.UserWhitelist)) { - (int)_timing.CurTick.Value, - GetNetEntity(ent).Id, - args.User == null ? 0 : GetNetEntity(args.User.Value).Id, - }; - var seed = SharedRandomExtensions.HashCodeCombine(hash); - var rand = new System.Random(seed); - - args.Cancelled |= !rand.Prob(ent.Comp.SuccessChance); // When not successful, Cancelled = true + args.Cancelled = true; // the user does not have the required role + } } } } diff --git a/Content.Shared/Trigger/Systems/TriggerSystem.cs b/Content.Shared/Trigger/Systems/TriggerSystem.cs index 25f8d51e11..a5fb509eed 100644 --- a/Content.Shared/Trigger/Systems/TriggerSystem.cs +++ b/Content.Shared/Trigger/Systems/TriggerSystem.cs @@ -3,7 +3,9 @@ using Content.Shared.Database; using Content.Shared.DeviceLinking; using Content.Shared.EntityTable; using Content.Shared.Item.ItemToggle; +using Content.Shared.Mind; using Content.Shared.Popups; +using Content.Shared.Roles; using Content.Shared.Timing; using Content.Shared.Trigger.Components; using Content.Shared.Whitelist; @@ -39,6 +41,8 @@ public sealed partial class TriggerSystem : EntitySystem [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; [Dependency] private readonly ItemToggleSystem _itemToggle = default!; [Dependency] private readonly SharedDeviceLinkSystem _deviceLink = default!; + [Dependency] private readonly SharedRoleSystem _role = default!; + [Dependency] private readonly SharedMindSystem _mind = default!; [Dependency] private readonly EntityTableSystem _entityTable = default!; public const string DefaultTriggerKey = "trigger";