magazine fill repeating doafter (#19780)
Co-authored-by: deltanedas <@deltanedas:kde.org>
This commit is contained in:
@@ -53,4 +53,10 @@ public sealed partial class BallisticAmmoProviderComponent : Component
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite), DataField("mayTransfer")]
|
[ViewVariables(VVAccess.ReadWrite), DataField("mayTransfer")]
|
||||||
public bool MayTransfer = false;
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Shared.DoAfter;
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Interaction.Events;
|
using Content.Shared.Interaction.Events;
|
||||||
@@ -13,6 +14,8 @@ namespace Content.Shared.Weapons.Ranged.Systems;
|
|||||||
|
|
||||||
public abstract partial class SharedGunSystem
|
public abstract partial class SharedGunSystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||||
|
|
||||||
protected virtual void InitializeBallistic()
|
protected virtual void InitializeBallistic()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, ComponentInit>(OnBallisticInit);
|
SubscribeLocalEvent<BallisticAmmoProviderComponent, ComponentInit>(OnBallisticInit);
|
||||||
@@ -24,6 +27,7 @@ public abstract partial class SharedGunSystem
|
|||||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, GetVerbsEvent<Verb>>(OnBallisticVerb);
|
SubscribeLocalEvent<BallisticAmmoProviderComponent, GetVerbsEvent<Verb>>(OnBallisticVerb);
|
||||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, InteractUsingEvent>(OnBallisticInteractUsing);
|
SubscribeLocalEvent<BallisticAmmoProviderComponent, InteractUsingEvent>(OnBallisticInteractUsing);
|
||||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, AfterInteractEvent>(OnBallisticAfterInteract);
|
SubscribeLocalEvent<BallisticAmmoProviderComponent, AfterInteractEvent>(OnBallisticAfterInteract);
|
||||||
|
SubscribeLocalEvent<BallisticAmmoProviderComponent, AmmoFillDoAfterEvent>(OnBallisticAmmoFillDoAfter);
|
||||||
SubscribeLocalEvent<BallisticAmmoProviderComponent, UseInHandEvent>(OnBallisticUse);
|
SubscribeLocalEvent<BallisticAmmoProviderComponent, UseInHandEvent>(OnBallisticUse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +65,7 @@ public abstract partial class SharedGunSystem
|
|||||||
args.Target == null ||
|
args.Target == null ||
|
||||||
args.Used == args.Target ||
|
args.Used == args.Target ||
|
||||||
Deleted(args.Target) ||
|
Deleted(args.Target) ||
|
||||||
!TryComp(args.Target, out BallisticAmmoProviderComponent? targetComponent) ||
|
!TryComp<BallisticAmmoProviderComponent>(args.Target, out var targetComponent) ||
|
||||||
targetComponent.Whitelist == null)
|
targetComponent.Whitelist == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -69,7 +73,23 @@ public abstract partial class SharedGunSystem
|
|||||||
|
|
||||||
args.Handled = true;
|
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(
|
Popup(
|
||||||
Loc.GetString("gun-ballistic-transfer-target-full",
|
Loc.GetString("gun-ballistic-transfer-target-full",
|
||||||
@@ -83,8 +103,8 @@ public abstract partial class SharedGunSystem
|
|||||||
{
|
{
|
||||||
Popup(
|
Popup(
|
||||||
Loc.GetString("gun-ballistic-transfer-empty",
|
Loc.GetString("gun-ballistic-transfer-empty",
|
||||||
("entity", args.Used)),
|
("entity", uid)),
|
||||||
args.Used,
|
uid,
|
||||||
args.User);
|
args.User);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -96,27 +116,25 @@ public abstract partial class SharedGunSystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<(EntityUid? Entity, IShootable Shootable)> ammo = new();
|
List<(EntityUid? Entity, IShootable Shootable)> ammo = new();
|
||||||
var evTakeAmmo = new TakeAmmoEvent(1, ammo, Transform(args.Used).Coordinates, args.User);
|
var evTakeAmmo = new TakeAmmoEvent(1, ammo, Transform(uid).Coordinates, args.User);
|
||||||
RaiseLocalEvent(args.Used, evTakeAmmo);
|
RaiseLocalEvent(uid, evTakeAmmo);
|
||||||
|
|
||||||
foreach (var (ent, _) in ammo)
|
foreach (var (ent, _) in ammo)
|
||||||
{
|
{
|
||||||
if (ent == null)
|
if (ent == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!targetComponent.Whitelist.IsValid(ent.Value))
|
if (!target.Whitelist.IsValid(ent.Value))
|
||||||
{
|
{
|
||||||
Popup(
|
Popup(
|
||||||
Loc.GetString("gun-ballistic-transfer-invalid",
|
Loc.GetString("gun-ballistic-transfer-invalid",
|
||||||
("ammoEntity", ent.Value),
|
("ammoEntity", ent.Value),
|
||||||
("targetEntity", args.Target.Value)),
|
("targetEntity", args.Target.Value)),
|
||||||
args.Used,
|
uid,
|
||||||
args.User);
|
args.User);
|
||||||
|
|
||||||
// TODO: For better or worse, this will play a sound, but it's the
|
// play sound to be cool
|
||||||
// more future-proof thing to do than copying the same code
|
SimulateInsertAmmo(ent.Value, uid, Transform(uid).Coordinates);
|
||||||
// that OnBallisticInteractUsing has, sans sound.
|
|
||||||
SimulateInsertAmmo(ent.Value, args.Used, Transform(args.Used).Coordinates);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -126,6 +144,11 @@ public abstract partial class SharedGunSystem
|
|||||||
if (ent.Value.IsClientSide())
|
if (ent.Value.IsClientSide())
|
||||||
Del(ent.Value);
|
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)
|
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);
|
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
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user