Add space lube tube (#17387)
72
Content.Server/Lube/LubeSystem.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Server.Nutrition.Components;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Item;
|
||||
using Content.Shared.Lube;
|
||||
using Content.Shared.Popups;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Lube;
|
||||
|
||||
public sealed class LubeSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly SolutionContainerSystem _solutionContainer = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<LubeComponent, AfterInteractEvent>(OnInteract);
|
||||
}
|
||||
|
||||
// When glue bottle is used on item it will apply the glued and unremoveable components.
|
||||
private void OnInteract(EntityUid uid, LubeComponent component, AfterInteractEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (!args.CanReach || args.Target is not { Valid: true } target)
|
||||
return;
|
||||
|
||||
if (TryComp<DrinkComponent>(uid, out var drink) && !drink.Opened)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (TryLube(uid, component, target))
|
||||
{
|
||||
args.Handled = true;
|
||||
_audio.PlayPvs(component.Squeeze, uid);
|
||||
_popup.PopupEntity(Loc.GetString("lube-success", ("target", Identity.Entity(target, EntityManager))), args.User, args.User, PopupType.Medium);
|
||||
}
|
||||
else
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("lube-failure", ("target", Identity.Entity(target, EntityManager))), args.User, args.User, PopupType.Medium);
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryLube(EntityUid uid, LubeComponent component, EntityUid target)
|
||||
{
|
||||
if (HasComp<LubedComponent>(target) || !HasComp<ItemComponent>(target))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HasComp<ItemComponent>(target) && _solutionContainer.TryGetSolution(uid, component.Solution, out var solution))
|
||||
{
|
||||
var quantity = solution.RemoveReagent(component.Reagent, component.Consumption);
|
||||
if (quantity > 0)
|
||||
{
|
||||
var lubed = EnsureComp<LubedComponent>(target);
|
||||
lubed.SlipsLeft = _random.Next(component.MinSlips * quantity.Int(), component.MaxSlips * quantity.Int());
|
||||
lubed.SlipStrength = component.SlipStrength;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
49
Content.Server/Lube/LubedSystem.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Lube;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Throwing;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Lube;
|
||||
|
||||
public sealed class LubedSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||
[Dependency] private readonly ThrowingSystem _throwing = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<LubedComponent, ComponentInit>(OnInit);
|
||||
SubscribeLocalEvent<LubedComponent, ContainerGettingInsertedAttemptEvent>(OnHandPickUp);
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, LubedComponent component, ComponentInit args)
|
||||
{
|
||||
var meta = MetaData(uid);
|
||||
var name = meta.EntityName;
|
||||
component.BeforeLubedEntityName = meta.EntityName;
|
||||
_metaData.SetEntityName(uid, Loc.GetString("lubed-name-prefix", ("target", name)));
|
||||
}
|
||||
|
||||
private void OnHandPickUp(EntityUid uid, LubedComponent component, ContainerGettingInsertedAttemptEvent args)
|
||||
{
|
||||
if (component.SlipsLeft <= 0)
|
||||
{
|
||||
RemComp<LubedComponent>(uid);
|
||||
_metaData.SetEntityName(uid, component.BeforeLubedEntityName);
|
||||
return;
|
||||
}
|
||||
component.SlipsLeft--;
|
||||
args.Cancel();
|
||||
var user = args.Container.Owner;
|
||||
_transform.SetCoordinates(uid, Transform(user).Coordinates);
|
||||
_throwing.TryThrow(uid, _random.NextVector2(), strength: component.SlipStrength);
|
||||
_popup.PopupEntity(Loc.GetString("lube-slip", ("target", Identity.Entity(uid, EntityManager))), user, user, PopupType.MediumCaution);
|
||||
}
|
||||
}
|
||||
47
Content.Shared/Lube/LubeComponent.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Shared.Lube;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed class LubeComponent : Component
|
||||
{
|
||||
[DataField("squeeze")]
|
||||
public SoundSpecifier Squeeze = new SoundPathSpecifier("/Audio/Items/squeezebottle.ogg");
|
||||
|
||||
/// <summary>
|
||||
/// Solution on the entity that contains the glue.
|
||||
/// </summary>
|
||||
[DataField("solution")]
|
||||
public string Solution = "drink";
|
||||
|
||||
/// <summary>
|
||||
/// Reagent that will be used as glue.
|
||||
/// </summary>
|
||||
[DataField("reagent", customTypeSerializer: typeof(PrototypeIdSerializer<ReagentPrototype>))]
|
||||
public string Reagent = "SpaceLube";
|
||||
|
||||
/// <summary>
|
||||
/// Reagent consumption per use.
|
||||
/// </summary>
|
||||
[DataField("consumption"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public FixedPoint2 Consumption = FixedPoint2.New(3);
|
||||
|
||||
/// <summary>
|
||||
/// Min slips per unit
|
||||
/// </summary>
|
||||
[DataField("minSlips"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public int MinSlips = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Max slips per unit
|
||||
/// </summary>
|
||||
[DataField("maxSlips"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public int MaxSlips = 6;
|
||||
|
||||
[DataField("slipStrength"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public int SlipStrength = 10;
|
||||
}
|
||||
17
Content.Shared/Lube/LubedComponent.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace Content.Shared.Lube;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed class LubedComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Reverts name to before prefix event (essentially removes prefix).
|
||||
/// </summary>
|
||||
[DataField("beforeLubedEntityName")]
|
||||
public string BeforeLubedEntityName = string.Empty;
|
||||
|
||||
[DataField("slipsLeft"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public int SlipsLeft;
|
||||
|
||||
[DataField("slipStrength"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public int SlipStrength;
|
||||
}
|
||||
4
Resources/Locale/en-US/lube/lube.ftl
Normal file
@@ -0,0 +1,4 @@
|
||||
lube-success = {THE($target)} has been covered in lube!
|
||||
lubed-name-prefix = Lubed {$target}
|
||||
lube-failure = Can't cover {THE($target)} in lube!
|
||||
lube-slip = {THE($target)} slips out of your hands!
|
||||
@@ -129,6 +129,8 @@
|
||||
prob: 0.20
|
||||
- id: DrinkSpaceGlue
|
||||
prob: 0.20
|
||||
- id: DrinkSpaceLube
|
||||
prob: 0.20
|
||||
|
||||
- type: entity
|
||||
id: ClosetWallMaintenanceFilledRandom
|
||||
|
||||
@@ -29,3 +29,36 @@
|
||||
- type: SolutionContainerVisuals
|
||||
maxFillLevels: 6
|
||||
fillBaseName: fill
|
||||
|
||||
- type: entity
|
||||
parent: DrinkBase
|
||||
id: DrinkSpaceLube
|
||||
name: space lube tube
|
||||
description: High performance lubricant intended for maintenance of extremely complex mechanical equipment.
|
||||
components:
|
||||
- type: Drink
|
||||
isOpen: false
|
||||
openSounds:
|
||||
collection: packetOpenSounds
|
||||
- type: Sprite
|
||||
sprite: Objects/Consumable/Drinks/lube-tube.rsi
|
||||
layers:
|
||||
- state: icon
|
||||
map: [ "enum.SolutionContainerLayers.Base" ]
|
||||
- state: fill1
|
||||
map: [ "enum.SolutionContainerLayers.Fill" ]
|
||||
visible: false
|
||||
- state: icon-front
|
||||
map: [ "enum.SolutionContainerLayers.Overlay" ]
|
||||
- type: Appearance
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
drink:
|
||||
maxVol: 30
|
||||
reagents:
|
||||
- ReagentId: SpaceLube
|
||||
Quantity: 30
|
||||
- type: SolutionContainerVisuals
|
||||
maxFillLevels: 6
|
||||
fillBaseName: fill
|
||||
- type: Lube
|
||||
|
||||
|
After Width: | Height: | Size: 717 B |
|
After Width: | Height: | Size: 718 B |
|
After Width: | Height: | Size: 717 B |
|
After Width: | Height: | Size: 717 B |
|
After Width: | Height: | Size: 718 B |
|
After Width: | Height: | Size: 680 B |
|
After Width: | Height: | Size: 712 B |
|
After Width: | Height: | Size: 713 B |
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"version": 1,
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"license": "CC-BY-NC-SA-4.0",
|
||||
"copyright": "Created by discord: brainfood#7460 / github: brainfood1183.",
|
||||
"states": [
|
||||
{
|
||||
"name": "icon"
|
||||
},
|
||||
{
|
||||
"name": "icon-front"
|
||||
},
|
||||
{
|
||||
"name": "fill1"
|
||||
},
|
||||
{
|
||||
"name": "fill2"
|
||||
},
|
||||
{
|
||||
"name": "fill3"
|
||||
},
|
||||
{
|
||||
"name": "fill4"
|
||||
},
|
||||
{
|
||||
"name": "fill5"
|
||||
},
|
||||
{
|
||||
"name": "fill6"
|
||||
}
|
||||
]
|
||||
}
|
||||