Create Generic DamageOnInteract/Attacked Comps/Systems (#30244)
* Everything but the submodule * stuff I forgot * heat * missed lights * behonky * LocId * I guess it was a skill issue? * predicted audio * It works with lights now * Borg equality * Gorilla gauntlet grants protection from anomaly returned damage when attacking it * woops, there we go * NONE * Use DamageModifierSets, remove Behonker damage * Reviews dealt with --------- Co-authored-by: plykiya <plykiya@protonmail.com>
This commit is contained in:
@@ -1,12 +0,0 @@
|
|||||||
namespace Content.Server.Clothing.Components;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// TODO this needs removed somehow.
|
|
||||||
/// Handles 'heat resistance' for gloves touching bulbs and that's it, ick.
|
|
||||||
/// </summary>
|
|
||||||
[RegisterComponent]
|
|
||||||
public sealed partial class GloveHeatResistanceComponent : Component
|
|
||||||
{
|
|
||||||
[DataField("heatResistance")]
|
|
||||||
public int HeatResistance = 323;
|
|
||||||
}
|
|
||||||
@@ -30,10 +30,6 @@ namespace Content.Server.Light.Components
|
|||||||
[DataField("on")]
|
[DataField("on")]
|
||||||
public bool On = true;
|
public bool On = true;
|
||||||
|
|
||||||
[DataField("damage", required: true)]
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
public DamageSpecifier Damage = default!;
|
|
||||||
|
|
||||||
[DataField("ignoreGhostsBoo")]
|
[DataField("ignoreGhostsBoo")]
|
||||||
public bool IgnoreGhostsBoo;
|
public bool IgnoreGhostsBoo;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Administration.Logs;
|
||||||
using Content.Server.Clothing.Components;
|
|
||||||
using Content.Server.DeviceLinking.Events;
|
using Content.Server.DeviceLinking.Events;
|
||||||
using Content.Server.DeviceLinking.Systems;
|
using Content.Server.DeviceLinking.Systems;
|
||||||
using Content.Server.DeviceNetwork;
|
using Content.Server.DeviceNetwork;
|
||||||
@@ -24,6 +23,8 @@ using Robust.Shared.Containers;
|
|||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
|
using Content.Shared.Damage.Systems;
|
||||||
|
using Content.Shared.Damage.Components;
|
||||||
|
|
||||||
namespace Content.Server.Light.EntitySystems
|
namespace Content.Server.Light.EntitySystems
|
||||||
{
|
{
|
||||||
@@ -33,11 +34,8 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
public sealed class PoweredLightSystem : EntitySystem
|
public sealed class PoweredLightSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
|
||||||
[Dependency] private readonly SharedAmbientSoundSystem _ambientSystem = default!;
|
[Dependency] private readonly SharedAmbientSoundSystem _ambientSystem = default!;
|
||||||
[Dependency] private readonly LightBulbSystem _bulbSystem = default!;
|
[Dependency] private readonly LightBulbSystem _bulbSystem = default!;
|
||||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
|
||||||
[Dependency] private readonly IAdminLogManager _adminLogger= default!;
|
|
||||||
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
||||||
[Dependency] private readonly DeviceLinkSystem _signalSystem = default!;
|
[Dependency] private readonly DeviceLinkSystem _signalSystem = default!;
|
||||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||||
@@ -45,7 +43,7 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
[Dependency] private readonly PointLightSystem _pointLight = default!;
|
[Dependency] private readonly PointLightSystem _pointLight = default!;
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
[Dependency] private readonly DamageOnInteractSystem _damageOnInteractSystem = default!;
|
||||||
|
|
||||||
private static readonly TimeSpan ThunkDelay = TimeSpan.FromSeconds(2);
|
private static readonly TimeSpan ThunkDelay = TimeSpan.FromSeconds(2);
|
||||||
public const string LightBulbContainer = "light_bulb";
|
public const string LightBulbContainer = "light_bulb";
|
||||||
@@ -106,40 +104,7 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
if (bulbUid == null)
|
if (bulbUid == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// check if it's possible to apply burn damage to user
|
|
||||||
var userUid = args.User;
|
var userUid = args.User;
|
||||||
if (EntityManager.TryGetComponent(bulbUid.Value, out LightBulbComponent? lightBulb))
|
|
||||||
{
|
|
||||||
// get users heat resistance
|
|
||||||
var res = int.MinValue;
|
|
||||||
if (_inventory.TryGetSlotEntity(userUid, "gloves", out var slotEntity) &&
|
|
||||||
TryComp<GloveHeatResistanceComponent>(slotEntity, out var gloves))
|
|
||||||
{
|
|
||||||
res = gloves.HeatResistance;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check heat resistance against user
|
|
||||||
var burnedHand = light.CurrentLit && res < lightBulb.BurningTemperature;
|
|
||||||
if (burnedHand)
|
|
||||||
{
|
|
||||||
var damage = _damageableSystem.TryChangeDamage(userUid, light.Damage, origin: userUid);
|
|
||||||
|
|
||||||
// If damage is null then the entity could not take heat damage so they did not get burned.
|
|
||||||
if (damage != null)
|
|
||||||
{
|
|
||||||
|
|
||||||
var burnMsg = Loc.GetString("powered-light-component-burn-hand");
|
|
||||||
_popupSystem.PopupEntity(burnMsg, uid, userUid);
|
|
||||||
_adminLogger.Add(LogType.Damaged, $"{ToPrettyString(args.User):user} burned their hand on {ToPrettyString(args.Target):target} and received {damage.GetTotal():damage} damage");
|
|
||||||
_audio.PlayEntity(light.BurnHandSound, Filter.Pvs(uid), uid, true);
|
|
||||||
|
|
||||||
args.Handled = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//removing a broken/burned bulb, so allow instant removal
|
//removing a broken/burned bulb, so allow instant removal
|
||||||
if(TryComp<LightBulbComponent>(bulbUid.Value, out var bulb) && bulb.State != LightBulbState.Normal)
|
if(TryComp<LightBulbComponent>(bulbUid.Value, out var bulb) && bulb.State != LightBulbState.Normal)
|
||||||
{
|
{
|
||||||
@@ -435,6 +400,10 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
if (softness != null)
|
if (softness != null)
|
||||||
_pointLight.SetSoftness(uid, (float) softness, pointLight);
|
_pointLight.SetSoftness(uid, (float) softness, pointLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// light bulbs burn your hands!
|
||||||
|
if (TryComp<DamageOnInteractComponent>(uid, out var damageOnInteractComp))
|
||||||
|
_damageOnInteractSystem.SetIsDamageActiveTo((uid, damageOnInteractComp), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ToggleLight(EntityUid uid, PoweredLightComponent? light = null)
|
public void ToggleLight(EntityUid uid, PoweredLightComponent? light = null)
|
||||||
|
|||||||
@@ -202,20 +202,6 @@ public sealed partial class AnomalyComponent : Component
|
|||||||
public float GrowingPointMultiplier = 1.5f;
|
public float GrowingPointMultiplier = 1.5f;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The amount of damage dealt when either a player touches the anomaly
|
|
||||||
/// directly or by hitting the anomaly.
|
|
||||||
/// </summary>
|
|
||||||
[DataField(required: true)]
|
|
||||||
public DamageSpecifier AnomalyContactDamage = default!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The sound effect played when a player
|
|
||||||
/// burns themselves on an anomaly via contact.
|
|
||||||
/// </summary>
|
|
||||||
[DataField]
|
|
||||||
public SoundSpecifier AnomalyContactDamageSound = new SoundPathSpecifier("/Audio/Effects/lightburn.ogg");
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A prototype entity that appears when an anomaly supercrit collapse.
|
/// A prototype entity that appears when an anomaly supercrit collapse.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ public abstract class SharedAnomalySystem : EntitySystem
|
|||||||
[Dependency] private readonly INetManager _net = default!;
|
[Dependency] private readonly INetManager _net = default!;
|
||||||
[Dependency] protected readonly IRobustRandom Random = default!;
|
[Dependency] protected readonly IRobustRandom Random = default!;
|
||||||
[Dependency] protected readonly ISharedAdminLogManager AdminLog = default!;
|
[Dependency] protected readonly ISharedAdminLogManager AdminLog = default!;
|
||||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
|
||||||
[Dependency] protected readonly SharedAudioSystem Audio = default!;
|
[Dependency] protected readonly SharedAudioSystem Audio = default!;
|
||||||
[Dependency] protected readonly SharedAppearanceSystem Appearance = default!;
|
[Dependency] protected readonly SharedAppearanceSystem Appearance = default!;
|
||||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||||
@@ -42,26 +41,10 @@ public abstract class SharedAnomalySystem : EntitySystem
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<AnomalyComponent, InteractHandEvent>(OnInteractHand);
|
|
||||||
SubscribeLocalEvent<AnomalyComponent, AttackedEvent>(OnAttacked);
|
|
||||||
SubscribeLocalEvent<AnomalyComponent, MeleeThrowOnHitStartEvent>(OnAnomalyThrowStart);
|
SubscribeLocalEvent<AnomalyComponent, MeleeThrowOnHitStartEvent>(OnAnomalyThrowStart);
|
||||||
SubscribeLocalEvent<AnomalyComponent, MeleeThrowOnHitEndEvent>(OnAnomalyThrowEnd);
|
SubscribeLocalEvent<AnomalyComponent, MeleeThrowOnHitEndEvent>(OnAnomalyThrowEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnInteractHand(EntityUid uid, AnomalyComponent component, InteractHandEvent args)
|
|
||||||
{
|
|
||||||
DoAnomalyBurnDamage(uid, args.User, component);
|
|
||||||
args.Handled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnAttacked(EntityUid uid, AnomalyComponent component, AttackedEvent args)
|
|
||||||
{
|
|
||||||
if (HasComp<CorePoweredThrowerComponent>(args.Used))
|
|
||||||
return;
|
|
||||||
|
|
||||||
DoAnomalyBurnDamage(uid, args.User, component);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnAnomalyThrowStart(Entity<AnomalyComponent> ent, ref MeleeThrowOnHitStartEvent args)
|
private void OnAnomalyThrowStart(Entity<AnomalyComponent> ent, ref MeleeThrowOnHitStartEvent args)
|
||||||
{
|
{
|
||||||
if (!TryComp<CorePoweredThrowerComponent>(args.Used, out var corePowered) || !TryComp<PhysicsComponent>(ent, out var body))
|
if (!TryComp<CorePoweredThrowerComponent>(args.Used, out var corePowered) || !TryComp<PhysicsComponent>(ent, out var body))
|
||||||
@@ -75,15 +58,6 @@ public abstract class SharedAnomalySystem : EntitySystem
|
|||||||
_physics.SetBodyType(ent, BodyType.Static);
|
_physics.SetBodyType(ent, BodyType.Static);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DoAnomalyBurnDamage(EntityUid source, EntityUid target, AnomalyComponent component)
|
|
||||||
{
|
|
||||||
_damageable.TryChangeDamage(target, component.AnomalyContactDamage, true);
|
|
||||||
if (!Timing.IsFirstTimePredicted || _net.IsServer)
|
|
||||||
return;
|
|
||||||
Audio.PlayPvs(component.AnomalyContactDamageSound, source);
|
|
||||||
Popup.PopupEntity(Loc.GetString("anomaly-component-contact-damage"), target, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DoAnomalyPulse(EntityUid uid, AnomalyComponent? component = null)
|
public void DoAnomalyPulse(EntityUid uid, AnomalyComponent? component = null)
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref component))
|
if (!Resolve(uid, ref component))
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Damage.Components;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This component is added to entities that you want to damage the player
|
||||||
|
/// if the player interacts with it. For example, if a player tries touching
|
||||||
|
/// a hot light bulb or an anomaly. This damage can be cancelled if the user
|
||||||
|
/// has a component that protects them from this.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
|
public sealed partial class DamageOnAttackedComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// How much damage to apply to the person making contact
|
||||||
|
/// </summary>
|
||||||
|
[DataField(required: true), AutoNetworkedField]
|
||||||
|
public DamageSpecifier Damage = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the damage should be resisted by a person's armor values
|
||||||
|
/// and the <see cref="DamageOnAttackedProtectionComponent"/>
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public bool IgnoreResistances = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// What kind of localized text should pop up when they interact with the entity
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public LocId? PopupText;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sound that should be made when interacting with the entity
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public SoundSpecifier InteractSound = new SoundPathSpecifier("/Audio/Effects/lightburn.ogg");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generic boolean to toggle the damage application on and off
|
||||||
|
/// This is useful for things that can be toggled on or off, like a stovetop
|
||||||
|
/// </summary>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public bool IsDamageActive = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using Content.Shared.Inventory;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Damage.Components;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This component is added to entities to protect them from being damaged
|
||||||
|
/// when attacking objects with the <see cref="DamageOnAttackedComponent"/>
|
||||||
|
/// If the entity has sufficient protection, the entity will take no damage.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent]
|
||||||
|
public sealed partial class DamageOnAttackedProtectionComponent : Component, IClothingSlots
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// How much and what kind of damage to protect the user from
|
||||||
|
/// when interacting with something with <see cref="DamageOnInteractComponent"/>
|
||||||
|
/// </summary>
|
||||||
|
[DataField(required: true)]
|
||||||
|
public DamageModifierSet DamageProtection = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Only protects if the item is in the correct slot
|
||||||
|
/// i.e. having gloves in your pocket doesn't protect you, it has to be on your hands
|
||||||
|
/// Set slots to NONE if it works while you hold the item in your main hand
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public SlotFlags Slots { get; set; } = SlotFlags.WITHOUT_POCKET;
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Damage.Components;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This component is added to entities that you want to damage the player
|
||||||
|
/// if the player interacts with it. For example, if a player tries touching
|
||||||
|
/// a hot light bulb or an anomaly. This damage can be cancelled if the user
|
||||||
|
/// has a component that protects them from this.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
|
public sealed partial class DamageOnInteractComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// How much damage to apply to the person making contact
|
||||||
|
/// </summary>
|
||||||
|
[DataField(required: true), AutoNetworkedField]
|
||||||
|
public DamageSpecifier Damage = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the damage should be resisted by a person's armor values
|
||||||
|
/// and the <see cref="DamageOnInteractProtectionComponent"/>
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public bool IgnoreResistances;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// What kind of localized text should pop up when they interact with the entity
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public LocId? PopupText;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sound that should be made when interacting with the entity
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public SoundSpecifier InteractSound = new SoundPathSpecifier("/Audio/Effects/lightburn.ogg");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generic boolean to toggle the damage application on and off
|
||||||
|
/// This is useful for things that can be toggled on or off, like a stovetop
|
||||||
|
/// </summary>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public bool IsDamageActive = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using Content.Shared.Inventory;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Damage.Components;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This component is added to entities to protect them from being damaged
|
||||||
|
/// when interacting with objects with the <see cref="DamageOnInteractComponent"/>
|
||||||
|
/// If the entity has sufficient protection, interaction with the object is not cancelled.
|
||||||
|
/// This allows the user to do things like remove a lightbulb.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent]
|
||||||
|
public sealed partial class DamageOnInteractProtectionComponent : Component, IClothingSlots
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// How much and what kind of damage to protect the user from
|
||||||
|
/// when interacting with something with <see cref="DamageOnInteractComponent"/>
|
||||||
|
/// </summary>
|
||||||
|
[DataField(required: true)]
|
||||||
|
public DamageModifierSet DamageProtection = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Only protects if the item is in the correct slot
|
||||||
|
/// i.e. having gloves in your pocket doesn't protect you, it has to be on your hands
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public SlotFlags Slots { get; set; } = SlotFlags.GLOVES;
|
||||||
|
}
|
||||||
99
Content.Shared/Damage/Systems/DamageOnAttackedSystem.cs
Normal file
99
Content.Shared/Damage/Systems/DamageOnAttackedSystem.cs
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
using Content.Shared.Administration.Logs;
|
||||||
|
using Content.Shared.Damage.Components;
|
||||||
|
using Content.Shared.Database;
|
||||||
|
using Content.Shared.Hands.Components;
|
||||||
|
using Content.Shared.Hands.EntitySystems;
|
||||||
|
using Content.Shared.Inventory;
|
||||||
|
using Content.Shared.Popups;
|
||||||
|
using Content.Shared.Weapons.Melee.Events;
|
||||||
|
using Robust.Shared.Audio.Systems;
|
||||||
|
using Robust.Shared.Network;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
|
namespace Content.Shared.Damage.Systems;
|
||||||
|
|
||||||
|
public sealed class DamageOnAttackedSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||||
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
[Dependency] private readonly INetManager _net = default!;
|
||||||
|
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||||
|
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||||
|
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||||
|
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
||||||
|
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<DamageOnAttackedComponent, AttackedEvent>(OnAttacked);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Damages the user that attacks the entity and potentially
|
||||||
|
/// plays a sound or pops up text in response
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">The entity being hit</param>
|
||||||
|
/// <param name="args">Contains the user that hit the entity</param>
|
||||||
|
private void OnAttacked(Entity<DamageOnAttackedComponent> entity, ref AttackedEvent args)
|
||||||
|
{
|
||||||
|
if (!entity.Comp.IsDamageActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var totalDamage = entity.Comp.Damage;
|
||||||
|
|
||||||
|
if (!entity.Comp.IgnoreResistances)
|
||||||
|
{
|
||||||
|
// try to get the damage on attacked protection component from something the entity has in their inventory
|
||||||
|
_inventorySystem.TryGetInventoryEntity<DamageOnAttackedProtectionComponent>(args.User, out var protectiveEntity);
|
||||||
|
|
||||||
|
// if comp is null that means the user didn't have anything equipped that protected them
|
||||||
|
// let's check their hands to see if the thing they attacked with gives them protection, like the GORILLA gauntlet
|
||||||
|
if (protectiveEntity.Comp == null && TryComp<HandsComponent>(args.User, out var handsComp))
|
||||||
|
{
|
||||||
|
if (_handsSystem.TryGetActiveItem((args.User, handsComp), out var itemInHand) &&
|
||||||
|
TryComp<DamageOnAttackedProtectionComponent>(itemInHand, out var itemProtectComp)
|
||||||
|
&& itemProtectComp.Slots == SlotFlags.NONE)
|
||||||
|
{
|
||||||
|
protectiveEntity = (itemInHand.Value, itemProtectComp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if comp is null, that means both the inventory and hands had nothing to protect them
|
||||||
|
// let's check if the entity itself has the protective comp, like with borgs
|
||||||
|
if (protectiveEntity.Comp == null &&
|
||||||
|
TryComp<DamageOnAttackedProtectionComponent>(args.User, out var protectiveComp))
|
||||||
|
{
|
||||||
|
protectiveEntity = (args.User, protectiveComp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if comp is NOT NULL that means they have damage protection!
|
||||||
|
if (protectiveEntity.Comp != null)
|
||||||
|
{
|
||||||
|
totalDamage = DamageSpecifier.ApplyModifierSet(totalDamage, protectiveEntity.Comp.DamageProtection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
totalDamage = _damageableSystem.TryChangeDamage(args.User, totalDamage, entity.Comp.IgnoreResistances, origin: entity);
|
||||||
|
|
||||||
|
if (totalDamage != null && totalDamage.AnyPositive())
|
||||||
|
{
|
||||||
|
_adminLogger.Add(LogType.Damaged, $"{ToPrettyString(args.User):user} injured themselves by attacking {ToPrettyString(entity):target} and received {totalDamage.GetTotal():damage} damage");
|
||||||
|
_audioSystem.PlayPredicted(entity.Comp.InteractSound, entity, args.User);
|
||||||
|
|
||||||
|
if (entity.Comp.PopupText != null)
|
||||||
|
_popupSystem.PopupClient(Loc.GetString(entity.Comp.PopupText), args.User, args.User);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetIsDamageActiveTo(Entity<DamageOnAttackedComponent> entity, bool mode)
|
||||||
|
{
|
||||||
|
if (entity.Comp.IsDamageActive == mode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
entity.Comp.IsDamageActive = mode;
|
||||||
|
Dirty(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
85
Content.Shared/Damage/Systems/DamageOnInteractSystem.cs
Normal file
85
Content.Shared/Damage/Systems/DamageOnInteractSystem.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
using Content.Shared.Administration.Logs;
|
||||||
|
using Content.Shared.Damage.Components;
|
||||||
|
using Content.Shared.Database;
|
||||||
|
using Content.Shared.Interaction;
|
||||||
|
using Content.Shared.Inventory;
|
||||||
|
using Content.Shared.Popups;
|
||||||
|
using Robust.Shared.Audio.Systems;
|
||||||
|
using Robust.Shared.Network;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
|
namespace Content.Shared.Damage.Systems;
|
||||||
|
|
||||||
|
public sealed class DamageOnInteractSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||||
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
[Dependency] private readonly INetManager _net = default!;
|
||||||
|
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||||
|
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||||
|
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||||
|
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<DamageOnInteractComponent, InteractHandEvent>(OnHandInteract);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Damages the user that interacts with the entity with an empty hand and
|
||||||
|
/// plays a sound or pops up text in response. If the user does not have
|
||||||
|
/// proper protection, the user will only be damaged and other interactions
|
||||||
|
/// will be cancelled.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">The entity being interacted with</param>
|
||||||
|
/// <param name="args">Contains the user that interacted with the entity</param>
|
||||||
|
private void OnHandInteract(Entity<DamageOnInteractComponent> entity, ref InteractHandEvent args)
|
||||||
|
{
|
||||||
|
if (!entity.Comp.IsDamageActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var totalDamage = entity.Comp.Damage;
|
||||||
|
|
||||||
|
if (!entity.Comp.IgnoreResistances)
|
||||||
|
{
|
||||||
|
// try to get damage on interact protection from either the inventory slots of the entity
|
||||||
|
_inventorySystem.TryGetInventoryEntity<DamageOnInteractProtectionComponent>(args.User, out var protectiveEntity);
|
||||||
|
|
||||||
|
// or checking the entity for the comp itself if the inventory didn't work
|
||||||
|
if (protectiveEntity.Comp == null && TryComp<DamageOnInteractProtectionComponent>(args.User, out var protectiveComp))
|
||||||
|
{
|
||||||
|
protectiveEntity = (args.User, protectiveComp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if protectiveComp isn't null after all that, it means the user has protection,
|
||||||
|
// so let's calculate how much they resist
|
||||||
|
if (protectiveEntity.Comp != null)
|
||||||
|
{
|
||||||
|
totalDamage = DamageSpecifier.ApplyModifierSet(totalDamage, protectiveEntity.Comp.DamageProtection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
totalDamage = _damageableSystem.TryChangeDamage(args.User, totalDamage, origin: args.Target);
|
||||||
|
|
||||||
|
if (totalDamage != null && totalDamage.AnyPositive())
|
||||||
|
{
|
||||||
|
args.Handled = true;
|
||||||
|
_adminLogger.Add(LogType.Damaged, $"{ToPrettyString(args.User):user} injured their hand by interacting with {ToPrettyString(args.Target):target} and received {totalDamage.GetTotal():damage} damage");
|
||||||
|
_audioSystem.PlayPredicted(entity.Comp.InteractSound, args.Target, args.User);
|
||||||
|
|
||||||
|
if (entity.Comp.PopupText != null)
|
||||||
|
_popupSystem.PopupClient(Loc.GetString(entity.Comp.PopupText), args.User, args.User);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetIsDamageActiveTo(Entity<DamageOnInteractComponent> entity, bool mode)
|
||||||
|
{
|
||||||
|
if (entity.Comp.IsDamageActive == mode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
entity.Comp.IsDamageActive = mode;
|
||||||
|
Dirty(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,7 +30,7 @@ public partial class InventorySystem : EntitySystem
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tries to find an entity in the specified slot with the specified component.
|
/// Tries to find an entity in the specified slot with the specified component.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool TryGetInventoryEntity<T>(Entity<InventoryComponent?> entity, out EntityUid targetUid)
|
public bool TryGetInventoryEntity<T>(Entity<InventoryComponent?> entity, out Entity<T?> target)
|
||||||
where T : IComponent, IClothingSlots
|
where T : IComponent, IClothingSlots
|
||||||
{
|
{
|
||||||
if (TryGetContainerSlotEnumerator(entity.Owner, out var containerSlotEnumerator))
|
if (TryGetContainerSlotEnumerator(entity.Owner, out var containerSlotEnumerator))
|
||||||
@@ -43,12 +43,12 @@ public partial class InventorySystem : EntitySystem
|
|||||||
if ((((IClothingSlots) required).Slots & slot.SlotFlags) == 0x0)
|
if ((((IClothingSlots) required).Slots & slot.SlotFlags) == 0x0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
targetUid = item;
|
target = (item, required);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
targetUid = EntityUid.Invalid;
|
target = EntityUid.Invalid;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,10 @@
|
|||||||
tags:
|
tags:
|
||||||
- ClothMade
|
- ClothMade
|
||||||
- WhitelistChameleon
|
- WhitelistChameleon
|
||||||
|
- type: DamageOnInteractProtection
|
||||||
|
damageProtection:
|
||||||
|
flatReductions:
|
||||||
|
Heat: 5 # the average lightbulb only does around four damage!
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
abstract: true
|
abstract: true
|
||||||
|
|||||||
@@ -283,8 +283,6 @@
|
|||||||
color: "#535353"
|
color: "#535353"
|
||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Hands/Gloves/Color/black.rsi
|
sprite: Clothing/Hands/Gloves/Color/black.rsi
|
||||||
- type: GloveHeatResistance
|
|
||||||
heatResistance: 1400
|
|
||||||
- type: Butcherable
|
- type: Butcherable
|
||||||
butcheringType: Knife
|
butcheringType: Knife
|
||||||
spawned:
|
spawned:
|
||||||
@@ -305,8 +303,6 @@
|
|||||||
sprite: Clothing/Hands/Gloves/Color/yellow.rsi
|
sprite: Clothing/Hands/Gloves/Color/yellow.rsi
|
||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Hands/Gloves/Color/yellow.rsi
|
sprite: Clothing/Hands/Gloves/Color/yellow.rsi
|
||||||
- type: GloveHeatResistance
|
|
||||||
heatResistance: 1400
|
|
||||||
- type: Butcherable
|
- type: Butcherable
|
||||||
butcheringType: Knife
|
butcheringType: Knife
|
||||||
spawned:
|
spawned:
|
||||||
@@ -323,9 +319,6 @@
|
|||||||
name: budget insulated gloves
|
name: budget insulated gloves
|
||||||
description: These gloves are cheap knockoffs of the coveted ones - no way this can end badly.
|
description: These gloves are cheap knockoffs of the coveted ones - no way this can end badly.
|
||||||
components:
|
components:
|
||||||
- type: GloveHeatResistance
|
|
||||||
# can't take out lights using budgets
|
|
||||||
heatResistance: 0
|
|
||||||
- type: RandomInsulation
|
- type: RandomInsulation
|
||||||
# Why repeated numbers? So some numbers are more common, of course!
|
# Why repeated numbers? So some numbers are more common, of course!
|
||||||
list:
|
list:
|
||||||
|
|||||||
@@ -103,8 +103,6 @@
|
|||||||
sprite: Clothing/Hands/Gloves/captain.rsi
|
sprite: Clothing/Hands/Gloves/captain.rsi
|
||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Hands/Gloves/captain.rsi
|
sprite: Clothing/Hands/Gloves/captain.rsi
|
||||||
- type: GloveHeatResistance
|
|
||||||
heatResistance: 1400
|
|
||||||
- type: Insulated
|
- type: Insulated
|
||||||
- type: Fiber
|
- type: Fiber
|
||||||
fiberMaterial: fibers-durathread
|
fiberMaterial: fibers-durathread
|
||||||
@@ -169,8 +167,6 @@
|
|||||||
sprite: Clothing/Hands/Gloves/leather.rsi
|
sprite: Clothing/Hands/Gloves/leather.rsi
|
||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Hands/Gloves/leather.rsi
|
sprite: Clothing/Hands/Gloves/leather.rsi
|
||||||
- type: GloveHeatResistance
|
|
||||||
heatResistance: 1400
|
|
||||||
- type: Fiber
|
- type: Fiber
|
||||||
fiberMaterial: fibers-leather
|
fiberMaterial: fibers-leather
|
||||||
fiberColor: fibers-brown
|
fiberColor: fibers-brown
|
||||||
@@ -225,8 +221,6 @@
|
|||||||
enum.ToggleVisuals.Layer:
|
enum.ToggleVisuals.Layer:
|
||||||
True: {state: icon-green}
|
True: {state: icon-green}
|
||||||
False: {state: icon}
|
False: {state: icon}
|
||||||
- type: GloveHeatResistance
|
|
||||||
heatResistance: 1400
|
|
||||||
- type: Insulated
|
- type: Insulated
|
||||||
- type: Fiber
|
- type: Fiber
|
||||||
fiberMaterial: fibers-nanomachines
|
fiberMaterial: fibers-nanomachines
|
||||||
@@ -270,8 +264,6 @@
|
|||||||
sprite: Clothing/Hands/Gloves/combat.rsi
|
sprite: Clothing/Hands/Gloves/combat.rsi
|
||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Hands/Gloves/combat.rsi
|
sprite: Clothing/Hands/Gloves/combat.rsi
|
||||||
- type: GloveHeatResistance
|
|
||||||
heatResistance: 1400
|
|
||||||
- type: Insulated
|
- type: Insulated
|
||||||
- type: Fiber
|
- type: Fiber
|
||||||
fiberMaterial: fibers-insulative
|
fiberMaterial: fibers-insulative
|
||||||
@@ -287,8 +279,6 @@
|
|||||||
sprite: Clothing/Hands/Gloves/tacticalmaidgloves.rsi
|
sprite: Clothing/Hands/Gloves/tacticalmaidgloves.rsi
|
||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Hands/Gloves/tacticalmaidgloves.rsi
|
sprite: Clothing/Hands/Gloves/tacticalmaidgloves.rsi
|
||||||
- type: GloveHeatResistance
|
|
||||||
heatResistance: 1400
|
|
||||||
- type: Insulated
|
- type: Insulated
|
||||||
- type: Fiber
|
- type: Fiber
|
||||||
fiberColor: fibers-black
|
fiberColor: fibers-black
|
||||||
@@ -324,6 +314,10 @@
|
|||||||
- type: Fiber
|
- type: Fiber
|
||||||
fiberMaterial: fibers-synthetic
|
fiberMaterial: fibers-synthetic
|
||||||
fiberColor: fibers-black
|
fiberColor: fibers-black
|
||||||
|
- type: DamageOnInteractProtection
|
||||||
|
damageProtection:
|
||||||
|
flatReductions:
|
||||||
|
Heat: 0 # no protection
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingHandsBase
|
parent: ClothingHandsBase
|
||||||
@@ -338,6 +332,10 @@
|
|||||||
- type: Fiber
|
- type: Fiber
|
||||||
fiberMaterial: fibers-insulative
|
fiberMaterial: fibers-insulative
|
||||||
fiberColor: fibers-yellow
|
fiberColor: fibers-yellow
|
||||||
|
- type: DamageOnInteractProtection
|
||||||
|
damageProtection:
|
||||||
|
flatReductions:
|
||||||
|
Heat: 0 # no protection
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingHandsButcherable
|
parent: ClothingHandsButcherable
|
||||||
@@ -352,6 +350,10 @@
|
|||||||
- type: Fiber
|
- type: Fiber
|
||||||
fiberMaterial: fibers-insulative
|
fiberMaterial: fibers-insulative
|
||||||
fiberColor: fibers-olive
|
fiberColor: fibers-olive
|
||||||
|
- type: DamageOnInteractProtection
|
||||||
|
damageProtection:
|
||||||
|
flatReductions:
|
||||||
|
Heat: 0 # no protection
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
# Intentionally named after regular gloves, they're meant to be sneaky.
|
# Intentionally named after regular gloves, they're meant to be sneaky.
|
||||||
|
|||||||
@@ -136,6 +136,11 @@
|
|||||||
- WhitelistChameleon
|
- WhitelistChameleon
|
||||||
- type: ClothingRequiredStepTriggerImmune
|
- type: ClothingRequiredStepTriggerImmune
|
||||||
slots: WITHOUT_POCKET
|
slots: WITHOUT_POCKET
|
||||||
|
- type: DamageOnInteractProtection
|
||||||
|
damageProtection:
|
||||||
|
flatReductions:
|
||||||
|
Heat: 10 # the average lightbulb only does around four damage!
|
||||||
|
slots: OUTERCLOTHING
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
abstract: true
|
abstract: true
|
||||||
@@ -156,6 +161,11 @@
|
|||||||
size: Huge
|
size: Huge
|
||||||
- type: ClothingRequiredStepTriggerImmune
|
- type: ClothingRequiredStepTriggerImmune
|
||||||
slots: WITHOUT_POCKET
|
slots: WITHOUT_POCKET
|
||||||
|
- type: DamageOnInteractProtection
|
||||||
|
damageProtection:
|
||||||
|
flatReductions:
|
||||||
|
Heat: 10 # the average lightbulb only does around four damage!
|
||||||
|
slots: OUTERCLOTHING
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingOuterBase
|
parent: ClothingOuterBase
|
||||||
|
|||||||
@@ -230,6 +230,10 @@
|
|||||||
- Cyborgs
|
- Cyborgs
|
||||||
- Robotics
|
- Robotics
|
||||||
- type: StepTriggerImmune
|
- type: StepTriggerImmune
|
||||||
|
- type: DamageOnInteractProtection
|
||||||
|
damageProtection:
|
||||||
|
flatReductions:
|
||||||
|
Heat: 10 # capable of touching light bulbs and stoves without feeling pain!
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
abstract: true
|
abstract: true
|
||||||
|
|||||||
@@ -110,9 +110,6 @@
|
|||||||
collection: BananiumHorn
|
collection: BananiumHorn
|
||||||
params:
|
params:
|
||||||
volume: 5
|
volume: 5
|
||||||
anomalyContactDamage:
|
|
||||||
types:
|
|
||||||
Radiation: 10
|
|
||||||
- type: Input
|
- type: Input
|
||||||
context: "human"
|
context: "human"
|
||||||
- type: Bloodstream
|
- type: Bloodstream
|
||||||
@@ -158,9 +155,6 @@
|
|||||||
suffix: "Ice"
|
suffix: "Ice"
|
||||||
components:
|
components:
|
||||||
- type: Anomaly
|
- type: Anomaly
|
||||||
anomalyContactDamage:
|
|
||||||
types:
|
|
||||||
Cold: 10
|
|
||||||
- type: ExplosionAnomaly
|
- type: ExplosionAnomaly
|
||||||
supercriticalExplosion: Cryo
|
supercriticalExplosion: Cryo
|
||||||
explosionTotalIntensity: 1000
|
explosionTotalIntensity: 1000
|
||||||
|
|||||||
@@ -147,3 +147,10 @@
|
|||||||
- type: ContainerContainer
|
- type: ContainerContainer
|
||||||
containers:
|
containers:
|
||||||
core_slot: !type:ContainerSlot
|
core_slot: !type:ContainerSlot
|
||||||
|
- type: DamageOnAttackedProtection
|
||||||
|
damageProtection:
|
||||||
|
flatReductions:
|
||||||
|
Heat: 100
|
||||||
|
Cold: 100
|
||||||
|
Radiation: 100
|
||||||
|
slots: NONE
|
||||||
|
|||||||
@@ -154,7 +154,7 @@
|
|||||||
- type: DisarmMalus
|
- type: DisarmMalus
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: The Throngler
|
name: Throngler
|
||||||
parent: BaseSword
|
parent: BaseSword
|
||||||
id: Throngler
|
id: Throngler
|
||||||
description: Why would you make this?
|
description: Why would you make this?
|
||||||
@@ -180,3 +180,6 @@
|
|||||||
size: Ginormous
|
size: Ginormous
|
||||||
sprite: Objects/Weapons/Melee/Throngler-in-hand.rsi
|
sprite: Objects/Weapons/Melee/Throngler-in-hand.rsi
|
||||||
- type: DisarmMalus
|
- type: DisarmMalus
|
||||||
|
- type: Grammar
|
||||||
|
attributes:
|
||||||
|
proper: true
|
||||||
|
|||||||
@@ -89,9 +89,6 @@
|
|||||||
enabled: false
|
enabled: false
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
bulb: Tube
|
bulb: Tube
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 2
|
|
||||||
- type: ContainerContainer
|
- type: ContainerContainer
|
||||||
containers:
|
containers:
|
||||||
light_bulb: !type:ContainerSlot
|
light_bulb: !type:ContainerSlot
|
||||||
@@ -117,6 +114,11 @@
|
|||||||
on: base
|
on: base
|
||||||
broken: broken
|
broken: broken
|
||||||
burned: burned
|
burned: burned
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 2
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: Poweredlight
|
id: Poweredlight
|
||||||
@@ -130,15 +132,17 @@
|
|||||||
enabled: true
|
enabled: true
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
hasLampOnSpawn: LightTube
|
hasLampOnSpawn: LightTube
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 2
|
|
||||||
- type: AmbientOnPowered
|
- type: AmbientOnPowered
|
||||||
- type: AmbientSound
|
- type: AmbientSound
|
||||||
volume: -15
|
volume: -15
|
||||||
range: 2
|
range: 2
|
||||||
sound:
|
sound:
|
||||||
path: /Audio/Ambience/Objects/light_hum.ogg
|
path: /Audio/Ambience/Objects/light_hum.ogg
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 2
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
#LED lights
|
#LED lights
|
||||||
- type: entity
|
- type: entity
|
||||||
@@ -149,14 +153,16 @@
|
|||||||
components:
|
components:
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
hasLampOnSpawn: LedLightTube
|
hasLampOnSpawn: LedLightTube
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 1 #LEDs don't get as hot
|
|
||||||
- type: PointLight
|
- type: PointLight
|
||||||
radius: 15
|
radius: 15
|
||||||
energy: 1
|
energy: 1
|
||||||
softness: 0.9
|
softness: 0.9
|
||||||
color: "#EEEEFF"
|
color: "#EEEEFF"
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 1 # LEDs don't get as hot
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: AlwaysPoweredWallLight
|
parent: AlwaysPoweredWallLight
|
||||||
@@ -178,9 +184,11 @@
|
|||||||
components:
|
components:
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
hasLampOnSpawn: ExteriorLightTube
|
hasLampOnSpawn: ExteriorLightTube
|
||||||
|
- type: DamageOnInteract
|
||||||
damage:
|
damage:
|
||||||
types:
|
types:
|
||||||
Heat: 4 #brighter light gets hotter
|
Heat: 4 # brighter light gets hotter
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: AlwaysPoweredWallLight
|
parent: AlwaysPoweredWallLight
|
||||||
@@ -202,14 +210,16 @@
|
|||||||
components:
|
components:
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
hasLampOnSpawn: SodiumLightTube
|
hasLampOnSpawn: SodiumLightTube
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 2
|
|
||||||
- type: PointLight
|
- type: PointLight
|
||||||
radius: 10
|
radius: 10
|
||||||
energy: 2.5
|
energy: 2.5
|
||||||
softness: 0.9
|
softness: 0.9
|
||||||
color: "#FFAF38"
|
color: "#FFAF38"
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 2
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: AlwaysPoweredWallLight
|
parent: AlwaysPoweredWallLight
|
||||||
@@ -289,9 +299,6 @@
|
|||||||
light_bulb: !type:ContainerSlot
|
light_bulb: !type:ContainerSlot
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
bulb: Bulb
|
bulb: Bulb
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 2
|
|
||||||
- type: ApcPowerReceiver
|
- type: ApcPowerReceiver
|
||||||
- type: ExtensionCableReceiver
|
- type: ExtensionCableReceiver
|
||||||
- type: DeviceNetwork
|
- type: DeviceNetwork
|
||||||
@@ -312,6 +319,11 @@
|
|||||||
- On
|
- On
|
||||||
- Off
|
- Off
|
||||||
- Toggle
|
- Toggle
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 2
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: PoweredLEDSmallLight
|
id: PoweredLEDSmallLight
|
||||||
@@ -328,9 +340,11 @@
|
|||||||
color: "#EEEEFF"
|
color: "#EEEEFF"
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
hasLampOnSpawn: LedLightBulb
|
hasLampOnSpawn: LedLightBulb
|
||||||
|
- type: DamageOnInteract
|
||||||
damage:
|
damage:
|
||||||
types:
|
types:
|
||||||
Heat: 1
|
Heat: 1
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: PoweredSmallLight
|
id: PoweredSmallLight
|
||||||
@@ -343,9 +357,11 @@
|
|||||||
enabled: true
|
enabled: true
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
hasLampOnSpawn: LightBulb
|
hasLampOnSpawn: LightBulb
|
||||||
|
- type: DamageOnInteract
|
||||||
damage:
|
damage:
|
||||||
types:
|
types:
|
||||||
Heat: 2
|
Heat: 2
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
#Emergency Lights
|
#Emergency Lights
|
||||||
- type: entity
|
- type: entity
|
||||||
@@ -398,14 +414,16 @@
|
|||||||
components:
|
components:
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
hasLampOnSpawn: LightTubeCrystalCyan
|
hasLampOnSpawn: LightTubeCrystalCyan
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 2
|
|
||||||
- type: PointLight
|
- type: PointLight
|
||||||
radius: 8
|
radius: 8
|
||||||
energy: 3
|
energy: 3
|
||||||
softness: 0.5
|
softness: 0.5
|
||||||
color: "#47f8ff"
|
color: "#47f8ff"
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 2
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: AlwaysPoweredlightCyan
|
id: AlwaysPoweredlightCyan
|
||||||
@@ -425,14 +443,16 @@
|
|||||||
components:
|
components:
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
hasLampOnSpawn: LightTubeCrystalBlue
|
hasLampOnSpawn: LightTubeCrystalBlue
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 2
|
|
||||||
- type: PointLight
|
- type: PointLight
|
||||||
radius: 8
|
radius: 8
|
||||||
energy: 3
|
energy: 3
|
||||||
softness: 0.5
|
softness: 0.5
|
||||||
color: "#39a1ff"
|
color: "#39a1ff"
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 2
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: AlwaysPoweredlightBlue
|
id: AlwaysPoweredlightBlue
|
||||||
@@ -452,14 +472,16 @@
|
|||||||
components:
|
components:
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
hasLampOnSpawn: LightTubeCrystalPink
|
hasLampOnSpawn: LightTubeCrystalPink
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 2
|
|
||||||
- type: PointLight
|
- type: PointLight
|
||||||
radius: 8
|
radius: 8
|
||||||
energy: 3
|
energy: 3
|
||||||
softness: 0.5
|
softness: 0.5
|
||||||
color: "#ff66cc"
|
color: "#ff66cc"
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 2
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: AlwaysPoweredlightPink
|
id: AlwaysPoweredlightPink
|
||||||
@@ -479,14 +501,16 @@
|
|||||||
components:
|
components:
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
hasLampOnSpawn: LightTubeCrystalOrange
|
hasLampOnSpawn: LightTubeCrystalOrange
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 2
|
|
||||||
- type: PointLight
|
- type: PointLight
|
||||||
radius: 8
|
radius: 8
|
||||||
energy: 3
|
energy: 3
|
||||||
softness: 0.5
|
softness: 0.5
|
||||||
color: "#ff8227"
|
color: "#ff8227"
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 2
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: AlwaysPoweredlightOrange
|
id: AlwaysPoweredlightOrange
|
||||||
@@ -506,14 +530,16 @@
|
|||||||
components:
|
components:
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
hasLampOnSpawn: LightTubeCrystalRed
|
hasLampOnSpawn: LightTubeCrystalRed
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 2
|
|
||||||
- type: PointLight
|
- type: PointLight
|
||||||
radius: 8
|
radius: 8
|
||||||
energy: 3
|
energy: 3
|
||||||
softness: 0.5
|
softness: 0.5
|
||||||
color: "#fb4747"
|
color: "#fb4747"
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 2
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: AlwaysPoweredlightRed
|
id: AlwaysPoweredlightRed
|
||||||
@@ -533,14 +559,16 @@
|
|||||||
components:
|
components:
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
hasLampOnSpawn: LightTubeCrystalGreen
|
hasLampOnSpawn: LightTubeCrystalGreen
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 2
|
|
||||||
- type: PointLight
|
- type: PointLight
|
||||||
radius: 8
|
radius: 8
|
||||||
energy: 3
|
energy: 3
|
||||||
softness: 0.5
|
softness: 0.5
|
||||||
color: "#52ff39"
|
color: "#52ff39"
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 2
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: AlwaysPoweredlightGreen
|
id: AlwaysPoweredlightGreen
|
||||||
|
|||||||
@@ -77,9 +77,6 @@
|
|||||||
enabled: false
|
enabled: false
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
bulb: Tube
|
bulb: Tube
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 2
|
|
||||||
- type: ContainerContainer
|
- type: ContainerContainer
|
||||||
containers:
|
containers:
|
||||||
light_bulb: !type:ContainerSlot
|
light_bulb: !type:ContainerSlot
|
||||||
@@ -108,6 +105,11 @@
|
|||||||
on: base
|
on: base
|
||||||
broken: broken
|
broken: broken
|
||||||
burned: burned
|
burned: burned
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 2
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: PoweredLightPostSmall
|
id: PoweredLightPostSmall
|
||||||
@@ -122,9 +124,6 @@
|
|||||||
enabled: true
|
enabled: true
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
hasLampOnSpawn: LightTube
|
hasLampOnSpawn: LightTube
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 2
|
|
||||||
- type: StaticPrice
|
- type: StaticPrice
|
||||||
price: 25
|
price: 25
|
||||||
- type: AmbientOnPowered
|
- type: AmbientOnPowered
|
||||||
@@ -133,6 +132,11 @@
|
|||||||
range: 3
|
range: 3
|
||||||
sound:
|
sound:
|
||||||
path: /Audio/Ambience/Objects/light_hum.ogg
|
path: /Audio/Ambience/Objects/light_hum.ogg
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 2
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: PoweredLEDLightPostSmall
|
id: PoweredLEDLightPostSmall
|
||||||
@@ -151,9 +155,6 @@
|
|||||||
color: "#EEEEFF"
|
color: "#EEEEFF"
|
||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
hasLampOnSpawn: LedLightTube
|
hasLampOnSpawn: LedLightTube
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 1
|
|
||||||
- type: StaticPrice
|
- type: StaticPrice
|
||||||
price: 25
|
price: 25
|
||||||
- type: AmbientOnPowered
|
- type: AmbientOnPowered
|
||||||
@@ -162,3 +163,8 @@
|
|||||||
range: 3
|
range: 3
|
||||||
sound:
|
sound:
|
||||||
path: /Audio/Ambience/Objects/light_hum.ogg
|
path: /Audio/Ambience/Objects/light_hum.ogg
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 1
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|||||||
@@ -87,9 +87,6 @@
|
|||||||
- type: PoweredLight
|
- type: PoweredLight
|
||||||
bulb: Bulb
|
bulb: Bulb
|
||||||
on: false
|
on: false
|
||||||
damage:
|
|
||||||
types:
|
|
||||||
Heat: 2
|
|
||||||
- type: ApcPowerReceiver
|
- type: ApcPowerReceiver
|
||||||
- type: ExtensionCableReceiver
|
- type: ExtensionCableReceiver
|
||||||
- type: DeviceNetwork
|
- type: DeviceNetwork
|
||||||
@@ -113,6 +110,11 @@
|
|||||||
- type: Construction
|
- type: Construction
|
||||||
graph: LightFixture
|
graph: LightFixture
|
||||||
node: strobeLight
|
node: strobeLight
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 2
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: PoweredStrobeLightPolice
|
id: PoweredStrobeLightPolice
|
||||||
|
|||||||
@@ -9,9 +9,6 @@
|
|||||||
collection: RadiationPulse
|
collection: RadiationPulse
|
||||||
params:
|
params:
|
||||||
volume: 5
|
volume: 5
|
||||||
anomalyContactDamage:
|
|
||||||
types:
|
|
||||||
Radiation: 10
|
|
||||||
- type: AmbientSound
|
- type: AmbientSound
|
||||||
range: 5
|
range: 5
|
||||||
volume: -5
|
volume: -5
|
||||||
@@ -51,6 +48,15 @@
|
|||||||
- type: SecretDataAnomaly
|
- type: SecretDataAnomaly
|
||||||
randomStartSecretMin: 0
|
randomStartSecretMin: 0
|
||||||
randomStartSecretMax: 2
|
randomStartSecretMax: 2
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Radiation: 10
|
||||||
|
popupText: anomaly-component-contact-damage
|
||||||
|
- type: DamageOnAttacked
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Radiation: 10
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: AnomalyPyroclastic
|
id: AnomalyPyroclastic
|
||||||
@@ -99,6 +105,15 @@
|
|||||||
- type: IgniteOnCollide
|
- type: IgniteOnCollide
|
||||||
fixtureId: fix1
|
fixtureId: fix1
|
||||||
fireStacks: 1
|
fireStacks: 1
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 10
|
||||||
|
popupText: anomaly-component-contact-damage
|
||||||
|
- type: DamageOnAttacked
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 10
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: AnomalyGravity
|
id: AnomalyGravity
|
||||||
@@ -294,9 +309,6 @@
|
|||||||
collection: RadiationPulse
|
collection: RadiationPulse
|
||||||
params:
|
params:
|
||||||
volume: 5
|
volume: 5
|
||||||
anomalyContactDamage:
|
|
||||||
types:
|
|
||||||
Radiation: 10
|
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: AnomalyIce
|
id: AnomalyIce
|
||||||
@@ -319,9 +331,6 @@
|
|||||||
- type: Anomaly
|
- type: Anomaly
|
||||||
corePrototype: AnomalyCoreIce
|
corePrototype: AnomalyCoreIce
|
||||||
coreInertPrototype: AnomalyCoreIceInert
|
coreInertPrototype: AnomalyCoreIceInert
|
||||||
anomalyContactDamage:
|
|
||||||
types:
|
|
||||||
Cold: 10
|
|
||||||
- type: ExplosionAnomaly
|
- type: ExplosionAnomaly
|
||||||
supercriticalExplosion: Cryo
|
supercriticalExplosion: Cryo
|
||||||
explosionTotalIntensity: 300
|
explosionTotalIntensity: 300
|
||||||
@@ -345,6 +354,15 @@
|
|||||||
releasedGas: 8 # Frezon. Please replace if there is a better way to specify this
|
releasedGas: 8 # Frezon. Please replace if there is a better way to specify this
|
||||||
releaseOnMaxSeverity: true
|
releaseOnMaxSeverity: true
|
||||||
spawnRadius: 0
|
spawnRadius: 0
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Cold: 10
|
||||||
|
popupText: anomaly-component-contact-damage
|
||||||
|
- type: DamageOnAttacked
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Cold: 10
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: AnomalyRockBase
|
id: AnomalyRockBase
|
||||||
@@ -609,9 +627,6 @@
|
|||||||
coreInertPrototype: AnomalyCoreFloraInert
|
coreInertPrototype: AnomalyCoreFloraInert
|
||||||
minPulseLength: 60
|
minPulseLength: 60
|
||||||
maxPulseLength: 120
|
maxPulseLength: 120
|
||||||
anomalyContactDamage:
|
|
||||||
types:
|
|
||||||
Slash: 0
|
|
||||||
- type: TileSpawnAnomaly
|
- type: TileSpawnAnomaly
|
||||||
entries:
|
entries:
|
||||||
- settings:
|
- settings:
|
||||||
@@ -715,9 +730,6 @@
|
|||||||
coreInertPrototype: AnomalyCoreLiquidInert
|
coreInertPrototype: AnomalyCoreLiquidInert
|
||||||
minPulseLength: 60
|
minPulseLength: 60
|
||||||
maxPulseLength: 120
|
maxPulseLength: 120
|
||||||
anomalyContactDamage:
|
|
||||||
types:
|
|
||||||
Slash: 1
|
|
||||||
- type: EntitySpawnAnomaly
|
- type: EntitySpawnAnomaly
|
||||||
entries:
|
entries:
|
||||||
- settings:
|
- settings:
|
||||||
@@ -829,9 +841,6 @@
|
|||||||
coreInertPrototype: AnomalyCoreShadowInert
|
coreInertPrototype: AnomalyCoreShadowInert
|
||||||
minPulseLength: 60
|
minPulseLength: 60
|
||||||
maxPulseLength: 120
|
maxPulseLength: 120
|
||||||
anomalyContactDamage:
|
|
||||||
types:
|
|
||||||
Cold: 10
|
|
||||||
animationTime: 4
|
animationTime: 4
|
||||||
offset: "-0.1,0.1"
|
offset: "-0.1,0.1"
|
||||||
- type: EntitySpawnAnomaly
|
- type: EntitySpawnAnomaly
|
||||||
@@ -857,3 +866,12 @@
|
|||||||
- type: Tag
|
- type: Tag
|
||||||
tags:
|
tags:
|
||||||
- SpookyFog
|
- SpookyFog
|
||||||
|
- type: DamageOnInteract
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Cold: 10
|
||||||
|
popupText: anomaly-component-contact-damage
|
||||||
|
- type: DamageOnAttacked
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Cold: 10
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
bulb: Bulb
|
bulb: Bulb
|
||||||
on: false
|
on: false
|
||||||
hasLampOnSpawn: ServiceLightBulb
|
hasLampOnSpawn: ServiceLightBulb
|
||||||
|
- type: DamageOnInteract
|
||||||
damage:
|
damage:
|
||||||
types:
|
types:
|
||||||
Heat: 5
|
Heat: 5
|
||||||
|
popupText: powered-light-component-burn-hand
|
||||||
|
|||||||
Reference in New Issue
Block a user