magazine fill repeating doafter (#19780)

Co-authored-by: deltanedas <@deltanedas:kde.org>
This commit is contained in:
deltanedas
2023-09-04 05:49:49 +01:00
committed by GitHub
parent 892fc7c07b
commit 5ead3d5108
2 changed files with 49 additions and 12 deletions

View File

@@ -53,4 +53,10 @@ public sealed partial class BallisticAmmoProviderComponent : Component
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("mayTransfer")]
public bool MayTransfer = false;
/// <summary>
/// DoAfter delay for filling a bullet into another ballistic ammo provider.
/// </summary>
[DataField("fillDelay")]
public TimeSpan FillDelay = TimeSpan.FromSeconds(0.5);
}

View File

@@ -1,3 +1,4 @@
using Content.Shared.DoAfter;
using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.Interaction.Events;
@@ -13,6 +14,8 @@ namespace Content.Shared.Weapons.Ranged.Systems;
public abstract partial class SharedGunSystem
{
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
protected virtual void InitializeBallistic()
{
SubscribeLocalEvent<BallisticAmmoProviderComponent, ComponentInit>(OnBallisticInit);
@@ -24,6 +27,7 @@ public abstract partial class SharedGunSystem
SubscribeLocalEvent<BallisticAmmoProviderComponent, GetVerbsEvent<Verb>>(OnBallisticVerb);
SubscribeLocalEvent<BallisticAmmoProviderComponent, InteractUsingEvent>(OnBallisticInteractUsing);
SubscribeLocalEvent<BallisticAmmoProviderComponent, AfterInteractEvent>(OnBallisticAfterInteract);
SubscribeLocalEvent<BallisticAmmoProviderComponent, AmmoFillDoAfterEvent>(OnBallisticAmmoFillDoAfter);
SubscribeLocalEvent<BallisticAmmoProviderComponent, UseInHandEvent>(OnBallisticUse);
}
@@ -61,7 +65,7 @@ public abstract partial class SharedGunSystem
args.Target == null ||
args.Used == args.Target ||
Deleted(args.Target) ||
!TryComp(args.Target, out BallisticAmmoProviderComponent? targetComponent) ||
!TryComp<BallisticAmmoProviderComponent>(args.Target, out var targetComponent) ||
targetComponent.Whitelist == null)
{
return;
@@ -69,7 +73,23 @@ public abstract partial class SharedGunSystem
args.Handled = true;
if (targetComponent.Entities.Count + targetComponent.UnspawnedCount == targetComponent.Capacity)
_doAfter.TryStartDoAfter(new DoAfterArgs(args.User, component.FillDelay, new AmmoFillDoAfterEvent(), used: uid, target: args.Target, eventTarget: uid)
{
BreakOnTargetMove = true,
BreakOnUserMove = true,
BreakOnDamage = false,
NeedHand = true
});
}
private void OnBallisticAmmoFillDoAfter(EntityUid uid, BallisticAmmoProviderComponent component, AmmoFillDoAfterEvent args)
{
if (Deleted(args.Target) ||
!TryComp<BallisticAmmoProviderComponent>(args.Target, out var target) ||
target.Whitelist == null)
return;
if (target.Entities.Count + target.UnspawnedCount == target.Capacity)
{
Popup(
Loc.GetString("gun-ballistic-transfer-target-full",
@@ -83,8 +103,8 @@ public abstract partial class SharedGunSystem
{
Popup(
Loc.GetString("gun-ballistic-transfer-empty",
("entity", args.Used)),
args.Used,
("entity", uid)),
uid,
args.User);
return;
}
@@ -96,27 +116,25 @@ public abstract partial class SharedGunSystem
}
List<(EntityUid? Entity, IShootable Shootable)> ammo = new();
var evTakeAmmo = new TakeAmmoEvent(1, ammo, Transform(args.Used).Coordinates, args.User);
RaiseLocalEvent(args.Used, evTakeAmmo);
var evTakeAmmo = new TakeAmmoEvent(1, ammo, Transform(uid).Coordinates, args.User);
RaiseLocalEvent(uid, evTakeAmmo);
foreach (var (ent, _) in ammo)
{
if (ent == null)
continue;
if (!targetComponent.Whitelist.IsValid(ent.Value))
if (!target.Whitelist.IsValid(ent.Value))
{
Popup(
Loc.GetString("gun-ballistic-transfer-invalid",
("ammoEntity", ent.Value),
("targetEntity", args.Target.Value)),
args.Used,
uid,
args.User);
// TODO: For better or worse, this will play a sound, but it's the
// more future-proof thing to do than copying the same code
// that OnBallisticInteractUsing has, sans sound.
SimulateInsertAmmo(ent.Value, args.Used, Transform(args.Used).Coordinates);
// play sound to be cool
SimulateInsertAmmo(ent.Value, uid, Transform(uid).Coordinates);
}
else
{
@@ -126,6 +144,11 @@ public abstract partial class SharedGunSystem
if (ent.Value.IsClientSide())
Del(ent.Value);
}
// repeat if there is more space in the target and more ammo to fill it
var moreSpace = target.Entities.Count + target.UnspawnedCount < target.Capacity;
var moreAmmo = component.Entities.Count + component.UnspawnedCount > 0;
args.Repeat = moreSpace && moreAmmo;
}
private void OnBallisticVerb(EntityUid uid, BallisticAmmoProviderComponent component, GetVerbsEvent<Verb> args)
@@ -247,3 +270,11 @@ public abstract partial class SharedGunSystem
Appearance.SetData(uid, AmmoVisuals.AmmoMax, component.Capacity, appearance);
}
}
/// <summary>
/// DoAfter event for filling one ballistic ammo provider from another.
/// </summary>
[Serializable, NetSerializable]
public sealed partial class AmmoFillDoAfterEvent : SimpleDoAfterEvent
{
}