mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 10:21:18 +03:00
Bugfix: Guardian popup spam, mech attack blocker (#45013)
* guardian popup fixes * actually use the entityqueries * finish a thought challenge - difficulty impossible * curse of fildrance * can't believe he's done this
This commit is contained in:
parent
f196854844
commit
45f91a84a4
2 changed files with 62 additions and 40 deletions
|
|
@ -1,12 +1,14 @@
|
|||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Shared.Guardian.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Given to guardians to monitor their link with the host.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[AutoGenerateComponentState, AutoGenerateComponentPause]
|
||||
public sealed partial class GuardianComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -50,4 +52,16 @@ public sealed partial class GuardianComponent : Component
|
|||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier DeathSound = new SoundPathSpecifier("/Audio/Voice/Human/malescream_guardian.ogg", AudioParams.Default.WithVariation(0.2f));
|
||||
|
||||
/// <summary>
|
||||
/// The last time that the entity received an attack popup.
|
||||
/// </summary>
|
||||
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
|
||||
public TimeSpan LastAttackPopupTime;
|
||||
|
||||
/// <summary>
|
||||
/// The delay between showing popups to the guardian when trying to attack its host.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan AttackPopupDelay = TimeSpan.FromSeconds(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,35 +36,13 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
[Dependency] private SharedPopupSystem _popup = default!;
|
||||
[Dependency] private SharedTransformSystem _transform = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<GuardianCreatorComponent, UseInHandEvent>(OnCreatorUse);
|
||||
SubscribeLocalEvent<GuardianCreatorComponent, AfterInteractEvent>(OnCreatorInteract);
|
||||
SubscribeLocalEvent<GuardianCreatorComponent, ExaminedEvent>(OnCreatorExamine);
|
||||
SubscribeLocalEvent<GuardianCreatorComponent, GuardianCreatorDoAfterEvent>(OnDoAfter);
|
||||
|
||||
SubscribeLocalEvent<GuardianComponent, ComponentShutdown>(OnGuardianShutdown);
|
||||
SubscribeLocalEvent<GuardianComponent, MoveEvent>(OnGuardianMove);
|
||||
SubscribeLocalEvent<GuardianComponent, DamageDealtEvent>(OnGuardianDamaged);
|
||||
SubscribeLocalEvent<GuardianComponent, PlayerAttachedEvent>(OnGuardianPlayerAttached);
|
||||
SubscribeLocalEvent<GuardianComponent, PlayerDetachedEvent>(OnGuardianPlayerDetached);
|
||||
|
||||
SubscribeLocalEvent<GuardianHostComponent, ComponentInit>(OnHostInit);
|
||||
SubscribeLocalEvent<GuardianHostComponent, MoveEvent>(OnHostMove);
|
||||
SubscribeLocalEvent<GuardianHostComponent, MobStateChangedEvent>(OnHostStateChange);
|
||||
SubscribeLocalEvent<GuardianHostComponent, ComponentShutdown>(OnHostShutdown);
|
||||
|
||||
SubscribeLocalEvent<GuardianHostComponent, GuardianToggleActionEvent>(OnPerformAction);
|
||||
|
||||
SubscribeLocalEvent<GuardianComponent, AttackAttemptEvent>(OnGuardianAttackAttempt);
|
||||
|
||||
SubscribeLocalEvent<GuardianHostComponent, MechPilotRelayedEvent<GettingAttackedAttemptEvent>>(OnPilotAttackAttempt);
|
||||
}
|
||||
[Dependency] private EntityQuery<GuardianComponent> _guardianQuery;
|
||||
[Dependency] private EntityQuery<GuardianHostComponent> _guardianHostQuery;
|
||||
|
||||
[SubscribeLocalEvent]
|
||||
private void OnGuardianShutdown(Entity<GuardianComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
if (!TryComp<GuardianHostComponent>(ent, out var hostComponent))
|
||||
if (!_guardianHostQuery.TryComp(ent, out GuardianHostComponent? hostComponent))
|
||||
return;
|
||||
|
||||
_container.Remove(ent.Owner, hostComponent.GuardianContainer);
|
||||
|
|
@ -77,6 +55,7 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
Dirty(ent, hostComponent);
|
||||
}
|
||||
|
||||
[SubscribeLocalEvent]
|
||||
private void OnPerformAction(Entity<GuardianHostComponent> ent, ref GuardianToggleActionEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
|
|
@ -94,9 +73,10 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
args.Handled = true;
|
||||
}
|
||||
|
||||
[SubscribeLocalEvent]
|
||||
private void OnGuardianPlayerDetached(Entity<GuardianComponent> ent, ref PlayerDetachedEvent args)
|
||||
{
|
||||
if (!TryComp<GuardianHostComponent>(ent.Comp.Host, out var hostComponent) ||
|
||||
if (!_guardianHostQuery.TryComp(ent.Comp.Host, out GuardianHostComponent? hostComponent) ||
|
||||
TerminatingOrDeleted(ent.Owner))
|
||||
{
|
||||
PredictedQueueDel(ent.Owner);
|
||||
|
|
@ -108,10 +88,11 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
RetractGuardian((ent.Comp.Host.Value, hostComponent), (ent.Owner, ent.Comp));
|
||||
}
|
||||
|
||||
[SubscribeLocalEvent]
|
||||
private void OnGuardianPlayerAttached(Entity<GuardianComponent> ent, ref PlayerAttachedEvent args)
|
||||
{
|
||||
var host = ent.Comp.Host;
|
||||
if (!HasComp<GuardianHostComponent>(host))
|
||||
if (!_guardianHostQuery.HasComp(host))
|
||||
{
|
||||
PredictedQueueDel(ent.Owner);
|
||||
ent.Comp.Host = null;
|
||||
|
|
@ -122,12 +103,14 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
_popup.PopupEntity(Loc.GetString("guardian-available"), host.Value, host.Value);
|
||||
}
|
||||
|
||||
[SubscribeLocalEvent]
|
||||
private void OnHostInit(Entity<GuardianHostComponent> ent, ref ComponentInit args)
|
||||
{
|
||||
ent.Comp.GuardianContainer = _container.EnsureContainer<ContainerSlot>(ent.Owner, "GuardianContainer");
|
||||
_action.AddAction(ent.Owner, ref ent.Comp.ActionEntity, ent.Comp.Action);
|
||||
}
|
||||
|
||||
[SubscribeLocalEvent]
|
||||
private void OnHostShutdown(Entity<GuardianHostComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
if (ent.Comp.HostedGuardian is not { } guardian)
|
||||
|
|
@ -144,30 +127,46 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
Dirty(ent);
|
||||
}
|
||||
|
||||
[SubscribeLocalEvent]
|
||||
private void OnGuardianAttackAttempt(Entity<GuardianComponent> ent, ref AttackAttemptEvent args)
|
||||
{
|
||||
if (args.Cancelled || args.Target != ent.Comp.Host)
|
||||
return;
|
||||
|
||||
_popup.PopupCursor(Loc.GetString("guardian-attack-host"), ent.Owner, PopupType.LargeCaution);
|
||||
if (_timing.CurTime >= ent.Comp.LastAttackPopupTime + ent.Comp.AttackPopupDelay)
|
||||
{
|
||||
_popup.PopupCursor(Loc.GetString("guardian-attack-host"), ent.Owner, PopupType.LargeCaution);
|
||||
}
|
||||
ent.Comp.LastAttackPopupTime = _timing.CurTime;
|
||||
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
[SubscribeLocalEvent]
|
||||
private void OnPilotAttackAttempt(Entity<GuardianHostComponent> ent,
|
||||
ref MechPilotRelayedEvent<GettingAttackedAttemptEvent> args)
|
||||
{
|
||||
if (args.Args.Cancelled)
|
||||
if (args.Args.Cancelled || args.Args.Attacker != ent.Comp.HostedGuardian)
|
||||
return;
|
||||
|
||||
_popup.PopupCursor(Loc.GetString("guardian-attack-host"),
|
||||
args.Args.Attacker,
|
||||
PopupType.LargeCaution);
|
||||
if (_guardianQuery.TryComp(args.Args.Attacker, out var guardian))
|
||||
{
|
||||
if (_timing.CurTime >= guardian.LastAttackPopupTime + guardian.AttackPopupDelay)
|
||||
{
|
||||
_popup.PopupCursor(Loc.GetString("guardian-attack-host"),
|
||||
args.Args.Attacker,
|
||||
PopupType.LargeCaution);
|
||||
}
|
||||
guardian.LastAttackPopupTime = _timing.CurTime;
|
||||
}
|
||||
|
||||
args.Args.Cancelled = true;
|
||||
}
|
||||
|
||||
[SubscribeLocalEvent]
|
||||
private void ToggleGuardian(Entity<GuardianHostComponent> ent)
|
||||
{
|
||||
if (!TryComp<GuardianComponent>(ent.Comp.HostedGuardian, out var guardianComponent))
|
||||
if (!_guardianQuery.TryComp(ent.Comp.HostedGuardian, out var guardianComponent))
|
||||
return;
|
||||
|
||||
if (guardianComponent.GuardianLoose)
|
||||
|
|
@ -179,6 +178,7 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Adds the guardian host component to the user and spawns the guardian inside said component.
|
||||
/// </summary>
|
||||
[SubscribeLocalEvent]
|
||||
private void OnCreatorUse(Entity<GuardianCreatorComponent> ent, ref UseInHandEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
|
|
@ -188,6 +188,7 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
UseCreator(args.User, args.User, ent);
|
||||
}
|
||||
|
||||
[SubscribeLocalEvent]
|
||||
private void OnCreatorInteract(Entity<GuardianCreatorComponent> ent, ref AfterInteractEvent args)
|
||||
{
|
||||
if (args.Handled || args.Target == null || !args.CanReach)
|
||||
|
|
@ -216,7 +217,7 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
}
|
||||
|
||||
// If user is already a host don't duplicate.
|
||||
if (HasComp<GuardianHostComponent>(target))
|
||||
if (_guardianHostQuery.HasComp(target))
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("guardian-already-present-invalid-creation"), user, user);
|
||||
return;
|
||||
|
|
@ -236,12 +237,13 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
});
|
||||
}
|
||||
|
||||
[SubscribeLocalEvent]
|
||||
private void OnDoAfter(Entity<GuardianCreatorComponent> ent, ref GuardianCreatorDoAfterEvent args)
|
||||
{
|
||||
if (args.Handled || args.Args.Target == null || args.Cancelled || ent.Comp.Deleted || ent.Comp.Used)
|
||||
return;
|
||||
|
||||
if (!_hands.IsHolding(args.Args.User, ent.Owner) || HasComp<GuardianHostComponent>(args.Args.Target))
|
||||
if (!_hands.IsHolding(args.Args.User, ent.Owner) || _guardianHostQuery.HasComp(args.Args.Target))
|
||||
return;
|
||||
|
||||
var hostXform = Transform(args.Args.Target.Value);
|
||||
|
|
@ -253,9 +255,10 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
_container.Insert(guardian, host.GuardianContainer);
|
||||
host.HostedGuardian = guardian;
|
||||
|
||||
if (TryComp<GuardianComponent>(guardian, out var guardianComp))
|
||||
if (_guardianQuery.TryComp(guardian, out GuardianComponent? guardianComp))
|
||||
{
|
||||
guardianComp.Host = args.Args.Target.Value;
|
||||
Dirty(guardian, guardianComp);
|
||||
_audio.PlayPredicted(ent.Comp.UsedSound,
|
||||
ent.Owner,
|
||||
args.Args.Target);
|
||||
|
|
@ -278,10 +281,11 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Triggers when the host receives damage which puts the host in either critical or killed state.
|
||||
/// </summary>
|
||||
[SubscribeLocalEvent]
|
||||
private void OnHostStateChange(Entity<GuardianHostComponent> ent, ref MobStateChangedEvent args)
|
||||
{
|
||||
if (ent.Comp.HostedGuardian == null ||
|
||||
!TryComp<GuardianComponent>(ent.Comp.HostedGuardian, out var guardianComp))
|
||||
!_guardianQuery.TryComp(ent.Comp.HostedGuardian, out GuardianComponent? guardianComp))
|
||||
return;
|
||||
|
||||
if (args.NewMobState == MobState.Critical)
|
||||
|
|
@ -301,6 +305,7 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Handles guardian receiving damage and splitting it with the host according to his defense percent.
|
||||
/// </summary>
|
||||
[SubscribeLocalEvent]
|
||||
private void OnGuardianDamaged(Entity<GuardianComponent> ent, ref DamageDealtEvent args)
|
||||
{
|
||||
if (_timing.ApplyingState)
|
||||
|
|
@ -321,6 +326,7 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Triggers while trying to examine an activator to see if it's used.
|
||||
/// </summary>
|
||||
[SubscribeLocalEvent]
|
||||
private void OnCreatorExamine(Entity<GuardianCreatorComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
if (!ent.Comp.Used)
|
||||
|
|
@ -332,9 +338,10 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Called every time the host moves, to make sure the host and the guardian are not too far away from each other.
|
||||
/// </summary>
|
||||
[SubscribeLocalEvent]
|
||||
private void OnHostMove(Entity<GuardianHostComponent> ent, ref MoveEvent args)
|
||||
{
|
||||
if (!TryComp<GuardianComponent>(ent.Comp.HostedGuardian, out var guardianComponent) ||
|
||||
if (!_guardianQuery.TryComp(ent.Comp.HostedGuardian, out GuardianComponent? guardianComponent) ||
|
||||
!guardianComponent.GuardianLoose)
|
||||
{
|
||||
return;
|
||||
|
|
@ -346,6 +353,7 @@ public sealed partial class GuardianSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Called every time the guardian moves: makes sure it's not out of it's allowed distance.
|
||||
/// </summary>
|
||||
[SubscribeLocalEvent]
|
||||
private void OnGuardianMove(Entity<GuardianComponent> ent, ref MoveEvent args)
|
||||
{
|
||||
if (!ent.Comp.GuardianLoose)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue