Predict inflatable barriers verb (#32420)

* First commit

* evil

* Made it not do weird things

* address review!
This commit is contained in:
beck-thompson
2025-04-10 03:39:13 -07:00
committed by GitHub
parent 728603f714
commit 149c42f385
5 changed files with 93 additions and 89 deletions

View File

@@ -1,16 +0,0 @@
using System.Threading;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Engineering.Components
{
[RegisterComponent]
public sealed partial class DisassembleOnAltVerbComponent : Component
{
[DataField("prototype", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string? Prototype { get; private set; }
[DataField("doAfter")]
public float DoAfterTime = 0;
}
}

View File

@@ -1,69 +0,0 @@
using Content.Server.Engineering.Components;
using Content.Shared.DoAfter;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Verbs;
using JetBrains.Annotations;
namespace Content.Server.Engineering.EntitySystems
{
[UsedImplicitly]
public sealed class DisassembleOnAltVerbSystem : EntitySystem
{
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DisassembleOnAltVerbComponent, GetVerbsEvent<AlternativeVerb>>(AddDisassembleVerb);
}
private void AddDisassembleVerb(EntityUid uid, DisassembleOnAltVerbComponent component, GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanInteract || !args.CanAccess || args.Hands == null)
return;
AlternativeVerb verb = new()
{
Act = () =>
{
AttemptDisassemble(uid, args.User, args.Target, component);
},
Text = Loc.GetString("disassemble-system-verb-disassemble"),
Priority = 2
};
args.Verbs.Add(verb);
}
public async void AttemptDisassemble(EntityUid uid, EntityUid user, EntityUid target, DisassembleOnAltVerbComponent? component = null)
{
if (!Resolve(uid, ref component))
return;
if (string.IsNullOrEmpty(component.Prototype))
return;
if (component.DoAfterTime > 0 && TryGet<SharedDoAfterSystem>(out var doAfterSystem))
{
var doAfterArgs = new DoAfterArgs(EntityManager, user, component.DoAfterTime, new AwaitedDoAfterEvent(), null)
{
BreakOnMove = true,
};
var result = await doAfterSystem.WaitDoAfter(doAfterArgs);
if (result != DoAfterStatus.Finished)
return;
}
if (component.Deleted || Deleted(uid))
return;
if (!TryComp(uid, out TransformComponent? transformComp))
return;
var entity = EntityManager.SpawnEntity(component.Prototype, transformComp.Coordinates);
_handsSystem.TryPickup(user, entity);
EntityManager.DeleteEntity(uid);
}
}
}

View File

@@ -0,0 +1,28 @@
using Content.Shared.DoAfter;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared.Engineering.Components;
/// <summary>
/// Add a verb to entities that will disassemble them after an optional doafter to a specified prototype.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class DisassembleOnAltVerbComponent : Component
{
/// <summary>
/// The prototype that is spawned after disassembly. If null, nothing will spawn.
/// </summary>
[DataField, AutoNetworkedField]
public EntProtoId? PrototypeToSpawn;
/// <summary>
/// The time it takes to disassemble the entity.
/// </summary>
[DataField, AutoNetworkedField]
public TimeSpan DisassembleTime = TimeSpan.FromSeconds(0);
}
[Serializable, NetSerializable]
public sealed partial class DisassembleDoAfterEvent : SimpleDoAfterEvent;

View File

@@ -0,0 +1,61 @@
using Content.Shared.DoAfter;
using Content.Shared.Engineering.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Verbs;
using Robust.Shared.Network;
namespace Content.Shared.Engineering.Systems;
public sealed partial class DisassembleOnAltVerbSystem : EntitySystem
{
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
[Dependency] private readonly INetManager _net = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DisassembleOnAltVerbComponent, GetVerbsEvent<AlternativeVerb>>(AddDisassembleVerb);
SubscribeLocalEvent<DisassembleOnAltVerbComponent, DisassembleDoAfterEvent>(OnDisassembleDoAfter);
}
private void AddDisassembleVerb(Entity<DisassembleOnAltVerbComponent> entity, ref GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanInteract || !args.CanAccess || args.Hands == null)
return;
// Doafter setup
var doAfterArgs = new DoAfterArgs(EntityManager,
args.User,
entity.Comp.DisassembleTime,
new DisassembleDoAfterEvent(),
entity,
entity)
{
BreakOnMove = true,
};
// Actual verb stuff
AlternativeVerb verb = new()
{
Act = () =>
{
_doAfter.TryStartDoAfter(doAfterArgs);
},
Text = Loc.GetString("disassemble-system-verb-disassemble"),
Priority = 2
};
args.Verbs.Add(verb);
}
private void OnDisassembleDoAfter(Entity<DisassembleOnAltVerbComponent> entity, ref DisassembleDoAfterEvent args)
{
if (!_net.IsServer) // This is odd but it works :)
return;
if (TrySpawnNextTo(entity.Comp.PrototypeToSpawn, entity.Owner, out var spawnedEnt))
_handsSystem.TryPickup(args.User, spawnedEnt.Value);
QueueDel(entity.Owner);
}
}

View File

@@ -31,8 +31,8 @@
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: DisassembleOnAltVerb
prototype: InflatableWallStack1
doAfter: 3
prototypeToSpawn: InflatableWallStack1
disassembleTime: 3
- type: Airtight
- type: Transform
anchored: true
@@ -79,7 +79,7 @@
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: DisassembleOnAltVerb
prototype: InflatableDoorStack1
doAfter: 3
prototypeToSpawn: InflatableDoorStack1
disassembleTime: 3
- type: Occluder
enabled: false