Inflatable Module (#35100)
Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com> Co-authored-by: PJB3005 <pieterjan.briers+git@gmail.com>
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
using Content.Shared.Stacks;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.IntegrationTests.Tests.Interaction;
|
namespace Content.IntegrationTests.Tests.Interaction;
|
||||||
|
|
||||||
// This partial class contains various constant prototype IDs common to interaction tests.
|
// This partial class contains various constant prototype IDs common to interaction tests.
|
||||||
@@ -32,4 +35,9 @@ public abstract partial class InteractionTest
|
|||||||
protected const string Manipulator1 = "MicroManipulatorStockPart";
|
protected const string Manipulator1 = "MicroManipulatorStockPart";
|
||||||
protected const string Battery1 = "PowerCellSmall";
|
protected const string Battery1 = "PowerCellSmall";
|
||||||
protected const string Battery4 = "PowerCellHyper";
|
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";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Content.Shared.Popups;
|
|||||||
using Content.Shared.Tag;
|
using Content.Shared.Tag;
|
||||||
using Content.Shared.Weapons.Melee.Events;
|
using Content.Shared.Weapons.Melee.Events;
|
||||||
using Content.Shared.Throwing;
|
using Content.Shared.Throwing;
|
||||||
|
using Content.Shared.Weapons.Melee.Balloon;
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
|
|
||||||
namespace Content.Server.Weapons.Melee.Balloon;
|
namespace Content.Server.Weapons.Melee.Balloon;
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
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;
|
||||||
@@ -19,14 +19,12 @@ public sealed partial class DisassembleOnAltVerbSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<DisassembleOnAltVerbComponent, GetVerbsEvent<AlternativeVerb>>(AddDisassembleVerb);
|
SubscribeLocalEvent<DisassembleOnAltVerbComponent, GetVerbsEvent<AlternativeVerb>>(AddDisassembleVerb);
|
||||||
SubscribeLocalEvent<DisassembleOnAltVerbComponent, DisassembleDoAfterEvent>(OnDisassembleDoAfter);
|
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
|
// Doafter setup
|
||||||
var doAfterArgs = new DoAfterArgs(EntityManager,
|
var doAfterArgs = new DoAfterArgs(EntityManager,
|
||||||
args.User,
|
user,
|
||||||
entity.Comp.DisassembleTime,
|
entity.Comp.DisassembleTime,
|
||||||
new DisassembleDoAfterEvent(),
|
new DisassembleDoAfterEvent(),
|
||||||
entity,
|
entity,
|
||||||
@@ -35,12 +33,22 @@ public sealed partial class DisassembleOnAltVerbSystem : EntitySystem
|
|||||||
BreakOnMove = true,
|
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
|
// Actual verb stuff
|
||||||
AlternativeVerb verb = new()
|
AlternativeVerb verb = new()
|
||||||
{
|
{
|
||||||
Act = () =>
|
Act = () =>
|
||||||
{
|
{
|
||||||
_doAfter.TryStartDoAfter(doAfterArgs);
|
StartDisassembly(entity, user);
|
||||||
},
|
},
|
||||||
Text = Loc.GetString("disassemble-system-verb-disassemble"),
|
Text = Loc.GetString("disassemble-system-verb-disassemble"),
|
||||||
Priority = 2
|
Priority = 2
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
namespace Content.Server.Weapons.Melee.Balloon;
|
namespace Content.Shared.Weapons.Melee.Balloon;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is used for weapons that pop balloons on attack.
|
/// This is used for weapons that pop balloons on attack.
|
||||||
1
Resources/Locale/en-US/engineering/inflatables.ftl
Normal file
1
Resources/Locale/en-US/engineering/inflatables.ftl
Normal file
@@ -0,0 +1 @@
|
|||||||
|
inflatable-safe-disassembly = You expertly use { THE($item) } to open the valve on { THE($target) }, and start deflating { OBJECT($target) } without causing damage.
|
||||||
@@ -10,3 +10,5 @@ borg-slot-documents-empty = Books and papers
|
|||||||
borg-slot-soap-empty = Soap
|
borg-slot-soap-empty = Soap
|
||||||
borg-slot-instruments-empty = Instruments
|
borg-slot-instruments-empty = Instruments
|
||||||
borg-slot-beakers-empty = Beakers
|
borg-slot-beakers-empty = Beakers
|
||||||
|
borg-slot-inflatable-door-empty = Inflatable Door
|
||||||
|
borg-slot-inflatable-wall-empty = Inflatable Wall
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
- type: DisassembleOnAltVerb
|
- type: DisassembleOnAltVerb
|
||||||
prototypeToSpawn: InflatableWallStack1
|
prototypeToSpawn: InflatableWallStack1
|
||||||
disassembleTime: 3
|
disassembleTime: 3
|
||||||
|
- type: InflatableSafeDisassembly
|
||||||
- type: Airtight
|
- type: Airtight
|
||||||
- type: Transform
|
- type: Transform
|
||||||
anchored: true
|
anchored: true
|
||||||
@@ -81,5 +82,6 @@
|
|||||||
- type: DisassembleOnAltVerb
|
- type: DisassembleOnAltVerb
|
||||||
prototypeToSpawn: InflatableDoorStack1
|
prototypeToSpawn: InflatableDoorStack1
|
||||||
disassembleTime: 3
|
disassembleTime: 3
|
||||||
|
- type: InflatableSafeDisassembly
|
||||||
- type: Occluder
|
- type: Occluder
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|||||||
@@ -489,6 +489,36 @@
|
|||||||
- type: BorgModuleIcon
|
- type: BorgModuleIcon
|
||||||
icon: { sprite: Interface/Actions/actions_borg.rsi, state: tool-module }
|
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
|
# cargo modules
|
||||||
- type: entity
|
- type: entity
|
||||||
id: BorgModuleAppraisal
|
id: BorgModuleAppraisal
|
||||||
|
|||||||
@@ -20,6 +20,9 @@
|
|||||||
removeOnInteract: true
|
removeOnInteract: true
|
||||||
- type: Clickable
|
- type: Clickable
|
||||||
- type: PhysicalComposition
|
- type: PhysicalComposition
|
||||||
|
- type: Tag
|
||||||
|
tags:
|
||||||
|
- Inflatable
|
||||||
# TODO: Add stack sprites + visuals.
|
# TODO: Add stack sprites + visuals.
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
@@ -44,6 +47,9 @@
|
|||||||
removeOnInteract: true
|
removeOnInteract: true
|
||||||
- type: Clickable
|
- type: Clickable
|
||||||
- type: PhysicalComposition
|
- type: PhysicalComposition
|
||||||
|
- type: Tag
|
||||||
|
tags:
|
||||||
|
- Inflatable
|
||||||
# TODO: Add stack sprites + visuals.
|
# TODO: Add stack sprites + visuals.
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
- BorgModuleTool
|
- BorgModuleTool
|
||||||
- BorgModuleCable
|
- BorgModuleCable
|
||||||
- BorgModuleFireExtinguisher
|
- BorgModuleFireExtinguisher
|
||||||
|
- BorgModuleInflatable
|
||||||
|
|
||||||
- type: latheRecipePack
|
- type: latheRecipePack
|
||||||
id: BorgLimbsStatic
|
id: BorgLimbsStatic
|
||||||
|
|||||||
@@ -37,6 +37,11 @@
|
|||||||
id: BorgModuleFireExtinguisher
|
id: BorgModuleFireExtinguisher
|
||||||
result: BorgModuleFireExtinguisher
|
result: BorgModuleFireExtinguisher
|
||||||
|
|
||||||
|
- type: latheRecipe
|
||||||
|
parent: BaseBorgModuleRecipe
|
||||||
|
id: BorgModuleInflatable
|
||||||
|
result: BorgModuleInflatable
|
||||||
|
|
||||||
# Cargo Modules
|
# Cargo Modules
|
||||||
|
|
||||||
- type: latheRecipe
|
- type: latheRecipe
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
defaultModules:
|
defaultModules:
|
||||||
- BorgModuleTool
|
- BorgModuleTool
|
||||||
|
- BorgModuleInflatable
|
||||||
- BorgModuleArtifact
|
- BorgModuleArtifact
|
||||||
- BorgModuleAnomaly
|
- BorgModuleAnomaly
|
||||||
radioChannels:
|
radioChannels:
|
||||||
|
|||||||
@@ -801,6 +801,9 @@
|
|||||||
- type: Tag
|
- type: Tag
|
||||||
id: Ingot
|
id: Ingot
|
||||||
|
|
||||||
|
- type: Tag
|
||||||
|
id: Inflatable
|
||||||
|
|
||||||
- type: Tag
|
- type: Tag
|
||||||
id: InstantDoAfters
|
id: InstantDoAfters
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 5.4 KiB |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"license": "CC-BY-SA-3.0",
|
"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": {
|
"size": {
|
||||||
"x": 32,
|
"x": 32,
|
||||||
"y": 32
|
"y": 32
|
||||||
@@ -28,6 +28,9 @@
|
|||||||
{
|
{
|
||||||
"name":"geiger-module"
|
"name":"geiger-module"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name":"inflatable-module"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name":"rcd-module"
|
"name":"rcd-module"
|
||||||
},
|
},
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"license": "CC0-1.0",
|
"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": {
|
"size": {
|
||||||
"x": 32,
|
"x": 32,
|
||||||
"y": 32
|
"y": 32
|
||||||
@@ -28,6 +28,9 @@
|
|||||||
{
|
{
|
||||||
"name": "icon-cables"
|
"name": "icon-cables"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "icon-inflatable"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "icon-chemist"
|
"name": "icon-chemist"
|
||||||
},
|
},
|
||||||
@@ -226,4 +229,5 @@
|
|||||||
"directions": 4
|
"directions": 4
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user