--- /dev/null
+using Content.IntegrationTests.Tests.Interaction;
+using Content.Shared.Engineering.Systems;
+
+namespace Content.IntegrationTests.Tests.Engineering;
+
+[TestFixture]
+[TestOf(typeof(InflatableSafeDisassemblySystem))]
+public sealed class InflatablesDeflateTest : InteractionTest
+{
+ [Test]
+ public async Task Test()
+ {
+ await SpawnTarget(InflatableWall);
+
+ await InteractUsing(Needle);
+
+ AssertDeleted();
+ await AssertEntityLookup(new EntitySpecifier(InflatableWallStack.Id, 1));
+ }
+}
+using Content.Shared.Stacks;
+using Robust.Shared.Prototypes;
+
namespace Content.IntegrationTests.Tests.Interaction;
// This partial class contains various constant prototype IDs common to interaction tests.
protected const string Manipulator1 = "MicroManipulatorStockPart";
protected const string Battery1 = "PowerCellSmall";
protected const string Battery4 = "PowerCellHyper";
+
+ // Inflatables & Needle used to pop them
+ protected static readonly EntProtoId InflatableWall = "InflatableWall";
+ protected static readonly EntProtoId Needle = "WeaponMeleeNeedle";
+ protected static readonly ProtoId<StackPrototype> InflatableWallStack = "InflatableWall";
}
using Content.Shared.Tag;
using Content.Shared.Weapons.Melee.Events;
using Content.Shared.Throwing;
+using Content.Shared.Weapons.Melee.Balloon;
using Robust.Shared.Audio.Systems;
namespace Content.Server.Weapons.Melee.Balloon;
--- /dev/null
+using Content.Shared.Engineering.Systems;
+using Content.Shared.Weapons.Melee.Balloon;
+
+namespace Content.Shared.Engineering.Components;
+
+/// <summary>
+/// Implements logic to allow inflatable objects to be safely deflated by <see cref="BalloonPopperComponent"/> items.
+/// </summary>
+/// <remarks>
+/// The owning entity must have <see cref="DisassembleOnAltVerbComponent"/> to implement the logic.
+/// </remarks>
+/// <seealso cref="InflatableSafeDisassemblySystem"/>
+[RegisterComponent]
+public sealed partial class InflatableSafeDisassemblyComponent : Component;
SubscribeLocalEvent<DisassembleOnAltVerbComponent, GetVerbsEvent<AlternativeVerb>>(AddDisassembleVerb);
SubscribeLocalEvent<DisassembleOnAltVerbComponent, DisassembleDoAfterEvent>(OnDisassembleDoAfter);
}
- private void AddDisassembleVerb(Entity<DisassembleOnAltVerbComponent> entity, ref GetVerbsEvent<AlternativeVerb> args)
- {
- if (!args.CanInteract || !args.CanAccess || args.Hands == null)
- return;
+ public void StartDisassembly(Entity<DisassembleOnAltVerbComponent> entity, EntityUid user)
+ {
// Doafter setup
var doAfterArgs = new DoAfterArgs(EntityManager,
- args.User,
+ user,
entity.Comp.DisassembleTime,
new DisassembleDoAfterEvent(),
entity,
BreakOnMove = true,
};
+ _doAfter.TryStartDoAfter(doAfterArgs);
+ }
+
+ private void AddDisassembleVerb(Entity<DisassembleOnAltVerbComponent> entity, ref GetVerbsEvent<AlternativeVerb> args)
+ {
+ if (!args.CanInteract || !args.CanAccess || args.Hands == null)
+ return;
+
+ var user = args.User;
+
// Actual verb stuff
AlternativeVerb verb = new()
{
Act = () =>
{
- _doAfter.TryStartDoAfter(doAfterArgs);
+ StartDisassembly(entity, user);
},
Text = Loc.GetString("disassemble-system-verb-disassemble"),
Priority = 2
--- /dev/null
+using Content.Shared.Engineering.Components;
+using Content.Shared.Interaction;
+using Content.Shared.Popups;
+using Content.Shared.Weapons.Melee.Balloon;
+
+namespace Content.Shared.Engineering.Systems;
+
+/// <summary>
+/// Implements <see cref="InflatableSafeDisassemblyComponent"/>
+/// </summary>
+public sealed class InflatableSafeDisassemblySystem : EntitySystem
+{
+ [Dependency] private readonly DisassembleOnAltVerbSystem _disassembleOnAltVerbSystem = null!;
+ [Dependency] private readonly SharedPopupSystem _popupSystem = null!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent<InflatableSafeDisassemblyComponent, InteractUsingEvent>(InteractHandler);
+ }
+
+ private void InteractHandler(Entity<InflatableSafeDisassemblyComponent> ent, ref InteractUsingEvent args)
+ {
+ if (args.Handled)
+ return;
+
+ if (!HasComp<BalloonPopperComponent>(args.Used))
+ return;
+
+ _popupSystem.PopupPredicted(
+ Loc.GetString("inflatable-safe-disassembly", ("item", args.Used), ("target", ent.Owner)),
+ ent,
+ args.User);
+
+ _disassembleOnAltVerbSystem.StartDisassembly((ent, Comp<DisassembleOnAltVerbComponent>(ent)), args.User);
+ args.Handled = true;
+ }
+}
using Robust.Shared.Audio;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
-namespace Content.Server.Weapons.Melee.Balloon;
+namespace Content.Shared.Weapons.Melee.Balloon;
/// <summary>
/// This is used for weapons that pop balloons on attack.
--- /dev/null
+inflatable-safe-disassembly = You expertly use { THE($item) } to open the valve on { THE($target) }, and start deflating { OBJECT($target) } without causing damage.
borg-slot-soap-empty = Soap
borg-slot-instruments-empty = Instruments
borg-slot-beakers-empty = Beakers
+borg-slot-inflatable-door-empty = Inflatable Door
+borg-slot-inflatable-wall-empty = Inflatable Wall
- type: DisassembleOnAltVerb
prototypeToSpawn: InflatableWallStack1
disassembleTime: 3
+ - type: InflatableSafeDisassembly
- type: Airtight
- type: Transform
anchored: true
- type: DisassembleOnAltVerb
prototypeToSpawn: InflatableDoorStack1
disassembleTime: 3
+ - type: InflatableSafeDisassembly
- type: Occluder
enabled: false
- type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: tool-module }
+- type: entity
+ id: BorgModuleInflatable
+ parent: [ BaseBorgModule, BaseProviderBorgModule ]
+ name: inflatable cyborg module
+ components:
+ - type: Sprite
+ layers:
+ - state: generic
+ - state: icon-inflatable
+ - type: ItemBorgModule
+ hands:
+ - item: InflatableDoorStack
+ hand:
+ emptyRepresentative: InflatableDoorStack
+ emptyLabel: borg-slot-inflatable-door-empty
+ whitelist:
+ tags:
+ - Inflatable
+ - item: InflatableWallStack
+ hand:
+ emptyRepresentative: InflatableWallStack
+ emptyLabel: borg-slot-inflatable-wall-empty
+ whitelist:
+ tags:
+ - Inflatable
+ - item: BoxInflatable
+ - item: WeaponMeleeNeedle
+ - type: BorgModuleIcon
+ icon: { sprite: Interface/Actions/actions_borg.rsi, state: inflatable-module }
+
# cargo modules
- type: entity
id: BorgModuleAppraisal
description: A folded membrane which rapidly expands into a large cubical shape on activation.
suffix: Full
components:
- - type: Stack
- stackType: InflatableWall
- count: 10
- - type: Sprite
- sprite: Objects/Misc/inflatable_wall.rsi
- state: item_wall
- - type: Item
- sprite: Objects/Misc/inflatable_wall.rsi
- size: Small
- - type: SpawnAfterInteract
- prototype: InflatableWall
- doAfter: 1
- removeOnInteract: true
- - type: Clickable
- - type: PhysicalComposition
+ - type: Stack
+ stackType: InflatableWall
+ count: 10
+ - type: Sprite
+ sprite: Objects/Misc/inflatable_wall.rsi
+ state: item_wall
+ - type: Item
+ sprite: Objects/Misc/inflatable_wall.rsi
+ size: Small
+ - type: SpawnAfterInteract
+ prototype: InflatableWall
+ doAfter: 1
+ removeOnInteract: true
+ - type: Clickable
+ - type: PhysicalComposition
+ - type: Tag
+ tags:
+ - Inflatable
# TODO: Add stack sprites + visuals.
- type: entity
description: A folded membrane which rapidly expands into a large cubical shape on activation.
suffix: Full
components:
- - type: Stack
- stackType: InflatableDoor
- count: 4
- - type: Sprite
- sprite: Objects/Misc/inflatable_door.rsi
- state: item_door
- - type: Item
- sprite: Objects/Misc/inflatable_door.rsi
- size: Small
- - type: SpawnAfterInteract
- prototype: InflatableDoor
- doAfter: 1
- removeOnInteract: true
- - type: Clickable
- - type: PhysicalComposition
+ - type: Stack
+ stackType: InflatableDoor
+ count: 4
+ - type: Sprite
+ sprite: Objects/Misc/inflatable_door.rsi
+ state: item_door
+ - type: Item
+ sprite: Objects/Misc/inflatable_door.rsi
+ size: Small
+ - type: SpawnAfterInteract
+ prototype: InflatableDoor
+ doAfter: 1
+ removeOnInteract: true
+ - type: Clickable
+ - type: PhysicalComposition
+ - type: Tag
+ tags:
+ - Inflatable
# TODO: Add stack sprites + visuals.
- type: entity
id: InflatableWallStack5
suffix: 5
components:
- - type: Sprite
- state: item_wall
- - type: Stack
- count: 5
+ - type: Sprite
+ state: item_wall
+ - type: Stack
+ count: 5
- type: entity
parent: InflatableWallStack
id: InflatableWallStack1
suffix: 1
components:
- - type: Sprite
- state: item_wall
- - type: Stack
- count: 1
+ - type: Sprite
+ state: item_wall
+ - type: Stack
+ count: 1
- type: entity
parent: InflatableDoorStack
id: InflatableDoorStack1
suffix: 1
components:
- - type: Sprite
- state: item_door
- - type: Stack
- count: 1
+ - type: Sprite
+ state: item_door
+ - type: Stack
+ count: 1
- BorgModuleTool
- BorgModuleCable
- BorgModuleFireExtinguisher
+ - BorgModuleInflatable
- type: latheRecipePack
id: BorgLimbsStatic
id: BorgModuleFireExtinguisher
result: BorgModuleFireExtinguisher
+- type: latheRecipe
+ parent: BaseBorgModuleRecipe
+ id: BorgModuleInflatable
+ result: BorgModuleInflatable
+
# Cargo Modules
- type: latheRecipe
defaultModules:
- BorgModuleTool
+ - BorgModuleInflatable
- BorgModuleArtifact
- BorgModuleAnomaly
radioChannels:
- type: Tag
id: Ingot
+- type: Tag
+ id: Inflatable
+
- type: Tag
id: InstantDoAfters
{
"version": 1,
"license": "CC-BY-SA-3.0",
- "copyright": "Taken from vgstation at commit https://github.com/vgstation-coders/vgstation13/commit/cdbcb1e858b11f083994a7a269ed67ef5b452ce9, Module actions by Scarky0. chem, adv-chem, and adv-mining by mubururu_, xenoborg actions by Samuka-C (github), advclown by ThatGuyUSA. c20r and esword by RedBookcase on Github.",
+ "copyright": "Taken from vgstation at commit https://github.com/vgstation-coders/vgstation13/commit/cdbcb1e858b11f083994a7a269ed67ef5b452ce9, inflatable module by FungiFellow (GitHub), Module actions by Scarky0. chem, adv-chem, and adv-mining by mubururu_, xenoborg actions by Samuka-C (github), advclown by ThatGuyUSA. c20r and esword by RedBookcase on Github.",
"size": {
"x": 32,
"y": 32
{
"name":"geiger-module"
},
+ {
+ "name":"inflatable-module"
+ },
{
"name":"rcd-module"
},
{
"version": 1,
"license": "CC0-1.0",
- "copyright": "Created by EmoGarbage404 (github) for Space Station 14. icon-construction.png created by deltanedas (github). syndicateborgbomb.png created by Mangohydra (github). layered inhands by mubururu_ (github), icon-chem.png & icon-mining-adv.png created by mubururu_ (github), Xenoborg modules sprites by Samuka-C (github)",
+ "copyright": "Created by EmoGarbage404 (github) for Space Station 14. icon-construction.png created by deltanedas (github). syndicateborgbomb.png created by Mangohydra (github). icon-chem.png & icon-mining-adv.png created by mubururu_ (github) icon-inflatable.png made by FungiFellow (GitHub), Xenoborg modules sprites by Samuka-C (github)",
"size": {
"x": 32,
"y": 32
{
"name": "icon-cables"
},
+ {
+ "name": "icon-inflatable"
+ },
{
"name": "icon-chemist"
},
"directions": 4
}
]
+
}