--- /dev/null
+using Content.Shared.Whitelist;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Trigger.Components.Conditions;
+
+/// <summary>
+/// Checks if a triggered entity or the user of a trigger has a certain mindrole.
+/// Cancels the trigger otherwise.
+/// </summary>
+/// <remarks>
+/// Mind roles are only networked to their owner! So if you use this on any other entity than yourself it won't be predicted.
+/// </remarks>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class MindRoleTriggerConditionComponent : BaseTriggerConditionComponent
+{
+ /// <summary>
+ /// Whitelist for what mind role components on the owning entity allow this trigger.
+ /// </summary>
+ [DataField, AutoNetworkedField]
+ public EntityWhitelist? EntityWhitelist;
+
+ /// <summary>
+ /// Whitelist for what mind role components on the User allow this trigger.
+ /// </summary>
+ [DataField, AutoNetworkedField]
+ public EntityWhitelist? UserWhitelist;
+}
namespace Content.Shared.Trigger.Components.Conditions;
/// <summary>
-/// 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.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class WhitelistTriggerConditionComponent : BaseTriggerConditionComponent
{
/// <summary>
- /// Whitelist for what entites can cause this trigger.
+ /// Whitelist for what entities can cause this trigger.
/// </summary>
[DataField, AutoNetworkedField]
public EntityWhitelist? UserWhitelist;
/// <summary>
- /// Blacklist for what entites can cause this trigger.
+ /// Blacklist for what entities can cause this trigger.
/// </summary>
[DataField, AutoNetworkedField]
public EntityWhitelist? UserBlacklist;
private void InitializeCondition()
{
SubscribeLocalEvent<WhitelistTriggerConditionComponent, AttemptTriggerEvent>(OnWhitelistTriggerAttempt);
-
SubscribeLocalEvent<UseDelayTriggerConditionComponent, AttemptTriggerEvent>(OnUseDelayTriggerAttempt);
-
SubscribeLocalEvent<ToggleTriggerConditionComponent, AttemptTriggerEvent>(OnToggleTriggerAttempt);
- SubscribeLocalEvent<ToggleTriggerConditionComponent, GetVerbsEvent<AlternativeVerb>>(OnToggleGetAltVerbs);
-
SubscribeLocalEvent<RandomChanceTriggerConditionComponent, AttemptTriggerEvent>(OnRandomChanceTriggerAttempt);
+ SubscribeLocalEvent<MindRoleTriggerConditionComponent, AttemptTriggerEvent>(OnMindRoleTriggerAttempt);
+
+ SubscribeLocalEvent<ToggleTriggerConditionComponent, GetVerbsEvent<AlternativeVerb>>(OnToggleGetAltVerbs);
}
private void OnWhitelistTriggerAttempt(Entity<WhitelistTriggerConditionComponent> 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<UseDelayTriggerConditionComponent> 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<ToggleTriggerConditionComponent> 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<ToggleTriggerConditionComponent> ent, ref GetVerbsEvent<AlternativeVerb> args)
private void OnRandomChanceTriggerAttempt(Entity<RandomChanceTriggerConditionComponent> 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>
+ {
+ (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<MindRoleTriggerConditionComponent> 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<int>
+ 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
+ }
}
}
}
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;
[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";