--- /dev/null
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Trigger.Components.Conditions;
+
+/// <summary>
+/// This condition will cancel triggers based on random chance.
+/// </summary>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class RandomChanceTriggerConditionComponent : BaseTriggerConditionComponent
+{
+ /// <summary>
+ /// Chance for the trigger to succeed.
+ /// </summary>
+ [DataField, AutoNetworkedField]
+ public float SuccessChance = .9f;
+}
-using Content.Shared.Trigger.Components.Conditions;
+using Content.Shared.Random.Helpers;
+using Content.Shared.Trigger.Components.Conditions;
using Content.Shared.Verbs;
+using Robust.Shared.Random;
namespace Content.Shared.Trigger.Systems;
SubscribeLocalEvent<ToggleTriggerConditionComponent, AttemptTriggerEvent>(OnToggleTriggerAttempt);
SubscribeLocalEvent<ToggleTriggerConditionComponent, GetVerbsEvent<AlternativeVerb>>(OnToggleGetAltVerbs);
+
+ SubscribeLocalEvent<RandomChanceTriggerConditionComponent, AttemptTriggerEvent>(OnRandomChanceTriggerAttempt);
}
private void OnWhitelistTriggerAttempt(Entity<WhitelistTriggerConditionComponent> ent, ref AttemptTriggerEvent args)
ent.Comp.Enabled = !ent.Comp.Enabled;
Dirty(ent);
}
+
+ private void OnRandomChanceTriggerAttempt(Entity<RandomChanceTriggerConditionComponent> ent,
+ ref AttemptTriggerEvent args)
+ {
+ if (args.Key == null || ent.Comp.Keys.Contains(args.Key))
+ {
+ // 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
+ }
+ }
}