diff --git a/Content.Server/Item/ItemToggleSystem.cs b/Content.Server/Item/ItemToggleSystem.cs new file mode 100644 index 0000000000..5610582007 --- /dev/null +++ b/Content.Server/Item/ItemToggleSystem.cs @@ -0,0 +1,92 @@ +using Content.Server.CombatMode.Disarm; +using Content.Shared.Interaction; +using Content.Shared.Interaction.Events; +using Content.Shared.Item; +using Content.Shared.Toggleable; +using Content.Shared.Tools.Components; +using Robust.Shared.Player; + +namespace Content.Server.Weapons.Melee.ItemToggle; + +public sealed class ItemToggleSystem : EntitySystem +{ + [Dependency] private readonly SharedItemSystem _item = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnUseInHand); + SubscribeLocalEvent(OnInteractUsing); + SubscribeLocalEvent(TurnOff); + SubscribeLocalEvent(TurnOn); + } + + private void OnUseInHand(EntityUid uid, ItemToggleComponent comp, UseInHandEvent args) + { + if (args.Handled) + return; + + args.Handled = true; + + if (comp.Activated) + { + var ev = new ItemToggleDeactivatedEvent(); + RaiseLocalEvent(uid, ref ev); + } + else + { + var ev = new ItemToggleActivatedEvent(); + RaiseLocalEvent(uid, ref ev); + } + + UpdateAppearance(uid, comp); + } + + private void TurnOff(EntityUid uid, ItemToggleComponent comp, ref ItemToggleDeactivatedEvent args) + { + if (TryComp(uid, out ItemComponent? item)) + _item.SetSize(uid, comp.OffSize, item); + + if (TryComp(uid, out var malus)) + malus.Malus -= comp.ActivatedDisarmMalus; + + _audio.Play(comp.DeActivateSound, Filter.Pvs(uid, entityManager: EntityManager), uid, true, comp.DeActivateSound.Params); + + comp.Activated = false; + } + + private void TurnOn(EntityUid uid, ItemToggleComponent comp, ref ItemToggleActivatedEvent args) + { + if (TryComp(uid, out ItemComponent? item)) + _item.SetSize(uid, comp.OnSize, item); + + if (TryComp(uid, out var malus)) + malus.Malus += comp.ActivatedDisarmMalus; + + _audio.Play(comp.ActivateSound, Filter.Pvs(uid, entityManager: EntityManager), uid, true, comp.ActivateSound.Params); + + comp.Activated = true; + } + + private void UpdateAppearance(EntityUid uid, ItemToggleComponent component) + { + if (!TryComp(uid, out AppearanceComponent? appearanceComponent)) + return; + + _appearance.SetData(uid, ToggleableLightVisuals.Enabled, component.Activated, appearanceComponent); + } + + private void OnInteractUsing(EntityUid uid, ItemToggleComponent comp, InteractUsingEvent args) + { + if (args.Handled) + return; + + if (!TryComp(args.Used, out ToolComponent? tool) || !tool.Qualities.ContainsAny("Pulsing")) + return; + + args.Handled = true; + } +} diff --git a/Content.Server/Weapons/Reflect/ReflectSystem.cs b/Content.Server/Weapons/Reflect/ReflectSystem.cs index 3fe8dc8028..4045bf7b79 100644 --- a/Content.Server/Weapons/Reflect/ReflectSystem.cs +++ b/Content.Server/Weapons/Reflect/ReflectSystem.cs @@ -1,4 +1,5 @@ using Content.Server.Weapons.Melee.EnergySword; +using Content.Server.Weapons.Melee.ItemToggle; using Content.Shared.Weapons.Reflect; namespace Content.Server.Weapons.Reflect; @@ -10,6 +11,8 @@ public sealed class ReflectSystem : SharedReflectSystem base.Initialize(); SubscribeLocalEvent(EnableReflect); SubscribeLocalEvent(DisableReflect); + SubscribeLocalEvent(ShieldEnableReflect); + SubscribeLocalEvent(ShieldDisableReflect); } private void EnableReflect(EntityUid uid, ReflectComponent comp, ref EnergySwordActivatedEvent args) @@ -23,4 +26,16 @@ public sealed class ReflectSystem : SharedReflectSystem comp.Enabled = false; Dirty(comp); } -} \ No newline at end of file + + private void ShieldEnableReflect(EntityUid uid, ReflectComponent comp, ref ItemToggleActivatedEvent args) + { + comp.Enabled = true; + Dirty(comp); + } + + private void ShieldDisableReflect(EntityUid uid, ReflectComponent comp, ref ItemToggleDeactivatedEvent args) + { + comp.Enabled = false; + Dirty(comp); + } +} diff --git a/Content.Shared/Item/ItemToggleComponent.cs b/Content.Shared/Item/ItemToggleComponent.cs new file mode 100644 index 0000000000..9bcee120cd --- /dev/null +++ b/Content.Shared/Item/ItemToggleComponent.cs @@ -0,0 +1,34 @@ +using Robust.Shared.Audio; +using Robust.Shared.GameStates; + +namespace Content.Server.Weapons.Melee.ItemToggle; + +[RegisterComponent, NetworkedComponent] +public sealed class ItemToggleComponent : Component +{ + public bool Activated = false; + + [DataField("activateSound")] + public SoundSpecifier ActivateSound { get; set; } = default!; + + [DataField("deActivateSound")] + public SoundSpecifier DeActivateSound { get; set; } = default!; + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("activatedDisarmMalus")] + public float ActivatedDisarmMalus = 0.6f; + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("offSize")] + public int OffSize = 1; + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("onSize")] + public int OnSize = 9999; +} + +[ByRefEvent] +public readonly record struct ItemToggleActivatedEvent(); + +[ByRefEvent] +public readonly record struct ItemToggleDeactivatedEvent(); diff --git a/Resources/Locale/en-US/store/uplink-catalog.ftl b/Resources/Locale/en-US/store/uplink-catalog.ftl index db8ee3bb9b..4ac235a148 100644 --- a/Resources/Locale/en-US/store/uplink-catalog.ftl +++ b/Resources/Locale/en-US/store/uplink-catalog.ftl @@ -213,6 +213,9 @@ uplink-decoy-disk-desc = A piece of plastic with a lenticular printing, made to uplink-cigarettes-name = Syndicate Smokes Packet uplink-cigarettes-desc = Elite cigarettes for elite agents. Infused with medicine for when you need to do more than calm your nerves. +uplink-eshield-name = Energy Shield +uplink-eshield-desc = Exotic energy shield that reflects almost all laser beams, as well as a little protection from bullets and other physical attacks. + uplink-soap-name = Soap uplink-soap-desc = An untrustworthy bar of soap. Smells of fear. diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index ceea36350b..596de06ef9 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -839,6 +839,17 @@ categories: - UplinkMisc +- type: listing + id: UplinkEshield + name: uplink-eshield-name + description: uplink-eshield-desc + icon: { sprite: /Textures/Objects/Weapons/Melee/e_shield.rsi, state: eshield-on } + productEntity: EnergyShield + cost: + Telecrystal: 6 + categories: + - UplinkMisc + - type: listing id: UplinkSoapSyndie name: uplink-soap-name diff --git a/Resources/Prototypes/Entities/Objects/Shields/shields.yml b/Resources/Prototypes/Entities/Objects/Shields/shields.yml index 4f493f4832..1005558ea8 100644 --- a/Resources/Prototypes/Entities/Objects/Shields/shields.yml +++ b/Resources/Prototypes/Entities/Objects/Shields/shields.yml @@ -301,3 +301,108 @@ SheetGlass: min: 5 max: 5 + +- type: entity + name: energy shield + parent: BaseItem + id: EnergyShield + description: Exotic energy shield, when folded, can even fit in your pocket. + components: + - type: ItemToggle + activatedDisarmMalus: 0.6 + activateSound: + path: /Audio/Weapons/ebladeon.ogg + deActivateSound: + path: /Audio/Weapons/ebladeoff.ogg + offSize: 5 + - type: Sprite + sprite: Objects/Weapons/Melee/e_shield.rsi + layers: + - state: eshield-icon + - state: eshield-on + color: "#FFFFFF" + visible: false + shader: unshaded + map: [ "shield" ] + - type: Item + size: 5 + sprite: Objects/Weapons/Melee/e_shield.rsi + heldPrefix: eshield + - type: UseDelay + delay: 0.5 + - type: ToggleableLightVisuals + spriteLayer: shield + inhandVisuals: + left: + - state: inhand-left-shield + shader: unshaded + right: + - state: inhand-right-shield + shader: unshaded + - type: PointLight + netsync: false + enabled: false + radius: 1.5 + energy: 2 + color: blue + - type: Reflect + enabled: false + reflectProb: 0.95 + reflects: + - Energy + - type: Blocking + passiveBlockModifier: + coefficients: + Blunt: 1.0 + Slash: 0.9 + Piercing: 0.85 + Heat: 0.6 + activeBlockModifier: + coefficients: + Blunt: 1.2 + Slash: 0.85 + Piercing: 0.5 + Heat: 0.4 + flatReductions: + Heat: 1 + Piercing: 1 + - type: Appearance + - type: Damageable + damageContainer: Shield + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 180 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - trigger: + !type:DamageTrigger + damage: 150 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + BrokenEnergyShield: + min: 1 + max: 1 + - type: StaticPrice + price: 350 + +- type: entity + name: broken energy shield + parent: BaseItem + id: BrokenEnergyShield + description: Something inside is burned out, it is no longer functional. + components: + - type: Sprite + sprite: Objects/Weapons/Melee/e_shield.rsi + state: eshield-icon + - type: Item + sprite: Objects/Weapons/Melee/e_shield.rsi + size: 5 + heldPrefix: eshield diff --git a/Resources/Textures/Objects/Weapons/Melee/shields.rsi/eshield-icon.png b/Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/eshield-icon.png similarity index 100% rename from Resources/Textures/Objects/Weapons/Melee/shields.rsi/eshield-icon.png rename to Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/eshield-icon.png diff --git a/Resources/Textures/Objects/Weapons/Melee/shields.rsi/eshield-inhand-left.png b/Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/eshield-inhand-left.png similarity index 100% rename from Resources/Textures/Objects/Weapons/Melee/shields.rsi/eshield-inhand-left.png rename to Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/eshield-inhand-left.png diff --git a/Resources/Textures/Objects/Weapons/Melee/shields.rsi/eshield-inhand-right.png b/Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/eshield-inhand-right.png similarity index 100% rename from Resources/Textures/Objects/Weapons/Melee/shields.rsi/eshield-inhand-right.png rename to Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/eshield-inhand-right.png diff --git a/Resources/Textures/Objects/Weapons/Melee/shields.rsi/eshield-on.png b/Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/eshield-on.png similarity index 100% rename from Resources/Textures/Objects/Weapons/Melee/shields.rsi/eshield-on.png rename to Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/eshield-on.png diff --git a/Resources/Textures/Objects/Weapons/Melee/shields.rsi/eshield1-inhand-left-on.png b/Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/inhand-left-shield.png similarity index 100% rename from Resources/Textures/Objects/Weapons/Melee/shields.rsi/eshield1-inhand-left-on.png rename to Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/inhand-left-shield.png diff --git a/Resources/Textures/Objects/Weapons/Melee/shields.rsi/eshield-inhand-right-on.png b/Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/inhand-right-shield.png similarity index 100% rename from Resources/Textures/Objects/Weapons/Melee/shields.rsi/eshield-inhand-right-on.png rename to Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/inhand-right-shield.png diff --git a/Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/meta.json b/Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/meta.json new file mode 100644 index 0000000000..bf499bb7d3 --- /dev/null +++ b/Resources/Textures/Objects/Weapons/Melee/e_shield.rsi/meta.json @@ -0,0 +1,33 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from Citadel station 13 at https://github.com/Citadel-Station-13/Citadel-Station-13/commit/84223c65f5caf667a84f3c0f49bc2a41cdc6c4e3", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "eshield-icon" + }, + { + "name": "eshield-inhand-right", + "directions": 4 + }, + { + "name": "eshield-inhand-left", + "directions": 4 + }, + { + "name": "eshield-on" + }, + { + "name": "inhand-right-shield", + "directions": 4 + }, + { + "name": "inhand-left-shield", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Objects/Weapons/Melee/shields.rsi/meta.json b/Resources/Textures/Objects/Weapons/Melee/shields.rsi/meta.json index d44aa92605..2d2663c158 100644 --- a/Resources/Textures/Objects/Weapons/Melee/shields.rsi/meta.json +++ b/Resources/Textures/Objects/Weapons/Melee/shields.rsi/meta.json @@ -168,28 +168,6 @@ { "name": "teleriot-inhand-left-on", "directions": 4 - }, - { - "name": "eshield-icon" - }, - { - "name": "eshield-inhand-right", - "directions": 4 - }, - { - "name": "eshield-inhand-left", - "directions": 4 - }, - { - "name": "eshield-on" - }, - { - "name": "eshield-inhand-right-on", - "directions": 4 - }, - { - "name": "eshield1-inhand-left-on", - "directions": 4 } ] -} \ No newline at end of file +}