+using Content.Server.Audio;
using Content.Server.Explosion.EntitySystems;
+using Content.Shared.Damage.Systems;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.HotPotato;
{
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
+ [Dependency] private readonly AmbientSoundSystem _ambientSound = default!;
+ [Dependency] private readonly DamageOnHoldingSystem _damageOnHolding = default!;
public override void Initialize()
{
{
EnsureComp<ActiveHotPotatoComponent>(uid);
comp.CanTransfer = false;
+ _ambientSound.SetAmbience(uid, true);
+ _damageOnHolding.SetEnabled(uid, true);
Dirty(comp);
}
--- /dev/null
+using Content.Shared.Damage.Systems;
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
+
+namespace Content.Shared.Damage.Components;
+
+[RegisterComponent, NetworkedComponent]
+[AutoGenerateComponentState]
+[Access(typeof(DamageOnHoldingSystem))]
+public sealed partial class DamageOnHoldingComponent : Component
+{
+ [DataField("enabled"), ViewVariables(VVAccess.ReadWrite)]
+ [AutoNetworkedField]
+ public bool Enabled = true;
+
+ /// <summary>
+ /// Damage per interval dealt to entity holding the entity with this component
+ /// </summary>
+ [DataField("damage"), ViewVariables(VVAccess.ReadWrite)]
+ public DamageSpecifier Damage = new();
+ // TODO: make it networked
+
+ /// <summary>
+ /// Delay between damage events in seconds
+ /// </summary>
+ [DataField("interval"), ViewVariables(VVAccess.ReadWrite)]
+ [AutoNetworkedField]
+ public float Interval = 1f;
+
+ [DataField("nextDamage", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
+ [AutoNetworkedField]
+ public TimeSpan NextDamage = TimeSpan.Zero;
+}
--- /dev/null
+using Content.Shared.Damage.Components;
+using Robust.Shared.Containers;
+using Robust.Shared.Timing;
+
+namespace Content.Shared.Damage.Systems;
+
+public sealed class DamageOnHoldingSystem : EntitySystem
+{
+ [Dependency] private readonly SharedContainerSystem _container = default!;
+ [Dependency] private readonly DamageableSystem _damageableSystem = default!;
+ [Dependency] private readonly IGameTiming _timing = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent<DamageOnHoldingComponent, EntityUnpausedEvent>(OnUnpaused);
+ SubscribeLocalEvent<DamageOnHoldingComponent, MapInitEvent>(OnMapInit);
+ }
+
+ public void SetEnabled(EntityUid uid, bool enabled, DamageOnHoldingComponent? component = null)
+ {
+ if (Resolve(uid, ref component))
+ {
+ component.Enabled = enabled;
+ component.NextDamage = _timing.CurTime;
+ }
+ }
+
+ private void OnUnpaused(EntityUid uid, DamageOnHoldingComponent component, ref EntityUnpausedEvent args)
+ {
+ component.NextDamage += args.PausedTime;
+ }
+
+ private void OnMapInit(EntityUid uid, DamageOnHoldingComponent component, MapInitEvent args)
+ {
+ component.NextDamage = _timing.CurTime;
+ }
+
+ public override void Update(float frameTime)
+ {
+ var query = EntityQueryEnumerator<DamageOnHoldingComponent>();
+ while (query.MoveNext(out var uid, out var component))
+ {
+ if (!component.Enabled || component.NextDamage > _timing.CurTime)
+ continue;
+ if (_container.TryGetContainingContainer(uid, out var container))
+ {
+ _damageableSystem.TryChangeDamage(container.Owner, component.Damage, origin: uid);
+ }
+ component.NextDamage = _timing.CurTime + TimeSpan.FromSeconds(component.Interval);
+ }
+ }
+}
\ No newline at end of file
namespace Content.Shared.HotPotato;
/// <summary>
-/// Similar to <see cref="Content.Shared.Interaction.Components.UnremoveableComponent"/>
+/// Similar to <see cref="Interaction.Components.UnremoveableComponent"/>
/// except entities with this component can be removed in specific case: <see cref="CanTransfer"/>
/// </summary>
[RegisterComponent, NetworkedComponent]
- type: entity
name: hot potato
- description: Once activated, this time bomb can't be dropped - only passed to someone else!
+ description: Once activated, you can't drop this time bomb - hit someone else with it to save yourself! Don't burn your hands!
parent: BaseItem
id: HotPotato
components:
- type: Item
sprite: Objects/Weapons/Bombs/hot_potato.rsi
size: 5
+ - type: AmbientSound
+ enabled: false
+ range: 8
+ sound:
+ path: /Audio/Effects/lightburn.ogg
- type: MeleeWeapon
damage:
types:
canCreateVacuum: false
- type: DeleteOnTrigger
- type: HotPotato
+ - type: DamageOnHolding
+ enabled: false
+ damage:
+ types:
+ Heat: 1
- type: Appearance
visuals:
- type: GenericEnumVisualizer